pcb 4.1.1
An interactive printed circuit board layout editor.
|
00001 00035 #ifdef HAVE_CONFIG_H 00036 #include "config.h" 00037 #endif 00038 00039 #include "global.h" 00040 00041 #include <memory.h> 00042 00043 #include "data.h" 00044 #include "error.h" 00045 #include "mymem.h" 00046 #include "misc.h" 00047 #include "rats.h" 00048 #include "rtree.h" 00049 00050 #ifdef HAVE_LIBDMALLOC 00051 #include <dmalloc.h> 00052 #endif 00053 00054 /* --------------------------------------------------------------------------- 00055 * local prototypes 00056 */ 00057 static void DSRealloc (DynamicStringType *, size_t); 00058 00059 00060 /* This API is quite new, provide a version here */ 00061 #if !GLIB_CHECK_VERSION (2, 28, 0) 00062 static void 00063 g_list_free_full (GList *list, GDestroyNotify free_func) 00064 { 00065 g_list_foreach (list, (GFunc) free_func, NULL); 00066 g_list_free (list); 00067 } 00068 #endif 00069 00075 RubberbandType * 00076 GetRubberbandMemory (void) 00077 { 00078 RubberbandType *ptr = Crosshair.AttachedObject.Rubberband; 00079 00080 /* realloc new memory if necessary and clear it */ 00081 if (Crosshair.AttachedObject.RubberbandN >= 00082 Crosshair.AttachedObject.RubberbandMax) 00083 { 00084 Crosshair.AttachedObject.RubberbandMax += STEP_RUBBERBAND; 00085 ptr = (RubberbandType *)realloc (ptr, Crosshair.AttachedObject.RubberbandMax * 00086 sizeof (RubberbandType)); 00087 Crosshair.AttachedObject.Rubberband = ptr; 00088 memset (ptr + Crosshair.AttachedObject.RubberbandN, 0, 00089 STEP_RUBBERBAND * sizeof (RubberbandType)); 00090 } 00091 return (ptr + Crosshair.AttachedObject.RubberbandN++); 00092 } 00093 00094 void ** 00095 GetPointerMemory (PointerListType *list) 00096 { 00097 void **ptr = list->Ptr; 00098 00099 /* realloc new memory if necessary and clear it */ 00100 if (list->PtrN >= list->PtrMax) 00101 { 00102 list->PtrMax = STEP_POINT + (2 * list->PtrMax); 00103 ptr = (void **)realloc (ptr, list->PtrMax * sizeof (void *)); 00104 list->Ptr = ptr; 00105 memset (ptr + list->PtrN, 0, 00106 (list->PtrMax - list->PtrN) * sizeof (void *)); 00107 } 00108 return (ptr + list->PtrN++); 00109 } 00110 00111 void 00112 FreePointerListMemory (PointerListType *list) 00113 { 00114 free (list->Ptr); 00115 memset (list, 0, sizeof (PointerListType)); 00116 } 00117 00123 BoxType * 00124 GetBoxMemory (BoxListType *Boxes) 00125 { 00126 BoxType *box = Boxes->Box; 00127 00128 /* realloc new memory if necessary and clear it */ 00129 if (Boxes->BoxN >= Boxes->BoxMax) 00130 { 00131 Boxes->BoxMax = STEP_POINT + (2 * Boxes->BoxMax); 00132 box = (BoxType *)realloc (box, Boxes->BoxMax * sizeof (BoxType)); 00133 Boxes->Box = box; 00134 memset (box + Boxes->BoxN, 0, 00135 (Boxes->BoxMax - Boxes->BoxN) * sizeof (BoxType)); 00136 } 00137 return (box + Boxes->BoxN++); 00138 } 00139 00140 00146 ConnectionType * 00147 GetConnectionMemory (NetType *Net) 00148 { 00149 ConnectionType *con = Net->Connection; 00150 00151 /* realloc new memory if necessary and clear it */ 00152 if (Net->ConnectionN >= Net->ConnectionMax) 00153 { 00154 Net->ConnectionMax += STEP_POINT; 00155 con = (ConnectionType *)realloc (con, Net->ConnectionMax * sizeof (ConnectionType)); 00156 Net->Connection = con; 00157 memset (con + Net->ConnectionN, 0, 00158 STEP_POINT * sizeof (ConnectionType)); 00159 } 00160 return (con + Net->ConnectionN++); 00161 } 00162 00168 NetType * 00169 GetNetMemory (NetListType *Netlist) 00170 { 00171 NetType *net = Netlist->Net; 00172 00173 /* realloc new memory if necessary and clear it */ 00174 if (Netlist->NetN >= Netlist->NetMax) 00175 { 00176 Netlist->NetMax += STEP_POINT; 00177 net = (NetType *)realloc (net, Netlist->NetMax * sizeof (NetType)); 00178 Netlist->Net = net; 00179 memset (net + Netlist->NetN, 0, STEP_POINT * sizeof (NetType)); 00180 } 00181 return (net + Netlist->NetN++); 00182 } 00183 00189 NetListType * 00190 GetNetListMemory (NetListListType *Netlistlist) 00191 { 00192 NetListType *netlist = Netlistlist->NetList; 00193 00194 /* realloc new memory if necessary and clear it */ 00195 if (Netlistlist->NetListN >= Netlistlist->NetListMax) 00196 { 00197 Netlistlist->NetListMax += STEP_POINT; 00198 netlist = (NetListType *)realloc (netlist, 00199 Netlistlist->NetListMax * sizeof (NetListType)); 00200 Netlistlist->NetList = netlist; 00201 memset (netlist + Netlistlist->NetListN, 0, 00202 STEP_POINT * sizeof (NetListType)); 00203 } 00204 return (netlist + Netlistlist->NetListN++); 00205 } 00206 00212 PinType * 00213 GetPinMemory (ElementType *element) 00214 { 00215 PinType *new_obj; 00216 00217 new_obj = g_slice_new0 (PinType); 00218 element->Pin = g_list_append (element->Pin, new_obj); 00219 element->PinN ++; 00220 00221 return new_obj; 00222 } 00223 00224 static void 00225 FreePin (PinType *data) 00226 { 00227 g_slice_free (PinType, data); 00228 } 00229 00235 PadType * 00236 GetPadMemory (ElementType *element) 00237 { 00238 PadType *new_obj; 00239 00240 new_obj = g_slice_new0 (PadType); 00241 element->Pad = g_list_append (element->Pad, new_obj); 00242 element->PadN ++; 00243 00244 return new_obj; 00245 } 00246 00247 static void 00248 FreePad (PadType *data) 00249 { 00250 g_slice_free (PadType, data); 00251 } 00252 00258 PinType * 00259 GetViaMemory (DataType *data) 00260 { 00261 PinType *new_obj; 00262 00263 new_obj = g_slice_new0 (PinType); 00264 data->Via = g_list_append (data->Via, new_obj); 00265 data->ViaN ++; 00266 00267 return new_obj; 00268 } 00269 00270 static void 00271 FreeVia (PinType *data) 00272 { 00273 g_slice_free (PinType, data); 00274 } 00275 00281 RatType * 00282 GetRatMemory (DataType *data) 00283 { 00284 RatType *new_obj; 00285 00286 new_obj = g_slice_new0 (RatType); 00287 data->Rat = g_list_append (data->Rat, new_obj); 00288 data->RatN ++; 00289 00290 return new_obj; 00291 } 00292 00293 static void 00294 FreeRat (RatType *data) 00295 { 00296 g_slice_free (RatType, data); 00297 } 00298 00304 LineType * 00305 GetLineMemory (LayerType *layer) 00306 { 00307 LineType *new_obj; 00308 00309 new_obj = g_slice_new0 (LineType); 00310 layer->Line = g_list_append (layer->Line, new_obj); 00311 layer->LineN ++; 00312 00313 return new_obj; 00314 } 00315 00316 static void 00317 FreeLine (LineType *data) 00318 { 00319 g_slice_free (LineType, data); 00320 } 00321 00327 ArcType * 00328 GetArcMemory (LayerType *layer) 00329 { 00330 ArcType *new_obj; 00331 00332 new_obj = g_slice_new0 (ArcType); 00333 layer->Arc = g_list_append (layer->Arc, new_obj); 00334 layer->ArcN ++; 00335 00336 return new_obj; 00337 } 00338 00339 static void 00340 FreeArc (ArcType *data) 00341 { 00342 g_slice_free (ArcType, data); 00343 } 00344 00350 TextType * 00351 GetTextMemory (LayerType *layer) 00352 { 00353 TextType *new_obj; 00354 00355 new_obj = g_slice_new0 (TextType); 00356 layer->Text = g_list_append (layer->Text, new_obj); 00357 layer->TextN ++; 00358 00359 return new_obj; 00360 } 00361 00362 static void 00363 FreeText (TextType *data) 00364 { 00365 g_slice_free (TextType, data); 00366 } 00367 00373 PolygonType * 00374 GetPolygonMemory (LayerType *layer) 00375 { 00376 PolygonType *new_obj; 00377 00378 new_obj = g_slice_new0 (PolygonType); 00379 layer->Polygon = g_list_append (layer->Polygon, new_obj); 00380 layer->PolygonN ++; 00381 00382 return new_obj; 00383 } 00384 00385 static void 00386 FreePolygon (PolygonType *data) 00387 { 00388 g_slice_free (PolygonType, data); 00389 } 00390 00396 PointType * 00397 GetPointMemoryInPolygon (PolygonType *Polygon) 00398 { 00399 PointType *points = Polygon->Points; 00400 00401 /* realloc new memory if necessary and clear it */ 00402 if (Polygon->PointN >= Polygon->PointMax) 00403 { 00404 Polygon->PointMax += STEP_POLYGONPOINT; 00405 points = (PointType *)realloc (points, Polygon->PointMax * sizeof (PointType)); 00406 Polygon->Points = points; 00407 memset (points + Polygon->PointN, 0, 00408 STEP_POLYGONPOINT * sizeof (PointType)); 00409 } 00410 return (points + Polygon->PointN++); 00411 } 00412 00418 Cardinal * 00419 GetHoleIndexMemoryInPolygon (PolygonType *Polygon) 00420 { 00421 Cardinal *holeindex = Polygon->HoleIndex; 00422 00423 /* realloc new memory if necessary and clear it */ 00424 if (Polygon->HoleIndexN >= Polygon->HoleIndexMax) 00425 { 00426 Polygon->HoleIndexMax += STEP_POLYGONHOLEINDEX; 00427 holeindex = (Cardinal *)realloc (holeindex, Polygon->HoleIndexMax * sizeof (int)); 00428 Polygon->HoleIndex = holeindex; 00429 memset (holeindex + Polygon->HoleIndexN, 0, 00430 STEP_POLYGONHOLEINDEX * sizeof (int)); 00431 } 00432 return (holeindex + Polygon->HoleIndexN++); 00433 } 00434 00440 ElementType * 00441 GetElementMemory (DataType *data) 00442 { 00443 ElementType *new_obj; 00444 00445 new_obj = g_slice_new0 (ElementType); 00446 00447 if (data != NULL) 00448 { 00449 data->Element = g_list_append (data->Element, new_obj); 00450 data->ElementN ++; 00451 } 00452 00453 return new_obj; 00454 } 00455 00456 static void 00457 FreeElement (ElementType *data) 00458 { 00459 g_slice_free (ElementType, data); 00460 } 00461 00467 LibraryMenuType * 00468 GetLibraryMenuMemory (LibraryType *lib) 00469 { 00470 LibraryMenuType *menu = lib->Menu; 00471 00472 /* realloc new memory if necessary and clear it */ 00473 if (lib->MenuN >= lib->MenuMax) 00474 { 00475 lib->MenuMax += STEP_LIBRARYMENU; 00476 menu = (LibraryMenuType *)realloc (menu, lib->MenuMax * sizeof (LibraryMenuType)); 00477 lib->Menu = menu; 00478 memset (menu + lib->MenuN, 0, 00479 STEP_LIBRARYMENU * sizeof (LibraryMenuType)); 00480 } 00481 return (menu + lib->MenuN++); 00482 } 00483 00489 LibraryEntryType * 00490 GetLibraryEntryMemory (LibraryMenuType *Menu) 00491 { 00492 LibraryEntryType *entry = Menu->Entry; 00493 00494 /* realloc new memory if necessary and clear it */ 00495 if (Menu->EntryN >= Menu->EntryMax) 00496 { 00497 Menu->EntryMax += STEP_LIBRARYENTRY; 00498 entry = (LibraryEntryType *)realloc (entry, Menu->EntryMax * sizeof (LibraryEntryType)); 00499 Menu->Entry = entry; 00500 memset (entry + Menu->EntryN, 0, 00501 STEP_LIBRARYENTRY * sizeof (LibraryEntryType)); 00502 } 00503 return (entry + Menu->EntryN++); 00504 } 00505 00511 ElementType ** 00512 GetDrillElementMemory (DrillType *Drill) 00513 { 00514 ElementType **element; 00515 00516 element = Drill->Element; 00517 00518 /* realloc new memory if necessary and clear it */ 00519 if (Drill->ElementN >= Drill->ElementMax) 00520 { 00521 Drill->ElementMax += STEP_ELEMENT; 00522 element = (ElementType **)realloc (element, 00523 Drill->ElementMax * sizeof (ElementType *)); 00524 Drill->Element = element; 00525 memset (element + Drill->ElementN, 0, 00526 STEP_ELEMENT * sizeof (ElementType *)); 00527 } 00528 return (element + Drill->ElementN++); 00529 } 00530 00536 PinType ** 00537 GetDrillPinMemory (DrillType *Drill) 00538 { 00539 PinType **pin; 00540 00541 pin = Drill->Pin; 00542 00543 /* realloc new memory if necessary and clear it */ 00544 if (Drill->PinN >= Drill->PinMax) 00545 { 00546 Drill->PinMax += STEP_POINT; 00547 pin = (PinType **)realloc (pin, Drill->PinMax * sizeof (PinType *)); 00548 Drill->Pin = pin; 00549 memset (pin + Drill->PinN, 0, STEP_POINT * sizeof (PinType *)); 00550 } 00551 return (pin + Drill->PinN++); 00552 } 00553 00559 DrillType * 00560 GetDrillInfoDrillMemory (DrillInfoType *DrillInfo) 00561 { 00562 DrillType *drill = DrillInfo->Drill; 00563 00564 /* realloc new memory if necessary and clear it */ 00565 if (DrillInfo->DrillN >= DrillInfo->DrillMax) 00566 { 00567 DrillInfo->DrillMax += STEP_DRILL; 00568 drill = (DrillType *)realloc (drill, DrillInfo->DrillMax * sizeof (DrillType)); 00569 DrillInfo->Drill = drill; 00570 memset (drill + DrillInfo->DrillN, 0, STEP_DRILL * sizeof (DrillType)); 00571 } 00572 return (drill + DrillInfo->DrillN++); 00573 } 00574 00578 void 00579 FreePolygonMemory (PolygonType *polygon) 00580 { 00581 if (polygon == NULL) 00582 return; 00583 00584 free (polygon->Points); 00585 free (polygon->HoleIndex); 00586 00587 if (polygon->Clipped) 00588 poly_Free (&polygon->Clipped); 00589 poly_FreeContours (&polygon->NoHoles); 00590 00591 memset (polygon, 0, sizeof (PolygonType)); 00592 } 00593 00597 void 00598 FreeBoxListMemory (BoxListType *Boxlist) 00599 { 00600 if (Boxlist) 00601 { 00602 free (Boxlist->Box); 00603 memset (Boxlist, 0, sizeof (BoxListType)); 00604 } 00605 } 00606 00610 void 00611 FreeNetListMemory (NetListType *Netlist) 00612 { 00613 if (Netlist) 00614 { 00615 NET_LOOP (Netlist); 00616 { 00617 FreeNetMemory (net); 00618 } 00619 END_LOOP; 00620 free (Netlist->Net); 00621 memset (Netlist, 0, sizeof (NetListType)); 00622 } 00623 } 00624 00628 void 00629 FreeNetListListMemory (NetListListType *Netlistlist) 00630 { 00631 if (Netlistlist) 00632 { 00633 NETLIST_LOOP (Netlistlist); 00634 { 00635 FreeNetListMemory (netlist); 00636 } 00637 END_LOOP; 00638 free (Netlistlist->NetList); 00639 memset (Netlistlist, 0, sizeof (NetListListType)); 00640 } 00641 } 00642 00646 void 00647 FreeNetMemory (NetType *Net) 00648 { 00649 if (Net) 00650 { 00651 free (Net->Connection); 00652 memset (Net, 0, sizeof (NetType)); 00653 } 00654 } 00658 static void 00659 FreeAttributeListMemory (AttributeListType *list) 00660 { 00661 int i; 00662 00663 for (i = 0; i < list->Number; i++) 00664 { 00665 free (list->List[i].name); 00666 free (list->List[i].value); 00667 } 00668 free (list->List); 00669 list->List = NULL; 00670 list->Max = 0; 00671 } 00672 00676 void 00677 FreeElementMemory (ElementType *element) 00678 { 00679 if (element == NULL) 00680 return; 00681 00682 ELEMENTNAME_LOOP (element); 00683 { 00684 free (textstring); 00685 } 00686 END_LOOP; 00687 PIN_LOOP (element); 00688 { 00689 free (pin->Name); 00690 free (pin->Number); 00691 } 00692 END_LOOP; 00693 PAD_LOOP (element); 00694 { 00695 free (pad->Name); 00696 free (pad->Number); 00697 } 00698 END_LOOP; 00699 00700 g_list_free_full (element->Pin, (GDestroyNotify)FreePin); 00701 g_list_free_full (element->Pad, (GDestroyNotify)FreePad); 00702 g_list_free_full (element->Line, (GDestroyNotify)FreeLine); 00703 g_list_free_full (element->Arc, (GDestroyNotify)FreeArc); 00704 00705 FreeAttributeListMemory (&element->Attributes); 00706 memset (element, 0, sizeof (ElementType)); 00707 } 00708 00712 void 00713 FreePCBMemory (PCBType *pcb) 00714 { 00715 int i; 00716 00717 if (pcb == NULL) 00718 return; 00719 00720 free (pcb->Name); 00721 free (pcb->Filename); 00722 free (pcb->PrintFilename); 00723 FreeDataMemory (pcb->Data); 00724 free (pcb->Data); 00725 /* release font symbols */ 00726 for (i = 0; i <= MAX_FONTPOSITION; i++) 00727 free (pcb->Font.Symbol[i].Line); 00728 FreeLibraryMemory (&pcb->NetlistLib); 00729 NetlistChanged (0); 00730 FreeAttributeListMemory (&pcb->Attributes); 00731 /* clear struct */ 00732 memset (pcb, 0, sizeof (PCBType)); 00733 } 00734 00738 void 00739 FreeDataMemory (DataType *data) 00740 { 00741 LayerType *layer; 00742 int i; 00743 00744 if (data == NULL) 00745 return; 00746 00747 VIA_LOOP (data); 00748 { 00749 free (via->Name); 00750 } 00751 END_LOOP; 00752 g_list_free_full (data->Via, (GDestroyNotify)FreeVia); 00753 ELEMENT_LOOP (data); 00754 { 00755 FreeElementMemory (element); 00756 } 00757 END_LOOP; 00758 g_list_free_full (data->Element, (GDestroyNotify)FreeElement); 00759 g_list_free_full (data->Rat, (GDestroyNotify)FreeRat); 00760 00761 for (layer = data->Layer, i = 0; i < MAX_ALL_LAYER; layer++, i++) 00762 { 00763 FreeAttributeListMemory (&layer->Attributes); 00764 TEXT_LOOP (layer); 00765 { 00766 free (text->TextString); 00767 } 00768 END_LOOP; 00769 if (layer->Name) 00770 free (layer->Name); 00771 LINE_LOOP (layer); 00772 { 00773 if (line->Number) 00774 free (line->Number); 00775 } 00776 END_LOOP; 00777 g_list_free_full (layer->Line, (GDestroyNotify)FreeLine); 00778 g_list_free_full (layer->Arc, (GDestroyNotify)FreeArc); 00779 g_list_free_full (layer->Text, (GDestroyNotify)FreeText); 00780 POLYGON_LOOP (layer); 00781 { 00782 FreePolygonMemory (polygon); 00783 } 00784 END_LOOP; 00785 g_list_free_full (layer->Polygon, (GDestroyNotify)FreePolygon); 00786 if (layer->line_tree) 00787 r_destroy_tree (&layer->line_tree); 00788 if (layer->arc_tree) 00789 r_destroy_tree (&layer->arc_tree); 00790 if (layer->text_tree) 00791 r_destroy_tree (&layer->text_tree); 00792 if (layer->polygon_tree) 00793 r_destroy_tree (&layer->polygon_tree); 00794 } 00795 00796 if (data->element_tree) 00797 r_destroy_tree (&data->element_tree); 00798 for (i = 0; i < MAX_ELEMENTNAMES; i++) 00799 if (data->name_tree[i]) 00800 r_destroy_tree (&data->name_tree[i]); 00801 if (data->via_tree) 00802 r_destroy_tree (&data->via_tree); 00803 if (data->pin_tree) 00804 r_destroy_tree (&data->pin_tree); 00805 if (data->pad_tree) 00806 r_destroy_tree (&data->pad_tree); 00807 if (data->rat_tree) 00808 r_destroy_tree (&data->rat_tree); 00809 /* clear struct */ 00810 memset (data, 0, sizeof (DataType)); 00811 } 00812 00816 void 00817 FreeLibraryMemory (LibraryType *lib) 00818 { 00819 MENU_LOOP (lib); 00820 { 00821 ENTRY_LOOP (menu); 00822 { 00823 free (entry->AllocatedMemory); 00824 free (entry->ListEntry); 00825 } 00826 END_LOOP; 00827 free (menu->Entry); 00828 free (menu->Name); 00829 } 00830 END_LOOP; 00831 free (lib->Menu); 00832 00833 /* clear struct */ 00834 memset (lib, 0, sizeof (LibraryType)); 00835 } 00836 00840 static void 00841 DSRealloc (DynamicStringType *Ptr, size_t Length) 00842 { 00843 int input_null = (Ptr->Data == NULL); 00844 if (input_null || Length >= Ptr->MaxLength) 00845 { 00846 Ptr->MaxLength = Length + 512; 00847 Ptr->Data = (char *)realloc (Ptr->Data, Ptr->MaxLength); 00848 if (input_null) 00849 Ptr->Data[0] = '\0'; 00850 } 00851 } 00852 00856 void 00857 DSAddCharacter (DynamicStringType *Ptr, char Char) 00858 { 00859 size_t position = Ptr->Data ? strlen (Ptr->Data) : 0; 00860 00861 DSRealloc (Ptr, position + 1); 00862 Ptr->Data[position++] = Char; 00863 Ptr->Data[position] = '\0'; 00864 } 00865 00869 void 00870 DSAddString (DynamicStringType *Ptr, const char *S) 00871 { 00872 size_t position = Ptr->Data ? strlen (Ptr->Data) : 0; 00873 00874 if (S && *S) 00875 { 00876 DSRealloc (Ptr, position + 1 + strlen (S)); 00877 strcat (&Ptr->Data[position], S); 00878 } 00879 } 00880 00884 void 00885 DSClearString (DynamicStringType *Ptr) 00886 { 00887 if (Ptr->Data) 00888 Ptr->Data[0] = '\0'; 00889 } 00890 00897 char * 00898 StripWhiteSpaceAndDup (const char *S) 00899 { 00900 const char *p1, *p2; 00901 char *copy; 00902 size_t length; 00903 00904 if (!S || !*S) 00905 return (NULL); 00906 00907 /* strip leading blanks */ 00908 for (p1 = S; *p1 && isspace ((int) *p1); p1++); 00909 00910 /* strip trailing blanks and get string length */ 00911 length = strlen (p1); 00912 for (p2 = p1 + length - 1; length && isspace ((int) *p2); p2--, length--); 00913 00914 /* string is not empty -> allocate memory */ 00915 if (length) 00916 { 00917 copy = (char *)realloc (NULL, length + 1); 00918 strncpy (copy, p1, length); 00919 copy[length] = '\0'; 00920 return (copy); 00921 } 00922 else 00923 return (NULL); 00924 }