mirror of
https://github.com/RTimothyEdwards/netgen.git
synced 2026-08-24 15:07:18 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9148edde69 | ||
|
|
bb07a84ae1 | ||
|
|
d753e2c208 | ||
|
|
bd3b88de4a | ||
|
|
668aa38340 | ||
|
|
d99bffa74f | ||
|
|
7ce3b1dcd8 | ||
|
|
366821fe7f | ||
|
|
7ef7ae36de | ||
|
|
675b3e0743 | ||
|
|
cad7e0e293 | ||
|
|
19fdbfd185 | ||
|
|
22c2a31e7f | ||
|
|
950bb976e6 | ||
|
|
b7363862b3 | ||
|
|
29566bde4d | ||
|
|
99d096cfc1 | ||
|
|
9943676df4 | ||
|
|
568ed65c05 | ||
|
|
cb85aa7115 | ||
|
|
be819b7200 | ||
|
|
618f912cac | ||
|
|
17c2bff72b | ||
|
|
7e68f3a32e | ||
|
|
c60443b862 | ||
|
|
4a295dbfe4 | ||
|
|
eb72af6d54 | ||
|
|
e7f2cacc88 | ||
|
|
7dfe6ee19f | ||
|
|
c7f27c909f |
-394
@@ -1298,230 +1298,6 @@ typedef struct ecomplist {
|
||||
ECompListPtr next;
|
||||
} ECompList;
|
||||
|
||||
/*------------------------------------------------------*/
|
||||
/* Split a device into multiple devices based on a */
|
||||
/* critical property; e.g., MOSFET width. Devices with */
|
||||
/* property name equal to kl->key and value "value" */
|
||||
/* will be split into "ndev" devices with the property */
|
||||
/* of each divided down by "ndev". */
|
||||
/*------------------------------------------------------*/
|
||||
|
||||
void
|
||||
SplitDevice(struct nlist *tc, struct nlist *cell, struct property *kl,
|
||||
double value, int ndev, int file1, int file2, int which)
|
||||
{
|
||||
struct objlist *ob, *ob2, *newdevs, *ob3, *lastob, *nob;
|
||||
struct nlist *tsub;
|
||||
unsigned char found;
|
||||
int file = (which == 0) ? file1 : file2;
|
||||
|
||||
newdevs = NULL; /* Linked list of the copied devices */
|
||||
|
||||
for (ob = tc->cell; ob; ob = ob->next) {
|
||||
if (ob->type == FIRSTPIN) {
|
||||
tsub = LookupCellFile(ob->model.class, file);
|
||||
if (tsub == cell) {
|
||||
|
||||
// Advance ob to property list
|
||||
found = 0;
|
||||
for (ob2 = ob->next; ob2 && ob2->type != FIRSTPIN; ob2 = ob2->next) {
|
||||
if (ob2->type == PROPERTY) {
|
||||
struct valuelist *kv;
|
||||
int i;
|
||||
double dval = 0.0;
|
||||
for (i = 0; ; i++) {
|
||||
kv = &(ob2->instance.props[i]);
|
||||
if (kv->type == PROP_ENDLIST) break;
|
||||
if ((*matchfunc)(kv->key, kl->key)) {
|
||||
switch(kv->type) {
|
||||
case PROP_INTEGER:
|
||||
dval = (double)kv->value.ival;
|
||||
break;
|
||||
case PROP_DOUBLE:
|
||||
case PROP_VALUE:
|
||||
dval = kv->value.dval;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* To-do: Account for slop */
|
||||
|
||||
if (dval == value) {
|
||||
switch(kv->type) {
|
||||
case PROP_INTEGER:
|
||||
kv->value.ival /= ndev;
|
||||
found = 1;
|
||||
break;
|
||||
case PROP_DOUBLE:
|
||||
case PROP_VALUE:
|
||||
kv->value.dval /= ndev;
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (found) break;
|
||||
}
|
||||
if (found) {
|
||||
int i;
|
||||
for (i = 1; i < ndev; i++) {
|
||||
ob3 = CopyObjList(ob, 0); // Make exact copy
|
||||
for (nob = ob3; nob->next != NULL; nob = nob->next);
|
||||
nob->next = newdevs;
|
||||
newdevs = ob3;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
lastob = ob;
|
||||
}
|
||||
lastob->next = newdevs; // Append new devices to list
|
||||
}
|
||||
|
||||
/*------------------------------------------------------*/
|
||||
/* Survey a specific device in a cell and sort into a */
|
||||
/* hash by critical property. */
|
||||
/*------------------------------------------------------*/
|
||||
|
||||
void
|
||||
SurveyDevice(struct nlist *tc, struct hashdict *devdict,
|
||||
struct nlist *cell, struct property *kl,
|
||||
int file1, int file2, int which)
|
||||
{
|
||||
struct objlist *ob, *ob2;
|
||||
struct nlist *tsub, *teq;
|
||||
ECompare *dcomp, *ncomp, *qcomp;
|
||||
int file = (which == 0) ? file1 : file2;
|
||||
int ofile = (which == 0) ? file2 : file1;
|
||||
char *p1str, *p2str, *d1str, *d2str;
|
||||
|
||||
for (ob = tc->cell; ob; ob = ob->next) {
|
||||
if (ob->type == FIRSTPIN) {
|
||||
|
||||
tsub = LookupCellFile(ob->model.class, file);
|
||||
if (tsub == cell) {
|
||||
|
||||
p1str = (char *)MALLOC(strlen(ob->model.class) + 20);
|
||||
sprintf(p1str, "%s", ob->model.class);
|
||||
|
||||
if (tsub->flags & CELL_DUPLICATE) {
|
||||
// Always register a duplicate under the original name
|
||||
d1str = strstr(p1str, "[[");
|
||||
if (d1str) *d1str = '\0';
|
||||
}
|
||||
d1str = p1str + strlen(p1str);
|
||||
sprintf(d1str, "::");
|
||||
d1str += 2;
|
||||
|
||||
teq = LookupClassEquivalent(ob->model.class, file, ofile);
|
||||
p2str = (char *)MALLOC(strlen(teq->name) + 20);
|
||||
sprintf(p2str, "%s", teq->name);
|
||||
|
||||
if (teq->flags & CELL_DUPLICATE) {
|
||||
// Always register a duplicate under the original name
|
||||
d2str = strstr(p2str, "[[");
|
||||
if (d2str) *d2str = '\0';
|
||||
}
|
||||
d2str = p2str + strlen(p2str);
|
||||
sprintf(d2str, "::");
|
||||
d2str += 2;
|
||||
|
||||
// Advance ob to property list
|
||||
// To-do: Quantize values according to slop
|
||||
|
||||
for (ob2 = ob->next; ob2 && ob2->type != FIRSTPIN; ob2 = ob2->next) {
|
||||
if (ob2->type == PROPERTY) {
|
||||
struct valuelist *kv;
|
||||
int i;
|
||||
for (i = 0; ; i++) {
|
||||
kv = &(ob2->instance.props[i]);
|
||||
if (kv->type == PROP_ENDLIST) break;
|
||||
if ((*matchfunc)(kv->key, kl->key)) {
|
||||
switch(kv->type) {
|
||||
case PROP_INTEGER:
|
||||
sprintf(d1str, "%d", kv->value.ival);
|
||||
sprintf(d2str, "%d", kv->value.ival);
|
||||
break;
|
||||
case PROP_DOUBLE:
|
||||
case PROP_VALUE:
|
||||
// To-do: Round to tolerance
|
||||
sprintf(d1str, "%g", kv->value.dval);
|
||||
sprintf(d2str, "%g", kv->value.dval);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (*d1str == '\0') {
|
||||
// No critical property instanced, so use default
|
||||
switch(kl->type) {
|
||||
case PROP_INTEGER:
|
||||
sprintf(d1str, "%d", kl->pdefault.ival);
|
||||
sprintf(d2str, "%d", kl->pdefault.ival);
|
||||
break;
|
||||
case PROP_DOUBLE:
|
||||
case PROP_VALUE:
|
||||
// To-do: Round to tolerance
|
||||
sprintf(d1str, "%g", kl->pdefault.dval);
|
||||
sprintf(d2str, "%g", kl->pdefault.dval);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Create hash key from object class and the critical
|
||||
// property affecting the device count.
|
||||
|
||||
dcomp = (ECompare *)HashInt2Lookup(p1str, file, devdict);
|
||||
|
||||
// Fill in the values for this device::property combination
|
||||
|
||||
if (dcomp == NULL) {
|
||||
ncomp = (ECompare *)MALLOC(sizeof(ECompare));
|
||||
if (which == 0) {
|
||||
ncomp->num1 = 1;
|
||||
ncomp->num2 = 0;
|
||||
ncomp->cell1 = tsub;
|
||||
ncomp->cell2 = teq;
|
||||
}
|
||||
else {
|
||||
ncomp->num1 = 0;
|
||||
ncomp->num2 = 1;
|
||||
ncomp->cell2 = tsub;
|
||||
ncomp->cell1 = teq;
|
||||
}
|
||||
ncomp->add1 = 0;
|
||||
ncomp->add2 = 0;
|
||||
ncomp->refcount = (char)1;
|
||||
|
||||
HashInt2PtrInstall(p1str, file, ncomp, devdict);
|
||||
if (teq != NULL) {
|
||||
qcomp = (ECompare *)HashInt2Lookup(p2str, ofile,
|
||||
devdict);
|
||||
if (qcomp == NULL) {
|
||||
HashInt2PtrInstall(p2str, ofile, ncomp, devdict);
|
||||
ncomp->refcount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (which == 0)
|
||||
dcomp->num1++;
|
||||
else
|
||||
dcomp->num2++;
|
||||
}
|
||||
|
||||
FREE(p1str);
|
||||
FREE(p2str);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*------------------------------------------------------*/
|
||||
/* Survey the contents of a cell and sort into a hash */
|
||||
/*------------------------------------------------------*/
|
||||
@@ -1867,176 +1643,6 @@ PrematchLists(char *name1, int file1, char *name2, int file2)
|
||||
ecomp = (ECompare *)HashNext(&compdict);
|
||||
}
|
||||
|
||||
// Check for cells, either low-level devices or subcircuits,
|
||||
// that have properties allowing devices to be merged. If
|
||||
// the classes of both cells are the same, and the number of
|
||||
// instances is different, and merging the device with more
|
||||
// instances improves the matching, then perform the merge.
|
||||
|
||||
ecomp = (ECompare *)HashFirst(&compdict);
|
||||
while (ecomp != NULL) {
|
||||
|
||||
if ((ecomp->num1 != ecomp->num2) &&
|
||||
(ecomp->cell1 != NULL) &&
|
||||
(ecomp->cell2 != NULL) &&
|
||||
(ecomp->cell1->classhash == ecomp->cell2->classhash)) {
|
||||
|
||||
struct hashdict devdict;
|
||||
ECompare *dcomp;
|
||||
|
||||
// Determine if either device has mergeable properties. If so,
|
||||
// sort the device into bins by critical (mergeable) property,
|
||||
// and merge devices where merging makes a better match.
|
||||
|
||||
struct property *kl1, *kl2;
|
||||
double slop = 0.0;
|
||||
|
||||
// Look for a mergeable property in cell1
|
||||
|
||||
kl1 = (struct property *)HashFirst(&(ecomp->cell1->propdict));
|
||||
while (kl1 != NULL) {
|
||||
if (kl1->merge == MERGE_ADD_CRIT || kl1->merge == MERGE_PAR_CRIT)
|
||||
break;
|
||||
kl1 = (struct property *)HashNext(&(ecomp->cell1->propdict));
|
||||
}
|
||||
|
||||
// Look for the equivalent property in cell2 (mergeable or not).
|
||||
// If cell1 had no mergeable properties, then look for one is cell2.
|
||||
|
||||
kl2 = (struct property *)HashFirst(&(ecomp->cell2->propdict));
|
||||
while (kl2 != NULL) {
|
||||
if (kl1 != NULL) {
|
||||
if ((*matchfunc)(kl1->key, kl2->key))
|
||||
break;
|
||||
}
|
||||
else if (kl2->merge == MERGE_ADD_CRIT || kl2->merge == MERGE_PAR_CRIT)
|
||||
break;
|
||||
kl2 = (struct property *)HashNext(&(ecomp->cell2->propdict));
|
||||
}
|
||||
if (kl2 != NULL) {
|
||||
// Get slop value
|
||||
switch (kl2->type) {
|
||||
case PROP_INTEGER:
|
||||
slop = (double)kl2->slop.ival;
|
||||
break;
|
||||
case PROP_DOUBLE:
|
||||
case PROP_VALUE:
|
||||
slop = kl2->slop.dval;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If cell2 had a mergeable property but cell1 didn't, then look
|
||||
// through cell1 again to find the equivalent property.
|
||||
|
||||
if ((kl1 == NULL) && (kl2 != NULL)) {
|
||||
kl1 = (struct property *)HashFirst(&(ecomp->cell1->propdict));
|
||||
while (kl1 != NULL) {
|
||||
if ((*matchfunc)(kl1->key, kl2->key))
|
||||
break;
|
||||
kl1 = (struct property *)HashNext(&(ecomp->cell1->propdict));
|
||||
}
|
||||
}
|
||||
if (kl1 != NULL) {
|
||||
// Get slop value
|
||||
switch (kl1->type) {
|
||||
case PROP_INTEGER:
|
||||
slop = MAX(slop, (double)kl1->slop.ival);
|
||||
break;
|
||||
case PROP_DOUBLE:
|
||||
case PROP_VALUE:
|
||||
slop = MAX(slop, kl1->slop.dval);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ((kl1 != NULL) && (kl2 != NULL)) {
|
||||
|
||||
double dval, dval1, dval2, mindev, pd, df, dr;
|
||||
unsigned char dosplit;
|
||||
char *valptr;
|
||||
int ndev;
|
||||
|
||||
// Create the device hash table
|
||||
|
||||
InitializeHashTable(&devdict, OBJHASHSIZE);
|
||||
|
||||
// Populate the device hash table
|
||||
|
||||
SurveyDevice(tc1, &devdict, ecomp->cell1, kl1, file1, file2, 0);
|
||||
SurveyDevice(tc2, &devdict, ecomp->cell2, kl2, file1, file2, 1);
|
||||
|
||||
// Scan the device hash table. If devices can be merged
|
||||
// and this improves the matching between cells, then do
|
||||
// the merge.
|
||||
|
||||
mindev = 1E20;
|
||||
dval1 = dval2 = 0.0;
|
||||
|
||||
dcomp = (ECompare *)HashFirst(&devdict);
|
||||
while (dcomp != NULL) {
|
||||
if ((dcomp->num1 == 0) || (dcomp->num2 == 0)) {
|
||||
valptr = strstr(devdict.hashfirstptr->name, "::");
|
||||
if (sscanf(valptr + 2, "%lg", &dval) == 1) {
|
||||
if (dval < mindev) mindev = dval;
|
||||
if (dcomp->num1 == 0)
|
||||
dval2 += (dval * dcomp->num2) / dcomp->refcount;
|
||||
else
|
||||
dval1 += (dval * dcomp->num1) / dcomp->refcount;
|
||||
}
|
||||
}
|
||||
dcomp = (ECompare *)HashNext(&devdict);
|
||||
}
|
||||
|
||||
// If dval2 and dval1 agree within slop, and both are
|
||||
// divisible by mindev, then break up all devices into
|
||||
// sizes of mindev.
|
||||
|
||||
dosplit = 0;
|
||||
pd = 2 * fabs(dval1 - dval2) / (dval1 + dval2);
|
||||
if (pd < slop) {
|
||||
df = dval1 / mindev;
|
||||
dr = round(df);
|
||||
pd = 2 * fabs(df - dr) / (df + dr);
|
||||
if (pd < slop) dosplit = 1;
|
||||
}
|
||||
|
||||
if (dosplit) {
|
||||
dcomp = (ECompare *)HashFirst(&devdict);
|
||||
while (dcomp != NULL) {
|
||||
if (dcomp->num1 == 0 || dcomp->num2 == 0) {
|
||||
valptr = strstr(devdict.hashfirstptr->name, "::");
|
||||
sscanf(valptr + 2, "%lg", &dval);
|
||||
ndev = (int)round(dval / mindev);
|
||||
}
|
||||
if (dcomp->num1 == 0) {
|
||||
SplitDevice(tc2, ecomp->cell2, kl2, dval, ndev,
|
||||
file1, file2, 1);
|
||||
modified++;
|
||||
}
|
||||
else if (dcomp->num2 == 0) {
|
||||
SplitDevice(tc1, ecomp->cell1, kl1, dval, ndev,
|
||||
file1, file2, 0);
|
||||
modified++;
|
||||
}
|
||||
dcomp = (ECompare *)HashNext(&devdict);
|
||||
}
|
||||
}
|
||||
|
||||
// Free the device hash table
|
||||
|
||||
dcomp = (ECompare *)HashFirst(&devdict);
|
||||
while (dcomp != NULL) {
|
||||
if (--dcomp->refcount == (char)0) FREE(dcomp);
|
||||
dcomp = (ECompare *)HashNext(&devdict);
|
||||
}
|
||||
HashKill(&devdict);
|
||||
}
|
||||
}
|
||||
|
||||
ecomp = (ECompare *)HashNext(&compdict);
|
||||
}
|
||||
|
||||
// Remove non-matching zero-value devices. This can
|
||||
// be done on a per-instance basis.
|
||||
|
||||
|
||||
+349
-88
@@ -618,7 +618,10 @@ struct FormattedList *FormatBadElementFragment(struct Element *E)
|
||||
count++;
|
||||
|
||||
elemlist->flist[k].count = count;
|
||||
elemlist->flist[k].name = ob->name + strlen(ob->instance.name) + 1;
|
||||
if (*ob->name != *ob->instance.name) // e.g., "port_match_error"
|
||||
elemlist->flist[k].name = ob->name;
|
||||
else
|
||||
elemlist->flist[k].name = ob->name + strlen(ob->instance.name) + 1;
|
||||
elemlist->flist[k].permute = (char)1;
|
||||
k++;
|
||||
}
|
||||
@@ -632,7 +635,10 @@ struct FormattedList *FormatBadElementFragment(struct Element *E)
|
||||
m = k;
|
||||
for (j = i; j < fanout; j++) {
|
||||
if (nodes[j] != NULL && nodes[i]->pin_magic == nodes[j]->pin_magic) {
|
||||
elemlist->flist[k].name = ob2->name + strlen(ob2->instance.name) + 1;
|
||||
if (*ob2->name != *ob2->instance.name) // e.g., "port_match_error"
|
||||
elemlist->flist[k].name = ob2->name;
|
||||
else
|
||||
elemlist->flist[k].name = ob2->name + strlen(ob2->instance.name) + 1;
|
||||
elemlist->flist[k].permute = (char)0;
|
||||
elemlist->flist[k].count = -1; // Put total count at end
|
||||
k++;
|
||||
@@ -1800,11 +1806,12 @@ struct Node *CreateNodeList(char *name, short graph)
|
||||
return (head);
|
||||
}
|
||||
|
||||
void CreateLists(char *name, short graph)
|
||||
/* creates two lists of the correct 'shape', then traverses nodes
|
||||
in sequence to link up 'subelement' field of ElementList,
|
||||
then 'node' field of NodeList structures.
|
||||
*/
|
||||
* in sequence to link up 'subelement' field of ElementList,
|
||||
* then 'node' field of NodeList structures.
|
||||
*/
|
||||
|
||||
void CreateLists(char *name, short graph)
|
||||
{
|
||||
struct Element *ElementScan;
|
||||
struct ElementList *EListScan;
|
||||
@@ -1826,6 +1833,8 @@ void CreateLists(char *name, short graph)
|
||||
return;
|
||||
}
|
||||
|
||||
CombineParallel(name, graph);
|
||||
|
||||
Elements = CreateElementList(name, graph);
|
||||
Nodes = CreateNodeList(name, graph);
|
||||
if (LookupElementList == NULL) return;
|
||||
@@ -1952,6 +1961,7 @@ void CreateLists(char *name, short graph)
|
||||
}
|
||||
|
||||
ConnectAllNodes(name, graph);
|
||||
CombineParallel(name, graph);
|
||||
|
||||
E = CreateElementList(name, graph);
|
||||
N = CreateNodeList(name, graph);
|
||||
@@ -3255,6 +3265,308 @@ int Iterate(void)
|
||||
return(!notdone);
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------*/
|
||||
/* "ob" points to the first property record of an object */
|
||||
/* instance. Check if there are multiple property records. If */
|
||||
/* so, group them by same properties of interest, order them by */
|
||||
/* critical property (if defined), and merge devices with the */
|
||||
/* same properties (by summing property "M" for devices; does */
|
||||
/* not apply to subcircuits, which must maintain individual */
|
||||
/* property records for each instance). */
|
||||
/*--------------------------------------------------------------*/
|
||||
|
||||
typedef struct _proplink *proplinkptr;
|
||||
typedef struct _proplink {
|
||||
struct property *prop;
|
||||
proplinkptr next;
|
||||
} proplink;
|
||||
|
||||
void PropertyOptimize(struct objlist *ob, struct nlist *tp)
|
||||
{
|
||||
struct objlist *ob2, *obt;
|
||||
struct property *kl, *m_rec, **plist;
|
||||
struct valuelist ***vlist, *vl, *vl2, *newvlist;
|
||||
proplinkptr plink, ptop;
|
||||
int pcount, p, i, j, icount, pmatch, ival, crit, ctype;
|
||||
double dval;
|
||||
static struct valuelist nullvl;
|
||||
|
||||
nullvl.type = PROP_INTEGER;
|
||||
nullvl.value.ival = 0;
|
||||
|
||||
// How many property records are there?
|
||||
// If there are not at least two property records then there
|
||||
// is nothing to be optimized.
|
||||
icount = 0;
|
||||
for (ob2 = ob; ob2 && ob2->type == PROPERTY; ob2 = ob2->next) icount++;
|
||||
if (icount < 2) return;
|
||||
|
||||
// Look through master cell property list and create
|
||||
// an array of properties of interest to fill in order.
|
||||
|
||||
m_rec = NULL;
|
||||
ptop = NULL;
|
||||
pcount = 1;
|
||||
crit = -1;
|
||||
ctype = -1;
|
||||
kl = (struct property *)HashFirst(&(tp->propdict));
|
||||
while (kl != NULL) {
|
||||
// Make a linked list so we don't have to iterate through the hash again
|
||||
plink = (proplinkptr)MALLOC(sizeof(proplink));
|
||||
plink->prop = kl;
|
||||
plink->next = ptop;
|
||||
ptop = plink;
|
||||
if ((*matchfunc)(kl->key, "M")) {
|
||||
kl->idx = 0;
|
||||
m_rec = kl;
|
||||
}
|
||||
else
|
||||
kl->idx = pcount++;
|
||||
|
||||
// Set critical property index, if there is one (TO-DO: Handle types
|
||||
// other than MERGE_ADD_CRIT, and deal with possibility of multiple
|
||||
// critical properties per instance).
|
||||
if (kl->merge == MERGE_ADD_CRIT) {
|
||||
crit = kl->idx;
|
||||
ctype = kl->merge;
|
||||
}
|
||||
kl = (struct property *)HashNext(&(tp->propdict));
|
||||
}
|
||||
// Recast the linked list as an array
|
||||
plist = (struct property **)CALLOC(pcount, sizeof(struct property *));
|
||||
vlist = (struct valuelist ***)CALLOC(pcount, sizeof(struct valuelist **));
|
||||
if (m_rec == NULL)
|
||||
vlist[0] = (struct valuelist **)CALLOC(icount, sizeof(struct valuelist *));
|
||||
|
||||
while (ptop != NULL) {
|
||||
plist[ptop->prop->idx] = ptop->prop;
|
||||
vlist[ptop->prop->idx] = (struct valuelist **)CALLOC(icount,
|
||||
sizeof(struct valuelist *));
|
||||
plink = ptop;
|
||||
FREE(ptop);
|
||||
ptop = plink->next;
|
||||
}
|
||||
|
||||
// Now, for each property record, sort the properties of interest
|
||||
// so that they are all in order. Property "M" goes in position
|
||||
// zero.
|
||||
|
||||
i = 0;
|
||||
for (ob2 = ob; ob2 && ob2->type == PROPERTY; ob2 = ob2->next) {
|
||||
for (p = 0;; p++) {
|
||||
vl = &(ob2->instance.props[p]);
|
||||
if (vl->type == PROP_ENDLIST) break;
|
||||
if (vl->key == NULL) continue;
|
||||
kl = (struct property *)HashLookup(vl->key, &(tp->propdict));
|
||||
if (kl == NULL && m_rec == NULL) {
|
||||
if ((*matchfunc)(vl->key, "M")) {
|
||||
vlist[0][i] = vl;
|
||||
}
|
||||
}
|
||||
else if (kl != NULL) {
|
||||
vlist[kl->idx][i] = vl;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
// Check for "M" records with type double and promote them to integer
|
||||
for (i = 0; i < icount; i++) {
|
||||
vl = vlist[0][i];
|
||||
if (vl != NULL) {
|
||||
if (vl->type == PROP_DOUBLE) {
|
||||
vl->type = PROP_INTEGER;
|
||||
vl->value.ival = (int)(vl->value.dval + 0.5);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Now combine records with same properties by summing M.
|
||||
for (i = 0; i < icount - 1; i++) {
|
||||
for (j = 1; j < icount; j++) {
|
||||
pmatch = 0;
|
||||
for (p = 1; p < pcount; p++) {
|
||||
kl = plist[p];
|
||||
vl = vlist[p][i];
|
||||
vl2 = vlist[p][j];
|
||||
if (vl == NULL && vl2 == NULL) {
|
||||
pmatch++;
|
||||
continue;
|
||||
}
|
||||
// TO-DO: If either value is missing, it takes kl->pdefault
|
||||
// and must apply promotions if necessary.
|
||||
else if (vl == NULL || vl2 == NULL) continue;
|
||||
|
||||
// Critical properties will be multiplied up by M and do not
|
||||
// need to match. May want a more nuanced comparison, though.
|
||||
if (p == crit) {
|
||||
pmatch++;
|
||||
continue;
|
||||
}
|
||||
|
||||
switch(vl->type) {
|
||||
case PROP_DOUBLE:
|
||||
case PROP_VALUE:
|
||||
dval = fabs(vl->value.dval - vl2->value.dval);
|
||||
if (dval <= kl->slop.dval) pmatch++;
|
||||
break;
|
||||
case PROP_INTEGER:
|
||||
ival = abs(vl->value.ival - vl2->value.ival);
|
||||
if (ival <= kl->slop.ival) pmatch++;
|
||||
break;
|
||||
case PROP_STRING:
|
||||
if ((*matchfunc)(vl->value.string, vl2->value.string)) pmatch++;
|
||||
break;
|
||||
|
||||
/* will not attempt to match expressions, but it could
|
||||
* be done with some minor effort by matching each
|
||||
* stack token and comparing those that are strings.
|
||||
*/
|
||||
}
|
||||
}
|
||||
if (pmatch == (pcount - 1)) {
|
||||
// Sum M (p == 0) records and remove one record
|
||||
if (vlist[0][i] == NULL) {
|
||||
// Add this to the end of the property record
|
||||
// find ith record in ob
|
||||
p = 0;
|
||||
for (ob2 = ob; p != i; ob2 = ob2->next, p++);
|
||||
// Count entries, add one, reallocate
|
||||
for (p = 0;; p++) {
|
||||
vl = &ob2->instance.props[p];
|
||||
if (vl->type == PROP_ENDLIST) break;
|
||||
}
|
||||
p++;
|
||||
newvlist = (struct valuelist *)CALLOC(p + 1,
|
||||
sizeof(struct valuelist));
|
||||
// Move end record forward
|
||||
vl = &newvlist[p];
|
||||
vl->key = NULL;
|
||||
vl->type = PROP_ENDLIST;
|
||||
vl->value.ival = 0;
|
||||
|
||||
// Add "M" record behind it
|
||||
vl = &newvlist[--p];
|
||||
vl->key = strsave("M");
|
||||
vl->type = PROP_INTEGER;
|
||||
vl->value.ival = 1;
|
||||
vlist[0][i] = vl;
|
||||
// Copy the rest of the records and regenerate vlist
|
||||
for (--p; p >= 0; p--) {
|
||||
vl = &newvlist[p];
|
||||
vl->key = ob2->instance.props[p].key;
|
||||
vl->type = ob2->instance.props[p].type;
|
||||
vl->value = ob2->instance.props[p].value;
|
||||
|
||||
kl = (struct property *)HashLookup(vl->key, &(tp->propdict));
|
||||
if (kl != NULL) vlist[kl->idx][i] = vl;
|
||||
}
|
||||
|
||||
// Replace instance properties with the new list
|
||||
FREE(ob2->instance.props);
|
||||
ob2->instance.props = newvlist;
|
||||
}
|
||||
|
||||
// If there is a critical property, then M is never
|
||||
// greater than 1.
|
||||
if (crit >= 0) {
|
||||
if (vlist[0][i] != NULL) {
|
||||
if (vlist[0][i]->value.ival > 1) {
|
||||
vl = vlist[crit][i];
|
||||
if (vl->type == PROP_INTEGER)
|
||||
vl->value.ival *= vlist[0][i]->value.ival;
|
||||
else if (vl->type == PROP_DOUBLE)
|
||||
vl->value.dval *= (double)vlist[0][i]->value.ival;
|
||||
vlist[0][i]->value.ival = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (vlist[0][j] == NULL) {
|
||||
vlist[0][j] = &nullvl; // Mark this position
|
||||
if (crit >= 0) {
|
||||
vl = vlist[crit][i];
|
||||
if ((vl != NULL) && (ctype == MERGE_ADD_CRIT)) {
|
||||
if (vl->type == PROP_INTEGER)
|
||||
vl->value.ival += vlist[crit][j]->value.ival;
|
||||
else if (vl->type == PROP_DOUBLE)
|
||||
vl->value.dval += vlist[crit][j]->value.dval;
|
||||
}
|
||||
else if (vl != NULL) { /* MERGE_PAR_CRIT */
|
||||
if (vl->type == PROP_INTEGER) {
|
||||
double di = vl->value.ival;
|
||||
double dj = vlist[crit][j]->value.ival;
|
||||
di = 1.0 / (1.0 / di + 1.0 / dj);
|
||||
vl->value.ival = (int)di;
|
||||
}
|
||||
else if (vl->type == PROP_DOUBLE) {
|
||||
vl->value.dval += 1.0 / (1.0 / vl->value.dval +
|
||||
1.0 / vlist[crit][j]->value.dval);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
vlist[0][i]->value.ival++;
|
||||
}
|
||||
}
|
||||
else if (vlist[0][i]->value.ival > 0) {
|
||||
if (crit >= 0) {
|
||||
vl = vlist[crit][i];
|
||||
if ((vl != NULL) && (ctype == MERGE_ADD_CRIT)) {
|
||||
if (vl->type == PROP_INTEGER)
|
||||
vl->value.ival += vlist[0][j]->value.ival *
|
||||
vlist[crit][j]->value.ival;
|
||||
else if (vl->type == PROP_DOUBLE)
|
||||
vl->value.dval += (double)vlist[0][j]->value.ival *
|
||||
vlist[crit][j]->value.dval;
|
||||
}
|
||||
else if (vl != NULL) { /* MERGE_PAR_CRIT */
|
||||
if (vl->type == PROP_INTEGER) {
|
||||
double d = (double)vlist[crit][j]->value.ival /
|
||||
(double)vlist[0][j]->value.ival;
|
||||
vl->value.ival = (int)(1.0 / (1.0 / (double)vl->value.ival
|
||||
+ 1.0 / d));
|
||||
}
|
||||
else if (vl->type == PROP_DOUBLE) {
|
||||
double d = vlist[crit][j]->value.dval /
|
||||
(double)vlist[0][j]->value.ival;
|
||||
vl->value.dval = 1.0 / (1.0 / vl->value.dval + 1.0 / d);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
vlist[0][i]->value.ival += vlist[0][j]->value.ival;
|
||||
}
|
||||
vlist[0][j]->value.ival = 0;
|
||||
}
|
||||
}
|
||||
else j++;
|
||||
}
|
||||
}
|
||||
|
||||
// Remove entries with M = 0
|
||||
ob2 = ob;
|
||||
for (i = 1; i < icount; i++) {
|
||||
vl = vlist[0][i];
|
||||
if (vl != NULL && vl->value.ival == 0) {
|
||||
obt = ob2->next;
|
||||
ob2->next = ob2->next->next;
|
||||
FreeObjectAndHash(obt, tp);
|
||||
}
|
||||
else
|
||||
ob2 = ob2->next;
|
||||
}
|
||||
|
||||
// Cleanup memory allocation
|
||||
for (p = 0; p < pcount; p++) {
|
||||
kl = (struct property *)plist[p];
|
||||
if (kl) kl->idx = 0;
|
||||
FREE(vlist[p]);
|
||||
}
|
||||
FREE(plist);
|
||||
FREE(vlist);
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------*/
|
||||
/* Compare the properties of two objects. The passed values */
|
||||
/* ob1 and ob2 are pointers to the first entry (firstpin) of */
|
||||
@@ -3310,6 +3622,10 @@ int PropertyMatch(struct objlist *ob1, struct objlist *ob2, int do_print)
|
||||
|
||||
if ((t1type != PROPERTY) && (t2type != PROPERTY)) return 0;
|
||||
|
||||
// Organize and merge property records
|
||||
if (t1type == PROPERTY) PropertyOptimize(tp1, tc1);
|
||||
if (t2type == PROPERTY) PropertyOptimize(tp2, tc2);
|
||||
|
||||
if (t1type != PROPERTY) {
|
||||
// t1 has no properties. See if t2's properties are required
|
||||
// to be checked. If so, flag t1 as missing required properties
|
||||
@@ -3894,80 +4210,6 @@ int ResolveAutomorphisms()
|
||||
return(VerifyMatching());
|
||||
}
|
||||
|
||||
/*------------------------------------------------------*/
|
||||
/* CombineSetup -- */
|
||||
/* Add an entry to a cell describing the combination */
|
||||
/* allowances. */
|
||||
/* Return 1 if OK, 0 if error */
|
||||
/*------------------------------------------------------*/
|
||||
|
||||
int CombineSetup(char *model, int filenum, int comb_type)
|
||||
{
|
||||
struct nlist *tp;
|
||||
|
||||
// If -1 is passed as filenum, then re-run this routine on
|
||||
// each of Circuit1 and Circuit2 models.
|
||||
|
||||
if (filenum == -1) {
|
||||
if ((Circuit1 != NULL) && (Circuit1->file != -1))
|
||||
CombineSetup(model, Circuit1->file, comb_type);
|
||||
if ((Circuit2 != NULL) && (Circuit2->file != -1))
|
||||
CombineSetup(model, Circuit2->file, comb_type);
|
||||
return 1;
|
||||
}
|
||||
|
||||
tp = LookupCellFile(model, filenum);
|
||||
if (tp == NULL) {
|
||||
Printf("No such model %s\n", model);
|
||||
return 0;
|
||||
}
|
||||
|
||||
tp->flags |= comb_type;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------*/
|
||||
/* CombineForget -- */
|
||||
/* Remove combination allowances for a cell */
|
||||
/* */
|
||||
/* Return 1 if OK, 0 if error */
|
||||
/* */
|
||||
/* If comb_type is 0, then forget all allowed */
|
||||
/* combinations of the device. */
|
||||
/*------------------------------------------------------*/
|
||||
|
||||
int CombineForget(char *model, int filenum, int comb_type)
|
||||
{
|
||||
struct nlist *tp;
|
||||
|
||||
// If -1 is passed as filenum, then re-run this routine on
|
||||
// each of Circuit1 and Circuit2 models.
|
||||
|
||||
if (filenum == -1) {
|
||||
if ((Circuit1 != NULL) && (Circuit1->file != -1))
|
||||
CombineForget(model, Circuit1->file, comb_type);
|
||||
if ((Circuit2 != NULL) && (Circuit2->file != -1))
|
||||
CombineForget(model, Circuit2->file, comb_type);
|
||||
return 1;
|
||||
}
|
||||
|
||||
tp = LookupCellFile(model, filenum);
|
||||
if (tp == NULL) {
|
||||
Printf("No such model %s\n", model);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (comb_type != 0) {
|
||||
/* Remove this specific combination allowance */
|
||||
tp->flags &= ~comb_type;
|
||||
}
|
||||
else {
|
||||
/* Blanket remove all combinations for this device */
|
||||
tp->flags &= ~(COMB_SERIAL | COMB_PARALLEL);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------*/
|
||||
/* PermuteSetup -- */
|
||||
/* Add an entry to a cell's "permutes" linked list. */
|
||||
@@ -4309,13 +4551,13 @@ int EquivalenceNodes(char *name1, int file1, char *name2, int file2)
|
||||
/* database. */
|
||||
/*------------------------------------------------------*/
|
||||
|
||||
int IgnoreClass(char *name, int file)
|
||||
int IgnoreClass(char *name, int file, unsigned char type)
|
||||
{
|
||||
struct IgnoreList *newIgnore;
|
||||
|
||||
if ((file == -1) && (Circuit1 != NULL) && (Circuit2 != NULL)) {
|
||||
IgnoreClass(name, Circuit1->file);
|
||||
IgnoreClass(name, Circuit2->file);
|
||||
IgnoreClass(name, Circuit1->file, type);
|
||||
IgnoreClass(name, Circuit2->file, type);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -4325,9 +4567,13 @@ int IgnoreClass(char *name, int file)
|
||||
newIgnore->class = (char *)MALLOC(1 + strlen(name));
|
||||
strcpy(newIgnore->class, name);
|
||||
newIgnore->file = file;
|
||||
newIgnore->type = type;
|
||||
|
||||
/* Remove existing classes from database */
|
||||
ClassDelete(name, file);
|
||||
if (type == IGNORE_CLASS)
|
||||
ClassDelete(name, file);
|
||||
else
|
||||
RemoveShorted(name, file);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -4476,10 +4722,19 @@ int reorderpins(struct hashlist *p, int file)
|
||||
}
|
||||
ob = ob->next;
|
||||
ob2 = ob2->next;
|
||||
if (ob == NULL) {
|
||||
Fprintf(stderr, "Instance of %s has only %d of %d ports\n",
|
||||
if (i < numports - 1) {
|
||||
if (ob == NULL || ob->type <= FIRSTPIN) {
|
||||
Fprintf(stderr, "Instance of %s has only "
|
||||
"%d of %d ports\n",
|
||||
tc2->name, i + 1, numports);
|
||||
break;
|
||||
break;
|
||||
}
|
||||
else if (ob2 == NULL || ob2->type != PORT) {
|
||||
Fprintf(stderr, "Instance of %s has "
|
||||
"%d ports, expected %d\n",
|
||||
tc2->name, i + 1, numports);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4557,7 +4812,7 @@ struct nlist *addproxies(struct hashlist *p, void *clientdata)
|
||||
tob = tc->cell;
|
||||
i = FIRSTPIN;
|
||||
firstpin = ob;
|
||||
while (ob && (tob->type == PORT || tob->type == UNKNOWN)) {
|
||||
while (tob && (tob->type == PORT || tob->type == UNKNOWN)) {
|
||||
if (tob->type == UNKNOWN) {
|
||||
obn = (struct objlist *)CALLOC(1, sizeof(struct objlist));
|
||||
obn->name = (char *)MALLOC(strlen(firstpin->instance.name)
|
||||
@@ -4579,6 +4834,12 @@ struct nlist *addproxies(struct hashlist *p, void *clientdata)
|
||||
HashPtrInstall(firstpin->instance.name, firstpin, &(ptr->instdict));
|
||||
}
|
||||
}
|
||||
else if (ob == NULL) {
|
||||
// This should not happen. . .
|
||||
Fprintf(stdout, "Error: Premature end of pin list on instance %s.\n",
|
||||
firstpin->instance.name);
|
||||
break;
|
||||
}
|
||||
else {
|
||||
lob = ob;
|
||||
ob->type = i++;
|
||||
|
||||
+1
-1
@@ -32,7 +32,7 @@ extern int PermuteForget(char *model, int filenum, char *pin1, char *pin2);
|
||||
extern int EquivalenceElements(char *name1, int file1, char *name2, int file2);
|
||||
extern int EquivalenceNodes(char *name1, int file1, char *name2, int file2);
|
||||
extern int EquivalenceClasses(char *name1, int file1, char *name2, int file2);
|
||||
extern int IgnoreClass(char *name, int file);
|
||||
extern int IgnoreClass(char *name, int file, unsigned char type);
|
||||
extern int MatchPins(struct nlist *tp1, struct nlist *tp2);
|
||||
|
||||
extern int CreateCompareQueue(char *, int, char *, int);
|
||||
|
||||
+472
-296
@@ -30,6 +30,10 @@ the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
#include <alloc.h>
|
||||
#endif
|
||||
|
||||
#ifdef TCL_NETGEN
|
||||
#include <tcl.h>
|
||||
#endif
|
||||
|
||||
#include "netgen.h"
|
||||
#include "hash.h"
|
||||
#include "objlist.h"
|
||||
@@ -278,261 +282,279 @@ int ReduceExpressions(struct objlist *instprop, struct objlist *parprops,
|
||||
for (i = 0;; i++) {
|
||||
|
||||
kv = &(instprop->instance.props[i]);
|
||||
switch (kv->type) {
|
||||
case PROP_ENDLIST:
|
||||
break;
|
||||
|
||||
if (kv->type == PROP_ENDLIST)
|
||||
break;
|
||||
else if (kv->type == PROP_EXPRESSION) {
|
||||
expstack = kv->value.stack;
|
||||
}
|
||||
else if (kv->type == PROP_STRING) {
|
||||
expstack = NULL;
|
||||
estr = kv->value.string;
|
||||
tstr = estr;
|
||||
case PROP_INTEGER:
|
||||
case PROP_DOUBLE:
|
||||
case PROP_VALUE:
|
||||
continue;
|
||||
|
||||
numlast = 0;
|
||||
while (*tstr != '\0') {
|
||||
switch(*tstr) {
|
||||
case PROP_EXPRESSION:
|
||||
expstack = kv->value.stack;
|
||||
break;
|
||||
|
||||
case PROP_STRING:
|
||||
|
||||
expstack = NULL;
|
||||
estr = kv->value.string;
|
||||
tstr = estr;
|
||||
|
||||
numlast = 0;
|
||||
while (*tstr != '\0') {
|
||||
switch(*tstr) {
|
||||
|
||||
case '+':
|
||||
if (numlast == 0) {
|
||||
/* This is part of a number */
|
||||
dval = strtod(estr, &sstr);
|
||||
if (sstr > estr && sstr > tstr) {
|
||||
tstr = sstr - 1;
|
||||
numlast = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
/* Not a number, so must be arithmetic */
|
||||
*tstr = '\0';
|
||||
result = TokGetValue(estr, parent, parprops, glob, &dval);
|
||||
if (result == 1) PushTok(TOK_DOUBLE, &dval, &expstack);
|
||||
else if (result == -1) PushTok(TOK_STRING, estr, &expstack);
|
||||
PushTok(TOK_PLUS, NULL, &expstack);
|
||||
estr = tstr + 1;
|
||||
numlast = 0;
|
||||
break;
|
||||
|
||||
case '-':
|
||||
if (numlast == 0) {
|
||||
/* This is part of a number */
|
||||
dval = strtod(estr, &sstr);
|
||||
if (sstr > estr && sstr > tstr) {
|
||||
tstr = sstr - 1;
|
||||
numlast = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
/* Not a number, so must be arithmetic */
|
||||
*tstr = '\0';
|
||||
result = TokGetValue(estr, parent, parprops, glob, &dval);
|
||||
if (result == 1) PushTok(TOK_DOUBLE, &dval, &expstack);
|
||||
else if (result == -1) PushTok(TOK_STRING, estr, &expstack);
|
||||
PushTok(TOK_MINUS, NULL, &expstack);
|
||||
estr = tstr + 1;
|
||||
numlast = 0;
|
||||
break;
|
||||
|
||||
case '1': case '2': case '3': case '4': case '5':
|
||||
case '6': case '7': case '8': case '9': case '0':
|
||||
/* Numerical value. Use strtod() to capture */
|
||||
if (numlast == 1) break;
|
||||
dval = strtod(estr, &sstr);
|
||||
if (sstr > estr && sstr > tstr) {
|
||||
tstr = sstr - 1;
|
||||
numlast = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case '/':
|
||||
*tstr = '\0';
|
||||
result = TokGetValue(estr, parent, parprops, glob, &dval);
|
||||
if (result == 1) PushTok(TOK_DOUBLE, &dval, &expstack);
|
||||
else if (result == -1) PushTok(TOK_STRING, estr, &expstack);
|
||||
PushTok(TOK_DIVIDE, NULL, &expstack);
|
||||
estr = tstr + 1;
|
||||
numlast = 0;
|
||||
break;
|
||||
|
||||
case '*':
|
||||
*tstr = '\0';
|
||||
result = TokGetValue(estr, parent, parprops, glob, &dval);
|
||||
if (result == 1) PushTok(TOK_DOUBLE, &dval, &expstack);
|
||||
else if (result == -1) PushTok(TOK_STRING, estr, &expstack);
|
||||
PushTok(TOK_MULTIPLY, NULL, &expstack);
|
||||
estr = tstr + 1;
|
||||
numlast = 0;
|
||||
break;
|
||||
|
||||
case '(':
|
||||
*tstr = '\0';
|
||||
|
||||
/* Check for predefined function keywords */
|
||||
|
||||
if (!strcmp(estr, "IF")) {
|
||||
PushTok(TOK_FUNC_IF, NULL, &expstack);
|
||||
}
|
||||
else {
|
||||
/* Treat as a parenthetical grouping */
|
||||
|
||||
result = TokGetValue(estr, parent, parprops, glob, &dval);
|
||||
if (result == 1) PushTok(TOK_DOUBLE, &dval, &expstack);
|
||||
else if (result == -1) PushTok(TOK_STRING, estr, &expstack);
|
||||
PushTok(TOK_FUNC_OPEN, NULL, &expstack);
|
||||
}
|
||||
estr = tstr + 1;
|
||||
numlast = 0;
|
||||
break;
|
||||
|
||||
case ')':
|
||||
*tstr = '\0';
|
||||
|
||||
if (expstack == NULL) break;
|
||||
savetok = expstack->toktype;
|
||||
|
||||
result = TokGetValue(estr, parent, parprops, glob, &dval);
|
||||
if (result == 1) PushTok(TOK_DOUBLE, &dval, &expstack);
|
||||
else if (result == -1) PushTok(TOK_STRING, estr, &expstack);
|
||||
|
||||
switch (savetok) {
|
||||
case TOK_FUNC_THEN:
|
||||
PushTok(TOK_FUNC_ELSE, NULL, &expstack);
|
||||
case '+':
|
||||
if (numlast == 0) {
|
||||
/* This is part of a number */
|
||||
dval = strtod(estr, &sstr);
|
||||
if (sstr > estr && sstr > tstr) {
|
||||
tstr = sstr - 1;
|
||||
numlast = 1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
PushTok(TOK_FUNC_CLOSE, NULL, &expstack);
|
||||
break;
|
||||
}
|
||||
numlast = 1;
|
||||
estr = tstr + 1;
|
||||
break;
|
||||
|
||||
case '\'':
|
||||
*tstr = '\0';
|
||||
result = TokGetValue(estr, parent, parprops, glob, &dval);
|
||||
if (result == 1) PushTok(TOK_DOUBLE, &dval, &expstack);
|
||||
else if (result == -1) PushTok(TOK_STRING, estr, &expstack);
|
||||
PushTok(TOK_SGL_QUOTE, NULL, &expstack);
|
||||
estr = tstr + 1;
|
||||
numlast = 0;
|
||||
break;
|
||||
|
||||
case '"':
|
||||
*tstr = '\0';
|
||||
result = TokGetValue(estr, parent, parprops, glob, &dval);
|
||||
if (result == 1) PushTok(TOK_DOUBLE, &dval, &expstack);
|
||||
else if (result == -1) PushTok(TOK_STRING, estr, &expstack);
|
||||
PushTok(TOK_DBL_QUOTE, NULL, &expstack);
|
||||
estr = tstr + 1;
|
||||
numlast = 0;
|
||||
break;
|
||||
|
||||
case '{':
|
||||
*tstr = '\0';
|
||||
result = TokGetValue(estr, parent, parprops, glob, &dval);
|
||||
if (result == 1) PushTok(TOK_DOUBLE, &dval, &expstack);
|
||||
else if (result == -1) PushTok(TOK_STRING, estr, &expstack);
|
||||
PushTok(TOK_GROUP_OPEN, NULL, &expstack);
|
||||
estr = tstr + 1;
|
||||
numlast = 0;
|
||||
break;
|
||||
|
||||
case '}':
|
||||
*tstr = '\0';
|
||||
result = TokGetValue(estr, parent, parprops, glob, &dval);
|
||||
if (result == 1) PushTok(TOK_DOUBLE, &dval, &expstack);
|
||||
PushTok(TOK_GROUP_CLOSE, NULL, &expstack);
|
||||
estr = tstr + 1;
|
||||
numlast = 1;
|
||||
break;
|
||||
|
||||
case '!':
|
||||
if (*(tstr + 1) == '=') {
|
||||
}
|
||||
/* Not a number, so must be arithmetic */
|
||||
*tstr = '\0';
|
||||
result = TokGetValue(estr, parent, parprops, glob, &dval);
|
||||
if (result == 1) PushTok(TOK_DOUBLE, &dval, &expstack);
|
||||
else if (result == -1) PushTok(TOK_STRING, estr, &expstack);
|
||||
PushTok(TOK_NE, NULL, &expstack);
|
||||
}
|
||||
numlast = 0;
|
||||
break;
|
||||
|
||||
case '=':
|
||||
if (*(tstr + 1) == '=') {
|
||||
*tstr = '\0';
|
||||
result = TokGetValue(estr, parent, parprops, glob, &dval);
|
||||
if (result == 1) PushTok(TOK_DOUBLE, &dval, &expstack);
|
||||
else if (result == -1) PushTok(TOK_STRING, estr, &expstack);
|
||||
PushTok(TOK_EQ, NULL, &expstack);
|
||||
PushTok(TOK_PLUS, NULL, &expstack);
|
||||
estr = tstr + 1;
|
||||
numlast = 0;
|
||||
}
|
||||
break;
|
||||
break;
|
||||
|
||||
case '>':
|
||||
*tstr = '\0';
|
||||
result = TokGetValue(estr, parent, parprops, glob, &dval);
|
||||
if (result == 1) PushTok(TOK_DOUBLE, &dval, &expstack);
|
||||
else if (result == -1) PushTok(TOK_STRING, estr, &expstack);
|
||||
|
||||
if (*(tstr + 1) == '=') {
|
||||
PushTok(TOK_GE, NULL, &expstack);
|
||||
tstr++;
|
||||
}
|
||||
else
|
||||
PushTok(TOK_GT, NULL, &expstack);
|
||||
estr = tstr + 1;
|
||||
numlast = 0;
|
||||
break;
|
||||
|
||||
case '<':
|
||||
*tstr = '\0';
|
||||
result = TokGetValue(estr, parent, parprops, glob, &dval);
|
||||
if (result == 1) PushTok(TOK_DOUBLE, &dval, &expstack);
|
||||
else if (result == -1) PushTok(TOK_STRING, estr, &expstack);
|
||||
|
||||
if (*(tstr + 1) == '=') {
|
||||
PushTok(TOK_LE, NULL, &expstack);
|
||||
tstr++;
|
||||
}
|
||||
else
|
||||
PushTok(TOK_LT, NULL, &expstack);
|
||||
estr = tstr + 1;
|
||||
numlast = 0;
|
||||
break;
|
||||
|
||||
case ',':
|
||||
*tstr = '\0';
|
||||
result = TokGetValue(estr, parent, parprops, glob, &dval);
|
||||
if (result == 1) PushTok(TOK_DOUBLE, &dval, &expstack);
|
||||
else if (result == -1) PushTok(TOK_STRING, estr, &expstack);
|
||||
if (expstack == NULL) break;
|
||||
lptr = expstack;
|
||||
while (lptr->next) {
|
||||
lptr = lptr->next;
|
||||
if (lptr->toktype == TOK_FUNC_THEN) {
|
||||
PushTok(TOK_FUNC_ELSE, NULL, &expstack);
|
||||
case '-':
|
||||
if (numlast == 0) {
|
||||
/* This is part of a number */
|
||||
dval = strtod(estr, &sstr);
|
||||
if (sstr > estr && sstr > tstr) {
|
||||
tstr = sstr - 1;
|
||||
numlast = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
else if (lptr->toktype == TOK_FUNC_IF) {
|
||||
PushTok(TOK_FUNC_THEN, NULL, &expstack);
|
||||
break;
|
||||
}
|
||||
}
|
||||
estr = tstr + 1;
|
||||
numlast = 0;
|
||||
break;
|
||||
/* Not a number, so must be arithmetic */
|
||||
*tstr = '\0';
|
||||
result = TokGetValue(estr, parent, parprops, glob, &dval);
|
||||
if (result == 1) PushTok(TOK_DOUBLE, &dval, &expstack);
|
||||
else if (result == -1) PushTok(TOK_STRING, estr, &expstack);
|
||||
PushTok(TOK_MINUS, NULL, &expstack);
|
||||
estr = tstr + 1;
|
||||
numlast = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
case '1': case '2': case '3': case '4': case '5':
|
||||
case '6': case '7': case '8': case '9': case '0':
|
||||
/* Numerical value. Use strtod() to capture */
|
||||
if (numlast == 1) break;
|
||||
dval = strtod(estr, &sstr);
|
||||
if (sstr > estr && sstr > tstr) {
|
||||
tstr = sstr - 1;
|
||||
numlast = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case '/':
|
||||
*tstr = '\0';
|
||||
result = TokGetValue(estr, parent, parprops, glob, &dval);
|
||||
if (result == 1) PushTok(TOK_DOUBLE, &dval, &expstack);
|
||||
else if (result == -1) PushTok(TOK_STRING, estr, &expstack);
|
||||
PushTok(TOK_DIVIDE, NULL, &expstack);
|
||||
estr = tstr + 1;
|
||||
numlast = 0;
|
||||
break;
|
||||
|
||||
case '*':
|
||||
*tstr = '\0';
|
||||
result = TokGetValue(estr, parent, parprops, glob, &dval);
|
||||
if (result == 1) PushTok(TOK_DOUBLE, &dval, &expstack);
|
||||
else if (result == -1) PushTok(TOK_STRING, estr, &expstack);
|
||||
PushTok(TOK_MULTIPLY, NULL, &expstack);
|
||||
estr = tstr + 1;
|
||||
numlast = 0;
|
||||
break;
|
||||
|
||||
case '(':
|
||||
*tstr = '\0';
|
||||
|
||||
/* Check for predefined function keywords */
|
||||
|
||||
if (!strcmp(estr, "IF")) {
|
||||
PushTok(TOK_FUNC_IF, NULL, &expstack);
|
||||
}
|
||||
else {
|
||||
/* Treat as a parenthetical grouping */
|
||||
|
||||
result = TokGetValue(estr, parent, parprops,
|
||||
glob, &dval);
|
||||
if (result == 1)
|
||||
PushTok(TOK_DOUBLE, &dval, &expstack);
|
||||
else if (result == -1)
|
||||
PushTok(TOK_STRING, estr, &expstack);
|
||||
PushTok(TOK_FUNC_OPEN, NULL, &expstack);
|
||||
}
|
||||
estr = tstr + 1;
|
||||
numlast = 0;
|
||||
break;
|
||||
|
||||
case ')':
|
||||
*tstr = '\0';
|
||||
|
||||
if (expstack == NULL) break;
|
||||
savetok = expstack->toktype;
|
||||
|
||||
result = TokGetValue(estr, parent, parprops, glob, &dval);
|
||||
if (result == 1) PushTok(TOK_DOUBLE, &dval, &expstack);
|
||||
else if (result == -1) PushTok(TOK_STRING, estr, &expstack);
|
||||
|
||||
switch (savetok) {
|
||||
case TOK_FUNC_THEN:
|
||||
PushTok(TOK_FUNC_ELSE, NULL, &expstack);
|
||||
break;
|
||||
default:
|
||||
PushTok(TOK_FUNC_CLOSE, NULL, &expstack);
|
||||
break;
|
||||
}
|
||||
numlast = 1;
|
||||
estr = tstr + 1;
|
||||
break;
|
||||
|
||||
case '\'':
|
||||
*tstr = '\0';
|
||||
result = TokGetValue(estr, parent, parprops, glob, &dval);
|
||||
if (result == 1) PushTok(TOK_DOUBLE, &dval, &expstack);
|
||||
else if (result == -1) PushTok(TOK_STRING, estr, &expstack);
|
||||
PushTok(TOK_SGL_QUOTE, NULL, &expstack);
|
||||
estr = tstr + 1;
|
||||
numlast = 0;
|
||||
break;
|
||||
|
||||
case '"':
|
||||
*tstr = '\0';
|
||||
result = TokGetValue(estr, parent, parprops, glob, &dval);
|
||||
if (result == 1) PushTok(TOK_DOUBLE, &dval, &expstack);
|
||||
else if (result == -1) PushTok(TOK_STRING, estr, &expstack);
|
||||
PushTok(TOK_DBL_QUOTE, NULL, &expstack);
|
||||
estr = tstr + 1;
|
||||
numlast = 0;
|
||||
break;
|
||||
|
||||
case '{':
|
||||
*tstr = '\0';
|
||||
result = TokGetValue(estr, parent, parprops, glob, &dval);
|
||||
if (result == 1) PushTok(TOK_DOUBLE, &dval, &expstack);
|
||||
else if (result == -1) PushTok(TOK_STRING, estr, &expstack);
|
||||
PushTok(TOK_GROUP_OPEN, NULL, &expstack);
|
||||
estr = tstr + 1;
|
||||
numlast = 0;
|
||||
break;
|
||||
|
||||
case '}':
|
||||
*tstr = '\0';
|
||||
result = TokGetValue(estr, parent, parprops, glob, &dval);
|
||||
if (result == 1) PushTok(TOK_DOUBLE, &dval, &expstack);
|
||||
PushTok(TOK_GROUP_CLOSE, NULL, &expstack);
|
||||
estr = tstr + 1;
|
||||
numlast = 1;
|
||||
break;
|
||||
|
||||
case '!':
|
||||
if (*(tstr + 1) == '=') {
|
||||
*tstr = '\0';
|
||||
result = TokGetValue(estr, parent, parprops,
|
||||
glob, &dval);
|
||||
if (result == 1)
|
||||
PushTok(TOK_DOUBLE, &dval, &expstack);
|
||||
else if (result == -1)
|
||||
PushTok(TOK_STRING, estr, &expstack);
|
||||
PushTok(TOK_NE, NULL, &expstack);
|
||||
}
|
||||
numlast = 0;
|
||||
break;
|
||||
|
||||
case '=':
|
||||
if (*(tstr + 1) == '=') {
|
||||
*tstr = '\0';
|
||||
result = TokGetValue(estr, parent, parprops,
|
||||
glob, &dval);
|
||||
if (result == 1)
|
||||
PushTok(TOK_DOUBLE, &dval, &expstack);
|
||||
else if (result == -1)
|
||||
PushTok(TOK_STRING, estr, &expstack);
|
||||
PushTok(TOK_EQ, NULL, &expstack);
|
||||
numlast = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case '>':
|
||||
*tstr = '\0';
|
||||
result = TokGetValue(estr, parent, parprops, glob, &dval);
|
||||
if (result == 1) PushTok(TOK_DOUBLE, &dval, &expstack);
|
||||
else if (result == -1) PushTok(TOK_STRING, estr, &expstack);
|
||||
|
||||
if (*(tstr + 1) == '=') {
|
||||
PushTok(TOK_GE, NULL, &expstack);
|
||||
tstr++;
|
||||
}
|
||||
else
|
||||
PushTok(TOK_GT, NULL, &expstack);
|
||||
estr = tstr + 1;
|
||||
numlast = 0;
|
||||
break;
|
||||
|
||||
case '<':
|
||||
*tstr = '\0';
|
||||
result = TokGetValue(estr, parent, parprops, glob, &dval);
|
||||
if (result == 1) PushTok(TOK_DOUBLE, &dval, &expstack);
|
||||
else if (result == -1) PushTok(TOK_STRING, estr, &expstack);
|
||||
|
||||
if (*(tstr + 1) == '=') {
|
||||
PushTok(TOK_LE, NULL, &expstack);
|
||||
tstr++;
|
||||
}
|
||||
else
|
||||
PushTok(TOK_LT, NULL, &expstack);
|
||||
estr = tstr + 1;
|
||||
numlast = 0;
|
||||
break;
|
||||
|
||||
case ',':
|
||||
*tstr = '\0';
|
||||
result = TokGetValue(estr, parent, parprops, glob, &dval);
|
||||
if (result == 1) PushTok(TOK_DOUBLE, &dval, &expstack);
|
||||
else if (result == -1) PushTok(TOK_STRING, estr, &expstack);
|
||||
if (expstack == NULL) break;
|
||||
lptr = expstack;
|
||||
while (lptr->next) {
|
||||
lptr = lptr->next;
|
||||
if (lptr->toktype == TOK_FUNC_THEN) {
|
||||
PushTok(TOK_FUNC_ELSE, NULL, &expstack);
|
||||
break;
|
||||
}
|
||||
else if (lptr->toktype == TOK_FUNC_IF) {
|
||||
PushTok(TOK_FUNC_THEN, NULL, &expstack);
|
||||
break;
|
||||
}
|
||||
}
|
||||
estr = tstr + 1;
|
||||
numlast = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
tstr++;
|
||||
}
|
||||
tstr++;
|
||||
}
|
||||
result = TokGetValue(estr, parent, parprops, glob, &dval);
|
||||
if (result == 1) PushTok(TOK_DOUBLE, &dval, &expstack);
|
||||
else if (result == -1) PushTok(TOK_STRING, estr, &expstack);
|
||||
result = TokGetValue(estr, parent, parprops, glob, &dval);
|
||||
if (result == 1) PushTok(TOK_DOUBLE, &dval, &expstack);
|
||||
else if (result == -1) PushTok(TOK_STRING, estr, &expstack);
|
||||
|
||||
FREE(kv->value.string);
|
||||
kv->value.stack = expstack;
|
||||
kv->type = PROP_EXPRESSION;
|
||||
FREE(kv->value.string);
|
||||
kv->value.stack = expstack;
|
||||
kv->type = PROP_EXPRESSION;
|
||||
break;
|
||||
}
|
||||
|
||||
// Find the beginning of the expression, which is the bottom of
|
||||
@@ -1115,51 +1137,6 @@ struct property *PropertyString(char *name, int fnum, char *key, int range,
|
||||
return kl;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* Find all instances of type "instance" in cell "name". For each one, */
|
||||
/* determine if it can be combined in parallel with other devices. */
|
||||
/* Capacitors add area or value. Resistors add width, or run a */
|
||||
/* parallel calculation on value. Transistors add width. */
|
||||
/* If "aggressive" is FALSE, then combinations may be made only if */
|
||||
/* the devices have the same properties (except "M"), and will combine */
|
||||
/* by incrementing "M". If "aggressive" is TRUE, then the device */
|
||||
/* properties (width, area, etc.) will be modified in combination. */
|
||||
/* Devices with pin permutations are parallel if nodes match when */
|
||||
/* permuted. */
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
void CombineParallel(char *name, int fnum, char *instance, int aggressive)
|
||||
{
|
||||
struct nlist *tc, *tp;
|
||||
struct objlist *ob1, *ob2;
|
||||
|
||||
if ((tc = LookupCellFile(name, fnum)) == NULL) return;
|
||||
if ((tp = LookupCellFile(instance, fnum)) == NULL) return;
|
||||
|
||||
for (ob1 = tc->cell; ob1; ob1 = ob1->next) {
|
||||
if (ob1->type == FIRSTPIN && (*matchfunc)(ob1->model.class, tc->name)) {
|
||||
for (ob2 = ob1->next; ob2; ob2 = ob2->next) {
|
||||
if (ob2->type == FIRSTPIN && (*matchfunc)(ob2->model.class,
|
||||
tc->name)) {
|
||||
/* To-do: Handle permutations! */
|
||||
while (ob1->node == ob2->node) {
|
||||
ob1 = ob1->next;
|
||||
ob2 = ob2->next;
|
||||
if (ob1 == NULL || ob1->type <= FIRSTPIN) break;
|
||||
if (ob2 == NULL || ob2->type <= FIRSTPIN) break;
|
||||
}
|
||||
if ((ob1 && ob1->type == PROPERTY) &&
|
||||
(ob2 && ob2->type == PROPERTY)) {
|
||||
if (PropertyMatch(ob1, ob2, FALSE)) {
|
||||
/* WIP */
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* Declare the element class of the current cell */
|
||||
/*----------------------------------------------------------------------*/
|
||||
@@ -1235,6 +1212,10 @@ void CellDefNoCase(char *name, int file)
|
||||
CurrentCell->flags |= CELL_NOCASE;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* Return 0 if class 'name' is not being ignored (per the 'ignore' */
|
||||
/* command); 1 if it is ignored, and 2 if shorted instances should be */
|
||||
/* ignored. */
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
int IsIgnored(char *name, int file)
|
||||
@@ -1246,7 +1227,7 @@ int IsIgnored(char *name, int file)
|
||||
{
|
||||
if ((file == -1) || (ilist->file == -1) || (file == ilist->file))
|
||||
if ((*matchfunc)(ilist->class, nptr))
|
||||
return 1;
|
||||
return ilist->type; /* IGNORE_CLASS or IGNORE_SHORTED */
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -1384,10 +1365,6 @@ void Instance(char *model, char *instancename)
|
||||
return;
|
||||
}
|
||||
fnum = CurrentCell->file;
|
||||
if (IsIgnored(model, fnum)) {
|
||||
Printf("Class '%s' instanced in input but is being ignored.\n", model);
|
||||
return;
|
||||
}
|
||||
instanced_cell = LookupCellFile(model, fnum);
|
||||
if (instanced_cell == NULL) {
|
||||
Printf("Attempt to instance undefined model '%s'\n", model);
|
||||
@@ -1527,7 +1504,7 @@ char *Cell(char *inststr, char *model, ...)
|
||||
struct objlist *namedporthead, *namedportp, *namedlisthead, *namedlistp;
|
||||
int portnum, portlist, done;
|
||||
char namedport[512]; /* tmp buffers */
|
||||
int filenum;
|
||||
int filenum, itype, samenode;
|
||||
|
||||
static char *instancename = NULL;
|
||||
char *instnameptr;
|
||||
@@ -1540,7 +1517,7 @@ char *Cell(char *inststr, char *model, ...)
|
||||
filenum = CurrentCell->file;
|
||||
|
||||
if (Debug) Printf(" calling cell: %s\n",model);
|
||||
if (IsIgnored(model, filenum)) {
|
||||
if ((itype = IsIgnored(model, filenum)) == IGNORE_CLASS) {
|
||||
Printf("Class '%s' instanced in input but is being ignored.\n", model);
|
||||
return NULL;
|
||||
}
|
||||
@@ -1623,6 +1600,21 @@ char *Cell(char *inststr, char *model, ...)
|
||||
}
|
||||
va_end(ap);
|
||||
|
||||
/* Check for shorted pins */
|
||||
if ((itype == IGNORE_SHORTED) && (head != NULL)) {
|
||||
unsigned char shorted = (unsigned char)1;
|
||||
for (tp = head->next; tp; tp = tp->next) {
|
||||
if (strcasecmp(head->name, tp->name))
|
||||
shorted = (unsigned char)0;
|
||||
break;
|
||||
}
|
||||
if (shorted == (unsigned char)1) {
|
||||
Printf("Instance of '%s' is shorted, ignoring.\n", model);
|
||||
FreeObject(head);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (inststr == NULL) {
|
||||
if (instancename != NULL)
|
||||
FreeString(instancename);
|
||||
@@ -2015,7 +2007,7 @@ struct objlist *LinkProperties(char *model, struct keyvalue *topptr)
|
||||
else
|
||||
filenum = CurrentCell->file;
|
||||
|
||||
if (IsIgnored(model, filenum)) {
|
||||
if (IsIgnored(model, filenum) == IGNORE_CLASS) {
|
||||
Printf("Class '%s' instanced in input but is being ignored.\n", model);
|
||||
return NULL;
|
||||
}
|
||||
@@ -2833,12 +2825,12 @@ void Array(char *Cell, int num)
|
||||
int NoDisconnectedNodes = 0;
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* Within the definition of 'model', traverse the object list */
|
||||
/* and connect all the otherwise disconnected nodes (i.e., those */
|
||||
/* with node==-1) to unique node numbers */
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
void ConnectAllNodes(char *model, int file)
|
||||
/* Within the definition of 'model', traverse the object list
|
||||
and connect all the otherwise disconnected nodes (i.e., those
|
||||
with node==-1) to unique node numbers */
|
||||
{
|
||||
int nodenum;
|
||||
struct nlist *tp;
|
||||
@@ -2857,6 +2849,190 @@ void ConnectAllNodes(char *model, int file)
|
||||
if (ob->node == -1) ob->node = nodenum++;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* Find all devices that are of the same class and check for parallel */
|
||||
/* combinations, and combine them where found, adjusting property "M" */
|
||||
/* as needed. */
|
||||
/* */
|
||||
/* Procedure: Hash each cell by the model name and a space-separated */
|
||||
/* list of node numbers connected to each pin, and the value of the */
|
||||
/* property that affects number of devices (if any). The hash stores */
|
||||
/* the instance record and property record (if any) of the first cell. */
|
||||
/* If there is a hash match, then the cell instance gets deleted and */
|
||||
/* the property M of the instance pointed to in the hash gets */
|
||||
/* incremented. If it has no property M, one is created and the value */
|
||||
/* set to 2. */
|
||||
/* */
|
||||
/* If the device has permutable pins, then duplicate hashes are made */
|
||||
/* for each permutation. */
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
void CombineParallel(char *model, int file)
|
||||
{
|
||||
struct nlist *tp, *tsub;
|
||||
struct objlist *ob, *ob2, *nextob;
|
||||
struct objlist *sob, *lob, *tlob, *nob, *pob, *obr;
|
||||
struct hashdict devdict;
|
||||
struct Permutation *perm;
|
||||
size_t pcnt;
|
||||
int dcnt = 0;
|
||||
char *pstr, *p2str, *pptr;
|
||||
struct valuelist *kv;
|
||||
|
||||
if ((tp = LookupCellFile(model, file)) == NULL) {
|
||||
Printf("Cell: %s does not exist.\n", model);
|
||||
return;
|
||||
}
|
||||
|
||||
InitializeHashTable(&devdict, OBJHASHSIZE);
|
||||
|
||||
lob = NULL;
|
||||
for (ob = tp->cell; ob; ) {
|
||||
if (ob->type == FIRSTPIN) {
|
||||
|
||||
/* ------------------------------------*/
|
||||
/* Generate hash key from pins */
|
||||
/* Handle pin permuations */
|
||||
/* ------------------------------------*/
|
||||
|
||||
tsub = LookupCellFile(ob->model.class, file);
|
||||
if ((tsub != NULL) && (tsub->permutes != NULL))
|
||||
perm = tsub->permutes;
|
||||
else
|
||||
perm = NULL; /* Device has no pin permutations */
|
||||
|
||||
pcnt = strlen(ob->model.class) + 2;
|
||||
pptr = (char *)pcnt;
|
||||
for (ob2 = ob; ob2 && (ob2->type > FIRSTPIN || ob2 == ob); ob2 = ob2->next) {
|
||||
tlob = ob2;
|
||||
pcnt += 10;
|
||||
}
|
||||
|
||||
/* Find last record in device and first record in next object */
|
||||
while (ob2 && ob2->type == PROPERTY) {
|
||||
tlob = ob2;
|
||||
ob2 = ob2->next;
|
||||
}
|
||||
nextob = ob2;
|
||||
|
||||
pstr = (char *)MALLOC(pcnt);
|
||||
sprintf(pstr, "%s", ob->model.class);
|
||||
pptr += pstr - (char *)2;
|
||||
|
||||
for (ob2 = ob; ob2 && (ob2->type > FIRSTPIN || ob2 == ob); ob2 = ob2->next) {
|
||||
sprintf(pptr, "_%d", ob2->node);
|
||||
pptr += strlen(pptr);
|
||||
}
|
||||
|
||||
/* Now check the hash table for any similar instance */
|
||||
sob = (struct objlist *)HashLookup(pstr, &devdict);
|
||||
if (sob == NULL) {
|
||||
/* Generate hash entry */
|
||||
HashPtrInstall(pstr, ob, &devdict);
|
||||
|
||||
/* If pins are permutable, generate alternative hash entries */
|
||||
|
||||
if (perm != NULL) {
|
||||
char *pname;
|
||||
struct objlist *pob1, *pob2;
|
||||
|
||||
/* NOTE: This is only set up for a single permutation */
|
||||
/* per cell and needs to be expanded to the general */
|
||||
/* case, which requires one nested loop per permute */
|
||||
/* pair */
|
||||
|
||||
p2str = (char *)MALLOC(pcnt);
|
||||
sprintf(p2str, "%s", ob->model.class);
|
||||
pptr = p2str + strlen(ob->model.class);
|
||||
|
||||
for (ob2 = ob; ob2 && (ob2->type > FIRSTPIN || ob2 == ob);
|
||||
ob2 = ob2->next) {
|
||||
pname = ob2->name + strlen(ob2->instance.name) + 1;
|
||||
if ((*matchfunc)(perm->pin1, pname))
|
||||
pob1 = ob2;
|
||||
else if ((*matchfunc)(perm->pin2, pname))
|
||||
pob2 = ob2;
|
||||
}
|
||||
for (ob2 = ob; ob2 && (ob2->type > FIRSTPIN || ob2 == ob);
|
||||
ob2 = ob2->next) {
|
||||
if (ob2 == pob1)
|
||||
sprintf(pptr, "_%d", pob2->node);
|
||||
else if (ob2 == pob2)
|
||||
sprintf(pptr, "_%d", pob1->node);
|
||||
else
|
||||
sprintf(pptr, "_%d", ob2->node);
|
||||
pptr += strlen(pptr);
|
||||
}
|
||||
HashPtrInstall(p2str, ob, &devdict);
|
||||
FREE((char *)p2str);
|
||||
}
|
||||
|
||||
/* Set last object ptr to end of this record */
|
||||
lob = tlob;
|
||||
}
|
||||
else {
|
||||
/* Remove parallel device "ob" and append properties of */
|
||||
/* "sob" to it. If "ob" does not have properties, then */
|
||||
/* create a property record and set property "M" to 2. */
|
||||
|
||||
for (obr = ob; obr != ob2 ; ) {
|
||||
nob = obr->next;
|
||||
FreeObjectAndHash(obr, tp);
|
||||
obr = nob;
|
||||
}
|
||||
dcnt++;
|
||||
/* Find (first) property record of sob */
|
||||
for (pob = sob->next; pob->type > FIRSTPIN; pob = pob->next) {
|
||||
if (pob->next->type == PROPERTY)
|
||||
break;
|
||||
else if (pob->next->type == FIRSTPIN) {
|
||||
/* Create new property instance record if one doesn't exist */
|
||||
nob = GetObject();
|
||||
nob->type = PROPERTY;
|
||||
nob->name = strsave("properties");
|
||||
nob->node = -2; /* Don't report as disconnected node */
|
||||
nob->model.class = strsave(sob->model.class);
|
||||
nob->instance.props = NewPropValue(2);
|
||||
|
||||
/* Create property record for property "M" and set to 1 */
|
||||
kv = &(nob->instance.props[0]);
|
||||
kv->key = strsave("M");
|
||||
kv->type = PROP_INTEGER;
|
||||
kv->value.ival = (obr->type != PROPERTY) ? 2 : 1;
|
||||
|
||||
/* End of property list */
|
||||
kv = &(nob->instance.props[1]);
|
||||
kv->key = NULL;
|
||||
kv->type = PROP_ENDLIST;
|
||||
kv->value.ival = 0;
|
||||
|
||||
nob->next = pob->next;
|
||||
pob->next = nob;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (lob == pob) lob = tlob;
|
||||
if (obr->type == PROPERTY) {
|
||||
/* Pull out property records and append to sob's */
|
||||
/* property list */
|
||||
tlob->next = pob->next;
|
||||
pob->next = obr;
|
||||
}
|
||||
lob->next = nextob;
|
||||
}
|
||||
FREE((char *)pstr);
|
||||
}
|
||||
else
|
||||
nextob = ob->next;
|
||||
ob = nextob;
|
||||
}
|
||||
HashKill(&devdict);
|
||||
if (dcnt > 0) {
|
||||
Fprintf(stdout, "Class %s: Merged %d devices.\n", model, dcnt);
|
||||
}
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
|
||||
@@ -116,6 +116,7 @@ extern void FlattenCurrent();
|
||||
extern void ConvertGlobals(char *name, int fnum);
|
||||
extern int CleanupPins(char *name, int fnum);
|
||||
extern void ConnectAllNodes(char *model, int fnum);
|
||||
extern void CombineParallel(char *model, int fnum);
|
||||
extern int NoDisconnectedNodes;
|
||||
extern int PropertyKeyMatch(char *, char *);
|
||||
extern int PropertyValueMatch(char *, char *);
|
||||
|
||||
+66
-1
@@ -340,6 +340,71 @@ void CellRehash(char *name, char *newname, int file)
|
||||
|
||||
struct nlist *OldCell;
|
||||
|
||||
int removeshorted(struct hashlist *p, int file)
|
||||
{
|
||||
struct nlist *ptr;
|
||||
struct objlist *ob, *lob, *nob, *tob;
|
||||
unsigned char shorted;
|
||||
|
||||
ptr = (struct nlist *)(p->ptr);
|
||||
|
||||
if ((file != -1) && (ptr->file != file)) return;
|
||||
|
||||
lob = NULL;
|
||||
for (ob = ptr->cell; ob != NULL;) {
|
||||
nob = ob->next;
|
||||
if ((ob->type == FIRSTPIN) && (ob->model.class != NULL)) {
|
||||
if ((*matchfunc)(ob->model.class, OldCell->name)) {
|
||||
shorted = (unsigned char)1;
|
||||
for (tob = nob; tob->type > FIRSTPIN; tob = tob->next) {
|
||||
if (tob->node != ob->node) {
|
||||
shorted = (unsigned char)0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (shorted == (unsigned char)0) {
|
||||
lob = ob;
|
||||
ob = nob;
|
||||
continue;
|
||||
}
|
||||
HashDelete(ob->instance.name, &(ptr->instdict));
|
||||
while (1) {
|
||||
FreeObjectAndHash(ob, ptr);
|
||||
ob = nob;
|
||||
if (ob == NULL) break;
|
||||
nob = ob->next;
|
||||
if (ob->type != PROPERTY && ob->type <= FIRSTPIN) break;
|
||||
}
|
||||
if (lob == NULL)
|
||||
ptr->cell = ob;
|
||||
else
|
||||
lob->next = ob;
|
||||
}
|
||||
else {
|
||||
lob = ob;
|
||||
ob = nob;
|
||||
}
|
||||
}
|
||||
else {
|
||||
lob = ob;
|
||||
ob = nob;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Remove shorted instances of class "class" from the database */
|
||||
|
||||
void RemoveShorted(char *class, int file)
|
||||
{
|
||||
if (file == -1)
|
||||
OldCell = LookupCell(class);
|
||||
else
|
||||
OldCell = LookupCellFile(class, file);
|
||||
|
||||
if (OldCell == NULL) return;
|
||||
RecurseCellFileHashTable(removeshorted, file);
|
||||
}
|
||||
|
||||
int deleteclass(struct hashlist *p, int file)
|
||||
{
|
||||
struct nlist *ptr;
|
||||
@@ -360,7 +425,7 @@ int deleteclass(struct hashlist *p, int file)
|
||||
ob = nob;
|
||||
if (ob == NULL) break;
|
||||
nob = ob->next;
|
||||
if (ob->type <= FIRSTPIN) break;
|
||||
if (ob->type != PROPERTY && ob->type <= FIRSTPIN) break;
|
||||
}
|
||||
if (lob == NULL)
|
||||
ptr->cell = ob;
|
||||
|
||||
@@ -159,9 +159,16 @@ extern struct objlist *LastPlaced;
|
||||
struct IgnoreList {
|
||||
char *class;
|
||||
int file;
|
||||
unsigned char type;
|
||||
struct IgnoreList *next;
|
||||
};
|
||||
|
||||
/* Types used by IgnoreList above */
|
||||
|
||||
#define IGNORE_NONE (unsigned char)0
|
||||
#define IGNORE_CLASS (unsigned char)1
|
||||
#define IGNORE_SHORTED (unsigned char)2
|
||||
|
||||
/* Record structure for handling pin permutations in a cell */
|
||||
/* Linked list structure allows multiple permutations per cell. */
|
||||
|
||||
|
||||
+10
-6
@@ -345,7 +345,7 @@ void ElementNodes(char *cell, char *element, int fnum)
|
||||
struct nlist *np;
|
||||
struct objlist *ob, *nob, *nob2;
|
||||
int ckto;
|
||||
char *elementname;
|
||||
char *elementname, *obname;
|
||||
|
||||
if ((fnum == -1) && (Circuit1 != NULL) && (Circuit2 != NULL)) {
|
||||
ElementNodes(cell, element, Circuit1->file);
|
||||
@@ -368,8 +368,10 @@ void ElementNodes(char *cell, char *element, int fnum)
|
||||
|
||||
ckto = strlen(elementname);
|
||||
for (ob = np->cell; ob != NULL; ob = ob->next) {
|
||||
if (!strncmp(elementname, ob->name, ckto))
|
||||
if (*(ob->name + ckto) == '/' || *(ob->name + ckto) == '\0')
|
||||
obname = ob->name;
|
||||
if (*obname == '/') obname++;
|
||||
if (!strncmp(elementname, obname, ckto))
|
||||
if (*(obname + ckto) == '/' || *(obname + ckto) == '\0')
|
||||
break;
|
||||
}
|
||||
if (ob == NULL) {
|
||||
@@ -379,13 +381,15 @@ void ElementNodes(char *cell, char *element, int fnum)
|
||||
|
||||
Printf("Device '%s' Pins:\n", elementname);
|
||||
for (; ob != NULL; ob = ob->next) {
|
||||
if (!strncmp(elementname, ob->name, ckto)) {
|
||||
if (*(ob->name + ckto) != '/' && *(ob->name + ckto) != '\0')
|
||||
obname = ob->name;
|
||||
if (*obname == '/') obname++;
|
||||
if (!strncmp(elementname, obname, ckto)) {
|
||||
if (*(obname + ckto) != '/' && *(obname + ckto) != '\0')
|
||||
continue;
|
||||
|
||||
Printf(" ");
|
||||
PrintObjectType(ob->type);
|
||||
Printf(" (%s)", ob->name + ckto + 1);
|
||||
Printf(" (%s)", obname + ckto + 1);
|
||||
for (nob = np->cell; nob != NULL; nob = nob->next) {
|
||||
if (nob->node == ob->node) {
|
||||
if (nob->type == NODE) {
|
||||
|
||||
+134
-165
@@ -42,6 +42,20 @@ the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
// Global storage for parameters from .PARAM
|
||||
struct hashdict spiceparams;
|
||||
|
||||
// Check if a token represents a numerical value (with
|
||||
// units) or an expression. This is basically a hack
|
||||
// to see if it either passes StringIsValue() or is
|
||||
// enclosed in braces. Probably should attempt to
|
||||
// parse the expression, to be pedantic. Not sure all
|
||||
// expressions have to be in braces.
|
||||
|
||||
int StringIsValueOrExpression(char *token)
|
||||
{
|
||||
if (StringIsValue(token)) return TRUE;
|
||||
else if (*token == '{') return TRUE;
|
||||
else return FALSE;
|
||||
}
|
||||
|
||||
void SpiceSubCell(struct nlist *tp, int IsSubCell)
|
||||
{
|
||||
struct objlist *ob;
|
||||
@@ -73,7 +87,7 @@ void SpiceSubCell(struct nlist *tp, int IsSubCell)
|
||||
for (ob = tp->cell; ob != NULL; ob = ob->next)
|
||||
if (ob->node > maxnode) maxnode = ob->node;
|
||||
|
||||
/* was: for (node = 0; node <= maxnode; node++) */
|
||||
/* was: for (node = 0; node <= maxnode; node++) */
|
||||
for (node = 1; node <= maxnode; node++)
|
||||
FlushString("# %3d = %s\n", node, NodeName(tp, node));
|
||||
|
||||
@@ -154,7 +168,6 @@ void SpiceSubCell(struct nlist *tp, int IsSubCell)
|
||||
|
||||
/* caps and resistors, print out device value */
|
||||
|
||||
|
||||
/* print out device type (model/subcircuit name) */
|
||||
|
||||
switch (tp2->class) {
|
||||
@@ -473,7 +486,7 @@ extern void IncludeSpice(char *, int, struct cellstack **, int);
|
||||
void ReadSpiceFile(char *fname, int filenum, struct cellstack **CellStackPtr,
|
||||
int blackbox)
|
||||
{
|
||||
int cdnum = 1, rdnum = 1, ndev, multi;
|
||||
int cdnum = 1, rdnum = 1;
|
||||
int warnings = 0, update = 0, hasports = 0;
|
||||
char *eqptr, devtype, in_subckt;
|
||||
struct keyvalue *kvlist = NULL;
|
||||
@@ -821,7 +834,6 @@ skip_ends:
|
||||
/* Read the device model */
|
||||
snprintf(model, 99, "%s", nexttok);
|
||||
|
||||
ndev = 1;
|
||||
while (nexttok != NULL)
|
||||
{
|
||||
/* Parse for M and other parameters */
|
||||
@@ -831,10 +843,7 @@ skip_ends:
|
||||
if ((eqptr = strchr(nexttok, '=')) != NULL)
|
||||
{
|
||||
*eqptr = '\0';
|
||||
if (!strcasecmp(nexttok, "M"))
|
||||
sscanf(eqptr + 1, "%d", &ndev);
|
||||
else
|
||||
AddProperty(&kvlist, nexttok, eqptr + 1);
|
||||
AddProperty(&kvlist, nexttok, eqptr + 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -843,6 +852,7 @@ skip_ends:
|
||||
Port("collector");
|
||||
Port("base");
|
||||
Port("emitter");
|
||||
PropertyInteger(model, filenum, "M", 0, 1);
|
||||
SetClass(CLASS_BJT);
|
||||
EndCell();
|
||||
ReopenCellDef((*CellStackPtr)->cellname, filenum); /* Reopen */
|
||||
@@ -853,16 +863,10 @@ skip_ends:
|
||||
goto baddevice;
|
||||
}
|
||||
|
||||
multi = (ndev > 1) ? 1 : 0;
|
||||
if (!multi) snprintf(instname, 255, "%s%s", model, inst);
|
||||
while (ndev > 0)
|
||||
{
|
||||
if (multi) snprintf(instname, 255, "%s%s.%d", model, inst, ndev);
|
||||
Cell(instname, model, collector, base, emitter);
|
||||
pobj = LinkProperties(model, kvlist);
|
||||
ReduceExpressions(pobj, NULL, CurrentCell, TRUE);
|
||||
ndev--;
|
||||
}
|
||||
snprintf(instname, 255, "%s%s", model, inst);
|
||||
Cell(instname, model, collector, base, emitter);
|
||||
pobj = LinkProperties(model, kvlist);
|
||||
ReduceExpressions(pobj, NULL, CurrentCell, TRUE);
|
||||
DeleteProperties(&kvlist);
|
||||
}
|
||||
else if (toupper(nexttok[0]) == 'M') {
|
||||
@@ -896,7 +900,6 @@ skip_ends:
|
||||
/* Read the device model */
|
||||
snprintf(model, 99, "%s", nexttok);
|
||||
|
||||
ndev = 1;
|
||||
while (nexttok != NULL)
|
||||
{
|
||||
/* Parse for parameters; treat "M" separately */
|
||||
@@ -906,14 +909,7 @@ skip_ends:
|
||||
if ((eqptr = strchr(nexttok, '=')) != NULL)
|
||||
{
|
||||
*eqptr = '\0';
|
||||
if (!strcasecmp(nexttok, "M"))
|
||||
sscanf(eqptr + 1, "%d", &ndev);
|
||||
else if (!strcasecmp(nexttok, "L"))
|
||||
AddProperty(&kvlist, "L", eqptr + 1);
|
||||
else if (!strcasecmp(nexttok, "W"))
|
||||
AddProperty(&kvlist, "W", eqptr + 1);
|
||||
else
|
||||
AddProperty(&kvlist, nexttok, eqptr + 1);
|
||||
AddProperty(&kvlist, nexttok, eqptr + 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -929,6 +925,7 @@ skip_ends:
|
||||
Port("bulk");
|
||||
PropertyDouble(model, filenum, "L", 0.01, 0.0);
|
||||
PropertyDouble(model, filenum, "W", 0.01, 0.0);
|
||||
PropertyInteger(model, filenum, "M", 0, 1);
|
||||
SetClass(CLASS_FET);
|
||||
EndCell();
|
||||
ReopenCellDef((*CellStackPtr)->cellname, filenum); /* Reopen */
|
||||
@@ -939,16 +936,10 @@ skip_ends:
|
||||
goto baddevice;
|
||||
}
|
||||
|
||||
multi = (ndev > 1) ? 1 : 0;
|
||||
if (!multi) snprintf(instname, 255, "%s%s", model, inst);
|
||||
while (ndev > 0)
|
||||
{
|
||||
if (multi) snprintf(instname, 255, "%s%s.%d", model, inst, ndev);
|
||||
Cell(instname, model, drain, gate, source, bulk);
|
||||
pobj = LinkProperties(model, kvlist);
|
||||
ReduceExpressions(pobj, NULL, CurrentCell, TRUE);
|
||||
ndev--;
|
||||
}
|
||||
snprintf(instname, 255, "%s%s", model, inst);
|
||||
Cell(instname, model, drain, gate, source, bulk);
|
||||
pobj = LinkProperties(model, kvlist);
|
||||
ReduceExpressions(pobj, NULL, CurrentCell, TRUE);
|
||||
DeleteProperties(&kvlist);
|
||||
SpiceSkipNewLine();
|
||||
}
|
||||
@@ -979,7 +970,7 @@ skip_ends:
|
||||
|
||||
/* Get capacitor value (if present), save as property "value" */
|
||||
if (nexttok != NULL) {
|
||||
if (StringIsValue(nexttok)) {
|
||||
if (StringIsValueOrExpression(nexttok)) {
|
||||
AddProperty(&kvlist, "value", nexttok);
|
||||
SpiceTokNoNewline();
|
||||
}
|
||||
@@ -993,17 +984,13 @@ skip_ends:
|
||||
snprintf(model, 99, "%s", nexttok);
|
||||
|
||||
/* Any other device properties? */
|
||||
ndev = 1;
|
||||
while (nexttok != NULL)
|
||||
{
|
||||
SpiceTokNoNewline();
|
||||
if ((nexttok == NULL) || (nexttok[0] == '\0')) break;
|
||||
if ((eqptr = strchr(nexttok, '=')) != NULL) {
|
||||
*eqptr = '\0';
|
||||
if (!strcasecmp(nexttok, "M"))
|
||||
sscanf(eqptr + 1, "%d", &ndev);
|
||||
else
|
||||
AddProperty(&kvlist, nexttok, eqptr + 1);
|
||||
AddProperty(&kvlist, nexttok, eqptr + 1);
|
||||
}
|
||||
else if (!strncmp(nexttok, "$[", 2)) {
|
||||
// Support for CDL modeled capacitor format
|
||||
@@ -1011,7 +998,7 @@ skip_ends:
|
||||
if ((eqptr = strchr(model, ']')) != NULL)
|
||||
*eqptr = '\0';
|
||||
}
|
||||
else if (StringIsValue(nexttok)) {
|
||||
else if (StringIsValueOrExpression(nexttok)) {
|
||||
// Suport for value passed to modeled capacitor
|
||||
AddProperty(&kvlist, "value", nexttok);
|
||||
}
|
||||
@@ -1026,6 +1013,7 @@ skip_ends:
|
||||
Port("top");
|
||||
Port("bottom");
|
||||
PropertyValue(model, filenum, "value", 0.01, 0.0);
|
||||
PropertyInteger(model, filenum, "M", 0, 1);
|
||||
SetClass(CLASS_CAP);
|
||||
EndCell();
|
||||
ReopenCellDef((*CellStackPtr)->cellname, filenum); /* Reopen */
|
||||
@@ -1039,19 +1027,13 @@ skip_ends:
|
||||
usemodel = 1;
|
||||
}
|
||||
|
||||
multi = (ndev > 1) ? 1 : 0;
|
||||
if (!multi) snprintf(instname, 255, "%s%s", model, inst);
|
||||
|
||||
while (ndev > 0) {
|
||||
if (multi) snprintf(instname, 255, "%s%s.%d", model, inst, ndev);
|
||||
if (usemodel)
|
||||
Cell(instname, model, ctop, cbot);
|
||||
else
|
||||
Cap((*CellStackPtr)->cellname, instname, ctop, cbot);
|
||||
pobj = LinkProperties(model, kvlist);
|
||||
ReduceExpressions(pobj, NULL, CurrentCell, TRUE);
|
||||
ndev--;
|
||||
}
|
||||
snprintf(instname, 255, "%s%s", model, inst);
|
||||
if (usemodel)
|
||||
Cell(instname, model, ctop, cbot);
|
||||
else
|
||||
Cap((*CellStackPtr)->cellname, instname, ctop, cbot);
|
||||
pobj = LinkProperties(model, kvlist);
|
||||
ReduceExpressions(pobj, NULL, CurrentCell, TRUE);
|
||||
DeleteProperties(&kvlist);
|
||||
}
|
||||
}
|
||||
@@ -1082,7 +1064,7 @@ skip_ends:
|
||||
/* Get resistor value (if present); save as property "value" */
|
||||
|
||||
if (nexttok != NULL) {
|
||||
if (StringIsValue(nexttok)) {
|
||||
if (StringIsValueOrExpression(nexttok)) {
|
||||
AddProperty(&kvlist, "value", nexttok);
|
||||
SpiceTokNoNewline();
|
||||
}
|
||||
@@ -1096,16 +1078,12 @@ skip_ends:
|
||||
snprintf(model, 99, "%s", nexttok);
|
||||
|
||||
/* Any other device properties? */
|
||||
ndev = 1;
|
||||
while (nexttok != NULL) {
|
||||
SpiceTokNoNewline();
|
||||
if ((nexttok == NULL) || (nexttok[0] == '\0')) break;
|
||||
if ((eqptr = strchr(nexttok, '=')) != NULL) {
|
||||
*eqptr = '\0';
|
||||
if (!strcasecmp(nexttok, "M"))
|
||||
sscanf(eqptr + 1, "%d", &ndev);
|
||||
else
|
||||
AddProperty(&kvlist, nexttok, eqptr + 1);
|
||||
AddProperty(&kvlist, nexttok, eqptr + 1);
|
||||
}
|
||||
else if (!strncmp(nexttok, "$[", 2)) {
|
||||
// Support for CDL modeled resistor format
|
||||
@@ -1113,7 +1091,7 @@ skip_ends:
|
||||
if ((eqptr = strchr(model, ']')) != NULL)
|
||||
*eqptr = '\0';
|
||||
}
|
||||
else if (StringIsValue(nexttok)) {
|
||||
else if (StringIsValueOrExpression(nexttok)) {
|
||||
// Suport for value passed to modeled resistor
|
||||
AddProperty(&kvlist, "value", nexttok);
|
||||
}
|
||||
@@ -1126,6 +1104,7 @@ skip_ends:
|
||||
Port("end_a");
|
||||
Port("end_b");
|
||||
PropertyValue(model, filenum, "value", 0.01, 0.0);
|
||||
PropertyInteger(model, filenum, "M", 0, 1);
|
||||
SetClass(CLASS_RES);
|
||||
EndCell();
|
||||
ReopenCellDef((*CellStackPtr)->cellname, filenum); /* Reopen */
|
||||
@@ -1141,19 +1120,13 @@ skip_ends:
|
||||
else
|
||||
strcpy(model, "r"); /* Use default resistor model */
|
||||
|
||||
multi = (ndev > 1) ? 1 : 0;
|
||||
if (!multi) snprintf(instname, 255, "%s%s", model, inst);
|
||||
|
||||
while (ndev > 0) {
|
||||
if (multi) snprintf(instname, 255, "%s%s.%d", model, inst, ndev);
|
||||
if (usemodel)
|
||||
Cell(instname, model, rtop, rbot);
|
||||
else
|
||||
Res((*CellStackPtr)->cellname, instname, rtop, rbot);
|
||||
pobj = LinkProperties(model, kvlist);
|
||||
ReduceExpressions(pobj, NULL, CurrentCell, TRUE);
|
||||
ndev--;
|
||||
}
|
||||
snprintf(instname, 255, "%s%s", model, inst);
|
||||
if (usemodel)
|
||||
Cell(instname, model, rtop, rbot);
|
||||
else
|
||||
Res((*CellStackPtr)->cellname, instname, rtop, rbot);
|
||||
pobj = LinkProperties(model, kvlist);
|
||||
ReduceExpressions(pobj, NULL, CurrentCell, TRUE);
|
||||
DeleteProperties(&kvlist);
|
||||
}
|
||||
}
|
||||
@@ -1178,7 +1151,6 @@ skip_ends:
|
||||
/* Read the device model */
|
||||
snprintf(model, 99, "%s", nexttok);
|
||||
|
||||
ndev = 1;
|
||||
while (nexttok != NULL)
|
||||
{
|
||||
/* Parse for M and other parameters */
|
||||
@@ -1188,10 +1160,7 @@ skip_ends:
|
||||
if ((eqptr = strchr(nexttok, '=')) != NULL)
|
||||
{
|
||||
*eqptr = '\0';
|
||||
if (!strcasecmp(nexttok, "M"))
|
||||
sscanf(eqptr + 1, "%d", &ndev);
|
||||
else
|
||||
AddProperty(&kvlist, nexttok, eqptr + 1);
|
||||
AddProperty(&kvlist, nexttok, eqptr + 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1199,6 +1168,7 @@ skip_ends:
|
||||
CellDefNoCase(model, filenum);
|
||||
Port("anode");
|
||||
Port("cathode");
|
||||
PropertyInteger(model, filenum, "M", 0, 1);
|
||||
SetClass(CLASS_DIODE);
|
||||
EndCell();
|
||||
ReopenCellDef((*CellStackPtr)->cellname, filenum); /* Reopen */
|
||||
@@ -1208,16 +1178,10 @@ skip_ends:
|
||||
Fprintf(stderr, "Device \"%s\" has wrong number of ports for a diode.\n");
|
||||
goto baddevice;
|
||||
}
|
||||
multi = (ndev > 1) ? 1 : 0;
|
||||
if (!multi) snprintf(instname, 255, "%s%s", model, inst);
|
||||
while (ndev > 0)
|
||||
{
|
||||
if (multi) snprintf(instname, 255, "%s%s.%d", model, inst, ndev);
|
||||
Cell(instname, model, anode, cathode);
|
||||
pobj = LinkProperties(model, kvlist);
|
||||
ReduceExpressions(pobj, NULL, CurrentCell, TRUE);
|
||||
ndev--;
|
||||
}
|
||||
snprintf(instname, 255, "%s%s", model, inst);
|
||||
Cell(instname, model, anode, cathode);
|
||||
pobj = LinkProperties(model, kvlist);
|
||||
ReduceExpressions(pobj, NULL, CurrentCell, TRUE);
|
||||
DeleteProperties(&kvlist);
|
||||
}
|
||||
else if (toupper(nexttok[0]) == 'T') { /* transmission line */
|
||||
@@ -1260,16 +1224,12 @@ skip_ends:
|
||||
snprintf(model, 99, "%s", nexttok);
|
||||
|
||||
/* Any other device properties? */
|
||||
ndev = 1;
|
||||
while (nexttok != NULL) {
|
||||
SpiceTokNoNewline();
|
||||
if ((nexttok == NULL) || (nexttok[0] == '\0')) break;
|
||||
if ((eqptr = strchr(nexttok, '=')) != NULL) {
|
||||
*eqptr = '\0';
|
||||
if (!strcasecmp(nexttok, "M"))
|
||||
sscanf(eqptr + 1, "%d", &ndev);
|
||||
else
|
||||
AddProperty(&kvlist, nexttok, eqptr + 1);
|
||||
AddProperty(&kvlist, nexttok, eqptr + 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1281,6 +1241,7 @@ skip_ends:
|
||||
Port("node2");
|
||||
Port("node3");
|
||||
Port("node4");
|
||||
PropertyInteger(model, filenum, "M", 0, 1);
|
||||
SetClass(CLASS_XLINE);
|
||||
EndCell();
|
||||
ReopenCellDef((*CellStackPtr)->cellname, filenum); /* Reopen */
|
||||
@@ -1296,20 +1257,15 @@ skip_ends:
|
||||
else
|
||||
strcpy(model, "t"); /* Use default xline model */
|
||||
|
||||
multi = (ndev > 1) ? 1 : 0;
|
||||
if (!multi) snprintf(instname, 255, "%s%s", model, inst);
|
||||
snprintf(instname, 255, "%s%s", model, inst);
|
||||
|
||||
while (ndev > 0) {
|
||||
if (multi) snprintf(instname, 255, "%s%s.%d", model, inst, ndev);
|
||||
if (usemodel)
|
||||
Cell(instname, model, node1, node2, node3, node4);
|
||||
else
|
||||
XLine((*CellStackPtr)->cellname, instname, node1, node2,
|
||||
if (usemodel)
|
||||
Cell(instname, model, node1, node2, node3, node4);
|
||||
else
|
||||
XLine((*CellStackPtr)->cellname, instname, node1, node2,
|
||||
node3, node4);
|
||||
pobj = LinkProperties(model, kvlist);
|
||||
ReduceExpressions(pobj, NULL, CurrentCell, TRUE);
|
||||
ndev--;
|
||||
}
|
||||
pobj = LinkProperties(model, kvlist);
|
||||
ReduceExpressions(pobj, NULL, CurrentCell, TRUE);
|
||||
DeleteProperties(&kvlist);
|
||||
}
|
||||
}
|
||||
@@ -1335,7 +1291,7 @@ skip_ends:
|
||||
/* Get inductance value (if present); save as property "value" */
|
||||
|
||||
if (nexttok != NULL) {
|
||||
if (StringIsValue(nexttok)) {
|
||||
if (StringIsValueOrExpression(nexttok)) {
|
||||
AddProperty(&kvlist, "value", nexttok);
|
||||
SpiceTokNoNewline();
|
||||
}
|
||||
@@ -1349,7 +1305,6 @@ skip_ends:
|
||||
snprintf(model, 99, "%s", nexttok);
|
||||
|
||||
/* Any other device properties? */
|
||||
ndev = 1;
|
||||
while (nexttok != NULL)
|
||||
{
|
||||
/* Parse for M and other parameters */
|
||||
@@ -1359,10 +1314,7 @@ skip_ends:
|
||||
if ((eqptr = strchr(nexttok, '=')) != NULL)
|
||||
{
|
||||
*eqptr = '\0';
|
||||
if (!strcasecmp(nexttok, "M"))
|
||||
sscanf(eqptr + 1, "%d", &ndev);
|
||||
else
|
||||
AddProperty(&kvlist, nexttok, eqptr + 1);
|
||||
AddProperty(&kvlist, nexttok, eqptr + 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1372,6 +1324,7 @@ skip_ends:
|
||||
CellDefNoCase(model, filenum);
|
||||
Port("end_a");
|
||||
Port("end_b");
|
||||
PropertyInteger(model, filenum, "M", 0, 1);
|
||||
SetClass(CLASS_INDUCTOR);
|
||||
EndCell();
|
||||
ReopenCellDef((*CellStackPtr)->cellname, filenum); /* Reopen */
|
||||
@@ -1387,19 +1340,13 @@ skip_ends:
|
||||
else
|
||||
strcpy(model, "l"); /* Use default inductor model */
|
||||
|
||||
multi = (ndev > 1) ? 1 : 0;
|
||||
if (!multi) snprintf(instname, 255, "%s%s", model, inst);
|
||||
while (ndev > 0)
|
||||
{
|
||||
if (multi) snprintf(instname, 255, "%s%s.%d", model, inst, ndev);
|
||||
if (usemodel)
|
||||
Cell(instname, model, end_a, end_b);
|
||||
else
|
||||
Inductor((*CellStackPtr)->cellname, instname, end_a, end_b);
|
||||
pobj = LinkProperties(model, kvlist);
|
||||
ReduceExpressions(pobj, NULL, CurrentCell, TRUE);
|
||||
ndev--;
|
||||
}
|
||||
snprintf(instname, 255, "%s%s", model, inst);
|
||||
if (usemodel)
|
||||
Cell(instname, model, end_a, end_b);
|
||||
else
|
||||
Inductor((*CellStackPtr)->cellname, instname, end_a, end_b);
|
||||
pobj = LinkProperties(model, kvlist);
|
||||
ReduceExpressions(pobj, NULL, CurrentCell, TRUE);
|
||||
DeleteProperties(&kvlist);
|
||||
}
|
||||
|
||||
@@ -1435,7 +1382,7 @@ skip_ends:
|
||||
*eqptr = '\0';
|
||||
AddProperty(&kvlist, nexttok, eqptr + 1);
|
||||
}
|
||||
else if (StringIsValue(nexttok)) {
|
||||
else if (StringIsValueOrExpression(nexttok)) {
|
||||
AddProperty(&kvlist, "value", nexttok);
|
||||
SpiceTokNoNewline();
|
||||
}
|
||||
@@ -1445,6 +1392,7 @@ skip_ends:
|
||||
CellDefNoCase(model, filenum);
|
||||
Port("pos");
|
||||
Port("neg");
|
||||
PropertyInteger(model, filenum, "M", 0, 1);
|
||||
SetClass(CLASS_MODULE);
|
||||
EndCell();
|
||||
ReopenCellDef((*CellStackPtr)->cellname, filenum); /* Reopen */
|
||||
@@ -1488,7 +1436,7 @@ skip_ends:
|
||||
*eqptr = '\0';
|
||||
AddProperty(&kvlist, nexttok, eqptr + 1);
|
||||
}
|
||||
else if (StringIsValue(nexttok)) {
|
||||
else if (StringIsValueOrExpression(nexttok)) {
|
||||
AddProperty(&kvlist, "value", nexttok);
|
||||
SpiceTokNoNewline();
|
||||
}
|
||||
@@ -1498,6 +1446,7 @@ skip_ends:
|
||||
CellDefNoCase(model, filenum);
|
||||
Port("pos");
|
||||
Port("neg");
|
||||
PropertyInteger(model, filenum, "M", 0, 1);
|
||||
SetClass(CLASS_MODULE);
|
||||
EndCell();
|
||||
ReopenCellDef((*CellStackPtr)->cellname, filenum); /* Reopen */
|
||||
@@ -1550,7 +1499,7 @@ skip_ends:
|
||||
*eqptr = '\0';
|
||||
AddProperty(&kvlist, nexttok, eqptr + 1);
|
||||
}
|
||||
else if (StringIsValue(nexttok)) {
|
||||
else if (StringIsValueOrExpression(nexttok)) {
|
||||
AddProperty(&kvlist, "value", nexttok);
|
||||
SpiceTokNoNewline();
|
||||
}
|
||||
@@ -1562,6 +1511,7 @@ skip_ends:
|
||||
Port("neg");
|
||||
Port("ctrlp");
|
||||
Port("ctrln");
|
||||
PropertyInteger(model, filenum, "M", 0, 1);
|
||||
SetClass(CLASS_MODULE);
|
||||
EndCell();
|
||||
ReopenCellDef((*CellStackPtr)->cellname, filenum); /* Reopen */
|
||||
@@ -1580,6 +1530,8 @@ skip_ends:
|
||||
|
||||
else if (toupper(nexttok[0]) == 'X') { /* subcircuit instances */
|
||||
char instancename[100], subcktname[100];
|
||||
int itype;
|
||||
|
||||
instancename[99] = '\0';
|
||||
subcktname[99] = '\0';
|
||||
|
||||
@@ -1601,7 +1553,6 @@ skip_ends:
|
||||
head = NULL;
|
||||
tail = NULL;
|
||||
SpiceTokNoNewline();
|
||||
ndev = 1;
|
||||
while (nexttok != NULL) {
|
||||
/* must still be a node or a parameter */
|
||||
struct portelement *new_port;
|
||||
@@ -1629,10 +1580,7 @@ skip_ends:
|
||||
((tp = LookupCellFile(nexttok, filenum)) == NULL))
|
||||
{
|
||||
*eqptr = '\0';
|
||||
if (!strcasecmp(nexttok, "M"))
|
||||
sscanf(eqptr + 1, "%d", &ndev);
|
||||
else
|
||||
AddProperty(&kvlist, nexttok, eqptr + 1);
|
||||
AddProperty(&kvlist, nexttok, eqptr + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1656,6 +1604,34 @@ skip_ends:
|
||||
if (scan->next != NULL) scan = scan->next;
|
||||
tail->next = NULL;
|
||||
|
||||
/* Check for ignored class */
|
||||
|
||||
if ((itype = IsIgnored(subcktname, filenum)) == IGNORE_CLASS) {
|
||||
Printf("Class '%s' instanced in input but is being ignored.\n", model);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Check for shorted pins */
|
||||
|
||||
if ((itype == IGNORE_SHORTED) && (head != NULL)) {
|
||||
unsigned char shorted = (unsigned char)1;
|
||||
struct portelement *p;
|
||||
for (p = head->next; p; p = p->next) {
|
||||
if (strcasecmp(head->name, p->name))
|
||||
shorted = (unsigned char)0;
|
||||
break;
|
||||
}
|
||||
if (shorted == (unsigned char)1) {
|
||||
Printf("Instance of '%s' is shorted, ignoring.\n", subcktname);
|
||||
while (head) {
|
||||
p = head->next;
|
||||
FREE(head);
|
||||
head = p;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Create cell name and revise instance name based on the cell name */
|
||||
/* For clarity, if "instancename" does not contain the cellname, */
|
||||
/* then prepend the cellname to the instance name. HOWEVER, if any */
|
||||
@@ -1704,6 +1680,7 @@ skip_ends:
|
||||
if (head == NULL) {
|
||||
Port((char *)NULL); // Must have something for pin 1
|
||||
}
|
||||
PropertyInteger(subcktname, filenum, "M", 0, 1);
|
||||
SetClass(CLASS_MODULE);
|
||||
EndCell();
|
||||
ReopenCellDef((*CellStackPtr)->cellname, filenum); /* Reopen */
|
||||
@@ -1711,38 +1688,31 @@ skip_ends:
|
||||
}
|
||||
|
||||
/* nexttok is now NULL, scan->name points to class */
|
||||
multi = (ndev > 1) ? 1 : 0;
|
||||
if (multi) strcat(instancename, ".");
|
||||
while (ndev > 0) {
|
||||
if (multi) {
|
||||
char *dotptr = strrchr(instancename, '.');
|
||||
sprintf(dotptr + 1, "%d", ndev);
|
||||
}
|
||||
Instance(subcktname, instancename);
|
||||
pobj = LinkProperties(subcktname, kvlist);
|
||||
ReduceExpressions(pobj, NULL, CurrentCell, TRUE);
|
||||
ndev--;
|
||||
|
||||
/* (Diagnostic) */
|
||||
/* Fprintf(stderr, "instancing subcell: %s (%s):", subcktname, instancename); */
|
||||
/*
|
||||
Instance(subcktname, instancename);
|
||||
pobj = LinkProperties(subcktname, kvlist);
|
||||
ReduceExpressions(pobj, NULL, CurrentCell, TRUE);
|
||||
|
||||
/* (Diagnostic) */
|
||||
/* Fprintf(stderr, "instancing subcell: %s (%s):", subcktname, instancename); */
|
||||
/*
|
||||
for (scan = head; scan != NULL; scan = scan->next)
|
||||
Fprintf(stderr," %s", scan->name);
|
||||
Fprintf(stderr," %s", scan->name);
|
||||
Fprintf(stderr,"\n");
|
||||
*/
|
||||
*/
|
||||
|
||||
obptr = LookupInstance(instancename, CurrentCell);
|
||||
if (obptr != NULL) {
|
||||
scan = head;
|
||||
if (scan != NULL)
|
||||
do {
|
||||
if (LookupObject(scan->name, CurrentCell) == NULL) Node(scan->name);
|
||||
join(scan->name, obptr->name);
|
||||
obptr = obptr->next;
|
||||
scan = scan->next;
|
||||
} while (obptr != NULL && obptr->type > FIRSTPIN && scan != NULL);
|
||||
obptr = LookupInstance(instancename, CurrentCell);
|
||||
if (obptr != NULL) {
|
||||
scan = head;
|
||||
if (scan != NULL)
|
||||
do {
|
||||
if (LookupObject(scan->name, CurrentCell) == NULL) Node(scan->name);
|
||||
join(scan->name, obptr->name);
|
||||
obptr = obptr->next;
|
||||
scan = scan->next;
|
||||
} while (obptr != NULL && obptr->type > FIRSTPIN && scan != NULL);
|
||||
|
||||
if ((obptr == NULL && scan != NULL) ||
|
||||
if ((obptr == NULL && scan != NULL) ||
|
||||
(obptr != NULL && scan == NULL && obptr->type > FIRSTPIN)) {
|
||||
if (warnings <= 100) {
|
||||
Fprintf(stderr,"Parameter list mismatch in %s: ", instancename);
|
||||
@@ -1756,8 +1726,7 @@ skip_ends:
|
||||
Fprintf(stderr, "Too many warnings. . . will not report any more.\n");
|
||||
}
|
||||
warnings++;
|
||||
}
|
||||
} // repeat over ndev
|
||||
}
|
||||
}
|
||||
DeleteProperties(&kvlist);
|
||||
|
||||
|
||||
@@ -56,7 +56,8 @@ RANLIB = ranlib
|
||||
SHDLIB_EXT = .so
|
||||
LDDL_FLAGS = -shared -Wl,-soname,$@ -Wl,--version-script=${NETGENDIR}/netgen/symbol.map
|
||||
LD_RUN_PATH =
|
||||
LIB_SPECS = -L/usr/lib64 -ltk8.6 -L/usr/lib64 -ltcl8.6
|
||||
LIB_SPECS = -L/usr/lib64 -ltkstub8.6 -L/usr/lib64 -ltclstub8.6
|
||||
LIB_SPECS_NOSTUB = -L/usr/lib64 -ltk8.6 -L/usr/lib64 -ltcl8.6
|
||||
WISH_EXE = /usr/bin/wish
|
||||
TCL_LIB_DIR = /usr/lib
|
||||
|
||||
@@ -65,7 +66,8 @@ CPP = gcc -E -x c
|
||||
CXX = @CXX@
|
||||
|
||||
CPPFLAGS = -I. -I${NETGENDIR}
|
||||
DFLAGS = -DCAD_DIR=\"${LIBDIR}\" -DTCL_DIR=\"${TCLDIR}\" -DPACKAGE_NAME=\"netgen\" -DPACKAGE_TARNAME=\"netgen\" -DPACKAGE_VERSION=\"1.3\" -DPACKAGE_STRING=\"netgen\ 1.3\" -DPACKAGE_BUGREPORT=\"[email protected]\" -DPACKAGE_URL=\"\" -DNETGEN_VERSION=\"1.5\" -DNETGEN_REVISION=\"54\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DSIZEOF_VOID_P=8 -DSIZEOF_UNSIGNED_INT=4 -DSIZEOF_UNSIGNED_LONG=8 -DSIZEOF_UNSIGNED_LONG_LONG=8 -DSTDC_HEADERS=1 -DHAVE_SETENV=1 -DHAVE_PUTENV=1 -DHAVE_DIRENT_H=1 -DHAVE_LIMITS_H=1 -DHAVE_VA_COPY=1 -DHAVE___VA_COPY=1 -DDBUG_OFF=1 -DTCL_NETGEN=1 -Dlinux=1 -DSYSV=1 -DISC=1 -DSHDLIB_EXT=\".so\" -DNDEBUG
|
||||
DFLAGS = -DCAD_DIR=\"${LIBDIR}\" -DTCL_DIR=\"${TCLDIR}\" -DUSE_TCL_STUBS -DUSE_TK_STUBS -DPACKAGE_NAME=\"netgen\" -DPACKAGE_TARNAME=\"netgen\" -DPACKAGE_VERSION=\"1.3\" -DPACKAGE_STRING=\"netgen\ 1.3\" -DPACKAGE_BUGREPORT=\"[email protected]\" -DPACKAGE_URL=\"\" -DNETGEN_VERSION=\"1.5\" -DNETGEN_REVISION=\"60\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DSIZEOF_VOID_P=8 -DSIZEOF_UNSIGNED_INT=4 -DSIZEOF_UNSIGNED_LONG=8 -DSIZEOF_UNSIGNED_LONG_LONG=8 -DSTDC_HEADERS=1 -DHAVE_SETENV=1 -DHAVE_PUTENV=1 -DHAVE_DIRENT_H=1 -DHAVE_LIMITS_H=1 -DHAVE_VA_COPY=1 -DHAVE___VA_COPY=1 -DDBUG_OFF=1 -DTCL_NETGEN=1 -Dlinux=1 -DSYSV=1 -DISC=1 -DSHDLIB_EXT=\".so\" -DNDEBUG
|
||||
DFLAGS_NOSTUB = -DCAD_DIR=\"${LIBDIR}\" -DTCL_DIR=\"${TCLDIR}\" -DPACKAGE_NAME=\"netgen\" -DPACKAGE_TARNAME=\"netgen\" -DPACKAGE_VERSION=\"1.3\" -DPACKAGE_STRING=\"netgen\ 1.3\" -DPACKAGE_BUGREPORT=\"[email protected]\" -DPACKAGE_URL=\"\" -DNETGEN_VERSION=\"1.5\" -DNETGEN_REVISION=\"60\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DSIZEOF_VOID_P=8 -DSIZEOF_UNSIGNED_INT=4 -DSIZEOF_UNSIGNED_LONG=8 -DSIZEOF_UNSIGNED_LONG_LONG=8 -DSTDC_HEADERS=1 -DHAVE_SETENV=1 -DHAVE_PUTENV=1 -DHAVE_DIRENT_H=1 -DHAVE_LIMITS_H=1 -DHAVE_VA_COPY=1 -DHAVE___VA_COPY=1 -DDBUG_OFF=1 -DTCL_NETGEN=1 -Dlinux=1 -DSYSV=1 -DISC=1 -DSHDLIB_EXT=\".so\" -DNDEBUG
|
||||
CFLAGS = -g -m64 -fPIC -fPIC
|
||||
|
||||
DEPEND_FILE = Depend
|
||||
|
||||
+1
-1
@@ -23,7 +23,7 @@ tclnetgen${SHDLIB_EXT}: ${EXTRA_LIBS}
|
||||
${RM} tclnetgen${SHDLIB_EXT}
|
||||
${CC} ${CFLAGS} ${CPPFLAGS} -o $@ ${LDDL_FLAGS} \
|
||||
${LD_RUN_PATH} ${EXTRA_LIBS} ${LD_EXTRA_LIBS} -lc ${LIBS} \
|
||||
${TCL_LIB_SPEC} ${LDFLAGS}
|
||||
${LIB_SPECS} ${LDFLAGS}
|
||||
|
||||
$(DESTDIR)${BINDIR}/netgen:
|
||||
${RM} $@
|
||||
|
||||
+260
-259
@@ -33,31 +33,30 @@ PATH: /sbin
|
||||
PATH: /usr/bin
|
||||
PATH: /usr/sbin
|
||||
PATH: /usr/local/bin
|
||||
PATH: /home/tim/src/timberwolf-6.3/bin
|
||||
|
||||
|
||||
## ----------- ##
|
||||
## Core tests. ##
|
||||
## ----------- ##
|
||||
|
||||
configure:2395: checking build system type
|
||||
configure:2409: result: x86_64-unknown-linux-gnu
|
||||
configure:2429: checking host system type
|
||||
configure:2442: result: x86_64-unknown-linux-gnu
|
||||
configure:2462: checking target system type
|
||||
configure:2475: result: x86_64-unknown-linux-gnu
|
||||
configure:2566: checking for gcc
|
||||
configure:2582: found /bin/gcc
|
||||
configure:2593: result: gcc
|
||||
configure:2822: checking for C compiler version
|
||||
configure:2831: gcc --version >&5
|
||||
configure:2397: checking build system type
|
||||
configure:2411: result: x86_64-unknown-linux-gnu
|
||||
configure:2431: checking host system type
|
||||
configure:2444: result: x86_64-unknown-linux-gnu
|
||||
configure:2464: checking target system type
|
||||
configure:2477: result: x86_64-unknown-linux-gnu
|
||||
configure:2568: checking for gcc
|
||||
configure:2584: found /bin/gcc
|
||||
configure:2595: result: gcc
|
||||
configure:2824: checking for C compiler version
|
||||
configure:2833: gcc --version >&5
|
||||
gcc (GCC) 4.9.2 20141101 (Red Hat 4.9.2-1)
|
||||
Copyright (C) 2014 Free Software Foundation, Inc.
|
||||
This is free software; see the source for copying conditions. There is NO
|
||||
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
configure:2842: $? = 0
|
||||
configure:2831: gcc -v >&5
|
||||
configure:2844: $? = 0
|
||||
configure:2833: gcc -v >&5
|
||||
Using built-in specs.
|
||||
COLLECT_GCC=gcc
|
||||
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-redhat-linux/4.9.2/lto-wrapper
|
||||
@@ -65,58 +64,58 @@ Target: x86_64-redhat-linux
|
||||
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --enable-multilib --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-linker-hash-style=gnu --enable-languages=c,c++,objc,obj-c++,fortran,ada,go,lto --enable-plugin --enable-initfini-array --disable-libgcj --with-isl=/builddir/build/BUILD/gcc-4.9.2-20141101/obj-x86_64-redhat-linux/isl-install --with-cloog=/builddir/build/BUILD/gcc-4.9.2-20141101/obj-x86_64-redhat-linux/cloog-install --enable-gnu-indirect-function --with-tune=generic --with-arch_32=i686 --build=x86_64-redhat-linux
|
||||
Thread model: posix
|
||||
gcc version 4.9.2 20141101 (Red Hat 4.9.2-1) (GCC)
|
||||
configure:2842: $? = 0
|
||||
configure:2831: gcc -V >&5
|
||||
configure:2844: $? = 0
|
||||
configure:2833: gcc -V >&5
|
||||
gcc: error: unrecognized command line option '-V'
|
||||
gcc: fatal error: no input files
|
||||
compilation terminated.
|
||||
configure:2842: $? = 4
|
||||
configure:2831: gcc -qversion >&5
|
||||
configure:2844: $? = 4
|
||||
configure:2833: gcc -qversion >&5
|
||||
gcc: error: unrecognized command line option '-qversion'
|
||||
gcc: fatal error: no input files
|
||||
compilation terminated.
|
||||
configure:2842: $? = 4
|
||||
configure:2862: checking whether the C compiler works
|
||||
configure:2884: gcc -g conftest.c >&5
|
||||
configure:2888: $? = 0
|
||||
configure:2936: result: yes
|
||||
configure:2939: checking for C compiler default output file name
|
||||
configure:2941: result: a.out
|
||||
configure:2947: checking for suffix of executables
|
||||
configure:2954: gcc -o conftest -g conftest.c >&5
|
||||
configure:2958: $? = 0
|
||||
configure:2980: result:
|
||||
configure:3002: checking whether we are cross compiling
|
||||
configure:3010: gcc -o conftest -g conftest.c >&5
|
||||
configure:3014: $? = 0
|
||||
configure:3021: ./conftest
|
||||
configure:3025: $? = 0
|
||||
configure:3040: result: no
|
||||
configure:3045: checking for suffix of object files
|
||||
configure:3067: gcc -c -g conftest.c >&5
|
||||
configure:3071: $? = 0
|
||||
configure:3092: result: o
|
||||
configure:3096: checking whether we are using the GNU C compiler
|
||||
configure:3115: gcc -c -g conftest.c >&5
|
||||
configure:3115: $? = 0
|
||||
configure:3124: result: yes
|
||||
configure:3133: checking whether gcc accepts -g
|
||||
configure:3153: gcc -c -g conftest.c >&5
|
||||
configure:3153: $? = 0
|
||||
configure:3194: result: yes
|
||||
configure:3211: checking for gcc option to accept ISO C89
|
||||
configure:3274: gcc -c -g conftest.c >&5
|
||||
configure:3274: $? = 0
|
||||
configure:3287: result: none needed
|
||||
configure:3312: checking how to run the C preprocessor
|
||||
configure:3343: gcc -E conftest.c
|
||||
configure:3343: $? = 0
|
||||
configure:3357: gcc -E conftest.c
|
||||
configure:2844: $? = 4
|
||||
configure:2864: checking whether the C compiler works
|
||||
configure:2886: gcc -g conftest.c >&5
|
||||
configure:2890: $? = 0
|
||||
configure:2938: result: yes
|
||||
configure:2941: checking for C compiler default output file name
|
||||
configure:2943: result: a.out
|
||||
configure:2949: checking for suffix of executables
|
||||
configure:2956: gcc -o conftest -g conftest.c >&5
|
||||
configure:2960: $? = 0
|
||||
configure:2982: result:
|
||||
configure:3004: checking whether we are cross compiling
|
||||
configure:3012: gcc -o conftest -g conftest.c >&5
|
||||
configure:3016: $? = 0
|
||||
configure:3023: ./conftest
|
||||
configure:3027: $? = 0
|
||||
configure:3042: result: no
|
||||
configure:3047: checking for suffix of object files
|
||||
configure:3069: gcc -c -g conftest.c >&5
|
||||
configure:3073: $? = 0
|
||||
configure:3094: result: o
|
||||
configure:3098: checking whether we are using the GNU C compiler
|
||||
configure:3117: gcc -c -g conftest.c >&5
|
||||
configure:3117: $? = 0
|
||||
configure:3126: result: yes
|
||||
configure:3135: checking whether gcc accepts -g
|
||||
configure:3155: gcc -c -g conftest.c >&5
|
||||
configure:3155: $? = 0
|
||||
configure:3196: result: yes
|
||||
configure:3213: checking for gcc option to accept ISO C89
|
||||
configure:3276: gcc -c -g conftest.c >&5
|
||||
configure:3276: $? = 0
|
||||
configure:3289: result: none needed
|
||||
configure:3314: checking how to run the C preprocessor
|
||||
configure:3345: gcc -E conftest.c
|
||||
configure:3345: $? = 0
|
||||
configure:3359: gcc -E conftest.c
|
||||
conftest.c:11:28: fatal error: ac_nonexistent.h: No such file or directory
|
||||
#include <ac_nonexistent.h>
|
||||
^
|
||||
compilation terminated.
|
||||
configure:3357: $? = 1
|
||||
configure:3359: $? = 1
|
||||
configure: failed program was:
|
||||
| /* confdefs.h */
|
||||
| #define PACKAGE_NAME "netgen"
|
||||
@@ -126,18 +125,18 @@ configure: failed program was:
|
||||
| #define PACKAGE_BUGREPORT "[email protected]"
|
||||
| #define PACKAGE_URL ""
|
||||
| #define NETGEN_VERSION "1.5"
|
||||
| #define NETGEN_REVISION "54"
|
||||
| #define NETGEN_REVISION "60"
|
||||
| /* end confdefs.h. */
|
||||
| #include <ac_nonexistent.h>
|
||||
configure:3382: result: gcc -E
|
||||
configure:3402: gcc -E conftest.c
|
||||
configure:3402: $? = 0
|
||||
configure:3416: gcc -E conftest.c
|
||||
configure:3384: result: gcc -E
|
||||
configure:3404: gcc -E conftest.c
|
||||
configure:3404: $? = 0
|
||||
configure:3418: gcc -E conftest.c
|
||||
conftest.c:11:28: fatal error: ac_nonexistent.h: No such file or directory
|
||||
#include <ac_nonexistent.h>
|
||||
^
|
||||
compilation terminated.
|
||||
configure:3416: $? = 1
|
||||
configure:3418: $? = 1
|
||||
configure: failed program was:
|
||||
| /* confdefs.h */
|
||||
| #define PACKAGE_NAME "netgen"
|
||||
@@ -147,104 +146,104 @@ configure: failed program was:
|
||||
| #define PACKAGE_BUGREPORT "[email protected]"
|
||||
| #define PACKAGE_URL ""
|
||||
| #define NETGEN_VERSION "1.5"
|
||||
| #define NETGEN_REVISION "54"
|
||||
| #define NETGEN_REVISION "60"
|
||||
| /* end confdefs.h. */
|
||||
| #include <ac_nonexistent.h>
|
||||
configure:3445: checking for library containing strerror
|
||||
configure:3476: gcc -o conftest -g conftest.c >&5
|
||||
configure:3476: $? = 0
|
||||
configure:3493: result: none required
|
||||
configure:3515: checking for a BSD-compatible install
|
||||
configure:3583: result: /bin/install -c
|
||||
configure:3637: checking for ranlib
|
||||
configure:3653: found /bin/ranlib
|
||||
configure:3664: result: ranlib
|
||||
configure:3691: checking for gm4
|
||||
configure:3724: result: no
|
||||
configure:3691: checking for gnum4
|
||||
configure:3724: result: no
|
||||
configure:3691: checking for m4
|
||||
configure:3709: found /bin/m4
|
||||
configure:3721: result: /bin/m4
|
||||
configure:3762: checking for ld used by GCC
|
||||
configure:3825: result: /bin/ld
|
||||
configure:3832: checking if the linker (/bin/ld) is GNU ld
|
||||
configure:3447: checking for library containing strerror
|
||||
configure:3478: gcc -o conftest -g conftest.c >&5
|
||||
configure:3478: $? = 0
|
||||
configure:3495: result: none required
|
||||
configure:3517: checking for a BSD-compatible install
|
||||
configure:3585: result: /bin/install -c
|
||||
configure:3639: checking for ranlib
|
||||
configure:3655: found /bin/ranlib
|
||||
configure:3666: result: ranlib
|
||||
configure:3693: checking for gm4
|
||||
configure:3726: result: no
|
||||
configure:3693: checking for gnum4
|
||||
configure:3726: result: no
|
||||
configure:3693: checking for m4
|
||||
configure:3711: found /bin/m4
|
||||
configure:3723: result: /bin/m4
|
||||
configure:3764: checking for ld used by GCC
|
||||
configure:3827: result: /bin/ld
|
||||
configure:3834: checking if the linker (/bin/ld) is GNU ld
|
||||
GNU ld version 2.24
|
||||
configure:3844: result: yes
|
||||
configure:3851: checking for grep that handles long lines and -e
|
||||
configure:3909: result: /bin/grep
|
||||
configure:3914: checking for egrep
|
||||
configure:3976: result: /bin/grep -E
|
||||
configure:3981: checking for ANSI C header files
|
||||
configure:4001: gcc -c -g conftest.c >&5
|
||||
configure:4001: $? = 0
|
||||
configure:4074: gcc -o conftest -g conftest.c >&5
|
||||
configure:4074: $? = 0
|
||||
configure:4074: ./conftest
|
||||
configure:4074: $? = 0
|
||||
configure:4085: result: yes
|
||||
configure:4098: checking for sys/types.h
|
||||
configure:4098: gcc -c -g conftest.c >&5
|
||||
configure:4098: $? = 0
|
||||
configure:4098: result: yes
|
||||
configure:4098: checking for sys/stat.h
|
||||
configure:4098: gcc -c -g conftest.c >&5
|
||||
configure:4098: $? = 0
|
||||
configure:4098: result: yes
|
||||
configure:4098: checking for stdlib.h
|
||||
configure:4098: gcc -c -g conftest.c >&5
|
||||
configure:4098: $? = 0
|
||||
configure:4098: result: yes
|
||||
configure:4098: checking for string.h
|
||||
configure:4098: gcc -c -g conftest.c >&5
|
||||
configure:4098: $? = 0
|
||||
configure:4098: result: yes
|
||||
configure:4098: checking for memory.h
|
||||
configure:4098: gcc -c -g conftest.c >&5
|
||||
configure:4098: $? = 0
|
||||
configure:4098: result: yes
|
||||
configure:4098: checking for strings.h
|
||||
configure:4098: gcc -c -g conftest.c >&5
|
||||
configure:4098: $? = 0
|
||||
configure:4098: result: yes
|
||||
configure:4098: checking for inttypes.h
|
||||
configure:4098: gcc -c -g conftest.c >&5
|
||||
configure:4098: $? = 0
|
||||
configure:4098: result: yes
|
||||
configure:4098: checking for stdint.h
|
||||
configure:4098: gcc -c -g conftest.c >&5
|
||||
configure:4098: $? = 0
|
||||
configure:4098: result: yes
|
||||
configure:4098: checking for unistd.h
|
||||
configure:4098: gcc -c -g conftest.c >&5
|
||||
configure:4098: $? = 0
|
||||
configure:4098: result: yes
|
||||
configure:4114: checking size of void *
|
||||
configure:4119: gcc -o conftest -g conftest.c >&5
|
||||
configure:4119: $? = 0
|
||||
configure:4119: ./conftest
|
||||
configure:4119: $? = 0
|
||||
configure:4133: result: 8
|
||||
configure:4147: checking size of unsigned int
|
||||
configure:4152: gcc -o conftest -g conftest.c >&5
|
||||
configure:4152: $? = 0
|
||||
configure:4152: ./conftest
|
||||
configure:4152: $? = 0
|
||||
configure:4166: result: 4
|
||||
configure:4180: checking size of unsigned long
|
||||
configure:4185: gcc -o conftest -g conftest.c >&5
|
||||
configure:4185: $? = 0
|
||||
configure:4185: ./conftest
|
||||
configure:4185: $? = 0
|
||||
configure:4199: result: 8
|
||||
configure:4213: checking size of unsigned long long
|
||||
configure:4218: gcc -o conftest -g conftest.c >&5
|
||||
configure:4218: $? = 0
|
||||
configure:4218: ./conftest
|
||||
configure:4218: $? = 0
|
||||
configure:4232: result: 8
|
||||
configure:4243: checking whether byte ordering is bigendian
|
||||
configure:4258: gcc -c -g conftest.c >&5
|
||||
configure:3846: result: yes
|
||||
configure:3853: checking for grep that handles long lines and -e
|
||||
configure:3911: result: /bin/grep
|
||||
configure:3916: checking for egrep
|
||||
configure:3978: result: /bin/grep -E
|
||||
configure:3983: checking for ANSI C header files
|
||||
configure:4003: gcc -c -g conftest.c >&5
|
||||
configure:4003: $? = 0
|
||||
configure:4076: gcc -o conftest -g conftest.c >&5
|
||||
configure:4076: $? = 0
|
||||
configure:4076: ./conftest
|
||||
configure:4076: $? = 0
|
||||
configure:4087: result: yes
|
||||
configure:4100: checking for sys/types.h
|
||||
configure:4100: gcc -c -g conftest.c >&5
|
||||
configure:4100: $? = 0
|
||||
configure:4100: result: yes
|
||||
configure:4100: checking for sys/stat.h
|
||||
configure:4100: gcc -c -g conftest.c >&5
|
||||
configure:4100: $? = 0
|
||||
configure:4100: result: yes
|
||||
configure:4100: checking for stdlib.h
|
||||
configure:4100: gcc -c -g conftest.c >&5
|
||||
configure:4100: $? = 0
|
||||
configure:4100: result: yes
|
||||
configure:4100: checking for string.h
|
||||
configure:4100: gcc -c -g conftest.c >&5
|
||||
configure:4100: $? = 0
|
||||
configure:4100: result: yes
|
||||
configure:4100: checking for memory.h
|
||||
configure:4100: gcc -c -g conftest.c >&5
|
||||
configure:4100: $? = 0
|
||||
configure:4100: result: yes
|
||||
configure:4100: checking for strings.h
|
||||
configure:4100: gcc -c -g conftest.c >&5
|
||||
configure:4100: $? = 0
|
||||
configure:4100: result: yes
|
||||
configure:4100: checking for inttypes.h
|
||||
configure:4100: gcc -c -g conftest.c >&5
|
||||
configure:4100: $? = 0
|
||||
configure:4100: result: yes
|
||||
configure:4100: checking for stdint.h
|
||||
configure:4100: gcc -c -g conftest.c >&5
|
||||
configure:4100: $? = 0
|
||||
configure:4100: result: yes
|
||||
configure:4100: checking for unistd.h
|
||||
configure:4100: gcc -c -g conftest.c >&5
|
||||
configure:4100: $? = 0
|
||||
configure:4100: result: yes
|
||||
configure:4116: checking size of void *
|
||||
configure:4121: gcc -o conftest -g conftest.c >&5
|
||||
configure:4121: $? = 0
|
||||
configure:4121: ./conftest
|
||||
configure:4121: $? = 0
|
||||
configure:4135: result: 8
|
||||
configure:4149: checking size of unsigned int
|
||||
configure:4154: gcc -o conftest -g conftest.c >&5
|
||||
configure:4154: $? = 0
|
||||
configure:4154: ./conftest
|
||||
configure:4154: $? = 0
|
||||
configure:4168: result: 4
|
||||
configure:4182: checking size of unsigned long
|
||||
configure:4187: gcc -o conftest -g conftest.c >&5
|
||||
configure:4187: $? = 0
|
||||
configure:4187: ./conftest
|
||||
configure:4187: $? = 0
|
||||
configure:4201: result: 8
|
||||
configure:4215: checking size of unsigned long long
|
||||
configure:4220: gcc -o conftest -g conftest.c >&5
|
||||
configure:4220: $? = 0
|
||||
configure:4220: ./conftest
|
||||
configure:4220: $? = 0
|
||||
configure:4234: result: 8
|
||||
configure:4245: checking whether byte ordering is bigendian
|
||||
configure:4260: gcc -c -g conftest.c >&5
|
||||
conftest.c:26:9: error: unknown type name 'not'
|
||||
not a universal capable compiler
|
||||
^
|
||||
@@ -252,7 +251,7 @@ conftest.c:26:15: error: expected '=', ',', ';', 'asm' or '__attribute__' before
|
||||
not a universal capable compiler
|
||||
^
|
||||
conftest.c:26:15: error: unknown type name 'universal'
|
||||
configure:4258: $? = 1
|
||||
configure:4260: $? = 1
|
||||
configure: failed program was:
|
||||
| /* confdefs.h */
|
||||
| #define PACKAGE_NAME "netgen"
|
||||
@@ -262,7 +261,7 @@ configure: failed program was:
|
||||
| #define PACKAGE_BUGREPORT "[email protected]"
|
||||
| #define PACKAGE_URL ""
|
||||
| #define NETGEN_VERSION "1.5"
|
||||
| #define NETGEN_REVISION "54"
|
||||
| #define NETGEN_REVISION "60"
|
||||
| #define STDC_HEADERS 1
|
||||
| #define HAVE_SYS_TYPES_H 1
|
||||
| #define HAVE_SYS_STAT_H 1
|
||||
@@ -283,9 +282,9 @@ configure: failed program was:
|
||||
| #endif
|
||||
| typedef int dummy;
|
||||
|
|
||||
configure:4303: gcc -c -g conftest.c >&5
|
||||
configure:4303: $? = 0
|
||||
configure:4321: gcc -c -g conftest.c >&5
|
||||
configure:4305: gcc -c -g conftest.c >&5
|
||||
configure:4305: $? = 0
|
||||
configure:4323: gcc -c -g conftest.c >&5
|
||||
conftest.c: In function 'main':
|
||||
conftest.c:32:4: error: unknown type name 'not'
|
||||
not big endian
|
||||
@@ -293,7 +292,7 @@ conftest.c:32:4: error: unknown type name 'not'
|
||||
conftest.c:32:12: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'endian'
|
||||
not big endian
|
||||
^
|
||||
configure:4321: $? = 1
|
||||
configure:4323: $? = 1
|
||||
configure: failed program was:
|
||||
| /* confdefs.h */
|
||||
| #define PACKAGE_NAME "netgen"
|
||||
@@ -303,7 +302,7 @@ configure: failed program was:
|
||||
| #define PACKAGE_BUGREPORT "[email protected]"
|
||||
| #define PACKAGE_URL ""
|
||||
| #define NETGEN_VERSION "1.5"
|
||||
| #define NETGEN_REVISION "54"
|
||||
| #define NETGEN_REVISION "60"
|
||||
| #define STDC_HEADERS 1
|
||||
| #define HAVE_SYS_TYPES_H 1
|
||||
| #define HAVE_SYS_STAT_H 1
|
||||
@@ -332,48 +331,48 @@ configure: failed program was:
|
||||
| ;
|
||||
| return 0;
|
||||
| }
|
||||
configure:4449: result: no
|
||||
configure:4468: checking for ANSI C header files
|
||||
configure:4572: result: yes
|
||||
configure:4584: checking for setenv
|
||||
configure:4584: gcc -o conftest -g conftest.c >&5
|
||||
configure:4584: $? = 0
|
||||
configure:4584: result: yes
|
||||
configure:4584: checking for putenv
|
||||
configure:4584: gcc -o conftest -g conftest.c >&5
|
||||
configure:4584: $? = 0
|
||||
configure:4584: result: yes
|
||||
configure:4594: checking for vfork
|
||||
configure:4594: gcc -o conftest -g conftest.c >&5
|
||||
configure:4594: $? = 0
|
||||
configure:4594: result: yes
|
||||
configure:4602: checking dirent.h usability
|
||||
configure:4602: gcc -c -g conftest.c >&5
|
||||
configure:4602: $? = 0
|
||||
configure:4602: result: yes
|
||||
configure:4602: checking dirent.h presence
|
||||
configure:4602: gcc -E -x c conftest.c
|
||||
configure:4602: $? = 0
|
||||
configure:4602: result: yes
|
||||
configure:4602: checking for dirent.h
|
||||
configure:4602: result: yes
|
||||
configure:4615: checking limits.h usability
|
||||
configure:4615: gcc -c -g conftest.c >&5
|
||||
configure:4615: $? = 0
|
||||
configure:4615: result: yes
|
||||
configure:4615: checking limits.h presence
|
||||
configure:4615: gcc -E -x c conftest.c
|
||||
configure:4615: $? = 0
|
||||
configure:4615: result: yes
|
||||
configure:4615: checking for limits.h
|
||||
configure:4615: result: yes
|
||||
configure:4628: checking param.h usability
|
||||
configure:4628: gcc -c -g conftest.c >&5
|
||||
configure:4451: result: no
|
||||
configure:4470: checking for ANSI C header files
|
||||
configure:4574: result: yes
|
||||
configure:4586: checking for setenv
|
||||
configure:4586: gcc -o conftest -g conftest.c >&5
|
||||
configure:4586: $? = 0
|
||||
configure:4586: result: yes
|
||||
configure:4586: checking for putenv
|
||||
configure:4586: gcc -o conftest -g conftest.c >&5
|
||||
configure:4586: $? = 0
|
||||
configure:4586: result: yes
|
||||
configure:4596: checking for vfork
|
||||
configure:4596: gcc -o conftest -g conftest.c >&5
|
||||
configure:4596: $? = 0
|
||||
configure:4596: result: yes
|
||||
configure:4604: checking dirent.h usability
|
||||
configure:4604: gcc -c -g conftest.c >&5
|
||||
configure:4604: $? = 0
|
||||
configure:4604: result: yes
|
||||
configure:4604: checking dirent.h presence
|
||||
configure:4604: gcc -E -x c conftest.c
|
||||
configure:4604: $? = 0
|
||||
configure:4604: result: yes
|
||||
configure:4604: checking for dirent.h
|
||||
configure:4604: result: yes
|
||||
configure:4617: checking limits.h usability
|
||||
configure:4617: gcc -c -g conftest.c >&5
|
||||
configure:4617: $? = 0
|
||||
configure:4617: result: yes
|
||||
configure:4617: checking limits.h presence
|
||||
configure:4617: gcc -E -x c conftest.c
|
||||
configure:4617: $? = 0
|
||||
configure:4617: result: yes
|
||||
configure:4617: checking for limits.h
|
||||
configure:4617: result: yes
|
||||
configure:4630: checking param.h usability
|
||||
configure:4630: gcc -c -g conftest.c >&5
|
||||
conftest.c:63:19: fatal error: param.h: No such file or directory
|
||||
#include <param.h>
|
||||
^
|
||||
compilation terminated.
|
||||
configure:4628: $? = 1
|
||||
configure:4630: $? = 1
|
||||
configure: failed program was:
|
||||
| /* confdefs.h */
|
||||
| #define PACKAGE_NAME "netgen"
|
||||
@@ -383,7 +382,7 @@ configure: failed program was:
|
||||
| #define PACKAGE_BUGREPORT "[email protected]"
|
||||
| #define PACKAGE_URL ""
|
||||
| #define NETGEN_VERSION "1.5"
|
||||
| #define NETGEN_REVISION "54"
|
||||
| #define NETGEN_REVISION "60"
|
||||
| #define STDC_HEADERS 1
|
||||
| #define HAVE_SYS_TYPES_H 1
|
||||
| #define HAVE_SYS_STAT_H 1
|
||||
@@ -438,14 +437,14 @@ configure: failed program was:
|
||||
| # include <unistd.h>
|
||||
| #endif
|
||||
| #include <param.h>
|
||||
configure:4628: result: no
|
||||
configure:4628: checking param.h presence
|
||||
configure:4628: gcc -E -x c conftest.c
|
||||
configure:4630: result: no
|
||||
configure:4630: checking param.h presence
|
||||
configure:4630: gcc -E -x c conftest.c
|
||||
conftest.c:30:19: fatal error: param.h: No such file or directory
|
||||
#include <param.h>
|
||||
^
|
||||
compilation terminated.
|
||||
configure:4628: $? = 1
|
||||
configure:4630: $? = 1
|
||||
configure: failed program was:
|
||||
| /* confdefs.h */
|
||||
| #define PACKAGE_NAME "netgen"
|
||||
@@ -455,7 +454,7 @@ configure: failed program was:
|
||||
| #define PACKAGE_BUGREPORT "[email protected]"
|
||||
| #define PACKAGE_URL ""
|
||||
| #define NETGEN_VERSION "1.5"
|
||||
| #define NETGEN_REVISION "54"
|
||||
| #define NETGEN_REVISION "60"
|
||||
| #define STDC_HEADERS 1
|
||||
| #define HAVE_SYS_TYPES_H 1
|
||||
| #define HAVE_SYS_STAT_H 1
|
||||
@@ -477,52 +476,52 @@ configure: failed program was:
|
||||
| #define HAVE_LIMITS_H 1
|
||||
| /* end confdefs.h. */
|
||||
| #include <param.h>
|
||||
configure:4628: result: no
|
||||
configure:4628: checking for param.h
|
||||
configure:4628: result: no
|
||||
configure:4639: checking for va_copy
|
||||
configure:4657: gcc -o conftest -g conftest.c >&5
|
||||
configure:4657: $? = 0
|
||||
configure:4666: result: yes
|
||||
configure:4674: checking for __va_copy
|
||||
configure:4692: gcc -o conftest -g conftest.c >&5
|
||||
configure:4692: $? = 0
|
||||
configure:4701: result: yes
|
||||
configure:4831: checking for tclConfig.sh
|
||||
configure:4903: result: /usr/lib64/tclConfig.sh
|
||||
configure:4919: checking for tkConfig.sh
|
||||
configure:4992: result: /usr/lib64/tkConfig.sh
|
||||
configure:5106: checking for wish executable
|
||||
configure:5133: result: /usr/bin/wish
|
||||
configure:5139: checking for tclsh executable
|
||||
configure:5165: result: /usr/bin/tclsh
|
||||
configure:5288: checking for X
|
||||
configure:5427: gcc -o conftest -g conftest.c -lX11 >&5
|
||||
configure:5427: $? = 0
|
||||
configure:5477: result: libraries , headers
|
||||
configure:5576: gcc -o conftest -g conftest.c -lX11 >&5
|
||||
configure:5576: $? = 0
|
||||
configure:5674: checking for gethostbyname
|
||||
configure:5674: gcc -o conftest -g conftest.c >&5
|
||||
configure:5674: $? = 0
|
||||
configure:5674: result: yes
|
||||
configure:5771: checking for connect
|
||||
configure:5771: gcc -o conftest -g conftest.c >&5
|
||||
configure:5771: $? = 0
|
||||
configure:5771: result: yes
|
||||
configure:5820: checking for remove
|
||||
configure:5820: gcc -o conftest -g conftest.c >&5
|
||||
configure:5820: $? = 0
|
||||
configure:5820: result: yes
|
||||
configure:5869: checking for shmat
|
||||
configure:5869: gcc -o conftest -g conftest.c >&5
|
||||
configure:5869: $? = 0
|
||||
configure:5869: result: yes
|
||||
configure:5927: checking for IceConnectionNumber in -lICE
|
||||
configure:5952: gcc -o conftest -g conftest.c -lICE >&5
|
||||
configure:5952: $? = 0
|
||||
configure:5961: result: yes
|
||||
configure:6675: creating ./config.status
|
||||
configure:4630: result: no
|
||||
configure:4630: checking for param.h
|
||||
configure:4630: result: no
|
||||
configure:4641: checking for va_copy
|
||||
configure:4659: gcc -o conftest -g conftest.c >&5
|
||||
configure:4659: $? = 0
|
||||
configure:4668: result: yes
|
||||
configure:4676: checking for __va_copy
|
||||
configure:4694: gcc -o conftest -g conftest.c >&5
|
||||
configure:4694: $? = 0
|
||||
configure:4703: result: yes
|
||||
configure:4834: checking for tclConfig.sh
|
||||
configure:4906: result: /usr/lib64/tclConfig.sh
|
||||
configure:4922: checking for tkConfig.sh
|
||||
configure:4995: result: /usr/lib64/tkConfig.sh
|
||||
configure:5128: checking for wish executable
|
||||
configure:5155: result: /usr/bin/wish
|
||||
configure:5161: checking for tclsh executable
|
||||
configure:5187: result: /usr/bin/tclsh
|
||||
configure:5310: checking for X
|
||||
configure:5449: gcc -o conftest -g conftest.c -lX11 >&5
|
||||
configure:5449: $? = 0
|
||||
configure:5499: result: libraries , headers
|
||||
configure:5598: gcc -o conftest -g conftest.c -lX11 >&5
|
||||
configure:5598: $? = 0
|
||||
configure:5696: checking for gethostbyname
|
||||
configure:5696: gcc -o conftest -g conftest.c >&5
|
||||
configure:5696: $? = 0
|
||||
configure:5696: result: yes
|
||||
configure:5793: checking for connect
|
||||
configure:5793: gcc -o conftest -g conftest.c >&5
|
||||
configure:5793: $? = 0
|
||||
configure:5793: result: yes
|
||||
configure:5842: checking for remove
|
||||
configure:5842: gcc -o conftest -g conftest.c >&5
|
||||
configure:5842: $? = 0
|
||||
configure:5842: result: yes
|
||||
configure:5891: checking for shmat
|
||||
configure:5891: gcc -o conftest -g conftest.c >&5
|
||||
configure:5891: $? = 0
|
||||
configure:5891: result: yes
|
||||
configure:5949: checking for IceConnectionNumber in -lICE
|
||||
configure:5974: gcc -o conftest -g conftest.c -lICE >&5
|
||||
configure:5974: $? = 0
|
||||
configure:5983: result: yes
|
||||
configure:6705: creating ./config.status
|
||||
|
||||
## ---------------------- ##
|
||||
## Running config.status. ##
|
||||
@@ -539,8 +538,8 @@ generated by GNU Autoconf 2.69. Invocation command line was
|
||||
|
||||
on stravinsky
|
||||
|
||||
config.status:781: creating defs.mak
|
||||
config.status:884: WARNING: 'defs.mak.in' seems to ignore the --datarootdir setting
|
||||
config.status:783: creating defs.mak
|
||||
config.status:886: WARNING: 'defs.mak.in' seems to ignore the --datarootdir setting
|
||||
|
||||
## ---------------- ##
|
||||
## Cache variables. ##
|
||||
@@ -622,7 +621,7 @@ CC='gcc'
|
||||
CFLAGS='-g -m64 -fPIC'
|
||||
CPP='gcc -E -x c'
|
||||
CPPFLAGS=''
|
||||
DEFS='-DPACKAGE_NAME=\"netgen\" -DPACKAGE_TARNAME=\"netgen\" -DPACKAGE_VERSION=\"1.3\" -DPACKAGE_STRING=\"netgen\ 1.3\" -DPACKAGE_BUGREPORT=\"[email protected]\" -DPACKAGE_URL=\"\" -DNETGEN_VERSION=\"1.5\" -DNETGEN_REVISION=\"54\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DSIZEOF_VOID_P=8 -DSIZEOF_UNSIGNED_INT=4 -DSIZEOF_UNSIGNED_LONG=8 -DSIZEOF_UNSIGNED_LONG_LONG=8 -DSTDC_HEADERS=1 -DHAVE_SETENV=1 -DHAVE_PUTENV=1 -DHAVE_DIRENT_H=1 -DHAVE_LIMITS_H=1 -DHAVE_VA_COPY=1 -DHAVE___VA_COPY=1 -DDBUG_OFF=1 -DTCL_NETGEN=1 -Dlinux=1 -DSYSV=1 -DISC=1'
|
||||
DEFS='-DPACKAGE_NAME=\"netgen\" -DPACKAGE_TARNAME=\"netgen\" -DPACKAGE_VERSION=\"1.3\" -DPACKAGE_STRING=\"netgen\ 1.3\" -DPACKAGE_BUGREPORT=\"[email protected]\" -DPACKAGE_URL=\"\" -DNETGEN_VERSION=\"1.5\" -DNETGEN_REVISION=\"60\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DSIZEOF_VOID_P=8 -DSIZEOF_UNSIGNED_INT=4 -DSIZEOF_UNSIGNED_LONG=8 -DSIZEOF_UNSIGNED_LONG_LONG=8 -DSTDC_HEADERS=1 -DHAVE_SETENV=1 -DHAVE_PUTENV=1 -DHAVE_DIRENT_H=1 -DHAVE_LIMITS_H=1 -DHAVE_VA_COPY=1 -DHAVE___VA_COPY=1 -DDBUG_OFF=1 -DTCL_NETGEN=1 -Dlinux=1 -DSYSV=1 -DISC=1'
|
||||
DEPEND_FLAG='-MM'
|
||||
ECHO_C=''
|
||||
ECHO_N='printf'
|
||||
@@ -642,7 +641,8 @@ LDFLAGS=''
|
||||
LD_RUN_PATH=''
|
||||
LIBOBJS=''
|
||||
LIBS=''
|
||||
LIB_SPECS=' -L/usr/lib64 -ltk8.6 -L/usr/lib64 -ltcl8.6'
|
||||
LIB_SPECS=' -L/usr/lib64 -ltkstub8.6 -L/usr/lib64 -ltclstub8.6'
|
||||
LIB_SPECS_NOSTUB=' -L/usr/lib64 -ltk8.6 -L/usr/lib64 -ltcl8.6'
|
||||
LTLIBOBJS=''
|
||||
M4='/bin/m4'
|
||||
OBJEXT='o'
|
||||
@@ -713,6 +713,7 @@ programs=' tcltk'
|
||||
psdir='${docdir}'
|
||||
sbindir='${exec_prefix}/sbin'
|
||||
sharedstatedir='${prefix}/com'
|
||||
stub_defs=' -DUSE_TCL_STUBS -DUSE_TK_STUBS'
|
||||
sub_extra_libs=''
|
||||
sysconfdir='${prefix}/etc'
|
||||
target='x86_64-unknown-linux-gnu'
|
||||
@@ -735,7 +736,7 @@ unused=''
|
||||
#define PACKAGE_BUGREPORT "[email protected]"
|
||||
#define PACKAGE_URL ""
|
||||
#define NETGEN_VERSION "1.5"
|
||||
#define NETGEN_REVISION "54"
|
||||
#define NETGEN_REVISION "60"
|
||||
#define STDC_HEADERS 1
|
||||
#define HAVE_SYS_TYPES_H 1
|
||||
#define HAVE_SYS_STAT_H 1
|
||||
|
||||
@@ -601,6 +601,7 @@ S["sub_extra_libs"]=""
|
||||
S["top_extra_libs"]=""
|
||||
S["ld_extra_objs"]=""
|
||||
S["ld_extra_libs"]=""
|
||||
S["stub_defs"]=" -DUSE_TCL_STUBS -DUSE_TK_STUBS"
|
||||
S["extra_defs"]=" -DCAD_DIR=\\\"${LIBDIR}\\\" -DTCL_DIR=\\\"${TCLDIR}\\\""
|
||||
S["extra_libs"]=" ${NETGENDIR}/tcltk/libtcltk.o"
|
||||
S["SCRIPTS"]=""
|
||||
@@ -609,7 +610,8 @@ S["VERSION"]=""
|
||||
S["TCL_LIB_DIR"]="/usr/lib"
|
||||
S["TCLSH_EXE"]="/usr/bin/tclsh"
|
||||
S["WISH_EXE"]="/usr/bin/wish"
|
||||
S["LIB_SPECS"]=" -L/usr/lib64 -ltk8.6 -L/usr/lib64 -ltcl8.6"
|
||||
S["LIB_SPECS_NOSTUB"]=" -L/usr/lib64 -ltk8.6 -L/usr/lib64 -ltcl8.6"
|
||||
S["LIB_SPECS"]=" -L/usr/lib64 -ltkstub8.6 -L/usr/lib64 -ltclstub8.6"
|
||||
S["INC_SPECS"]=""
|
||||
S["EXTRA_LIB_SPECS"]="-ldl"
|
||||
S["SHLIB_LIB_SPECS"]=""
|
||||
@@ -657,7 +659,7 @@ S["ECHO_T"]=""
|
||||
S["ECHO_N"]="-n"
|
||||
S["ECHO_C"]=""
|
||||
S["DEFS"]="-DPACKAGE_NAME=\\\"netgen\\\" -DPACKAGE_TARNAME=\\\"netgen\\\" -DPACKAGE_VERSION=\\\"1.3\\\" -DPACKAGE_STRING=\\\"netgen\\ 1.3\\\" -DPACKAGE_BUGREPORT=\\\"eda-dev@open"\
|
||||
"circuitdesign.com\\\" -DPACKAGE_URL=\\\"\\\" -DNETGEN_VERSION=\\\"1.5\\\" -DNETGEN_REVISION=\\\"54\\\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -"\
|
||||
"circuitdesign.com\\\" -DPACKAGE_URL=\\\"\\\" -DNETGEN_VERSION=\\\"1.5\\\" -DNETGEN_REVISION=\\\"60\\\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -"\
|
||||
"DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DSIZEOF_VOID_P=8 -D"\
|
||||
"SIZEOF_UNSIGNED_INT=4 -DSIZEOF_UNSIGNED_LONG=8 -DSIZEOF_UNSIGNED_LONG_LONG=8 -DSTDC_HEADERS=1 -DHAVE_SETENV=1 -DHAVE_PUTENV=1 -DHAVE_DIRENT_H=1 -DHA"\
|
||||
"VE_LIMITS_H=1 -DHAVE_VA_COPY=1 -DHAVE___VA_COPY=1 -DDBUG_OFF=1 -DTCL_NETGEN=1 -Dlinux=1 -DSYSV=1 -DISC=1"
|
||||
|
||||
Vendored
+36
-6
@@ -641,6 +641,7 @@ sub_extra_libs
|
||||
top_extra_libs
|
||||
ld_extra_objs
|
||||
ld_extra_libs
|
||||
stub_defs
|
||||
extra_defs
|
||||
extra_libs
|
||||
SCRIPTS
|
||||
@@ -649,6 +650,7 @@ VERSION
|
||||
TCL_LIB_DIR
|
||||
TCLSH_EXE
|
||||
WISH_EXE
|
||||
LIB_SPECS_NOSTUB
|
||||
LIB_SPECS
|
||||
INC_SPECS
|
||||
EXTRA_LIB_SPECS
|
||||
@@ -4712,6 +4714,7 @@ fi
|
||||
$as_echo "#define DBUG_OFF 1" >>confdefs.h
|
||||
|
||||
|
||||
stub_defs=""
|
||||
extra_defs="$extra_defs -DCAD_DIR=\\\"\${LIBDIR}\\\""
|
||||
X_LIBS=
|
||||
X_CFLAGS=
|
||||
@@ -4861,7 +4864,7 @@ $as_echo_n "checking for tclConfig.sh... " >&6; }
|
||||
# 1. Search previously named locations.
|
||||
|
||||
for dir in \
|
||||
$prefix \
|
||||
$ac_default_prefix \
|
||||
$exec_prefix
|
||||
do
|
||||
if test -r "$dir/tclConfig.sh" ; then
|
||||
@@ -4948,7 +4951,7 @@ $as_echo_n "checking for tkConfig.sh... " >&6; }
|
||||
# 1. Search previously named locations.
|
||||
#
|
||||
for dir in \
|
||||
$prefix \
|
||||
$ac_default_prefix \
|
||||
$exec_prefix
|
||||
do
|
||||
if test -r "$dir/tkConfig.sh" ; then
|
||||
@@ -5007,6 +5010,25 @@ if test $usingTcl ; then
|
||||
. $tcl_config_sh
|
||||
. $tk_config_sh
|
||||
|
||||
# Should probably trust the config file contents, but this configure
|
||||
# file checks the Tcl and Tk include and lib directories. Since
|
||||
# the config file doesn't separate out the libraries from the strings
|
||||
# passed to the compiler/linker, do it manually here.
|
||||
#
|
||||
# Extract TCL_LIB_DIR from TCL_LIB_SPEC
|
||||
# Extract TK_LIB_DIR from TK_LIB_SPEC
|
||||
# Extract TCL_INC_DIR from TCL_INCLUDE_SPEC
|
||||
# Extract TK_INC_DIR from TK_INCLUDE_SPEC
|
||||
#
|
||||
# These will be the defaults unless overridden by configure command line
|
||||
|
||||
tmpstr=${TCL_LIB_SPEC#*-L}
|
||||
TCL_LIB_DIR=${tmpstr% -l*}
|
||||
tmpstr=${TK_LIB_SPEC#*-L}
|
||||
TK_LIB_DIR=${tmpstr% -l*}
|
||||
TCL_INC_DIR=${TCL_INCLUDE_SPEC#*-I}
|
||||
TK_INC_DIR=${TK_INCLUDE_SPEC#*-I}
|
||||
|
||||
if test "$TCL_VERSION" = "7.6" -a "$TK_VERSION" = "4.2" ; then
|
||||
:
|
||||
elif test "$TCL_VERSION" = "7.5" -a "$TK_VERSION" = "4.1" ; then
|
||||
@@ -5992,6 +6014,7 @@ if test $usingTcl ; then
|
||||
|
||||
extra_libs="$extra_libs \${NETGENDIR}/tcltk/libtcltk.o"
|
||||
extra_defs="$extra_defs -DTCL_DIR=\\\"\${TCLDIR}\\\""
|
||||
stub_defs="$stub_defs -DUSE_TCL_STUBS -DUSE_TK_STUBS"
|
||||
else
|
||||
programs="$programs netgen"
|
||||
unused="$unused tcltk"
|
||||
@@ -6070,6 +6093,7 @@ esac
|
||||
# -----------------------------------------------------------------------
|
||||
|
||||
if test $usingTcl ; then
|
||||
LIB_SPECS_NOSTUB="${LIB_SPECS}"
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
#
|
||||
@@ -6081,9 +6105,11 @@ if test $usingTcl ; then
|
||||
fi
|
||||
if test "${TK_LIB_DIR}" = "/usr/lib" -o \
|
||||
"${TK_LIB_DIR}" = "/usr/lib64" ; then
|
||||
LIB_SPECS="${LIB_SPECS} ${TK_LIB_SPEC}"
|
||||
LIB_SPECS_NOSTUB="${LIB_SPECS_NOSTUB} ${TK_LIB_SPEC}"
|
||||
LIB_SPECS="${LIB_SPECS} ${TK_STUB_LIB_SPEC}"
|
||||
else
|
||||
LIB_SPECS="${LIB_SPECS} -L${TK_LIB_DIR} ${TK_LIB_SPEC}"
|
||||
LIB_SPECS_NOSTUB="${LIB_SPECS_NOSTUB} -L${TK_LIB_DIR} ${TK_LIB_SPEC}"
|
||||
LIB_SPECS="${LIB_SPECS} -L${TK_LIB_DIR} ${TK_STUB_LIB_SPEC}"
|
||||
if test "x${loader_run_path}" = "x" ; then
|
||||
loader_run_path="${TK_LIB_DIR}"
|
||||
else
|
||||
@@ -6107,9 +6133,11 @@ if test $usingTcl ; then
|
||||
if test "${TCL_LIB_DIR}" = "/usr/lib" -o \
|
||||
"${TCL_LIB_DIR}" = "/usr/lib64" -o \
|
||||
"${TCL_LIB_DIR}" = "${TK_LIB_DIR}" ; then
|
||||
LIB_SPECS="${LIB_SPECS} ${TCL_LIB_SPEC}"
|
||||
LIB_SPECS_NOSTUB="${LIB_SPECS_NOSTUB} ${TCL_LIB_SPEC}"
|
||||
LIB_SPECS="${LIB_SPECS} ${TCL_STUB_LIB_SPEC}"
|
||||
else
|
||||
LIB_SPECS="${LIB_SPECS} -L${TCL_LIB_DIR} ${TCL_LIB_SPEC}"
|
||||
LIB_SPECS_NOSTUB="${LIB_SPECS_NOSTUB} -L${TCL_LIB_DIR} ${TCL_LIB_SPEC}"
|
||||
LIB_SPECS="${LIB_SPECS} -L${TCL_LIB_DIR} ${TCL_STUB_LIB_SPEC}"
|
||||
if test "x${loader_run_path}" = "x" ; then
|
||||
loader_run_path="${TCL_LIB_DIR}"
|
||||
else
|
||||
@@ -6482,6 +6510,7 @@ fi
|
||||
|
||||
|
||||
|
||||
|
||||
fi
|
||||
|
||||
if test "$GCC" = "yes" ; then
|
||||
@@ -6517,6 +6546,7 @@ fi
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
ac_config_files="$ac_config_files defs.mak"
|
||||
|
||||
+32
-4
@@ -195,6 +195,7 @@ fi
|
||||
# not ANSI-compliant and won't compile without quite a bit of work.
|
||||
AC_DEFINE(DBUG_OFF)
|
||||
|
||||
stub_defs=""
|
||||
extra_defs="$extra_defs -DCAD_DIR=\\\"\${LIBDIR}\\\""
|
||||
X_LIBS=
|
||||
X_CFLAGS=
|
||||
@@ -472,6 +473,25 @@ if test $usingTcl ; then
|
||||
. $tcl_config_sh
|
||||
. $tk_config_sh
|
||||
|
||||
# Should probably trust the config file contents, but this configure
|
||||
# file checks the Tcl and Tk include and lib directories. Since
|
||||
# the config file doesn't separate out the libraries from the strings
|
||||
# passed to the compiler/linker, do it manually here.
|
||||
#
|
||||
# Extract TCL_LIB_DIR from TCL_LIB_SPEC
|
||||
# Extract TK_LIB_DIR from TK_LIB_SPEC
|
||||
# Extract TCL_INC_DIR from TCL_INCLUDE_SPEC
|
||||
# Extract TK_INC_DIR from TK_INCLUDE_SPEC
|
||||
#
|
||||
# These will be the defaults unless overridden by configure command line
|
||||
|
||||
tmpstr=${TCL_LIB_SPEC#*-L}
|
||||
TCL_LIB_DIR=${tmpstr% -l*}
|
||||
tmpstr=${TK_LIB_SPEC#*-L}
|
||||
TK_LIB_DIR=${tmpstr% -l*}
|
||||
TCL_INC_DIR=${TCL_INCLUDE_SPEC#*-I}
|
||||
TK_INC_DIR=${TK_INCLUDE_SPEC#*-I}
|
||||
|
||||
if test "$TCL_VERSION" = "7.6" -a "$TK_VERSION" = "4.2" ; then
|
||||
:
|
||||
elif test "$TCL_VERSION" = "7.5" -a "$TK_VERSION" = "4.1" ; then
|
||||
@@ -779,6 +799,7 @@ if test $usingTcl ; then
|
||||
AC_DEFINE(TCL_NETGEN)
|
||||
extra_libs="$extra_libs \${NETGENDIR}/tcltk/libtcltk.o"
|
||||
extra_defs="$extra_defs -DTCL_DIR=\\\"\${TCLDIR}\\\""
|
||||
stub_defs="$stub_defs -DUSE_TCL_STUBS -DUSE_TK_STUBS"
|
||||
else
|
||||
programs="$programs netgen"
|
||||
unused="$unused tcltk"
|
||||
@@ -858,6 +879,7 @@ esac
|
||||
# -----------------------------------------------------------------------
|
||||
|
||||
if test $usingTcl ; then
|
||||
LIB_SPECS_NOSTUB="${LIB_SPECS}"
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
#
|
||||
@@ -869,9 +891,11 @@ if test $usingTcl ; then
|
||||
fi
|
||||
if test "${TK_LIB_DIR}" = "/usr/lib" -o \
|
||||
"${TK_LIB_DIR}" = "/usr/lib64" ; then
|
||||
LIB_SPECS="${LIB_SPECS} ${TK_LIB_SPEC}"
|
||||
LIB_SPECS_NOSTUB="${LIB_SPECS_NOSTUB} ${TK_LIB_SPEC}"
|
||||
LIB_SPECS="${LIB_SPECS} ${TK_STUB_LIB_SPEC}"
|
||||
else
|
||||
LIB_SPECS="${LIB_SPECS} -L${TK_LIB_DIR} ${TK_LIB_SPEC}"
|
||||
LIB_SPECS_NOSTUB="${LIB_SPECS_NOSTUB} -L${TK_LIB_DIR} ${TK_LIB_SPEC}"
|
||||
LIB_SPECS="${LIB_SPECS} -L${TK_LIB_DIR} ${TK_STUB_LIB_SPEC}"
|
||||
if test "x${loader_run_path}" = "x" ; then
|
||||
loader_run_path="${TK_LIB_DIR}"
|
||||
else
|
||||
@@ -895,9 +919,11 @@ if test $usingTcl ; then
|
||||
if test "${TCL_LIB_DIR}" = "/usr/lib" -o \
|
||||
"${TCL_LIB_DIR}" = "/usr/lib64" -o \
|
||||
"${TCL_LIB_DIR}" = "${TK_LIB_DIR}" ; then
|
||||
LIB_SPECS="${LIB_SPECS} ${TCL_LIB_SPEC}"
|
||||
LIB_SPECS_NOSTUB="${LIB_SPECS_NOSTUB} ${TCL_LIB_SPEC}"
|
||||
LIB_SPECS="${LIB_SPECS} ${TCL_STUB_LIB_SPEC}"
|
||||
else
|
||||
LIB_SPECS="${LIB_SPECS} -L${TCL_LIB_DIR} ${TCL_LIB_SPEC}"
|
||||
LIB_SPECS_NOSTUB="${LIB_SPECS_NOSTUB} -L${TCL_LIB_DIR} ${TCL_LIB_SPEC}"
|
||||
LIB_SPECS="${LIB_SPECS} -L${TCL_LIB_DIR} ${TCL_STUB_LIB_SPEC}"
|
||||
if test "x${loader_run_path}" = "x" ; then
|
||||
loader_run_path="${TCL_LIB_DIR}"
|
||||
else
|
||||
@@ -1216,6 +1242,7 @@ if test $usingTcl ; then
|
||||
AC_SUBST(LDFLAGS)
|
||||
AC_SUBST(INC_SPECS)
|
||||
AC_SUBST(LIB_SPECS)
|
||||
AC_SUBST(LIB_SPECS_NOSTUB)
|
||||
AC_SUBST(WISH_EXE)
|
||||
AC_SUBST(TCLSH_EXE)
|
||||
AC_SUBST(TCL_LIB_DIR)
|
||||
@@ -1233,6 +1260,7 @@ AC_SUBST(PACKAGE)
|
||||
AC_SUBST(SCRIPTS)
|
||||
AC_SUBST(extra_libs)
|
||||
AC_SUBST(extra_defs)
|
||||
AC_SUBST(stub_defs)
|
||||
AC_SUBST(ld_extra_libs)
|
||||
AC_SUBST(ld_extra_objs)
|
||||
AC_SUBST(top_extra_libs)
|
||||
|
||||
+4
-2
@@ -56,7 +56,8 @@ RANLIB = ranlib
|
||||
SHDLIB_EXT = .so
|
||||
LDDL_FLAGS = -shared -Wl,-soname,$@ -Wl,--version-script=${NETGENDIR}/netgen/symbol.map
|
||||
LD_RUN_PATH =
|
||||
LIB_SPECS = -L/usr/lib64 -ltk8.6 -L/usr/lib64 -ltcl8.6
|
||||
LIB_SPECS = -L/usr/lib64 -ltkstub8.6 -L/usr/lib64 -ltclstub8.6
|
||||
LIB_SPECS_NOSTUB = -L/usr/lib64 -ltk8.6 -L/usr/lib64 -ltcl8.6
|
||||
WISH_EXE = /usr/bin/wish
|
||||
TCL_LIB_DIR = /usr/lib
|
||||
|
||||
@@ -65,7 +66,8 @@ CPP = gcc -E -x c
|
||||
CXX = @CXX@
|
||||
|
||||
CPPFLAGS = -I. -I${NETGENDIR}
|
||||
DFLAGS = -DCAD_DIR=\"${LIBDIR}\" -DTCL_DIR=\"${TCLDIR}\" -DPACKAGE_NAME=\"netgen\" -DPACKAGE_TARNAME=\"netgen\" -DPACKAGE_VERSION=\"1.3\" -DPACKAGE_STRING=\"netgen\ 1.3\" -DPACKAGE_BUGREPORT=\"[email protected]\" -DPACKAGE_URL=\"\" -DNETGEN_VERSION=\"1.5\" -DNETGEN_REVISION=\"54\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DSIZEOF_VOID_P=8 -DSIZEOF_UNSIGNED_INT=4 -DSIZEOF_UNSIGNED_LONG=8 -DSIZEOF_UNSIGNED_LONG_LONG=8 -DSTDC_HEADERS=1 -DHAVE_SETENV=1 -DHAVE_PUTENV=1 -DHAVE_DIRENT_H=1 -DHAVE_LIMITS_H=1 -DHAVE_VA_COPY=1 -DHAVE___VA_COPY=1 -DDBUG_OFF=1 -DTCL_NETGEN=1 -Dlinux=1 -DSYSV=1 -DISC=1 -DSHDLIB_EXT=\".so\" -DNDEBUG
|
||||
DFLAGS = -DCAD_DIR=\"${LIBDIR}\" -DTCL_DIR=\"${TCLDIR}\" -DUSE_TCL_STUBS -DUSE_TK_STUBS -DPACKAGE_NAME=\"netgen\" -DPACKAGE_TARNAME=\"netgen\" -DPACKAGE_VERSION=\"1.3\" -DPACKAGE_STRING=\"netgen\ 1.3\" -DPACKAGE_BUGREPORT=\"[email protected]\" -DPACKAGE_URL=\"\" -DNETGEN_VERSION=\"1.5\" -DNETGEN_REVISION=\"60\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DSIZEOF_VOID_P=8 -DSIZEOF_UNSIGNED_INT=4 -DSIZEOF_UNSIGNED_LONG=8 -DSIZEOF_UNSIGNED_LONG_LONG=8 -DSTDC_HEADERS=1 -DHAVE_SETENV=1 -DHAVE_PUTENV=1 -DHAVE_DIRENT_H=1 -DHAVE_LIMITS_H=1 -DHAVE_VA_COPY=1 -DHAVE___VA_COPY=1 -DDBUG_OFF=1 -DTCL_NETGEN=1 -Dlinux=1 -DSYSV=1 -DISC=1 -DSHDLIB_EXT=\".so\" -DNDEBUG
|
||||
DFLAGS_NOSTUB = -DCAD_DIR=\"${LIBDIR}\" -DTCL_DIR=\"${TCLDIR}\" -DPACKAGE_NAME=\"netgen\" -DPACKAGE_TARNAME=\"netgen\" -DPACKAGE_VERSION=\"1.3\" -DPACKAGE_STRING=\"netgen\ 1.3\" -DPACKAGE_BUGREPORT=\"[email protected]\" -DPACKAGE_URL=\"\" -DNETGEN_VERSION=\"1.5\" -DNETGEN_REVISION=\"60\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DSIZEOF_VOID_P=8 -DSIZEOF_UNSIGNED_INT=4 -DSIZEOF_UNSIGNED_LONG=8 -DSIZEOF_UNSIGNED_LONG_LONG=8 -DSTDC_HEADERS=1 -DHAVE_SETENV=1 -DHAVE_PUTENV=1 -DHAVE_DIRENT_H=1 -DHAVE_LIMITS_H=1 -DHAVE_VA_COPY=1 -DHAVE___VA_COPY=1 -DDBUG_OFF=1 -DTCL_NETGEN=1 -Dlinux=1 -DSYSV=1 -DISC=1 -DSHDLIB_EXT=\".so\" -DNDEBUG
|
||||
CFLAGS = -g -m64 -fPIC -fPIC
|
||||
|
||||
DEPEND_FILE = Depend
|
||||
|
||||
+3
-1
@@ -57,6 +57,7 @@ SHDLIB_EXT = @SHDLIB_EXT@
|
||||
LDDL_FLAGS = @LDDL_FLAGS@
|
||||
LD_RUN_PATH = @LD_RUN_PATH@
|
||||
LIB_SPECS = @LIB_SPECS@
|
||||
LIB_SPECS_NOSTUB = @LIB_SPECS_NOSTUB@
|
||||
WISH_EXE = @WISH_EXE@
|
||||
TCL_LIB_DIR = @TCL_LIB_DIR@
|
||||
|
||||
@@ -65,7 +66,8 @@ CPP = @CPP@
|
||||
CXX = @CXX@
|
||||
|
||||
CPPFLAGS = -I. -I${NETGENDIR} @CPPFLAGS@
|
||||
DFLAGS = @extra_defs@ @DEFS@ -DSHDLIB_EXT=\"@SHDLIB_EXT@\" -DNDEBUG
|
||||
DFLAGS = @extra_defs@ @stub_defs@ @DEFS@ -DSHDLIB_EXT=\"@SHDLIB_EXT@\" -DNDEBUG
|
||||
DFLAGS_NOSTUB = @extra_defs@ @DEFS@ -DSHDLIB_EXT=\"@SHDLIB_EXT@\" -DNDEBUG
|
||||
CFLAGS = @CFLAGS@ @SHLIB_CFLAGS@ @INC_SPECS@
|
||||
|
||||
DEPEND_FILE = Depend
|
||||
|
||||
+3
-2
@@ -23,8 +23,9 @@ install-tcl: netgenexec${EXEEXT} $(DESTDIR)${BINDIR}/netgen.sh ${TCL_FILES}
|
||||
${CP} netgenexec${EXEEXT} $(DESTDIR)${TCLDIR}/netgenexec${EXEEXT}
|
||||
|
||||
netgenexec${EXEEXT}: netgenexec.c
|
||||
${CC} ${CFLAGS} ${CPPFLAGS} ${DFLAGS} netgenexec.c -o netgenexec${EXEEXT} \
|
||||
${LDFLAGS} ${LIBS} ${LIB_SPECS}
|
||||
${CC} ${CFLAGS} ${CPPFLAGS} ${DFLAGS_NOSTUB} netgenexec.c \
|
||||
-o netgenexec${EXEEXT} \
|
||||
${LDFLAGS} ${LIBS} ${LIB_SPECS_NOSTUB}
|
||||
|
||||
netgen.tcl: netgen.tcl.in
|
||||
sed -e /TCL_DIR/s%TCL_DIR%${TCLDIR}%g \
|
||||
|
||||
+6
-2
@@ -20,7 +20,11 @@ foreach i $nlist {
|
||||
}
|
||||
}
|
||||
|
||||
load TCL_DIR/tclnetgenSHDLIB_EXT
|
||||
if {${tcl_version} >= 8.6} {
|
||||
load -lazy TCL_DIR/tclnetgenSHDLIB_EXT
|
||||
} else {
|
||||
load TCL_DIR/tclnetgenSHDLIB_EXT
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------
|
||||
# Define the "lvs" command as a way of calling the netgen options
|
||||
@@ -126,7 +130,7 @@ proc netgen::lvs { name1 name2 {setupfile setup.tcl} {logfile comp.out}} {
|
||||
}
|
||||
} else {
|
||||
netgen::permute default ;# transistors and resistors
|
||||
netgen::combine default ;# standard parallel/serial allowances
|
||||
netgen::property default
|
||||
}
|
||||
|
||||
puts stdout "Comparison output logged to file $logfile"
|
||||
|
||||
+52
-181
@@ -91,7 +91,6 @@ int _netcmp_automorphs(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]);
|
||||
int _netcmp_equate(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]);
|
||||
int _netcmp_ignore(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]);
|
||||
int _netcmp_permute(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]);
|
||||
int _netcmp_combine(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]);
|
||||
int _netcmp_property(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]);
|
||||
int _netcmp_exhaustive(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]);
|
||||
int _netcmp_restart(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]);
|
||||
@@ -231,14 +230,8 @@ Command netcmp_cmds[] = {
|
||||
"capacitor: enable capacitor permutations\n "
|
||||
"transistor: enable transistor permutations\n "
|
||||
"(none): enable transistor and resistor permutations"},
|
||||
{"combine", _netcmp_combine,
|
||||
"[transistors|resistors|capacitors|<model>]\n "
|
||||
"<model> [<serial>|<parallel>]: enable combinations of device model\n "
|
||||
"resistor: enable resistor serial/parallel combinations\n "
|
||||
"capacitor: enable capacitor parallel combinations\n "
|
||||
"transistor: enable transistor parallel combinations\n "
|
||||
"(none): enable standard combinations"},
|
||||
{"property", _netcmp_property,
|
||||
"default: apply property defaults\n "
|
||||
"<device>|<model> <property_key> [...]\n "
|
||||
"<device>: name of a device type (capacitor, etc.)\n "
|
||||
"<model>: name of a device model\n "
|
||||
@@ -2525,10 +2518,10 @@ _netcmp_ignore(ClientData clientData,
|
||||
Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
|
||||
{
|
||||
char *options[] = {
|
||||
"class", NULL
|
||||
"class", "shorted", NULL
|
||||
};
|
||||
enum OptionIdx {
|
||||
CLASS_IDX
|
||||
CLASS_IDX, SHORTED_IDX
|
||||
};
|
||||
int result, index;
|
||||
int file = -1;
|
||||
@@ -2549,7 +2542,14 @@ _netcmp_ignore(ClientData clientData,
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "[class] valid_cellname");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
IgnoreClass(name, file);
|
||||
switch (index) {
|
||||
case CLASS_IDX:
|
||||
IgnoreClass(name, file, IGNORE_CLASS);
|
||||
break;
|
||||
case SHORTED_IDX:
|
||||
IgnoreClass(name, file, IGNORE_SHORTED);
|
||||
break;
|
||||
}
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -2971,6 +2971,8 @@ _netcmp_equate(ClientData clientData,
|
||||
/* remove --- delete existing property */
|
||||
/* tolerance --- set property tolerance */
|
||||
/* merge --- set property merge behavior */
|
||||
/* or */
|
||||
/* netgen::property default */
|
||||
/* Formerly: (none) */
|
||||
/* Results: */
|
||||
/* Side Effects: */
|
||||
@@ -3013,6 +3015,44 @@ _netcmp_property(ClientData clientData,
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "valid_cellname ?option?");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
/* Check for special command "property default" */
|
||||
if ((objc == 2) && (!strcmp(Tcl_GetString(objv[1]), "default"))) {
|
||||
|
||||
/* For each FET device, do "merge {w add_critical}" and */
|
||||
/* "remove as ad ps pd". This allows parallel devices */
|
||||
/* to be added by width, and prevents attempts to */
|
||||
/* compare source/drain area and perimeter. */
|
||||
|
||||
tp = FirstCell();
|
||||
while (tp != NULL) {
|
||||
switch (tp->class) {
|
||||
case CLASS_NMOS: case CLASS_PMOS: case CLASS_FET3:
|
||||
case CLASS_NMOS4: case CLASS_PMOS4: case CLASS_FET4:
|
||||
case CLASS_FET:
|
||||
PropertyMerge(tp->name, tp->file, "w", MERGE_ADD_CRIT);
|
||||
PropertyDelete(tp->name, tp->file, "as");
|
||||
PropertyDelete(tp->name, tp->file, "ad");
|
||||
PropertyDelete(tp->name, tp->file, "ps");
|
||||
PropertyDelete(tp->name, tp->file, "pd");
|
||||
break;
|
||||
case CLASS_RES: case CLASS_RES3:
|
||||
PropertyMerge(tp->name, tp->file, "l", MERGE_PAR_CRIT);
|
||||
break;
|
||||
case CLASS_CAP: case CLASS_ECAP: case CLASS_CAP3:
|
||||
// NOTE: No attempt to combine area, width, or length;
|
||||
// only value.
|
||||
PropertyMerge(tp->name, tp->file, "value", MERGE_ADD_CRIT);
|
||||
break;
|
||||
case CLASS_INDUCTOR:
|
||||
PropertyMerge(tp->name, tp->file, "value", MERGE_PAR_CRIT);
|
||||
break;
|
||||
}
|
||||
tp = NextCell();
|
||||
}
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
result = CommonParseCell(interp, objv[1], &tp, &fnum);
|
||||
if (result != TCL_OK) return result;
|
||||
|
||||
@@ -3279,175 +3319,6 @@ _netcmp_property(ClientData clientData,
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------*/
|
||||
/* Function name: _netcmp_combine */
|
||||
/* Syntax: netgen::combine [default] */
|
||||
/* netgen::combine combine_class */
|
||||
/* netgen::combine valid_cellname serial|parallel */
|
||||
/* netgen::combine forget valid_cellname */
|
||||
/* netgen::combine forget */
|
||||
/* Formerly: t */
|
||||
/* Results: */
|
||||
/* Side Effects: */
|
||||
/*--------------------------------------------------------------*/
|
||||
|
||||
int
|
||||
_netcmp_combine(ClientData clientData,
|
||||
Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
|
||||
{
|
||||
char *model;
|
||||
char *combineclass[] = {
|
||||
"transistors", "resistors", "capacitors", "default", "forget",
|
||||
"cell", NULL
|
||||
};
|
||||
enum OptionIdx {
|
||||
TRANS_IDX, RES_IDX, CAP_IDX, DEFLT_IDX, FORGET_IDX, CELL_IDX
|
||||
};
|
||||
int result, index, index2, fnum = -1;
|
||||
struct nlist *tp = NULL;
|
||||
|
||||
char *combinetype[] = {
|
||||
"serial", "parallel", NULL
|
||||
};
|
||||
enum SubOptionIdx {
|
||||
SERIAL_IDX, PARALLEL_IDX
|
||||
};
|
||||
|
||||
if (objc > 3) {
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "?valid_cellname serial|parallel?");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if (objc == 1) {
|
||||
index = DEFLT_IDX;
|
||||
}
|
||||
else {
|
||||
if (Tcl_GetIndexFromObj(interp, objv[1], (CONST84 char **)combineclass,
|
||||
"combine class", 0, &index) != TCL_OK) {
|
||||
if (objc != 3) {
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "?valid_cellname serial|parallel?");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
result = CommonParseCell(interp, objv[1], &tp, &fnum);
|
||||
if (result != TCL_OK) {
|
||||
Fprintf(stdout, "No such device \"%s\".\n",
|
||||
Tcl_GetString(objv[1]));
|
||||
return result;
|
||||
}
|
||||
index = CELL_IDX;
|
||||
if (Tcl_GetIndexFromObj(interp, objv[2],
|
||||
(CONST84 char **)combinetype,
|
||||
"combine type", 0, &index2) != TCL_OK) {
|
||||
Tcl_WrongNumArgs(interp, 1, objv,
|
||||
"?valid_cellname serial|parallel?");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
}
|
||||
else if (index == CELL_IDX) {
|
||||
if (objc != 4) {
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "cell ?valid_cellname serial|parallel?");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
result = CommonParseCell(interp, objv[2], &tp, &fnum);
|
||||
if (result != TCL_OK) {
|
||||
Fprintf(stdout, "No such device \"%s\".\n",
|
||||
Tcl_GetString(objv[2]));
|
||||
return result;
|
||||
}
|
||||
if (Tcl_GetIndexFromObj(interp, objv[3],
|
||||
(CONST84 char **)combinetype,
|
||||
"combine type", 0, &index2) != TCL_OK) {
|
||||
Tcl_WrongNumArgs(interp, 1, objv,
|
||||
"?valid_cellname serial|parallel?");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
}
|
||||
else if (index == FORGET_IDX) {
|
||||
if (objc < 3) {
|
||||
/* General purpose combine forget */
|
||||
tp = FirstCell();
|
||||
while (tp != NULL) {
|
||||
CombineForget(tp->name, tp->file, NULL);
|
||||
tp = NextCell();
|
||||
}
|
||||
return TCL_OK;
|
||||
}
|
||||
else {
|
||||
/* Specific combine forget */
|
||||
result = CommonParseCell(interp, objv[2], &tp, &fnum);
|
||||
if (result != TCL_OK) {
|
||||
Fprintf(stdout, "No such device \"%s\".\n",
|
||||
Tcl_GetString(objv[2]));
|
||||
return result;
|
||||
}
|
||||
if (objc != 4) {
|
||||
if (Tcl_GetIndexFromObj(interp, objv[3],
|
||||
(CONST84 char **)combinetype,
|
||||
"combine type", 0, &index2) != TCL_OK) {
|
||||
Tcl_WrongNumArgs(interp, 1, objv,
|
||||
"?valid_cellname serial|parallel?");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if (CombineForget(tp->name, fnum, (index2 == SERIAL_IDX)
|
||||
? COMB_SERIAL : COMB_PARALLEL))
|
||||
Fprintf(stdout, "Model %s combine %s\n", tp->name,
|
||||
(index2 == SERIAL_IDX) ? "serial" : "parallel");
|
||||
else
|
||||
Fprintf(stderr, "Unable to reset model %s %s combination.\n",
|
||||
tp->name, (index2 == SERIAL_IDX) ? "serial" : "parallel");
|
||||
}
|
||||
else {
|
||||
if (CombineForget(tp->name, fnum, NULL))
|
||||
Fprintf(stdout, "No combinations of circuit %s allowed\n", tp->name);
|
||||
else
|
||||
Fprintf(stderr, "Unable to reset model %s %s combinations\n",
|
||||
tp->name, (index2 == SERIAL_IDX) ? "serial" : "parallel");
|
||||
}
|
||||
return TCL_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (objc == 1 || objc == 2) {
|
||||
tp = FirstCell();
|
||||
while (tp != NULL) {
|
||||
switch (tp->class) {
|
||||
case CLASS_NMOS: case CLASS_PMOS: case CLASS_FET3:
|
||||
case CLASS_NMOS4: case CLASS_PMOS4: case CLASS_FET4:
|
||||
case CLASS_FET:
|
||||
if (index == TRANS_IDX || index == DEFLT_IDX)
|
||||
CombineSetup(tp->name, tp->file, COMB_PARALLEL);
|
||||
break;
|
||||
case CLASS_RES: case CLASS_RES3:
|
||||
if (index == RES_IDX || index == DEFLT_IDX) {
|
||||
CombineSetup(tp->name, tp->file, COMB_SERIAL);
|
||||
CombineSetup(tp->name, tp->file, COMB_PARALLEL);
|
||||
}
|
||||
break;
|
||||
case CLASS_CAP: case CLASS_ECAP: case CLASS_CAP3:
|
||||
if (index == CAP_IDX)
|
||||
CombineSetup(tp->name, tp->file, COMB_PARALLEL);
|
||||
break;
|
||||
}
|
||||
tp = NextCell();
|
||||
}
|
||||
}
|
||||
else if (index == CELL_IDX) {
|
||||
if (CombineSetup(tp->name, fnum, ((index2 == SERIAL_IDX) ?
|
||||
COMB_SERIAL : COMB_PARALLEL)))
|
||||
Fprintf(stdout, "Model %s allow %s combinations\n", tp->name,
|
||||
(index2 == SERIAL_IDX) ? "serial" : "parallel");
|
||||
else
|
||||
Fprintf(stderr, "Unable to set model %s %s combinations.\n",
|
||||
tp->name, (index2 == SERIAL_IDX) ?
|
||||
"serial" : "parallel");
|
||||
}
|
||||
else {
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "?valid_cellname serial|parallel?");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------*/
|
||||
/* Function name: _netcmp_permute */
|
||||
/* Syntax: netgen::permute [default] */
|
||||
@@ -3922,7 +3793,7 @@ int Tclnetgen_Init(Tcl_Interp *interp)
|
||||
/* Remember the interpreter */
|
||||
netgeninterp = interp;
|
||||
|
||||
if (Tcl_InitStubs(interp, "8.1", 0) == NULL) return TCL_ERROR;
|
||||
if (Tcl_InitStubs(interp, "8.5", 0) == NULL) return TCL_ERROR;
|
||||
|
||||
for (n = 0; netgen_cmds[n].name != NULL; n++) {
|
||||
sprintf(keyword, "netgen::%s", netgen_cmds[n].name);
|
||||
|
||||
Reference in New Issue
Block a user