pcb 4.1.1
An interactive printed circuit board layout editor.

mymem.c

Go to the documentation of this file.
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 }