77
89
* number of characters processed from the string, otherwise
80
static Boolean ParseConnection(char *InString, char *ElementName, char *PinNum)
93
ParseConnection (char *InString, char *ElementName, char *PinNum)
84
/* copy element name portion */
85
for (j = 0; InString[j] != '\0' && InString[j] != '-'; j++)
86
ElementName[j] = InString[j];
87
if (InString[j] == '-')
89
for (i = j; i > 0 && ElementName[i-1] >= 'a'; i--);
90
ElementName[i] = '\0';
91
for (i = 0, j++; InString[j] != '\0'; i++, j++)
92
PinNum[i] = InString[j];
98
ElementName[j] = '\0';
99
Message("Bad net-list format encountered near: \"%s\"\n",
97
/* copy element name portion */
98
for (j = 0; InString[j] != '\0' && InString[j] != '-'; j++)
99
ElementName[j] = InString[j];
100
if (InString[j] == '-')
102
for (i = j; i > 0 && ElementName[i - 1] >= 'a'; i--);
103
ElementName[i] = '\0';
104
for (i = 0, j++; InString[j] != '\0'; i++, j++)
105
PinNum[i] = InString[j];
111
ElementName[j] = '\0';
112
Message ("Bad net-list format encountered near: \"%s\"\n", ElementName);
105
117
/* ---------------------------------------------------------------------------
106
118
* Find a particular pad from an element name and pin number
108
static Boolean FindPad(char *ElementName, char *PinNum, ConnectionType *conn)
121
FindPad (char *ElementName, char *PinNum, ConnectionType * conn, Boolean Same)
110
ElementTypePtr element;
113
if ((element = SearchElementByName(PCB->Data, ElementName)) != NULL)
123
ElementTypePtr element;
126
if ((element = SearchElementByName (PCB->Data, ElementName)) != NULL)
128
for (i = 0; i < element->PadN; i++)
129
if (NSTRCMP (PinNum, element->Pad[i].Number) == 0 && (!Same
136
conn->type = PAD_TYPE;
137
conn->ptr2 = &element->Pad[i];
139
TEST_FLAG (ONSOLDERFLAG, &element->Pad[i]) ? SLayer : CLayer;
140
if (TEST_FLAG (EDGE2FLAG, &element->Pad[i]))
142
conn->X = element->Pad[i].Point2.X;
143
conn->Y = element->Pad[i].Point2.Y;
147
conn->X = element->Pad[i].Point1.X;
148
conn->Y = element->Pad[i].Point1.Y;
152
if (i == element->PadN)
115
for (i = 0; i < element->PadN; i++)
116
if (strcmp(PinNum, element->Pad[i].Number) == 0)
118
conn->type = PAD_TYPE;
119
conn->ptr2 = &element->Pad[i];
120
conn->group = TEST_FLAG(ONSOLDERFLAG, element) ? SLayer : CLayer;
121
conn->X = element->Pad[i].Point1.X;
122
conn->Y = element->Pad[i].Point1.Y;
125
if (i == element->PadN)
127
for (i = 0; i < element->PinN; i++)
128
if (strcmp(PinNum, element->Pin[i].Number) == 0)
130
conn->type = PIN_TYPE;
131
conn->ptr2 = &element->Pin[i];
132
conn->group = SLayer; /* any layer will do */
133
conn->X = element->Pin[i].X;
134
conn->Y = element->Pin[i].Y;
137
if (i == element->PinN)
140
conn->ptr1 = element;
154
for (i = 0; i < element->PinN; i++)
155
if (!TEST_FLAG (HOLEFLAG, &element->Pin[i]) &&
156
element->Pin[i].Number &&
157
NSTRCMP (PinNum, element->Pin[i].Number) == 0 &&
158
(!Same || !TEST_FLAG (DRCFLAG, &element->Pin[i])))
160
conn->type = PIN_TYPE;
161
conn->ptr2 = &element->Pin[i];
162
conn->group = SLayer; /* any layer will do */
163
conn->X = element->Pin[i].X;
164
conn->Y = element->Pin[i].Y;
167
if (i == element->PinN)
170
conn->ptr1 = element;
146
176
/*--------------------------------------------------------------------------
147
177
* parse a netlist menu entry and locate the cooresponding pad
148
178
* returns True if found, and fills in Connection information
150
Boolean SeekPad(LibraryEntryType *entry, ConnectionType *conn)
181
SeekPad (LibraryEntryType * entry, ConnectionType * conn, Boolean Same)
153
char ElementName[256];
184
char ElementName[256];
156
if (ParseConnection(entry->ListEntry, ElementName, PinNum))
158
for (j = 0; PinNum[j] != '\0'; j++) ;
161
Message("ERROR! Netlist file is missing pin!\n"
162
"white space after \"%s-\"\n", ElementName);
167
if (PinNum[j -1] < '0' || PinNum[j -1] > '9')
169
Message("WARNING! Pin number ending with '%c'"
170
" encountered in netlist file\n"
171
"Probably a bad netlist file format\n", PinNum[j-1]);
173
if (FindPad(ElementName, PinNum, conn))
176
Message("Can't find %s pin %s called for in netlist.\n",
177
ElementName, PinNum);
187
if (ParseConnection (entry->ListEntry, ElementName, PinNum))
189
for (j = 0; PinNum[j] != '\0'; j++);
192
Message ("ERROR! Netlist file is missing pin!\n"
193
"white space after \"%s-\"\n", ElementName);
198
if (FindPad (ElementName, PinNum, conn, Same))
202
if (PinNum[j - 1] < '0' || PinNum[j - 1] > '9')
204
Message ("WARNING! Pin number ending with '%c'"
205
" encountered in netlist file\n"
206
"Probably a bad netlist file format\n", PinNum[j - 1]);
209
Message ("Can't find %s pin %s called for in netlist.\n",
210
ElementName, PinNum);
181
214
/* ---------------------------------------------------------------------------
182
215
* Read the library-netlist build a true Netlist structure
185
static NetListTypePtr ProcNetlist(LibraryTypePtr net_menu)
187
ConnectionTypePtr connection;
188
ConnectionType LastPoint;
190
static NetListTypePtr Wantlist = NULL;
192
if (!net_menu->MenuN)
194
FreeNetListMemory(Wantlist);
197
/* find layer groups of the component side and solder side */
198
SLayer = GetLayerGroupNumberByNumber(MAX_LAYER + SOLDER_LAYER);
199
CLayer = GetLayerGroupNumberByNumber(MAX_LAYER + COMPONENT_LAYER);
201
Wantlist = MyCalloc(1, sizeof(NetListType), "ProcNetlist()");
219
ProcNetlist (LibraryTypePtr net_menu)
221
ConnectionTypePtr connection;
222
ConnectionType LastPoint;
224
static NetListTypePtr Wantlist = NULL;
226
if (!net_menu->MenuN)
228
FreeNetListMemory (Wantlist);
229
MyFree ((char **) &Wantlist);
232
/* find layer groups of the component side and solder side */
233
SLayer = GetLayerGroupNumberByNumber (MAX_LAYER + SOLDER_LAYER);
234
CLayer = GetLayerGroupNumberByNumber (MAX_LAYER + COMPONENT_LAYER);
236
Wantlist = MyCalloc (1, sizeof (NetListType), "ProcNetlist()");
239
ALLPIN_LOOP (PCB->Data);
242
CLEAR_FLAG (DRCFLAG, pin);
245
ALLPAD_LOOP (PCB->Data);
248
CLEAR_FLAG (DRCFLAG, pad);
251
MENU_LOOP (net_menu);
253
if (menu->Name[0] == '*')
258
net = GetNetMemory (Wantlist);
263
if (style->Name && !NSTRCMP (style->Name, menu->Style))
271
else /* default to NULL if none found */
204
ALLPIN_LOOP(PCB->Data, pin->Spare = NULL);
205
ALLPAD_LOOP(PCB->Data, pad->Spare = NULL);
207
if (menu->Name[0] == '*')
212
net = GetNetMemory(Wantlist);
214
if (SeekPad(entry, &LastPoint))
216
if (TEST_FLAG(DRCFLAG, (PinTypePtr) LastPoint.ptr2))
217
Message("Argh - element %s pin %s appears multiple times\n"
218
"in the netlist file. That's a problem.\n",
219
((ElementTypePtr) LastPoint.ptr1)->Name,
220
(LastPoint.type == PIN_TYPE) ?
221
((PinTypePtr) LastPoint.ptr2)->Number
222
: ((PadTypePtr) LastPoint.ptr2)->Number);
225
connection = GetConnectionMemory(net);
226
*connection = LastPoint;
227
/* indicate expect net */
228
connection->menu = menu;
229
/* mark as visited */
230
SET_FLAG(DRCFLAG, (PinTypePtr) LastPoint.ptr2);
231
if (LastPoint.type == PIN_TYPE)
232
((PinTypePtr) LastPoint.ptr2)->Spare =
235
((PadTypePtr) LastPoint.ptr2)->Spare =
275
if (SeekPad (entry, &LastPoint, False))
277
if (TEST_FLAG (DRCFLAG, (PinTypePtr) LastPoint.ptr2))
279
("Argh - element %s pin %s appears multiple times\n"
280
"in the netlist file. That's a problem.\n",
281
NAMEONPCB_NAME ((ElementTypePtr)
284
PIN_TYPE) ? ((PinTypePtr) LastPoint.
285
ptr2)->Number : ((PadTypePtr)
286
LastPoint.ptr2)->Number);
289
connection = GetConnectionMemory (net);
290
*connection = LastPoint;
291
/* indicate expect net */
292
connection->menu = menu;
293
/* mark as visited */
294
SET_FLAG (DRCFLAG, (PinTypePtr) LastPoint.ptr2);
295
if (LastPoint.type == PIN_TYPE)
296
((PinTypePtr) LastPoint.ptr2)->Spare = (void *) menu;
298
((PadTypePtr) LastPoint.ptr2)->Spare = (void *) menu;
303
/* check for more pins with the same number */
304
for (; SeekPad (entry, &LastPoint, True);)
306
connection = GetConnectionMemory (net);
307
*connection = LastPoint;
308
/* indicate expect net */
309
connection->menu = menu;
310
/* mark as visited */
311
SET_FLAG (DRCFLAG, (PinTypePtr) LastPoint.ptr2);
312
if (LastPoint.type == PIN_TYPE)
313
((PinTypePtr) LastPoint.ptr2)->Spare = (void *) menu;
315
((PadTypePtr) LastPoint.ptr2)->Spare = (void *) menu;
244
/* clear all visit marks */
245
ALLPIN_LOOP(PCB->Data, CLEAR_FLAG(DRCFLAG, pin));
246
ALLPAD_LOOP(PCB->Data, CLEAR_FLAG(DRCFLAG, pad));
322
/* clear all visit marks */
323
ALLPIN_LOOP (PCB->Data);
325
CLEAR_FLAG (DRCFLAG, pin);
328
ALLPAD_LOOP (PCB->Data);
330
CLEAR_FLAG (DRCFLAG, pad);
251
337
* copy all connections from one net into another
252
338
* and then remove the first net from its netlist
254
static void TransferNet(NetListTypePtr Netl, NetTypePtr SourceNet, NetTypePtr DestNet)
256
ConnectionTypePtr conn;
258
CONNECTION_LOOP(SourceNet,
259
conn = GetConnectionMemory(DestNet);
262
/* free the connection memory */
263
FreeNetMemory(SourceNet);
264
/* remove SourceNet from its netlist */
265
*SourceNet = Netl->Net[--(Netl->NetN)];
266
/* zero out old garbage */
267
memset(&Netl->Net[Netl->NetN], 0, sizeof(NetType));
270
static Boolean CheckShorts(LibraryMenuTypePtr theNet)
272
Boolean new, warn = False;
273
PointerListTypePtr generic = MyCalloc(1, sizeof(PointerListType),
275
/* the first connection was starting point so
276
* the menu is always non-null
278
void **menu = GetPointerMemory(generic);
281
ALLPIN_LOOP(PCB->Data,
282
if (TEST_FLAG(DRCFLAG, pin))
287
Message("WARNING!! net \"%s\" is shorted"
288
" to %s pin %s\n", &theNet->Name[2],
289
NAMEONPCB_NAME(element), pin->Number);
290
SET_FLAG(WARNFLAG, pin);
294
POINTER_LOOP(generic,
295
if (*ptr == pin->Spare)
303
menu = GetPointerMemory(generic);
305
Message("WARNING!! net \"%s\" is shorted"
308
&((LibraryMenuTypePtr) (pin->Spare))->Name[2]);
312
ALLPAD_LOOP(PCB->Data,
313
if (TEST_FLAG(DRCFLAG, pad))
318
Message("WARNING!! net \"%s\" is shorted"
319
" to %s pad %s\n", &theNet->Name[2],
320
NAMEONPCB_NAME(element), pad->Number);
321
SET_FLAG(WARNFLAG, pad);
325
POINTER_LOOP(generic,
326
if (*ptr == pad->Spare)
334
menu = GetPointerMemory(generic);
336
Message("WARNING!! net \"%s\" is shorted"
337
" to net \"%s\"\n", &theNet->Name[2],
338
&((LibraryMenuTypePtr) (pad->Spare))->Name[2]);
342
FreePointerListMemory(generic);
341
TransferNet (NetListTypePtr Netl, NetTypePtr SourceNet, NetTypePtr DestNet)
343
ConnectionTypePtr conn;
345
CONNECTION_LOOP (SourceNet);
347
conn = GetConnectionMemory (DestNet);
351
DestNet->Style = SourceNet->Style;
352
/* free the connection memory */
353
FreeNetMemory (SourceNet);
354
/* remove SourceNet from its netlist */
355
*SourceNet = Netl->Net[--(Netl->NetN)];
356
/* zero out old garbage */
357
memset (&Netl->Net[Netl->NetN], 0, sizeof (NetType));
361
CheckShorts (LibraryMenuTypePtr theNet)
363
Boolean new, warn = False;
364
PointerListTypePtr generic = MyCalloc (1, sizeof (PointerListType),
366
/* the first connection was starting point so
367
* the menu is always non-null
369
void **menu = GetPointerMemory (generic);
372
ALLPIN_LOOP (PCB->Data);
374
if (TEST_FLAG (DRCFLAG, pin))
379
Message ("WARNING!! net \"%s\" is shorted"
380
" to %s pin %s\n", &theNet->Name[2],
381
UNKNOWN(NAMEONPCB_NAME (element)), UNKNOWN(pin->Number));
382
SET_FLAG (WARNFLAG, pin);
386
POINTER_LOOP (generic);
388
if (*ptr == pin->Spare)
397
menu = GetPointerMemory (generic);
399
Message ("WARNING!! net \"%s\" is shorted"
402
&((LibraryMenuTypePtr) (pin->Spare))->Name[2]);
403
SET_FLAG (WARNFLAG, pin);
408
ALLPAD_LOOP (PCB->Data);
410
if (TEST_FLAG (DRCFLAG, pad))
415
Message ("WARNING!! net \"%s\" is shorted"
416
" to %s pad %s\n", &theNet->Name[2],
417
UNKNOWN(NAMEONPCB_NAME (element)), UNKNOWN(pad->Number));
418
SET_FLAG (WARNFLAG, pad);
422
POINTER_LOOP (generic);
424
if (*ptr == pad->Spare)
433
menu = GetPointerMemory (generic);
435
Message ("WARNING!! net \"%s\" is shorted"
436
" to net \"%s\"\n", &theNet->Name[2],
437
&((LibraryMenuTypePtr) (pad->Spare))->Name[2]);
438
SET_FLAG (WARNFLAG, pad);
443
FreePointerListMemory (generic);
348
449
/* ---------------------------------------------------------------------------
349
450
* Determine existing interconnections of the net and gather into sub-nets
351
452
* initially the netlist has each connection in its own individual net
352
453
* afterwards there can be many fewer nets with multiple connections each
354
static Boolean GatherSubnets(NetListTypePtr Netl, Boolean NoWarn)
456
GatherSubnets (NetListTypePtr Netl, Boolean NoWarn, Boolean AndRats)
357
ConnectionTypePtr conn;
359
Boolean Warned = False;
459
ConnectionTypePtr conn;
461
Boolean Warned = False;
361
for (m = 0; Netl->NetN > 0 && m < Netl->NetN; m++)
463
for (m = 0; Netl->NetN > 0 && m < Netl->NetN; m++)
466
ResetFoundPinsViasAndPads (False);
467
ResetFoundLinesAndPolygons (False);
468
RatFindHook (a->Connection[0].type, a->Connection[0].ptr1,
469
a->Connection[0].ptr2, a->Connection[0].ptr2, False,
471
/* now anybody connected to the first point has DRCFLAG set */
472
/* so move those to this subnet */
473
CLEAR_FLAG (DRCFLAG, (PinTypePtr) a->Connection[0].ptr2);
474
for (n = m + 1; n < Netl->NetN; n++)
364
ResetFoundPinsViasAndPads(False);
365
ResetFoundLinesAndPolygons(False);
366
RatFindHook(a->Connection[0].type, a->Connection[0].ptr1,
367
a->Connection[0].ptr2, a->Connection[0].ptr2, False);
368
/* now anybody connected to the first point has DRCFLAG set */
369
/* so move those to this subnet */
370
CLEAR_FLAG(DRCFLAG, (PinTypePtr)a->Connection[0].ptr2);
371
for (n = m + 1; n < Netl->NetN; n++)
374
/* There can be only one connection in net b */
375
if (TEST_FLAG(DRCFLAG, (PinTypePtr) b->Connection[0].ptr2))
377
CLEAR_FLAG(DRCFLAG, (PinTypePtr) b->Connection[0].ptr2);
378
TransferNet(Netl, b, a);
379
/* back up since new subnet is now at old index */
383
/* now add other possible attachment points to the subnet */
384
/* e.g. line end-points and vias */
385
ALLLINE_LOOP(PCB->Data,
386
if (TEST_FLAG(DRCFLAG, line))
388
conn = GetConnectionMemory(a);
389
conn->X = line->Point1.X;
390
conn->Y = line->Point1.Y;
391
conn->type = LINE_TYPE;
394
conn->group = GetLayerGroupNumberByPointer(layer);
395
conn->menu = NULL; /* agnostic view of where it belongs */
396
conn = GetConnectionMemory(a);
397
conn->X = line->Point2.X;
398
conn->Y = line->Point2.Y;
399
conn->type = LINE_TYPE;
402
conn->group = GetLayerGroupNumberByPointer(layer);
407
if (TEST_FLAG(DRCFLAG, via))
409
conn = GetConnectionMemory(a);
412
conn->type = VIA_TYPE;
415
conn->group = SLayer;
419
Warned |= CheckShorts(a->Connection[0].menu);
477
/* There can be only one connection in net b */
478
if (TEST_FLAG (DRCFLAG, (PinTypePtr) b->Connection[0].ptr2))
480
CLEAR_FLAG (DRCFLAG, (PinTypePtr) b->Connection[0].ptr2);
481
TransferNet (Netl, b, a);
482
/* back up since new subnet is now at old index */
421
ResetFoundPinsViasAndPads(False);
422
ResetFoundLinesAndPolygons(False);
486
/* now add other possible attachment points to the subnet */
487
/* e.g. line end-points and vias */
488
ALLLINE_LOOP (PCB->Data);
490
if (TEST_FLAG (DRCFLAG, line))
492
conn = GetConnectionMemory (a);
493
conn->X = line->Point1.X;
494
conn->Y = line->Point1.Y;
495
conn->type = LINE_TYPE;
498
conn->group = GetLayerGroupNumberByPointer (layer);
499
conn->menu = NULL; /* agnostic view of where it belongs */
500
conn = GetConnectionMemory (a);
501
conn->X = line->Point2.X;
502
conn->Y = line->Point2.Y;
503
conn->type = LINE_TYPE;
506
conn->group = GetLayerGroupNumberByPointer (layer);
511
/* add rectangular polygons so the auto-router can see them as targets */
512
ALLPOLYGON_LOOP (PCB->Data);
514
if (TEST_FLAG (DRCFLAG, polygon) && polygon->PointN == 4)
516
if (polygon->Points[0].X != polygon->Points[1].X &&
517
polygon->Points[0].Y != polygon->Points[1].Y)
519
if (polygon->Points[1].X != polygon->Points[2].X &&
520
polygon->Points[1].Y != polygon->Points[2].Y)
522
if (polygon->Points[2].X != polygon->Points[3].X &&
523
polygon->Points[2].Y != polygon->Points[3].Y)
525
if (polygon->Points[0].X != polygon->Points[3].X &&
526
polygon->Points[0].Y != polygon->Points[3].Y)
528
conn = GetConnectionMemory (a);
529
/* make point just inside rectangle */
530
conn->X = polygon->BoundingBox.X1+1;
531
conn->Y = polygon->BoundingBox.Y1+1;
532
conn->type = POLYGON_TYPE;
534
conn->ptr2 = polygon;
535
conn->group = GetLayerGroupNumberByPointer (layer);
536
conn->menu = NULL; /* agnostic view of where it belongs */
540
VIA_LOOP (PCB->Data);
542
if (TEST_FLAG (DRCFLAG, via))
544
conn = GetConnectionMemory (a);
547
conn->type = VIA_TYPE;
550
conn->group = SLayer;
555
Warned |= CheckShorts (a->Connection[0].menu);
557
ResetFoundPinsViasAndPads (False);
558
ResetFoundLinesAndPolygons (False);
426
562
/* ---------------------------------------------------------------------------
428
564
* this also frees the subnet memory as they are consumed
431
static Boolean DrawShortestRats(NetListTypePtr Netl)
568
DrawShortestRats (NetListTypePtr Netl, void (*funcp) ())
434
register float distance, temp;
435
register ConnectionTypePtr conn1, conn2,
436
firstpoint, secondpoint;
437
Boolean changed = False;
439
NetTypePtr next, subnet, theSubnet;
571
register float distance, temp;
572
register ConnectionTypePtr conn1, conn2, firstpoint, secondpoint;
573
Boolean changed = False;
575
NetTypePtr next, subnet, theSubnet;
441
while (Netl->NetN > 1)
577
firstpoint = secondpoint = NULL;
578
while (Netl->NetN > 1)
580
subnet = &Netl->Net[0];
581
distance = SQUARE (MAX_COORD);
582
for (j = 1; j < Netl->NetN; j++)
443
subnet = &Netl->Net[0];
445
for (j = 1; j < Netl->NetN; j++)
447
next = &Netl->Net[j];
448
for (n = subnet->ConnectionN -1; n != -1; n--)
584
next = &Netl->Net[j];
585
for (n = subnet->ConnectionN - 1; n != -1; n--)
587
conn1 = &subnet->Connection[n];
588
for (m = next->ConnectionN - 1; m != -1; m--)
450
conn1 = &subnet->Connection[n];
451
for (m = next->ConnectionN -1; m != -1; m--)
453
conn2 = &next->Connection[m];
454
if ((temp = (conn1->X - conn2->X)*(conn1->X - conn2->X) +
455
(conn1->Y - conn2->Y)*(conn1->Y - conn2->Y)) < distance)
590
conn2 = &next->Connection[m];
591
if ((temp = SQUARE (conn1->X - conn2->X) +
592
SQUARE (conn1->Y - conn2->Y)) < distance)
465
/* found the shortest distance subnet, draw the rat */
466
if ((line = CreateNewRat(PCB->Data,
467
firstpoint->X, firstpoint->Y, secondpoint->X, secondpoint->Y,
468
firstpoint->group, secondpoint->group, Settings.RatThickness,
471
AddObjectToCreateUndoList(RATLINE_TYPE, line, line, line);
476
/* copy theSubnet into the current subnet */
477
TransferNet(Netl, theSubnet, subnet);
479
/* presently nothing to do with the new subnet */
480
/* so we throw it away and free the space */
481
FreeNetMemory(&Netl->Net[--(Netl->NetN)]);
482
/* Sadly adding a rat line messes up the sorted arrays in connection finder */
483
/* hace: perhaps not necessarily now that they aren't stored in normal layers */
486
FreeConnectionLookupMemory();
487
InitConnectionLookup();
604
(*funcp) (firstpoint, secondpoint, subnet->Style);
608
/* found the shortest distance subnet, draw the rat */
609
if ((line = CreateNewRat (PCB->Data,
610
firstpoint->X, firstpoint->Y,
611
secondpoint->X, secondpoint->Y,
612
firstpoint->group, secondpoint->group,
613
Settings.RatThickness, NOFLAG)) != NULL)
615
AddObjectToCreateUndoList (RATLINE_TYPE, line, line, line);
621
/* copy theSubnet into the current subnet */
622
TransferNet (Netl, theSubnet, subnet);
624
/* presently nothing to do with the new subnet */
625
/* so we throw it away and free the space */
626
FreeNetMemory (&Netl->Net[--(Netl->NetN)]);
627
/* Sadly adding a rat line messes up the sorted arrays in connection finder */
628
/* hace: perhaps not necessarily now that they aren't stored in normal layers */
631
FreeConnectionLookupMemory ();
632
InitConnectionLookup ();
494
639
* AddAllRats puts the rats nest into the layout from the loaded netlist
495
640
* if SelectedOnly is true, it will only draw rats to selected pins and pads
497
Boolean AddAllRats(Boolean SelectedOnly)
499
NetListTypePtr Nets, Wantlist;
501
ConnectionTypePtr onepin;
502
Boolean changed, Warned = False;
504
/* the netlist library has the text form
505
* ProcNetlist fills in the Netlist
506
* structure the way the final routing
507
* is supposed to look
509
Wantlist = ProcNetlist(&PCB->NetlistLib);
512
Message("Can't add rat lines because no netlist is loaded.\n");
516
/* initialize finding engine */
517
InitConnectionLookup();
518
SaveFindFlag(DRCFLAG);
519
Nets = MyCalloc(1, sizeof(NetListType), "AddAllRats()");
520
/* now we build another netlist (Nets) for each
521
* net in Wantlist that shows how it actually looks now,
522
* then fill in any missing connections with rat lines.
524
* we first assume each connection is separate
525
* (no routing), then gather them into groups
526
* if the net is all routed, the new netlist (Nets)
527
* will have only one net entry.
528
* Note that DrawShortestRats consumes all nets
529
* from Nets, so *Nets is empty after the
530
* DrawShortestRats call
534
if (!SelectedOnly || TEST_FLAG(SELECTEDFLAG, (PinTypePtr) connection->ptr2))
536
lonesome = GetNetMemory(Nets);
537
onepin = GetConnectionMemory(lonesome);
538
*onepin = *connection;
541
Warned |= GatherSubnets(Nets, SelectedOnly);
543
changed |= DrawShortestRats(Nets);
545
FreeNetListMemory(Nets);
546
FreeConnectionLookupMemory();
548
if (Warned || changed)
551
Settings.RatWarn = True;
554
IncrementUndoSerialNumber();
557
if (!SelectedOnly && !Warned)
559
if (!PCB->Data->RatN && !badnet)
560
Message("Congratulations!!\n"
561
"The layout is complete!\n"
562
"And has no shorted nets.\n");
564
Message("Nothing more to add, but there are\n"
565
"rat-lines in the layout, or disabled nets\n"
566
"in the net-list.\n");
643
AddAllRats (Boolean SelectedOnly, void (*funcp) ())
645
NetListTypePtr Nets, Wantlist;
647
ConnectionTypePtr onepin;
648
Boolean changed, Warned = False;
650
/* the netlist library has the text form
651
* ProcNetlist fills in the Netlist
652
* structure the way the final routing
653
* is supposed to look
655
Wantlist = ProcNetlist (&PCB->NetlistLib);
658
Message ("Can't add rat lines because no netlist is loaded.\n");
662
/* initialize finding engine */
663
InitConnectionLookup ();
664
SaveFindFlag (DRCFLAG);
665
Nets = MyCalloc (1, sizeof (NetListType), "AddAllRats()");
666
/* now we build another netlist (Nets) for each
667
* net in Wantlist that shows how it actually looks now,
668
* then fill in any missing connections with rat lines.
670
* we first assume each connection is separate
671
* (no routing), then gather them into groups
672
* if the net is all routed, the new netlist (Nets)
673
* will have only one net entry.
674
* Note that DrawShortestRats consumes all nets
675
* from Nets, so *Nets is empty after the
676
* DrawShortestRats call
680
CONNECTION_LOOP (net);
683
|| TEST_FLAG (SELECTEDFLAG, (PinTypePtr) connection->ptr2))
685
lonesome = GetNetMemory (Nets);
686
onepin = GetConnectionMemory (lonesome);
687
*onepin = *connection;
688
lonesome->Style = net->Style;
692
Warned |= GatherSubnets (Nets, SelectedOnly, True);
694
changed |= DrawShortestRats (Nets, funcp);
697
FreeNetListMemory (Nets);
698
FreeConnectionLookupMemory ();
702
if (Warned || changed)
705
Settings.RatWarn = True;
708
IncrementUndoSerialNumber ();
711
if (!SelectedOnly && !Warned)
713
if (!PCB->Data->RatN && !badnet)
714
Message ("Congratulations!!\n"
715
"The layout is complete!\n" "And has no shorted nets.\n");
717
Message ("Nothing more to add, but there are\n"
718
"either rat-lines in the layout, disabled nets\n"
719
"in the net-list, or missing components\n");
724
/* XXX: This is copied in large part from AddAllRats above; for
725
* maintainability, AddAllRats probably wants to be tweaked to use this
726
* version of the code so that we don't have duplication. */
728
CollectSubnets (Boolean SelectedOnly)
730
NetListListType result = { 0, 0, NULL };
731
NetListTypePtr Nets, Wantlist;
733
ConnectionTypePtr onepin;
735
/* the netlist library has the text form
736
* ProcNetlist fills in the Netlist
737
* structure the way the final routing
738
* is supposed to look
740
Wantlist = ProcNetlist (&PCB->NetlistLib);
743
Message ("Can't add rat lines because no netlist is loaded.\n");
746
/* initialize finding engine */
747
InitConnectionLookup ();
748
SaveFindFlag (DRCFLAG);
749
/* now we build another netlist (Nets) for each
750
* net in Wantlist that shows how it actually looks now,
751
* then fill in any missing connections with rat lines.
753
* we first assume each connection is separate
754
* (no routing), then gather them into groups
755
* if the net is all routed, the new netlist (Nets)
756
* will have only one net entry.
757
* Note that DrawShortestRats consumes all nets
758
* from Nets, so *Nets is empty after the
759
* DrawShortestRats call
763
Nets = GetNetListMemory (&result);
764
CONNECTION_LOOP (net);
767
|| TEST_FLAG (SELECTEDFLAG, (PinTypePtr) connection->ptr2))
769
lonesome = GetNetMemory (Nets);
770
onepin = GetConnectionMemory (lonesome);
771
*onepin = *connection;
772
lonesome->Style = net->Style;
776
/* Note that AndRats is *FALSE* here! */
777
GatherSubnets (Nets, SelectedOnly, False);
780
FreeConnectionLookupMemory ();