Move internationalization macros to one header
[geda-pcb/gde.git] / src / mymem.c
blob4118cf0730afa102434dfeff3f3e1eb08cb3c8b3
1 /* $Id$ */
3 /*
4 * COPYRIGHT
6 * PCB, interactive printed circuit board design
7 * Copyright (C) 1994,1995,1996 Thomas Nau
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 * Contact addresses for paper mail and Email:
24 * Thomas Nau, Schlehenweg 15, 88471 Baustetten, Germany
25 * Thomas.Nau@rz.uni-ulm.de
30 /* memory management functions
33 #ifdef HAVE_CONFIG_H
34 #include "config.h"
35 #endif
37 #include "global.h"
39 #include <memory.h>
41 #include "data.h"
42 #include "error.h"
43 #include "mymem.h"
44 #include "misc.h"
45 #include "rats.h"
46 #include "rtree.h"
48 #ifdef HAVE_LIBDMALLOC
49 #include <dmalloc.h>
50 #endif
52 RCSID ("$Id$");
54 /* ---------------------------------------------------------------------------
55 * local prototypes
57 static void DSRealloc (DynamicStringTypePtr, size_t);
59 /* ---------------------------------------------------------------------------
60 * get next slot for a rubberband connection, allocates memory if necessary
62 RubberbandTypePtr
63 GetRubberbandMemory (void)
65 RubberbandTypePtr ptr = Crosshair.AttachedObject.Rubberband;
67 /* realloc new memory if necessary and clear it */
68 if (Crosshair.AttachedObject.RubberbandN >=
69 Crosshair.AttachedObject.RubberbandMax)
71 Crosshair.AttachedObject.RubberbandMax += STEP_RUBBERBAND;
72 ptr = MyRealloc (ptr,
73 Crosshair.AttachedObject.RubberbandMax *
74 sizeof (RubberbandType), "GetRubberbandMemory()");
75 Crosshair.AttachedObject.Rubberband = ptr;
76 memset (ptr + Crosshair.AttachedObject.RubberbandN, 0,
77 STEP_RUBBERBAND * sizeof (RubberbandType));
79 return (ptr + Crosshair.AttachedObject.RubberbandN++);
82 void **
83 GetPointerMemory (PointerListTypePtr list)
85 void **ptr = list->Ptr;
87 /* realloc new memory if necessary and clear it */
88 if (list->PtrN >= list->PtrMax)
90 list->PtrMax = STEP_POINT + (2 * list->PtrMax);
91 ptr = MyRealloc (ptr, list->PtrMax * sizeof (void *),
92 "GetPointerMemory()");
93 list->Ptr = ptr;
94 memset (ptr + list->PtrN, 0,
95 (list->PtrMax - list->PtrN) * sizeof (void *));
97 return (ptr + list->PtrN++);
100 void
101 FreePointerListMemory (PointerListTypePtr list)
103 MYFREE (list->Ptr);
104 memset (list, 0, sizeof (PointerListType));
107 /* ---------------------------------------------------------------------------
108 * get next slot for a box, allocates memory if necessary
110 BoxTypePtr
111 GetBoxMemory (BoxListTypePtr Boxes)
113 BoxTypePtr box = Boxes->Box;
115 /* realloc new memory if necessary and clear it */
116 if (Boxes->BoxN >= Boxes->BoxMax)
118 Boxes->BoxMax = STEP_POINT + (2 * Boxes->BoxMax);
119 box = MyRealloc (box, Boxes->BoxMax * sizeof (BoxType),
120 "GetBoxMemory()");
121 Boxes->Box = box;
122 memset (box + Boxes->BoxN, 0,
123 (Boxes->BoxMax - Boxes->BoxN) * sizeof (BoxType));
125 return (box + Boxes->BoxN++);
129 /* ---------------------------------------------------------------------------
130 * get next slot for a connection, allocates memory if necessary
132 ConnectionTypePtr
133 GetConnectionMemory (NetTypePtr Net)
135 ConnectionTypePtr con = Net->Connection;
137 /* realloc new memory if necessary and clear it */
138 if (Net->ConnectionN >= Net->ConnectionMax)
140 Net->ConnectionMax += STEP_POINT;
141 con = MyRealloc (con, Net->ConnectionMax * sizeof (ConnectionType),
142 "GetConnectionMemory()");
143 Net->Connection = con;
144 memset (con + Net->ConnectionN, 0,
145 STEP_POINT * sizeof (ConnectionType));
147 return (con + Net->ConnectionN++);
150 /* ---------------------------------------------------------------------------
151 * get next slot for a subnet, allocates memory if necessary
153 NetTypePtr
154 GetNetMemory (NetListTypePtr Netlist)
156 NetTypePtr net = Netlist->Net;
158 /* realloc new memory if necessary and clear it */
159 if (Netlist->NetN >= Netlist->NetMax)
161 Netlist->NetMax += STEP_POINT;
162 net = MyRealloc (net, Netlist->NetMax * sizeof (NetType),
163 "GetNetMemory()");
164 Netlist->Net = net;
165 memset (net + Netlist->NetN, 0, STEP_POINT * sizeof (NetType));
167 return (net + Netlist->NetN++);
170 /* ---------------------------------------------------------------------------
171 * get next slot for a net list, allocates memory if necessary
173 NetListTypePtr
174 GetNetListMemory (NetListListTypePtr Netlistlist)
176 NetListTypePtr netlist = Netlistlist->NetList;
178 /* realloc new memory if necessary and clear it */
179 if (Netlistlist->NetListN >= Netlistlist->NetListMax)
181 Netlistlist->NetListMax += STEP_POINT;
182 netlist = MyRealloc
183 (netlist, Netlistlist->NetListMax * sizeof (NetListType),
184 "GetNetListMemory()");
185 Netlistlist->NetList = netlist;
186 memset (netlist + Netlistlist->NetListN, 0,
187 STEP_POINT * sizeof (NetListType));
189 return (netlist + Netlistlist->NetListN++);
192 /* ---------------------------------------------------------------------------
193 * get next slot for a pin, allocates memory if necessary
195 PinTypePtr
196 GetPinMemory (ElementTypePtr Element)
198 PinTypePtr pin = Element->Pin;
199 Boolean onBoard = False;
201 /* realloc new memory if necessary and clear it */
202 if (Element->PinN >= Element->PinMax)
204 if (PCB->Data->pin_tree)
206 PIN_LOOP (Element);
208 if (r_delete_entry (PCB->Data->pin_tree, (BoxType *) pin))
209 onBoard = True;
211 END_LOOP;
213 Element->PinMax += STEP_PIN;
214 pin = MyRealloc (pin, Element->PinMax * sizeof (PinType),
215 "GetPinMemory()");
216 Element->Pin = pin;
217 memset (pin + Element->PinN, 0, STEP_PIN * sizeof (PinType));
218 if (onBoard)
220 PIN_LOOP (Element);
222 r_insert_entry (PCB->Data->pin_tree, (BoxType *) pin, 0);
224 END_LOOP;
227 return (pin + Element->PinN++);
230 /* ---------------------------------------------------------------------------
231 * get next slot for a pad, allocates memory if necessary
233 PadTypePtr
234 GetPadMemory (ElementTypePtr Element)
236 PadTypePtr pad = Element->Pad;
237 Boolean onBoard = False;
239 /* realloc new memory if necessary and clear it */
240 if (Element->PadN >= Element->PadMax)
242 if (PCB->Data->pad_tree)
244 PAD_LOOP (Element);
246 if (r_delete_entry (PCB->Data->pad_tree, (BoxType *) pad))
247 onBoard = True;
249 END_LOOP;
251 Element->PadMax += STEP_PAD;
252 pad = MyRealloc (pad, Element->PadMax * sizeof (PadType),
253 "GetPadMemory()");
254 Element->Pad = pad;
255 memset (pad + Element->PadN, 0, STEP_PAD * sizeof (PadType));
256 if (onBoard)
258 PAD_LOOP (Element);
260 r_insert_entry (PCB->Data->pad_tree, (BoxType *) pad, 0);
262 END_LOOP;
265 return (pad + Element->PadN++);
268 /* ---------------------------------------------------------------------------
269 * get next slot for a via, allocates memory if necessary
271 PinTypePtr
272 GetViaMemory (DataTypePtr Data)
274 PinTypePtr via = Data->Via;
276 /* realloc new memory if necessary and clear it */
277 if (Data->ViaN >= Data->ViaMax)
279 Data->ViaMax += STEP_VIA;
280 if (Data->via_tree)
281 r_destroy_tree (&Data->via_tree);
282 via = MyRealloc (via, Data->ViaMax * sizeof (PinType),
283 "GetViaMemory()");
284 Data->Via = via;
285 memset (via + Data->ViaN, 0, STEP_VIA * sizeof (PinType));
286 Data->via_tree = r_create_tree (NULL, 0, 0);
287 VIA_LOOP (Data);
289 r_insert_entry (Data->via_tree, (BoxType *) via, 0);
291 END_LOOP;
293 return (via + Data->ViaN++);
296 /* ---------------------------------------------------------------------------
297 * get next slot for a Rat, allocates memory if necessary
299 RatTypePtr
300 GetRatMemory (DataTypePtr Data)
302 RatTypePtr rat = Data->Rat;
304 /* realloc new memory if necessary and clear it */
305 if (Data->RatN >= Data->RatMax)
307 Data->RatMax += STEP_RAT;
308 /* all of the pointers move, so rebuild the whole tree */
309 if (Data->rat_tree)
310 r_destroy_tree (&Data->rat_tree);
311 rat = MyRealloc (rat, Data->RatMax * sizeof (RatType),
312 "GetRatMemory()");
313 Data->Rat = rat;
314 memset (rat + Data->RatN, 0, STEP_RAT * sizeof (RatType));
315 Data->rat_tree = r_create_tree (NULL, 0, 0);
316 RAT_LOOP (Data);
318 r_insert_entry (Data->rat_tree, (BoxTypePtr) line, 0);
320 END_LOOP;
322 return (rat + Data->RatN++);
325 /* ---------------------------------------------------------------------------
326 * get next slot for a line, allocates memory if necessary
328 LineTypePtr
329 GetLineMemory (LayerTypePtr Layer)
331 LineTypePtr line = Layer->Line;
333 /* realloc new memory if necessary and clear it */
334 if (Layer->LineN >= Layer->LineMax)
336 Layer->LineMax += STEP_LINE;
337 /* all of the pointers move, so rebuild the whole tree */
338 if (Layer->line_tree)
339 r_destroy_tree (&Layer->line_tree);
340 line = MyRealloc (line, Layer->LineMax * sizeof (LineType),
341 "GetLineMemory()");
342 Layer->Line = line;
343 memset (line + Layer->LineN, 0, STEP_LINE * sizeof (LineType));
344 Layer->line_tree = r_create_tree (NULL, 0, 0);
345 LINE_LOOP (Layer);
347 r_insert_entry (Layer->line_tree, (BoxTypePtr) line, 0);
349 END_LOOP;
351 return (line + Layer->LineN++);
354 /* ---------------------------------------------------------------------------
355 * get next slot for an arc, allocates memory if necessary
357 ArcTypePtr
358 GetArcMemory (LayerTypePtr Layer)
360 ArcTypePtr arc = Layer->Arc;
362 /* realloc new memory if necessary and clear it */
363 if (Layer->ArcN >= Layer->ArcMax)
365 Layer->ArcMax += STEP_ARC;
366 if (Layer->arc_tree)
367 r_destroy_tree (&Layer->arc_tree);
368 arc = MyRealloc (arc, Layer->ArcMax * sizeof (ArcType),
369 "GetArcMemory()");
370 Layer->Arc = arc;
371 memset (arc + Layer->ArcN, 0, STEP_ARC * sizeof (ArcType));
372 Layer->arc_tree = r_create_tree (NULL, 0, 0);
373 ARC_LOOP (Layer);
375 r_insert_entry (Layer->arc_tree, (BoxTypePtr) arc, 0);
377 END_LOOP;
379 return (arc + Layer->ArcN++);
382 /* ---------------------------------------------------------------------------
383 * get next slot for a text object, allocates memory if necessary
385 TextTypePtr
386 GetTextMemory (LayerTypePtr Layer)
388 TextTypePtr text = Layer->Text;
390 /* realloc new memory if necessary and clear it */
391 if (Layer->TextN >= Layer->TextMax)
393 Layer->TextMax += STEP_TEXT;
394 if (Layer->text_tree)
395 r_destroy_tree (&Layer->text_tree);
396 text = MyRealloc (text, Layer->TextMax * sizeof (TextType),
397 "GetTextMemory()");
398 Layer->Text = text;
399 memset (text + Layer->TextN, 0, STEP_TEXT * sizeof (TextType));
400 Layer->text_tree = r_create_tree (NULL, 0, 0);
401 TEXT_LOOP (Layer);
403 r_insert_entry (Layer->text_tree, (BoxTypePtr) text, 0);
405 END_LOOP;
407 return (text + Layer->TextN++);
410 /* ---------------------------------------------------------------------------
411 * get next slot for a polygon object, allocates memory if necessary
413 PolygonTypePtr
414 GetPolygonMemory (LayerTypePtr Layer)
416 PolygonTypePtr polygon = Layer->Polygon;
418 /* realloc new memory if necessary and clear it */
419 if (Layer->PolygonN >= Layer->PolygonMax)
421 Layer->PolygonMax += STEP_POLYGON;
422 if (Layer->polygon_tree)
423 r_destroy_tree (&Layer->polygon_tree);
424 polygon = MyRealloc (polygon, Layer->PolygonMax * sizeof (PolygonType),
425 "GetPolygonMemory()");
426 Layer->Polygon = polygon;
427 memset (polygon + Layer->PolygonN, 0,
428 STEP_POLYGON * sizeof (PolygonType));
429 Layer->polygon_tree = r_create_tree (NULL, 0, 0);
430 POLYGON_LOOP (Layer);
432 r_insert_entry (Layer->polygon_tree, (BoxType *) polygon, 0);
434 END_LOOP;
436 return (polygon + Layer->PolygonN++);
439 /* ---------------------------------------------------------------------------
440 * gets the next slot for a point in a polygon struct, allocates memory
441 * if necessary
443 PointTypePtr
444 GetPointMemoryInPolygon (PolygonTypePtr Polygon)
446 PointTypePtr points = Polygon->Points;
448 /* realloc new memory if necessary and clear it */
449 if (Polygon->PointN >= Polygon->PointMax)
451 Polygon->PointMax += STEP_POLYGONPOINT;
452 points = MyRealloc (points, Polygon->PointMax * sizeof (PointType),
453 "GetPointMemoryInPolygon()");
454 Polygon->Points = points;
455 memset (points + Polygon->PointN, 0,
456 STEP_POLYGONPOINT * sizeof (PointType));
458 return (points + Polygon->PointN++);
461 /* ---------------------------------------------------------------------------
462 * get next slot for an element, allocates memory if necessary
464 ElementTypePtr
465 GetElementMemory (DataTypePtr Data)
467 ElementTypePtr element = Data->Element;
468 int i;
470 /* realloc new memory if necessary and clear it */
471 if (Data->ElementN >= Data->ElementMax)
473 Data->ElementMax += STEP_ELEMENT;
474 if (Data->element_tree)
475 r_destroy_tree (&Data->element_tree);
476 element = MyRealloc (element, Data->ElementMax * sizeof (ElementType),
477 "GetElementMemory()");
478 Data->Element = element;
479 memset (element + Data->ElementN, 0,
480 STEP_ELEMENT * sizeof (ElementType));
481 Data->element_tree = r_create_tree (NULL, 0, 0);
482 for (i = 0; i < MAX_ELEMENTNAMES; i++)
484 if (Data->name_tree[i])
485 r_destroy_tree (&Data->name_tree[i]);
486 Data->name_tree[i] = r_create_tree (NULL, 0, 0);
489 ELEMENT_LOOP (Data);
491 r_insert_entry (Data->element_tree, (BoxType *) element, 0);
492 PIN_LOOP (element);
494 pin->Element = element;
496 END_LOOP;
497 PAD_LOOP (element);
499 pad->Element = element;
501 END_LOOP;
502 ELEMENTTEXT_LOOP (element);
504 text->Element = element;
505 r_insert_entry (Data->name_tree[n], (BoxType *) text, 0);
507 END_LOOP;
509 END_LOOP;
511 return (element + Data->ElementN++);
514 /* ---------------------------------------------------------------------------
515 * get next slot for a library menu, allocates memory if necessary
517 LibraryMenuTypePtr
518 GetLibraryMenuMemory (LibraryTypePtr lib)
520 LibraryMenuTypePtr menu = lib->Menu;
522 /* realloc new memory if necessary and clear it */
523 if (lib->MenuN >= lib->MenuMax)
525 lib->MenuMax += STEP_LIBRARYMENU;
526 menu = MyRealloc (menu, lib->MenuMax * sizeof (LibraryMenuType),
527 "GetLibraryMenuMemory()");
528 lib->Menu = menu;
529 memset (menu + lib->MenuN, 0,
530 STEP_LIBRARYMENU * sizeof (LibraryMenuType));
532 return (menu + lib->MenuN++);
535 /* ---------------------------------------------------------------------------
536 * get next slot for a library entry, allocates memory if necessary
538 LibraryEntryTypePtr
539 GetLibraryEntryMemory (LibraryMenuTypePtr Menu)
541 LibraryEntryTypePtr entry = Menu->Entry;
543 /* realloc new memory if necessary and clear it */
544 if (Menu->EntryN >= Menu->EntryMax)
546 Menu->EntryMax += STEP_LIBRARYENTRY;
547 entry = MyRealloc (entry, Menu->EntryMax * sizeof (LibraryEntryType),
548 "GetLibraryEntryMemory()");
549 Menu->Entry = entry;
550 memset (entry + Menu->EntryN, 0,
551 STEP_LIBRARYENTRY * sizeof (LibraryEntryType));
553 return (entry + Menu->EntryN++);
556 /* ---------------------------------------------------------------------------
557 * get next slot for a DrillElement, allocates memory if necessary
559 ElementTypeHandle
560 GetDrillElementMemory (DrillTypePtr Drill)
562 ElementTypePtr *element;
564 element = Drill->Element;
566 /* realloc new memory if necessary and clear it */
567 if (Drill->ElementN >= Drill->ElementMax)
569 Drill->ElementMax += STEP_ELEMENT;
570 element =
571 MyRealloc (element, Drill->ElementMax * sizeof (ElementTypeHandle),
572 "GetDrillElementMemory()");
573 Drill->Element = element;
574 memset (element + Drill->ElementN, 0,
575 STEP_ELEMENT * sizeof (ElementTypeHandle));
577 return (element + Drill->ElementN++);
580 /* ---------------------------------------------------------------------------
581 * get next slot for a DrillPoint, allocates memory if necessary
583 PinTypeHandle
584 GetDrillPinMemory (DrillTypePtr Drill)
586 PinTypePtr *pin;
588 pin = Drill->Pin;
590 /* realloc new memory if necessary and clear it */
591 if (Drill->PinN >= Drill->PinMax)
593 Drill->PinMax += STEP_POINT;
594 pin = MyRealloc (pin, Drill->PinMax * sizeof (PinTypeHandle),
595 "GetDrillPinMemory()");
596 Drill->Pin = pin;
597 memset (pin + Drill->PinN, 0, STEP_POINT * sizeof (PinTypeHandle));
599 return (pin + Drill->PinN++);
602 /* ---------------------------------------------------------------------------
603 * get next slot for a Drill, allocates memory if necessary
605 DrillTypePtr
606 GetDrillInfoDrillMemory (DrillInfoTypePtr DrillInfo)
608 DrillTypePtr drill = DrillInfo->Drill;
610 /* realloc new memory if necessary and clear it */
611 if (DrillInfo->DrillN >= DrillInfo->DrillMax)
613 DrillInfo->DrillMax += STEP_DRILL;
614 drill = MyRealloc (drill, DrillInfo->DrillMax * sizeof (DrillType),
615 "GetDrillInfoDrillMemory()");
616 DrillInfo->Drill = drill;
617 memset (drill + DrillInfo->DrillN, 0, STEP_DRILL * sizeof (DrillType));
619 return (drill + DrillInfo->DrillN++);
622 /* ---------------------------------------------------------------------------
623 * allocates memory with error handling
625 void *
626 MyCalloc (size_t Number, size_t Size, const char *Text)
628 void *p;
630 #ifdef MEM_DEBUG
631 fprintf (stderr, "MyCalloc %d by %d from %s ", Number, Size, Text);
632 #endif
633 /* InitComponentLookup() at least can ask for zero here, so return something
634 | that can be freed.
636 if (Number == 0)
637 Number = 1;
638 if (Size == 0)
639 Size = 1;
641 if ((p = calloc (Number, Size)) == NULL)
642 MyFatal ("out of memory during malloc() in '%s'()\n",
643 (Text ? Text : "(unknown)"));
644 #ifdef MEM_DEBUG
645 fprintf (stderr, "returned 0x%x\n", p);
646 #endif
647 return (p);
650 void *
651 MyMalloc (size_t Size, const char *Text)
653 void *p;
655 #ifdef MEM_DEBUG
656 fprintf (stderr, "MyMalloc %d by %d from %s ", Number, Size, Text);
657 #endif
658 /* avoid malloc of 0 bytes */
659 if (Size == 0)
660 Size = 1;
661 if ((p = malloc (Size)) == NULL)
662 MyFatal ("out of memory during malloc() in '%s'()\n",
663 (Text ? Text : "(unknown)"));
664 #ifdef MEM_DEBUG
665 fprintf (stderr, "returned 0x%x\n", p);
666 #endif
667 return (p);
670 /* ---------------------------------------------------------------------------
671 * allocates memory with error handling
672 * this is a save version because BSD doesn't support the
673 * handling of NULL pointers in realloc()
675 void *
676 MyRealloc (void *Ptr, size_t Size, const char *Text)
678 void *p;
680 #ifdef MEM_DEBUG
681 fprintf (stderr, "0x%x Realloc to %d from %s ", Ptr, Size, Text);
682 #endif
683 if (Size == 0)
684 Size = 1;
685 p = Ptr ? realloc (Ptr, Size) : malloc (Size);
686 if (!p)
687 MyFatal ("out of memory during realloc() in '%s'()\n",
688 (Text ? Text : "(unknown)"));
689 #ifdef MEM_DEBUG
690 fprintf (stderr, "returned 0x%x\n", p);
691 #endif
692 return (p);
695 /* ---------------------------------------------------------------------------
696 * allocates memory for a new string, does some error processing
698 char *
699 MyStrdup (char *S, const char *Text)
701 char *p = NULL;
703 /* bug-fix by Ulrich Pegelow (ulrpeg@bigcomm.gun.de) */
704 if (S && ((p = strdup (S)) == NULL))
705 MyFatal ("out of memory during g_strdup() in '%s'\n",
706 (Text ? Text : "(unknown)"));
707 #ifdef MEM_DEBUG
708 fprintf (stderr, "g_strdup returning 0x%x\n", p);
709 #endif
710 return (p);
713 /* ---------------------------------------------------------------------------
714 * frees memory and sets pointer to NULL
715 * too troublesome for modern C compiler,
716 * warning: dereferencing type-punned pointer will break strict-aliasing rules
717 * Use MYFREE() macro instead
719 #if 0
720 void
721 MyFree (char **Ptr)
723 SaveFree (*Ptr);
724 *Ptr = NULL;
726 #endif
728 /* ---------------------------------------------------------------------------
729 * frees memory used by a polygon
731 void
732 FreePolygonMemory (PolygonTypePtr Polygon)
734 if (Polygon)
736 MYFREE (Polygon->Points);
737 if (Polygon->Clipped)
738 poly_Free (&Polygon->Clipped);
739 poly_FreeContours (&Polygon->NoHoles);
740 memset (Polygon, 0, sizeof (PolygonType));
744 /* ---------------------------------------------------------------------------
745 * frees memory used by a box list
747 void
748 FreeBoxListMemory (BoxListTypePtr Boxlist)
750 if (Boxlist)
752 MYFREE (Boxlist->Box);
753 memset (Boxlist, 0, sizeof (BoxListType));
757 /* ---------------------------------------------------------------------------
758 * frees memory used by a net
760 void
761 FreeNetListMemory (NetListTypePtr Netlist)
763 if (Netlist)
765 NET_LOOP (Netlist);
767 FreeNetMemory (net);
769 END_LOOP;
770 MYFREE (Netlist->Net);
771 memset (Netlist, 0, sizeof (NetListType));
775 /* ---------------------------------------------------------------------------
776 * frees memory used by a net list
778 void
779 FreeNetListListMemory (NetListListTypePtr Netlistlist)
781 if (Netlistlist)
783 NETLIST_LOOP (Netlistlist);
785 FreeNetListMemory (netlist);
787 END_LOOP;
788 MYFREE (Netlistlist->NetList);
789 memset (Netlistlist, 0, sizeof (NetListListType));
793 /* ---------------------------------------------------------------------------
794 * frees memory used by a subnet
796 void
797 FreeNetMemory (NetTypePtr Net)
799 if (Net)
801 MYFREE (Net->Connection);
802 memset (Net, 0, sizeof (NetType));
805 /* ---------------------------------------------------------------------------
806 * frees memory used by an attribute list
808 static void
809 FreeAttributeListMemory (AttributeListTypePtr list)
811 int i;
813 for (i = 0; i < list->Number; i++)
815 SaveFree (list->List[i].name);
816 SaveFree (list->List[i].value);
818 SaveFree (list->List);
819 list->List = NULL;
820 list->Max = 0;
823 /* ---------------------------------------------------------------------------
824 * frees memory used by an element
826 void
827 FreeElementMemory (ElementTypePtr Element)
829 if (Element)
831 ELEMENTNAME_LOOP (Element);
833 MYFREE (textstring);
835 END_LOOP;
836 PIN_LOOP (Element);
838 MYFREE (pin->Name);
839 MYFREE (pin->Number);
841 END_LOOP;
842 PAD_LOOP (Element);
844 MYFREE (pad->Name);
845 MYFREE (pad->Number);
847 END_LOOP;
848 MYFREE (Element->Pin);
849 MYFREE (Element->Pad);
850 MYFREE (Element->Line);
851 MYFREE (Element->Arc);
852 FreeAttributeListMemory (&Element->Attributes);
853 memset (Element, 0, sizeof (ElementType));
857 /* ---------------------------------------------------------------------------
858 * free memory used by PCB
860 void
861 FreePCBMemory (PCBTypePtr PCBPtr)
863 int i;
865 if (PCBPtr)
867 MYFREE (PCBPtr->Name);
868 MYFREE (PCBPtr->Filename);
869 MYFREE (PCBPtr->PrintFilename);
870 if (PCBPtr->Data)
871 FreeDataMemory (PCBPtr->Data);
872 MYFREE (PCBPtr->Data);
873 /* release font symbols */
874 for (i = 0; i <= MAX_FONTPOSITION; i++)
875 MYFREE (PCBPtr->Font.Symbol[i].Line);
876 FreeLibraryMemory (&PCBPtr->NetlistLib);
877 FreeAttributeListMemory (&PCBPtr->Attributes);
878 /* clear struct */
879 memset (PCBPtr, 0, sizeof (PCBType));
881 else
883 fprintf (stderr, "Warning: Tried to FreePCBMemory(null)\n");
887 /* ---------------------------------------------------------------------------
888 * free memory used by data struct
890 void
891 FreeDataMemory (DataTypePtr Data)
893 LayerTypePtr layer;
894 int i;
896 if (Data)
898 VIA_LOOP (Data);
900 MYFREE (via->Name);
902 END_LOOP;
903 ELEMENT_LOOP (Data);
905 FreeElementMemory (element);
907 END_LOOP;
909 for (layer = Data->Layer, i = 0; i < MAX_LAYER + 2; layer++, i++)
911 FreeAttributeListMemory (&layer->Attributes);
912 TEXT_LOOP (layer);
914 MYFREE (text->TextString);
916 END_LOOP;
917 if (layer->Name)
918 MYFREE (layer->Name);
919 LINE_LOOP (layer);
921 if (line->Number)
922 MYFREE (line->Number);
924 END_LOOP;
925 MYFREE (layer->Line);
926 MYFREE (layer->Arc);
927 MYFREE (layer->Text);
928 POLYGON_LOOP (layer);
930 FreePolygonMemory (polygon);
932 END_LOOP;
933 MYFREE (layer->Polygon);
934 if (layer->line_tree)
935 r_destroy_tree (&layer->line_tree);
936 if (layer->arc_tree)
937 r_destroy_tree (&layer->arc_tree);
938 if (layer->text_tree)
939 r_destroy_tree (&layer->text_tree);
940 if (layer->polygon_tree)
941 r_destroy_tree (&layer->polygon_tree);
944 if (Data->element_tree)
945 r_destroy_tree (&Data->element_tree);
946 for (i = 0; i < MAX_ELEMENTNAMES; i++)
947 if (Data->name_tree[i])
948 r_destroy_tree (&Data->name_tree[i]);
949 if (Data->via_tree)
950 r_destroy_tree (&Data->via_tree);
951 if (Data->pin_tree)
952 r_destroy_tree (&Data->pin_tree);
953 if (Data->pad_tree)
954 r_destroy_tree (&Data->pad_tree);
955 if (Data->rat_tree)
956 r_destroy_tree (&Data->rat_tree);
957 /* clear struct */
958 memset (Data, 0, sizeof (DataType));
960 else
962 fprintf (stderr, "Warning: Tried to FreeDataMemory(null)\n");
966 /* ---------------------------------------------------------------------------
967 * releases the memory that's allocated by the library
969 void
970 FreeLibraryMemory (LibraryTypePtr lib)
972 MENU_LOOP (lib);
974 ENTRY_LOOP (menu);
976 SaveFree ((void *) entry->AllocatedMemory);
977 SaveFree ((void *) entry->ListEntry);
979 END_LOOP;
980 SaveFree ((void *) menu->Entry);
981 SaveFree ((void *) menu->Name);
983 END_LOOP;
984 SaveFree ((void *) lib->Menu);
986 /* clear struct */
987 memset (lib, 0, sizeof (LibraryType));
990 /* ---------------------------------------------------------------------------
991 * a 'save' free routine which first does a quick check if the pointer
992 * is zero. The routine isn't implemented as a macro to make additional
993 * safety features easier to implement
995 void
996 SaveFree (void *Ptr)
998 #ifdef MEM_DEBUG
999 fprintf (stderr, "Freeing 0x%x\n", Ptr);
1000 #endif
1001 if (Ptr)
1002 free (Ptr);
1005 /* ---------------------------------------------------------------------------
1006 * reallocates memory for a dynamic length string if necessary
1008 static void
1009 DSRealloc (DynamicStringTypePtr Ptr, size_t Length)
1011 int input_null = (Ptr->Data == NULL);
1012 if (input_null || Length >= Ptr->MaxLength)
1014 Ptr->MaxLength = Length + 512;
1015 Ptr->Data = MyRealloc (Ptr->Data, Ptr->MaxLength, "ReallocDS()");
1016 if (input_null)
1017 Ptr->Data[0] = '\0';
1021 /* ---------------------------------------------------------------------------
1022 * adds one character to a dynamic string
1024 void
1025 DSAddCharacter (DynamicStringTypePtr Ptr, char Char)
1027 size_t position = Ptr->Data ? strlen (Ptr->Data) : 0;
1029 DSRealloc (Ptr, position + 1);
1030 Ptr->Data[position++] = Char;
1031 Ptr->Data[position] = '\0';
1034 /* ---------------------------------------------------------------------------
1035 * add a string to a dynamic string
1037 void
1038 DSAddString (DynamicStringTypePtr Ptr, const char *S)
1040 size_t position = Ptr->Data ? strlen (Ptr->Data) : 0;
1042 if (S && *S)
1044 DSRealloc (Ptr, position + 1 + strlen (S));
1045 strcat (&Ptr->Data[position], S);
1049 /* ----------------------------------------------------------------------
1050 * clears a dynamic string
1052 void
1053 DSClearString (DynamicStringTypePtr Ptr)
1055 if (Ptr->Data)
1056 Ptr->Data[0] = '\0';
1059 /* ---------------------------------------------------------------------------
1060 * strips leading and trailing blanks from the passed string and
1061 * returns a pointer to the new 'duped' one or NULL if the old one
1062 * holds only white space characters
1064 char *
1065 StripWhiteSpaceAndDup (char *S)
1067 char *p1, *p2;
1068 size_t length;
1070 if (!S || !*S)
1071 return (NULL);
1073 /* strip leading blanks */
1074 for (p1 = S; *p1 && isspace ((int) *p1); p1++);
1076 /* strip trailing blanks and get string length */
1077 length = strlen (p1);
1078 for (p2 = p1 + length - 1; length && isspace ((int) *p2); p2--, length--);
1080 /* string is not empty -> allocate memory */
1081 if (length)
1083 p2 = MyRealloc (NULL, length + 1, "StripWhiteSpace()");
1084 strncpy (p2, p1, length);
1085 *(p2 + length) = '\0';
1086 return (p2);
1088 else
1089 return (NULL);