Continued optimizing poorly written routines in "extresist".
Changed the "ResDissolveContacts()" routine to avoid running both redundant and useless code. Changed the breakpoint sorting routine from a bubble sort to a merge sort for linked lists longer than 16, as merge sort is more efficient for long lists.
This commit is contained in:
parent
29447a35cd
commit
a062fdcfe0
|
|
@ -148,29 +148,32 @@ void
|
||||||
ResDissolveContacts(contacts)
|
ResDissolveContacts(contacts)
|
||||||
ResContactPoint *contacts;
|
ResContactPoint *contacts;
|
||||||
{
|
{
|
||||||
TileType t, oldtype;
|
TileType t, oldtype, lasttype = TT_SPACE;
|
||||||
Tile *tp;
|
Tile *tp;
|
||||||
TileTypeBitMask residues;
|
TileTypeBitMask residues;
|
||||||
|
|
||||||
for (; contacts != (ResContactPoint *)NULL; contacts = contacts->cp_nextcontact)
|
for (; contacts != (ResContactPoint *)NULL; contacts = contacts->cp_nextcontact)
|
||||||
{
|
{
|
||||||
oldtype=contacts->cp_type;
|
oldtype = contacts->cp_type;
|
||||||
|
|
||||||
#ifdef PARANOID
|
#ifdef PARANOID
|
||||||
if (oldtype == TT_SPACE)
|
if (oldtype == TT_SPACE)
|
||||||
TxError("Error in Contact Dissolving for %s \n",ResCurrentNode);
|
TxError("Error in Contact Dissolving for %s \n",ResCurrentNode);
|
||||||
#endif
|
#endif
|
||||||
DBFullResidueMask(oldtype, &residues);
|
if (oldtype != lasttype)
|
||||||
|
{
|
||||||
|
lasttype = oldtype;
|
||||||
|
DBFullResidueMask(oldtype, &residues);
|
||||||
|
}
|
||||||
|
|
||||||
DBErase(ResUse->cu_def, &(contacts->cp_rect), oldtype);
|
DBErase(ResUse->cu_def, &(contacts->cp_rect), oldtype);
|
||||||
for (t = TT_TECHDEPBASE; t < DBNumTypes; t++)
|
for (t = TT_TECHDEPBASE; t < DBNumTypes; t++)
|
||||||
if (TTMaskHasType(&residues, t))
|
if (TTMaskHasType(&residues, t))
|
||||||
DBPaint(ResUse->cu_def, &(contacts->cp_rect), t);
|
DBPaint(ResUse->cu_def, &(contacts->cp_rect), t);
|
||||||
|
|
||||||
|
#ifdef PARANOID
|
||||||
tp = PlaneGetHint(ResDef->cd_planes[DBPlane(contacts->cp_type)]);
|
tp = PlaneGetHint(ResDef->cd_planes[DBPlane(contacts->cp_type)]);
|
||||||
GOTOPOINT(tp, &(contacts->cp_rect.r_ll));
|
GOTOPOINT(tp, &(contacts->cp_rect.r_ll));
|
||||||
|
|
||||||
#ifdef PARANOID
|
|
||||||
if (TiGetTypeExact(tp) == contacts->cp_type)
|
if (TiGetTypeExact(tp) == contacts->cp_type)
|
||||||
TxError("Error in Contact Preprocess Routines\n");
|
TxError("Error in Contact Preprocess Routines\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -378,13 +381,14 @@ ResAddBreakpointFunc(tile, dinfo, node)
|
||||||
*
|
*
|
||||||
* ResFindNewContactTiles --
|
* ResFindNewContactTiles --
|
||||||
*
|
*
|
||||||
|
* Dissolving contacts eliminated the tiles that contacts->nextcontact
|
||||||
|
* pointed to. This procedure finds the tile now under center and sets
|
||||||
|
* that tile's ti_client field to point to the contact. The old value
|
||||||
|
* of clientdata is set to nextTilecontact.
|
||||||
*
|
*
|
||||||
* Results: none
|
* Results: none
|
||||||
*
|
*
|
||||||
* Side Effects: dissolving contacts eliminated the tiles that
|
* Side Effects: modifies information in the contact records.
|
||||||
* contacts->nextcontact pointed to. This procedure finds the tile now under
|
|
||||||
* center and sets that tile's ti_client field to point to the contact. The
|
|
||||||
* old value of clientdata is set to nextTilecontact.
|
|
||||||
*
|
*
|
||||||
*----------------------------------------------------------------------------
|
*----------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
@ -396,27 +400,37 @@ ResFindNewContactTiles(contacts)
|
||||||
int pNum;
|
int pNum;
|
||||||
Tile *tile;
|
Tile *tile;
|
||||||
TileTypeBitMask mask;
|
TileTypeBitMask mask;
|
||||||
|
TileType lastType = TT_SPACE;
|
||||||
|
|
||||||
for (; contacts != (ResContactPoint *) NULL; contacts = contacts->cp_nextcontact)
|
for (; contacts != (ResContactPoint *) NULL; contacts = contacts->cp_nextcontact)
|
||||||
{
|
{
|
||||||
DBFullResidueMask(contacts->cp_type, &mask);
|
/* Avoid re-running the following code for the same contact type */
|
||||||
|
if (contacts->cp_type != lastType)
|
||||||
/* Watch for types that connect to the substrate plane or well; */
|
|
||||||
/* e.g., psubstratepdiff connects to nwell but not through a */
|
|
||||||
/* contact. */
|
|
||||||
|
|
||||||
if (ExtCurStyle->exts_globSubstratePlane != -1)
|
|
||||||
{
|
{
|
||||||
TileTypeBitMask cMask;
|
lastType = contacts->cp_type;
|
||||||
TTMaskAndMask3(&cMask, &DBConnectTbl[contacts->cp_type],
|
DBFullResidueMask(contacts->cp_type, &mask);
|
||||||
&DBPlaneTypes[ExtCurStyle->exts_globSubstratePlane]);
|
|
||||||
|
|
||||||
if (!TTMaskIsZero(&cMask))
|
/* Watch for types that connect to the substrate plane or well; */
|
||||||
TTMaskSetMask(&mask, &cMask);
|
/* e.g., psubstratepdiff connects to nwell but not through a */
|
||||||
|
/* contact. */
|
||||||
|
|
||||||
|
if (ExtCurStyle->exts_globSubstratePlane != -1)
|
||||||
|
{
|
||||||
|
TileTypeBitMask cMask;
|
||||||
|
TTMaskAndMask3(&cMask, &DBConnectTbl[contacts->cp_type],
|
||||||
|
&DBPlaneTypes[ExtCurStyle->exts_globSubstratePlane]);
|
||||||
|
|
||||||
|
if (!TTMaskIsZero(&cMask))
|
||||||
|
TTMaskSetMask(&mask, &cMask);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (pNum = PL_TECHDEPBASE; pNum < DBNumPlanes; pNum++)
|
for (pNum = PL_TECHDEPBASE; pNum < DBNumPlanes; pNum++)
|
||||||
{
|
{
|
||||||
|
if (!DBTypeOnPlane(contacts->cp_type, pNum) &&
|
||||||
|
(pNum != ExtCurStyle->exts_globSubstratePlane))
|
||||||
|
continue;
|
||||||
|
|
||||||
tile = PlaneGetHint(ResDef->cd_planes[pNum]);
|
tile = PlaneGetHint(ResDef->cd_planes[pNum]);
|
||||||
GOTOPOINT(tile, &(contacts->cp_center));
|
GOTOPOINT(tile, &(contacts->cp_center));
|
||||||
#ifdef PARANOID
|
#ifdef PARANOID
|
||||||
|
|
@ -476,10 +490,11 @@ ResFindNewContactTiles(contacts)
|
||||||
/*
|
/*
|
||||||
*--------------------------------------------------------------------------
|
*--------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
* ResProcessTiles--Calls ResEachTile with processed tiles belonging to
|
* ResProcessTiles --
|
||||||
* nodes in ResNodeQueue. When all the tiles corresponding
|
*
|
||||||
* to a node have been processed, the node is moved to
|
* Calls ResEachTile with processed tiles belonging to nodes in ResNodeQueue.
|
||||||
* ResNodeList.
|
* When all the tiles corresponding to a node have been processed, the node
|
||||||
|
* is moved to ResNodeList.
|
||||||
*
|
*
|
||||||
* Results: Return 1 if any error occurred, 0 otherwise.
|
* Results: Return 1 if any error occurred, 0 otherwise.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -525,7 +525,7 @@ ResCalcNearDevice(tile, pendingList, doneList, resList)
|
||||||
(devedge & TOPEDGE) == devedge ||
|
(devedge & TOPEDGE) == devedge ||
|
||||||
(devedge & BOTTOMEDGE) == devedge)
|
(devedge & BOTTOMEDGE) == devedge)
|
||||||
{
|
{
|
||||||
ResSortBreaks(&info->breakList,TRUE);
|
ResSortBreaks(&info->breakList, TRUE);
|
||||||
p2 = NULL;
|
p2 = NULL;
|
||||||
for (p1 = info->breakList; p1 != NULL; p1 = p1->br_next)
|
for (p1 = info->breakList; p1 != NULL; p1 = p1->br_next)
|
||||||
{
|
{
|
||||||
|
|
@ -916,11 +916,182 @@ ResDoContacts(contact, nodes, resList)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
*-------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* BreakCompare --
|
||||||
|
*
|
||||||
|
* Helper routine for MergeSortBreaks() (below). Simple
|
||||||
|
* comparison of the breakpoint position. Comparison is
|
||||||
|
* done for the X position if "xsort" is TRUE, and the Y
|
||||||
|
* position if "xsort" is FALSE.
|
||||||
|
*
|
||||||
|
* Return value:
|
||||||
|
* Return -1 if the (x or y) position of a is less than the
|
||||||
|
* (x or y) position of b; return +1 if the position of a is
|
||||||
|
* greater than the position of b; and return 0 if they have
|
||||||
|
* equal positions.
|
||||||
|
*
|
||||||
|
* Side effect:
|
||||||
|
* None.
|
||||||
|
*
|
||||||
|
*-------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
int
|
||||||
|
BreakCompare(
|
||||||
|
Breakpoint *a,
|
||||||
|
Breakpoint *b,
|
||||||
|
int xsort)
|
||||||
|
{
|
||||||
|
if (xsort == TRUE)
|
||||||
|
{
|
||||||
|
if (a->br_loc.p_x < b->br_loc.p_x) return -1;
|
||||||
|
if (a->br_loc.p_x > b->br_loc.p_x) return 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (a->br_loc.p_y < b->br_loc.p_y) return -1;
|
||||||
|
if (a->br_loc.p_y > b->br_loc.p_y) return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
*-------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* MergeSorted --
|
||||||
|
*
|
||||||
|
* Helper routine for MergeSortBreaks() (below). Merge sort
|
||||||
|
* merging routine.
|
||||||
|
*
|
||||||
|
*-------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
Breakpoint *
|
||||||
|
MergeSorted(
|
||||||
|
Breakpoint *a,
|
||||||
|
Breakpoint *b,
|
||||||
|
int xsort)
|
||||||
|
{
|
||||||
|
Breakpoint head;
|
||||||
|
Breakpoint *tail = &head;
|
||||||
|
|
||||||
|
head.br_next = NULL;
|
||||||
|
|
||||||
|
while (a != NULL && b != NULL)
|
||||||
|
{
|
||||||
|
if (BreakCompare(a, b, xsort) <= 0)
|
||||||
|
{
|
||||||
|
tail->br_next = a;
|
||||||
|
a = a->br_next;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tail->br_next = b;
|
||||||
|
b = b->br_next;
|
||||||
|
}
|
||||||
|
tail = tail->br_next;
|
||||||
|
}
|
||||||
|
tail->br_next = (a != NULL) ? a : b;
|
||||||
|
|
||||||
|
return head.br_next;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
*-------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* SplitList --
|
||||||
|
*
|
||||||
|
* Helper routine for MergeSortBreaks() (below). Merge sort
|
||||||
|
* splitting routine.
|
||||||
|
*
|
||||||
|
* Results:
|
||||||
|
* None.
|
||||||
|
*
|
||||||
|
*-------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
SplitList(
|
||||||
|
Breakpoint *source,
|
||||||
|
Breakpoint **front,
|
||||||
|
Breakpoint **back)
|
||||||
|
{
|
||||||
|
Breakpoint *slow;
|
||||||
|
Breakpoint *fast;
|
||||||
|
|
||||||
|
if (source == NULL || source->br_next == NULL)
|
||||||
|
{
|
||||||
|
*front = source;
|
||||||
|
*back = NULL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
slow = source;
|
||||||
|
fast = source->br_next;
|
||||||
|
|
||||||
|
while (fast != NULL)
|
||||||
|
{
|
||||||
|
fast = fast->br_next;
|
||||||
|
|
||||||
|
if (fast != NULL)
|
||||||
|
{
|
||||||
|
slow = slow->br_next;
|
||||||
|
fast = fast->br_next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*front = source;
|
||||||
|
*back = slow->br_next;
|
||||||
|
slow->br_next = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
*-------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* MergeSortBreaks --
|
||||||
|
*
|
||||||
|
* See "ResSortBreaks" below. Alternative to bubble sort for long
|
||||||
|
* linked lists.
|
||||||
|
*
|
||||||
|
* Results:
|
||||||
|
* Pointer to a sorted breakpoint list.
|
||||||
|
*
|
||||||
|
* Side effects:
|
||||||
|
* The breakpoints are sorted.
|
||||||
|
*
|
||||||
|
*-------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
Breakpoint *
|
||||||
|
MergeSortBreaks(Breakpoint *list, int xsort)
|
||||||
|
{
|
||||||
|
Breakpoint *a, *b;
|
||||||
|
|
||||||
|
if (list == NULL || list->br_next == NULL)
|
||||||
|
return list;
|
||||||
|
|
||||||
|
SplitList(list, &a, &b);
|
||||||
|
|
||||||
|
a = MergeSortBreaks(a, xsort);
|
||||||
|
b = MergeSortBreaks(b, xsort);
|
||||||
|
|
||||||
|
return MergeSorted(a, b, xsort);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
* ResSortBreaks --
|
* ResSortBreaks --
|
||||||
*
|
*
|
||||||
|
* Sort breakpoints, either in the X direction (if "xsort" is TRUE)
|
||||||
|
* or in the Y direction (if "xsort" is FALSE). For short lists
|
||||||
|
* (< 16 elements), a simple bubble sort is used. For larger lists,
|
||||||
|
* a merge sort is used. Most resistor networks are short, but
|
||||||
|
* power/ground networks can be huge and cause a performance
|
||||||
|
* bottleneck.
|
||||||
|
*
|
||||||
* Results:
|
* Results:
|
||||||
* None
|
* None
|
||||||
*
|
*
|
||||||
|
|
@ -934,6 +1105,19 @@ ResSortBreaks(masterlist, xsort)
|
||||||
{
|
{
|
||||||
Breakpoint *p1, *p2, *p3, *p4;
|
Breakpoint *p1, *p2, *p3, *p4;
|
||||||
bool changed;
|
bool changed;
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
|
for (p1 = *masterlist; p1; p1 = p1->br_next)
|
||||||
|
{
|
||||||
|
count++;
|
||||||
|
if (count > 16)
|
||||||
|
{
|
||||||
|
*masterlist = MergeSortBreaks(*masterlist, xsort);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Simple bubble sort */
|
||||||
|
|
||||||
changed = TRUE;
|
changed = TRUE;
|
||||||
while (changed == TRUE)
|
while (changed == TRUE)
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@
|
||||||
static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/resis/ResSimple.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $";
|
static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/resis/ResSimple.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $";
|
||||||
#endif /* not lint */
|
#endif /* not lint */
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h> /* for qsort() */
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
@ -401,6 +402,29 @@ ResMoveDevices(node1, node2)
|
||||||
node1->rn_te = NULL;
|
node1->rn_te = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
*-------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* qrescompare ---
|
||||||
|
*
|
||||||
|
* Sort routine for qsort() to be used by ResScrunchNet(). Sorts in
|
||||||
|
* order of the resistor value, smallest to largest.
|
||||||
|
*-------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
int
|
||||||
|
qrescompare(const void *one, const void *two)
|
||||||
|
{
|
||||||
|
int cval;
|
||||||
|
|
||||||
|
resResistor *r1 = *((resResistor **)one);
|
||||||
|
resResistor *r2 = *((resResistor **)two);
|
||||||
|
|
||||||
|
if (r1->rr_value < r2->rr_value) return -1;
|
||||||
|
else if (r1->rr_value == r2->rr_value) return 0;
|
||||||
|
else return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
|
|
@ -424,29 +448,82 @@ ResScrunchNet(reslist, pendingList, biglist, tolerance)
|
||||||
float tolerance;
|
float tolerance;
|
||||||
|
|
||||||
{
|
{
|
||||||
resResistor *locallist = NULL, *current, *working;
|
resResistor *current, *working;
|
||||||
resNode *node1, *node2;
|
resNode *node1, *node2;
|
||||||
resElement *rcell1;
|
resElement *rcell1;
|
||||||
int c1, c2;
|
int c1, c2, count = 0;
|
||||||
|
|
||||||
/* Sort resistors by size */
|
/* Method used to sort resistors by size depends on list length */
|
||||||
current = *reslist;
|
for (current = *reslist; current; current = current->rr_nextResistor)
|
||||||
while (current != NULL)
|
|
||||||
{
|
{
|
||||||
working = current;
|
count++;
|
||||||
current = current->rr_nextResistor;
|
if (count >= 10) break;
|
||||||
if (working == *reslist)
|
}
|
||||||
*reslist = current;
|
|
||||||
else
|
/* Sort resistors by size */
|
||||||
working->rr_lastResistor->rr_nextResistor = current;
|
|
||||||
|
if (count >= 10)
|
||||||
if (current != NULL)
|
{
|
||||||
current->rr_lastResistor = working->rr_lastResistor;
|
int i;
|
||||||
|
resResistor **resSortList;
|
||||||
ResAddResistorToList(working, &locallist);
|
|
||||||
|
/* For long lists, sort using qsort() */
|
||||||
|
/* NOTE: It might be better to use the same merge sort used for
|
||||||
|
* MergeSortBreaks() in ResMakeRes.c, as it does not incur the
|
||||||
|
* overhead of allocating memory and populating the array.
|
||||||
|
*/
|
||||||
|
count = 0;
|
||||||
|
for (current = *reslist; current; current = current->rr_nextResistor)
|
||||||
|
count++;
|
||||||
|
|
||||||
|
resSortList = (resResistor **)mallocMagic(count * sizeof(resResistor *));
|
||||||
|
|
||||||
|
count = 0;
|
||||||
|
for (current = *reslist; current; current = current->rr_nextResistor)
|
||||||
|
{
|
||||||
|
resSortList[count] = current;
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Sort the list */
|
||||||
|
|
||||||
|
qsort(resSortList, count, sizeof(resResistor *), qrescompare);
|
||||||
|
|
||||||
|
/* Regenerate links on sorted list */
|
||||||
|
for (i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
current = resSortList[i];
|
||||||
|
current->rr_nextResistor = (i == count - 1) ? NULL : resSortList[i + 1];
|
||||||
|
current->rr_lastResistor = (i == 0) ? NULL : resSortList[i - 1];
|
||||||
|
}
|
||||||
|
*reslist = resSortList[0];
|
||||||
|
|
||||||
|
freeMagic(resSortList);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Original method: Walk the linked list and re-sort by size. */
|
||||||
|
|
||||||
|
resResistor *locallist = NULL;
|
||||||
|
|
||||||
|
current = *reslist;
|
||||||
|
while (current != NULL)
|
||||||
|
{
|
||||||
|
working = current;
|
||||||
|
current = current->rr_nextResistor;
|
||||||
|
if (working == *reslist)
|
||||||
|
*reslist = current;
|
||||||
|
else
|
||||||
|
working->rr_lastResistor->rr_nextResistor = current;
|
||||||
|
|
||||||
|
if (current != NULL)
|
||||||
|
current->rr_lastResistor = working->rr_lastResistor;
|
||||||
|
|
||||||
|
ResAddResistorToList(working, &locallist);
|
||||||
|
}
|
||||||
|
*reslist = locallist;
|
||||||
}
|
}
|
||||||
|
|
||||||
*reslist = locallist;
|
|
||||||
while (*reslist != NULL && (*reslist)->rr_value < tolerance)
|
while (*reslist != NULL && (*reslist)->rr_value < tolerance)
|
||||||
{
|
{
|
||||||
current = *reslist;
|
current = *reslist;
|
||||||
|
|
@ -501,8 +578,8 @@ ResScrunchNet(reslist, pendingList, biglist, tolerance)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* If the current resistor isn't a deadend, add its value and
|
* If the current resistor isn't a dead end, add its value and
|
||||||
* area to that of the next smallest one. If it is a deadend,
|
* area to that of the next smallest one. If it is a dead end,
|
||||||
* simply add its area to its node.
|
* simply add its area to its node.
|
||||||
*/
|
*/
|
||||||
if (c1 != 0 && c2 != 0)
|
if (c1 != 0 && c2 != 0)
|
||||||
|
|
@ -567,7 +644,7 @@ ResAddResistorToList(resistor, locallist)
|
||||||
resResistor *resistor, **locallist;
|
resResistor *resistor, **locallist;
|
||||||
|
|
||||||
{
|
{
|
||||||
resResistor *local,*last=NULL;
|
resResistor *local, *last = NULL;
|
||||||
|
|
||||||
for (local = *locallist; local != NULL; local = local->rr_nextResistor)
|
for (local = *locallist; local != NULL; local = local->rr_nextResistor)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue