Cleanup r_string when leaving make_route_string().
[geda-pcb/pcjc2.git] / src / drill.c
blobb391e89c303367408c2335b34e21f39e0a9902f5
1 /*!
2 * \file src/drill.c
4 * \brief .
6 * <hr>
8 * <h1><b>Copyright.</b></h1>\n
10 * PCB, interactive printed circuit board design
12 * Copyright (C) 1994,1995,1996 Thomas Nau
14 * This module, drill.c, was written and is Copyright (C) 1997 harry eaton
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
30 * Contact addresses for paper mail and Email:
31 * Thomas Nau, Schlehenweg 15, 88471 Baustetten, Germany
32 * Thomas.Nau@rz.uni-ulm.de
35 #ifdef HAVE_CONFIG_H
36 #include "config.h"
37 #endif
39 #include "data.h"
40 #include "error.h"
41 #include "mymem.h"
43 #ifdef HAVE_LIBDMALLOC
44 #include <dmalloc.h>
45 #endif
48 * some local prototypes
50 static void FillDrill (DrillType *, ElementType *, PinType *);
51 static void InitializeDrill (DrillType *, PinType *, ElementType *);
54 static void
55 FillDrill (DrillType *Drill, ElementType *Element, PinType *Pin)
57 Cardinal n;
58 ElementType **ptr;
59 PinType **pin;
61 pin = GetDrillPinMemory (Drill);
62 *pin = Pin;
63 if (Element)
65 Drill->PinCount++;
66 for (n = Drill->ElementN - 1; n != -1; n--)
67 if (Drill->Element[n] == Element)
68 break;
69 if (n == -1)
71 ptr = GetDrillElementMemory (Drill);
72 *ptr = Element;
75 else
76 Drill->ViaCount++;
77 if (TEST_FLAG (HOLEFLAG, Pin))
78 Drill->UnplatedCount++;
81 static void
82 InitializeDrill (DrillType *drill, PinType *pin, ElementType *element)
84 void *ptr;
86 drill->DrillSize = pin->DrillingHole;
87 drill->ElementN = 0;
88 drill->ViaCount = 0;
89 drill->PinCount = 0;
90 drill->UnplatedCount = 0;
91 drill->ElementMax = 0;
92 drill->Element = NULL;
93 drill->PinN = 0;
94 drill->Pin = NULL;
95 drill->PinMax = 0;
96 ptr = (void *) GetDrillPinMemory (drill);
97 *((PinType **) ptr) = pin;
98 if (element)
100 ptr = (void *) GetDrillElementMemory (drill);
101 *((ElementType **) ptr) = element;
102 drill->PinCount = 1;
104 else
105 drill->ViaCount = 1;
106 if (TEST_FLAG (HOLEFLAG, pin))
107 drill->UnplatedCount = 1;
110 static int
111 DrillQSort (const void *va, const void *vb)
113 DrillType *a = (DrillType *) va;
114 DrillType *b = (DrillType *) vb;
115 return a->DrillSize - b->DrillSize;
118 DrillInfoType *
119 GetDrillInfo (DataType *top)
121 DrillInfoType *AllDrills;
122 DrillType *Drill = NULL;
123 DrillType savedrill, swapdrill;
124 bool DrillFound = false;
125 bool NewDrill;
127 AllDrills = (DrillInfoType *)calloc (1, sizeof (DrillInfoType));
128 ALLPIN_LOOP (top);
130 if (!DrillFound)
132 DrillFound = true;
133 Drill = GetDrillInfoDrillMemory (AllDrills);
134 InitializeDrill (Drill, pin, element);
136 else
138 if (Drill->DrillSize == pin->DrillingHole)
139 FillDrill (Drill, element, pin);
140 else
142 NewDrill = false;
143 DRILL_LOOP (AllDrills);
145 if (drill->DrillSize == pin->DrillingHole)
147 Drill = drill;
148 FillDrill (Drill, element, pin);
149 break;
151 else if (drill->DrillSize > pin->DrillingHole)
153 if (!NewDrill)
155 NewDrill = true;
156 InitializeDrill (&swapdrill, pin, element);
157 Drill = GetDrillInfoDrillMemory (AllDrills);
158 Drill->DrillSize = pin->DrillingHole + 1;
159 Drill = drill;
161 savedrill = *drill;
162 *drill = swapdrill;
163 swapdrill = savedrill;
166 END_LOOP;
167 if (AllDrills->Drill[AllDrills->DrillN - 1].DrillSize <
168 pin->DrillingHole)
170 Drill = GetDrillInfoDrillMemory (AllDrills);
171 InitializeDrill (Drill, pin, element);
176 ENDALL_LOOP;
177 VIA_LOOP (top);
179 if (!DrillFound)
181 DrillFound = true;
182 Drill = GetDrillInfoDrillMemory (AllDrills);
183 Drill->DrillSize = via->DrillingHole;
184 FillDrill (Drill, NULL, via);
186 else
188 if (Drill->DrillSize != via->DrillingHole)
190 DRILL_LOOP (AllDrills);
192 if (drill->DrillSize == via->DrillingHole)
194 Drill = drill;
195 FillDrill (Drill, NULL, via);
196 break;
199 END_LOOP;
200 if (Drill->DrillSize != via->DrillingHole)
202 Drill = GetDrillInfoDrillMemory (AllDrills);
203 Drill->DrillSize = via->DrillingHole;
204 FillDrill (Drill, NULL, via);
207 else
208 FillDrill (Drill, NULL, via);
211 END_LOOP;
212 qsort (AllDrills->Drill, AllDrills->DrillN, sizeof (DrillType), DrillQSort);
213 return (AllDrills);
216 #define ROUND(x,n) ((int)(((x)+(n)/2)/(n))*(n))
219 Currently unused. Was used in ReportDrills() in report.c and in PrintFab()
220 in print.c (generation of the Gerber fab file), but not when generating the
221 actual CNC files, so the number of drills in the drill report and in the
222 CNC file could differ. This was confusing.
224 #if 0
226 \brief Join similar sized drill sets.
228 \param d Set of all drills to look at, in subsets for each drill size.
230 \param roundto Rounding error. Drills differing less than this value are
231 considered to be of the pame size and joined into a common set.
233 \note In case of hits the number of drill sets changes, so the number of
234 distinct drill sizes changes as well. This can be confusing if
235 RoundDisplayInfo() is used for one kind of display/output, but not for others.
237 void
238 RoundDrillInfo (DrillInfoType *d, int roundto)
240 unsigned int i = 0;
242 /* round in the case with only one drill, too */
243 if (d->DrillN == 1) {
244 d->Drill[0].DrillSize = ROUND (d->Drill[0].DrillSize, roundto);
247 while ((d->DrillN > 0) && (i < d->DrillN - 1))
249 int diam1 = ROUND (d->Drill[i].DrillSize, roundto);
250 int diam2 = ROUND (d->Drill[i + 1].DrillSize, roundto);
252 if (diam1 == diam2)
254 int ei, ej;
256 d->Drill[i].ElementMax
257 = d->Drill[i].ElementN + d->Drill[i+1].ElementN;
258 if (d->Drill[i].ElementMax)
260 d->Drill[i].Element = (ElementType **)realloc (d->Drill[i].Element,
261 d->Drill[i].ElementMax *
262 sizeof (ElementType *));
264 for (ei = 0; ei < d->Drill[i+1].ElementN; ei++)
266 for (ej = 0; ej < d->Drill[i].ElementN; ej++)
267 if (d->Drill[i].Element[ej] == d->Drill[i + 1].Element[ei])
268 break;
269 if (ej == d->Drill[i].ElementN)
270 d->Drill[i].Element[d->Drill[i].ElementN++]
271 = d->Drill[i + 1].Element[ei];
274 free (d->Drill[i + 1].Element);
275 d->Drill[i + 1].Element = NULL;
277 d->Drill[i].PinMax = d->Drill[i].PinN + d->Drill[i + 1].PinN;
278 d->Drill[i].Pin = (PinType **)realloc (d->Drill[i].Pin,
279 d->Drill[i].PinMax *
280 sizeof (PinType *));
281 memcpy (d->Drill[i].Pin + d->Drill[i].PinN, d->Drill[i + 1].Pin,
282 d->Drill[i + 1].PinN * sizeof (PinType *));
283 d->Drill[i].PinN += d->Drill[i + 1].PinN;
284 free (d->Drill[i + 1].Pin);
285 d->Drill[i + 1].Pin = NULL;
287 d->Drill[i].PinCount += d->Drill[i + 1].PinCount;
288 d->Drill[i].ViaCount += d->Drill[i + 1].ViaCount;
289 d->Drill[i].UnplatedCount += d->Drill[i + 1].UnplatedCount;
291 d->Drill[i].DrillSize = diam1;
293 memmove (d->Drill + i + 1,
294 d->Drill + i + 2,
295 (d->DrillN - i - 2) * sizeof (DrillType));
296 d->DrillN--;
298 else
300 d->Drill[i].DrillSize = diam1;
301 i++;
305 #endif
307 void
308 FreeDrillInfo (DrillInfoType *Drills)
310 DRILL_LOOP (Drills);
312 free (drill->Element);
313 free (drill->Pin);
315 END_LOOP;
316 free (Drills->Drill);
317 free (Drills);