diff --git a/ChangeLog b/ChangeLog
index d7bd0533d..3becf34f3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2005-02-08 Paolo Nenzi
+
+ * src/frontend/subckt.c: modified the file with the one supplied by
+ Dietmar Warning's (warning@danalyse.de). This fix the bug that
+ caused ngspice to crash with long subckt lines.
+
2004-09-05 Paolo Nenzi
* src/spicelib/devices/jfet/jfet.c: model type (njf or pjf) was
diff --git a/src/frontend/subckt.c b/src/frontend/subckt.c
index 7a9314763..54703a0d4 100644
--- a/src/frontend/subckt.c
+++ b/src/frontend/subckt.c
@@ -104,8 +104,8 @@ struct subs {
struct line *su_def; /* Pointer to the .subckt definition. */
struct subs *su_next;
} ;
-
-
+
+
/* submod is the list of original model names, modnames is the
* list of translated names (i.e. after subckt expansion)
*/
@@ -465,7 +465,7 @@ doit(struct line *deck)
/* Change the names of .models found in .subckts . . . */
if (modtranslate(lcc, scname)) /* this translates the model name in the .model line */
- devmodtranslate(lcc, scname); /* This translates the model name on all components in the deck */
+ devmodtranslate(lcc, scname); /* This translates the model name on all components in the deck */
s = sss->su_args;
txfree(gettok(&t)); /* Throw out the subcircuit refdes */
@@ -577,7 +577,7 @@ translate(struct line *deck, char *formal, char *actual, char *scname, char *sub
{
struct line *c;
char *buffer, *next_name, dev_type, *name, *s, *t, ch, *nametofree;
- int nnodes, i, dim;
+ int nnodes, i, dim, blen;
int rtn=0;
/* settrans builds the table holding the translated netnames. */
@@ -626,13 +626,13 @@ translate(struct line *deck, char *formal, char *actual, char *scname, char *sub
/* translate the instance name according to normal rules */
- buffer = tmalloc(2000); /* XXXXX */
s = c->li_line;
name = MIFgettok(&s);
/* maschmann
sprintf(buffer, "%s:%s ", name, scname); */
+ buffer = (char *)tmalloc((strlen(scname)+strlen(name)+5)*sizeof(char));
sprintf(buffer, "a:%s:%s ", scname, name+1 );
@@ -663,19 +663,25 @@ translate(struct line *deck, char *formal, char *actual, char *scname, char *sub
case '[':
case ']':
case '~':
- sprintf(buffer + strlen(buffer), "%s ", name);
+ blen = strlen(buffer);
+ buffer = (char *)trealloc(buffer, (blen+strlen(name)+2)*sizeof(char));
+ sprintf(buffer + blen, "%s ", name);
break;
case '%':
- sprintf(buffer + strlen(buffer), "%%");
+ blen = strlen(buffer);
+ buffer = (char *)trealloc(buffer, (blen+2)*sizeof(char));
+ sprintf(buffer + blen, "%%");
/* don't translate the port type identifier */
name = next_name;
next_name = MIFgettok(&s);
- sprintf(buffer + strlen(buffer), "%s ", name);
+ blen = strlen(buffer);
+ buffer = (char *)trealloc(buffer, (blen+strlen(name)+2)*sizeof(char));
+ sprintf(buffer + blen, "%s ", name);
break;
default:
@@ -685,23 +691,24 @@ translate(struct line *deck, char *formal, char *actual, char *scname, char *sub
t = gettrans(name);
if (t) {
- sprintf(buffer + strlen(buffer), "%s ", t);
- } else {
+ blen = strlen(buffer);
+ buffer = (char *)trealloc(buffer, (blen+strlen(t)+2)*sizeof(char));
+ sprintf(buffer + blen, "%s ", t);
+ } else {
/* maschmann: changed order
- * sprintf(buffer + strlen(buffer), "%s:%s ", name, scname); */
-
- if(name[0]=='v' || name[0]=='V')
- /* If the name begins with V (Vsource), translate it as a source:
- * V:subcircuitname:sourcename
- * SDB says: This is a bad hack. What if my netname has a V in it?!?!? */
- sprintf(buffer + strlen(buffer), "v:%s:%s ", scname, name+1);
- else
- /* Translate it as a normal node */
- sprintf(buffer + strlen(buffer), "%s:%s ", scname, name);
- }
-
+ sprintf(buffer + strlen(buffer), "%s:%s ", name, scname); */
+ if(name[0]=='v' || name[0]=='V') {
+ blen = strlen(buffer);
+ buffer = (char *)trealloc(buffer, (blen+strlen(scname)+strlen(name)+5)*sizeof(char));
+ sprintf(buffer + blen, "v:%s:%s ", scname, name+1);
+ } else {
+ blen = strlen(buffer);
+ buffer = (char *)trealloc(buffer, (blen+strlen(scname)+strlen(name)+3)*sizeof(char));
+ sprintf(buffer + blen, "%s:%s ", scname, name);
+ }
+ }
break;
-
+
} /* switch */
} /* while */
@@ -709,9 +716,11 @@ translate(struct line *deck, char *formal, char *actual, char *scname, char *sub
/* copy in the last token, which is the model name */
- if(name)
- sprintf(buffer + strlen(buffer), "%s ", name);
-
+ if(name) {
+ blen = strlen(buffer);
+ buffer = (char *)trealloc(buffer, (blen+strlen(name)+2)*sizeof(char));
+ sprintf(buffer + blen, "%s ", name);
+ }
/* Set s to null string for compatibility with code */
/* after switch statement */
@@ -746,17 +755,19 @@ translate(struct line *deck, char *formal, char *actual, char *scname, char *sub
* and stick the translated name into buffer.
*/
ch = *name; /* ch identifies the type of component */
- buffer = tmalloc(2000); /* XXXXX */
name++;
if (*name == ':')
name++; /* now name point to the rest of the refdes */
- if (*name)
- (void) sprintf(buffer, "%c:%s:%s ", ch, scname, /* F:subcircuitname:refdesname */
+ if (*name) {
+ buffer = (char *)tmalloc((strlen(scname)+strlen(name)+5)*sizeof(char));
+ sprintf(buffer, "%c:%s:%s ", ch, scname, /* F:subcircuitname:refdesname */
name);
- else
- (void) sprintf(buffer, "%c:%s ", ch, scname); /* F:subcircuitname */
+ } else {
+ buffer = (char *)tmalloc((strlen(scname)+4)*sizeof(char));
+ sprintf(buffer, "%c:%s ", ch, scname); /* F:subcircuitname */
+ }
tfree(t);
@@ -775,13 +786,16 @@ translate(struct line *deck, char *formal, char *actual, char *scname, char *sub
t = gettrans(name);
if (t) { /* the netname was used during the invocation; print it into the buffer */
- (void) sprintf(buffer + strlen(buffer), "%s ", t);
+ blen = strlen(buffer);
+ buffer = (char *)trealloc(buffer, (blen+strlen(t)+2)*sizeof(char));
+ sprintf(buffer + blen, "%s ", t);
}
else { /* net netname was not used during the invocation; place a
* translated name into the buffer.
*/
- (void) sprintf(buffer + strlen(buffer),
- "%s:%s ", scname, name);
+ blen = strlen(buffer);
+ buffer = (char *)trealloc(buffer, (blen+strlen(scname)+strlen(name)+3)*sizeof(char));
+ sprintf(buffer + blen, "%s:%s ", scname, name);
}
tfree(name);
} /* while (nnodes-- . . . . */
@@ -820,8 +834,9 @@ translate(struct line *deck, char *formal, char *actual, char *scname, char *sub
}
/* Write POLY(dim) into buffer */
- (void) sprintf(buffer + strlen(buffer),
- "POLY( %d ) ", dim);
+ blen = strlen(buffer);
+ buffer = (char *)trealloc(buffer, (blen+17)*sizeof(char));
+ sprintf(buffer + blen, "POLY( %d ) ", dim);
} /* if ( (strcmp(next_name, "POLY") == 0) . . . */
@@ -854,9 +869,10 @@ translate(struct line *deck, char *formal, char *actual, char *scname, char *sub
ch = *name; /* ch is the first char of the token. */
name++;
if (*name == ':')
- name++; /* name now points to the remainder of the token */
- (void) sprintf(buffer + strlen(buffer),
- "%c:%s:%s ", ch, scname, name);
+ name++; /* name now points to the remainder of the token */
+ blen = strlen(buffer);
+ buffer = (char *)trealloc(buffer, (blen+strlen(scname)+strlen(name)+5)*sizeof(char));
+ sprintf(buffer + blen, "%c:%s:%s ", ch, scname, name);
/* From Vsense and Urefdes creates V:Urefdes:sense */
}
else { /* Handle netname */
@@ -870,13 +886,16 @@ translate(struct line *deck, char *formal, char *actual, char *scname, char *sub
t = gettrans(name);
if (t) { /* the netname was used during the invocation; print it into the buffer */
- (void) sprintf(buffer + strlen(buffer), "%s ", t);
+ blen = strlen(buffer);
+ buffer = (char *)trealloc(buffer, (blen+strlen(t)+2)*sizeof(char));
+ sprintf(buffer + blen, "%s ", t);
}
else { /* net netname was not used during the invocation; place a
* translated name into the buffer.
*/
- (void) sprintf(buffer + strlen(buffer),
- "%s:%s ", scname, name);
+ blen = strlen(buffer);
+ buffer = (char *)trealloc(buffer, (blen+strlen(scname)+strlen(name)+3)*sizeof(char));
+ sprintf(buffer + blen, "%s:%s ", scname, name);
/* From netname and Urefdes creates Urefdes:netname */
}
}
@@ -884,7 +903,9 @@ translate(struct line *deck, char *formal, char *actual, char *scname, char *sub
} /* while (nnodes--. . . . */
/* Now write out remainder of line (polynomial coeffs) */
- finishLine(buffer + strlen(buffer), s, scname);
+ blen = strlen(buffer);
+ buffer = (char *)trealloc(buffer, (blen+strlen(s)+strlen(scname)+1000)*sizeof(char));
+ finishLine(buffer + blen, s, scname);
s = "";
break;
@@ -904,16 +925,18 @@ translate(struct line *deck, char *formal, char *actual, char *scname, char *sub
* and stick the translated name into buffer.
*/
ch = *name;
- buffer = tmalloc(2000); /* XXXXX */
+
name++;
if (*name == ':')
name++;
- if (*name)
- (void) sprintf(buffer, "%c:%s:%s ", ch, scname,
- name);
- else
- (void) sprintf(buffer, "%c:%s ", ch, scname);
+ if (*name) {
+ buffer = (char *)tmalloc((strlen(scname)+strlen(name)+5)*sizeof(char));
+ sprintf(buffer, "%c:%s:%s ", ch, scname, name);
+ } else {
+ buffer = (char *)tmalloc((strlen(scname)+4)*sizeof(char));
+ sprintf(buffer, "%c:%s ", ch, scname);
+ }
tfree(nametofree);
@@ -932,15 +955,18 @@ translate(struct line *deck, char *formal, char *actual, char *scname, char *sub
t = gettrans(name);
if (t) { /* the netname was used during the invocation; print it into the buffer */
- (void) sprintf(buffer + strlen(buffer), "%s ", t);
+ blen = strlen(buffer);
+ buffer = (char *)trealloc(buffer, (blen+strlen(t)+2)*sizeof(char));
+ sprintf(buffer + blen, "%s ", t);
}
else { /* net netname was not used during the invocation; place a
* translated name into the buffer.
*/
- (void) sprintf(buffer + strlen(buffer),
- "%s:%s ", scname, name);
+ blen = strlen(buffer);
+ buffer = (char *)trealloc(buffer, (blen+strlen(scname)+strlen(name)+3)*sizeof(char));
+ sprintf(buffer + blen, "%s:%s ", scname, name);
}
- free(name);
+ tfree(name);
} /* while (nnodes-- . . . . */
/* Now translate any devices (i.e. controlling sources).
@@ -960,12 +986,15 @@ translate(struct line *deck, char *formal, char *actual, char *scname, char *sub
if (*name == ':')
name++;
- if (*name)
- (void) sprintf(buffer + strlen(buffer),
- "%c:%s:%s ", ch, scname, name);
- else
- (void) sprintf(buffer + strlen(buffer),
- "%c:%s ", ch, scname);
+ if (*name) {
+ blen = strlen(buffer);
+ buffer = (char *)trealloc(buffer, (blen+strlen(scname)+strlen(name)+5)*sizeof(char));
+ sprintf(buffer + blen, "%c:%s:%s ", ch, scname, name);
+ } else {
+ blen = strlen(buffer);
+ buffer = (char *)trealloc(buffer, (blen+strlen(scname)+4)*sizeof(char));
+ sprintf(buffer + blen, "%c:%s ", ch, scname);
+ }
tfree(t);
} /* while (nnodes--. . . . */
@@ -975,14 +1004,18 @@ translate(struct line *deck, char *formal, char *actual, char *scname, char *sub
* We also scan through the line for v(something) and
* i(something)...
*/
- finishLine(buffer + strlen(buffer), s, scname);
- s = "";
+ blen = strlen(buffer);
+ buffer = (char *)trealloc(buffer, (blen+strlen(s)+strlen(scname)+1000)*sizeof(char));
+ finishLine(buffer + blen, s, scname);
+ s = "";
} /* switch(c->li_line . . . . */
- (void) strcat(buffer, s);
- tfree(c->li_line);
- c->li_line = copy(buffer);
+ blen = strlen(buffer);
+ buffer = (char *)trealloc(buffer, (blen+strlen(s)+1)*sizeof(char));
+ strcat(buffer, s);
+ tfree(c->li_line);
+ c->li_line = copy(buffer);
#ifdef TRACE
/* SDB debug statement */
@@ -1102,6 +1135,7 @@ finishLine(char *dst, char *src, char *scname)
}
}
+ *dst = '\0'; /* va, append in each case '\0' */
return;
}
@@ -1221,7 +1255,7 @@ numnodes(char *name)
i = 0;
s = buf;
gotit = 0;
- txfree(gettok(&s)); /* Skip component name */
+ txfree(gettok(&s)); /* Skip component name */
while ((i < n) && (*s) && !gotit) {
t = gettok_node(&s); /* get nodenames . . . */
for (wl = modnames; wl; wl = wl->wl_next)
@@ -1308,7 +1342,7 @@ numdevs(char *s)
}
/*----------------------------------------------------------------------*
- * modtranslate -- translates .model liness found in subckt definitions.
+ * modtranslate -- translates .model lines found in subckt definitions.
* Calling arguments are:
* *deck = pointer to the .subckt definition (linked list)
* *subname = pointer to the subcircuit name used at the subcircuit invocation (string)
@@ -1339,8 +1373,7 @@ modtranslate(struct line *deck, char *subname)
buffer = tmalloc(strlen(name) + strlen(t) +
strlen(subname) + 4);
(void) sprintf(buffer, "%s ",name); /* at this point, buffer = ".model " */
- tfree(name);
-
+ tfree(name);
name = gettok(&t); /* name now holds model name */
wlsub = alloc(struct wordlist);
wlsub->wl_next = submod;