Browse Source

patch for translate(), R. Larice, .global bug

pre-master-46
h_vogt 16 years ago
parent
commit
ecf5665104
  1. 7
      ChangeLog
  2. 369
      src/frontend/subckt.c
  3. 1
      src/include/ngspice.h

7
ChangeLog

@ -1,4 +1,9 @@
2010-01-02 Holger Vogt
2010-01-15 Holger Vogt
* subckt.c: patch for translate() by R. Larice, .global bug
removed (add null character after storing global to node[])
ngspice.h: _inline for _MSC_VER
2010-01-06 Holger Vogt
* x11.c: hardcopy by button click, error removed * x11.c: hardcopy by button click, error removed
2010-01-02 Holger Vogt 2010-01-02 Holger Vogt

369
src/frontend/subckt.c

@ -5,6 +5,15 @@ Modified: 2000 AlansFixes
$Id$ $Id$
**********/ **********/
/*------------------------------------------------------------------------------
* encapsulated string assembly in translate() and finishLine()
* this string facility (bxx_buffer) mainly abstracts away buffer allocation.
* this fixes a buffer overflow in finishLine, caused by lengthy descriptions
* of the kind:
* B1 1 2 I=v(1)+v(2)+v(3)+...
* Larice, 22nd Aug 2009
*----------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------ /*------------------------------------------------------------------------------
* Added changes supplied by by H.Tanaka with some tidy up of comments, debug * Added changes supplied by by H.Tanaka with some tidy up of comments, debug
* statements, and variables. This fixes a problem with nested .subsck elements * statements, and variables. This fixes a problem with nested .subsck elements
@ -52,6 +61,8 @@ $Id$
#include "ftedefs.h" #include "ftedefs.h"
#include "fteinp.h" #include "fteinp.h"
#include <stdarg.h>
#ifdef XSPICE #ifdef XSPICE
/* gtri - add - wbk - 11/9/90 - include MIF function prototypes */ /* gtri - add - wbk - 11/9/90 - include MIF function prototypes */
#include "mifproto.h" #include "mifproto.h"
@ -70,9 +81,10 @@ extern void line_free_x(struct line * deck, bool recurse);
static struct line * doit(struct line *deck); static struct line * doit(struct line *deck);
static int translate(struct line *deck, char *formal, char *actual, char *scname, static int translate(struct line *deck, char *formal, char *actual, char *scname,
char *subname); char *subname);
static void finishLine(char *dst, char *src, char *scname);
struct bxx_buffer;
static void finishLine(struct bxx_buffer *dst, char *src, char *scname);
static int settrans(char *formal, char *actual, char *subname); static int settrans(char *formal, char *actual, char *subname);
static char * gettrans(char *name);
static char * gettrans(const char *name, const char *name_end);
static int numnodes(char *name); static int numnodes(char *name);
static int numdevs(char *s); static int numdevs(char *s);
static bool modtranslate(struct line *deck, char *subname); static bool modtranslate(struct line *deck, char *subname);
@ -241,7 +253,7 @@ inp_subcktexpand(struct line *deck)
i=0; i=0;
t=s; t=s;
for (/*s*/; *s && !isspace(*s); s++) i++; for (/*s*/; *s && !isspace(*s); s++) i++;
strncpy(node[numgnode],t,i);
strncpy(node[numgnode],t,i+1); /* i+1: include \0 character */
while (isspace(*s)) s++; while (isspace(*s)) s++;
numgnode++; numgnode++;
} /* node[] holds name of global node */ } /* node[] holds name of global node */
@ -682,6 +694,141 @@ inp_deckcopy(struct line *deck)
return (nd); return (nd);
} }
/*-------------------------------------------------------------------
* struct bxx_buffer,
* a string assembly facility.
*
* usage:
*
* struct bxx_buffer thing;
* bxx_init(&thing);
* ...
* while(...) {
* bxx_rewind(&thing);
* ...
* bxx_putc(&thing, ...)
* bxx_printf(&thing, ...)
* bxx_put_cstring(&thing, ...)
* bxx_put_substring(&thing, ...)
* ...
* strcpy(bxx_buffer(&thing)
* }
* ..
* bxx_free(&thing)
*
* main aspect:
* reallocates/extends its buffer itself.
*
* note:
* during asssembly the internal buffer is
* not necessarily '\0' terminated.
* but will be when bxx_buffer() is invoked
*/
struct bxx_buffer
{
char *dst;
char *limit;
char *buffer;
};
/* must be a power of 2 */
static const int bxx_chunksize = 1024;
static void
bxx_init(struct bxx_buffer *t)
{
/* assert(0 == (bxx_chunksize & (bxx_chunksize - 1))); */
t->buffer = tmalloc(bxx_chunksize);
t->dst = t->buffer;
t->limit = t->buffer + bxx_chunksize;
}
static void
bxx_free(struct bxx_buffer *t)
{
tfree(t->buffer);
}
static void
bxx_rewind(struct bxx_buffer *t)
{
t->dst = t->buffer;
}
static void
bxx_extend(struct bxx_buffer *t, int howmuch)
{
int pos = t->dst - t->buffer;
int len = t->limit - t->buffer;
/* round up */
howmuch += (bxx_chunksize - 1);
howmuch &= ~(bxx_chunksize - 1);
t->buffer = trealloc(t->buffer, len += howmuch);
t->dst = t->buffer + pos;
t->limit = t->buffer + len;
}
static void
bxx_printf(struct bxx_buffer *t, const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
while(1) {
int size = t->limit - t->buffer;
int ret = vsnprintf(t->dst, size, fmt, ap);
if(ret == -1) {
bxx_extend(t, bxx_chunksize);
} else if(ret >= size) {
bxx_extend(t, ret - size + 1);
} else {
t->dst += ret;
break;
}
}
va_end(ap);
}
static inline char
bxx_putc(struct bxx_buffer *t, char c)
{
if(t->dst >= t->limit)
bxx_extend(t, 1);
return *(t->dst)++ = c;
}
static void
bxx_put_cstring(struct bxx_buffer *t, const char *cstring)
{
while(*cstring)
bxx_putc(t, *cstring++);
}
static void
bxx_put_substring(struct bxx_buffer *t, const char *str, const char *end)
{
while(str < end)
bxx_putc(t, *str++);
}
static char *
bxx_buffer(struct bxx_buffer *t)
{
if((t->dst == t->buffer) || (t->dst[-1] != '\0'))
bxx_putc(t, '\0');
return t->buffer;
}
/*------------------------------------------------------------------------------------------* /*------------------------------------------------------------------------------------------*
* Translate all of the device names and node names in the .subckt deck. They are * Translate all of the device names and node names in the .subckt deck. They are
* pre-pended with subname:, unless they are in the formal list, in which case * pre-pended with subname:, unless they are in the formal list, in which case
@ -700,10 +847,13 @@ static int
translate(struct line *deck, char *formal, char *actual, char *scname, char *subname) translate(struct line *deck, char *formal, char *actual, char *scname, char *subname)
{ {
struct line *c; struct line *c;
char *buffer, *next_name, dev_type, *name, *s, *t, ch, *nametofree, *paren_ptr, *new_str;
int nnodes, i, dim, blen;
struct bxx_buffer buffer;
char *next_name, dev_type, *name, *s, *t, ch, *nametofree, *paren_ptr, *new_str;
int nnodes, i, dim;
int rtn=0; int rtn=0;
bxx_init(&buffer);
/* settrans builds the table holding the translated netnames. */ /* settrans builds the table holding the translated netnames. */
i = settrans(formal, actual, subname); i = settrans(formal, actual, subname);
if (i < 0) { if (i < 0) {
@ -741,7 +891,7 @@ translate(struct line *deck, char *formal, char *actual, char *scname, char *sub
goto quit; goto quit;
} }
*paren_ptr = '\0'; *paren_ptr = '\0';
t = gettrans(name);
t = gettrans(name, NULL);
if (t) { if (t) {
new_str = tmalloc( strlen(s) + strlen(t) + strlen(paren_ptr+1) + 3 ); new_str = tmalloc( strlen(s) + strlen(t) + strlen(paren_ptr+1) + 3 );
@ -766,7 +916,7 @@ translate(struct line *deck, char *formal, char *actual, char *scname, char *sub
case '*': case '$': case '*': case '$':
case '.': case '.':
/* Just a pointer to the line into s and then break */ /* Just a pointer to the line into s and then break */
buffer = tmalloc(2000+strlen(c->li_line)); /* DW,VA */
bxx_rewind(&buffer);
s = c->li_line; s = c->li_line;
break; break;
@ -785,10 +935,11 @@ translate(struct line *deck, char *formal, char *actual, char *scname, char *sub
s = c->li_line; s = c->li_line;
name = MIFgettok(&s); name = MIFgettok(&s);
bxx_rewind(&buffer);
/* maschmann /* maschmann
sprintf(buffer, "%s:%s ", name, scname); */
buffer = (char *)tmalloc((strlen(scname)+strlen(name)+5)*sizeof(char));
sprintf(buffer, "a.%s.%s ", scname, name );
bxx_printf(&buffer, "%s:%s ", name, scname); */
bxx_printf(&buffer, "a.%s.%s ", scname, name );
@ -818,48 +969,36 @@ translate(struct line *deck, char *formal, char *actual, char *scname, char *sub
case '[': case '[':
case ']': case ']':
case '~': case '~':
blen = strlen(buffer);
buffer = (char *)trealloc(buffer, (blen+strlen(name)+2)*sizeof(char));
sprintf(buffer + blen, "%s ", name);
bxx_printf(&buffer, "%s ", name);
break; break;
case '%': case '%':
blen = strlen(buffer);
buffer = (char *)trealloc(buffer, (blen+2)*sizeof(char));
sprintf(buffer + blen, "%%");
bxx_printf(&buffer, "%%");
/* don't translate the port type identifier */ /* don't translate the port type identifier */
name = next_name; name = next_name;
next_name = MIFgettok(&s); next_name = MIFgettok(&s);
blen = strlen(buffer);
buffer = (char *)trealloc(buffer, (blen+strlen(name)+2)*sizeof(char));
sprintf(buffer + blen, "%s ", name);
bxx_printf(&buffer, "%s ", name);
break; break;
default: default:
/* must be a node name at this point, so translate it */ /* must be a node name at this point, so translate it */
t = gettrans(name);
t = gettrans(name, NULL);
if (t) { if (t) {
blen = strlen(buffer);
buffer = (char *)trealloc(buffer, (blen+strlen(t)+2)*sizeof(char));
sprintf(buffer + blen, "%s ", t);
bxx_printf(&buffer, "%s ", t);
} else { } else {
/* maschmann: changed order /* maschmann: changed order
sprintf(buffer + strlen(buffer), "%s:%s ", name, scname); */
bxx_printf(&buffer, "%s:%s ", name, scname); */
if(name[0]=='v' || name[0]=='V') { 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);
bxx_printf(&buffer, "v.%s.%s ", scname, name);
} else { } else {
blen = strlen(buffer);
buffer = (char *)trealloc(buffer, (blen+strlen(scname)+strlen(name)+3)*sizeof(char));
sprintf(buffer + blen, "%s.%s ", scname, name);
bxx_printf(&buffer, "%s.%s ", scname, name);
} }
} }
break; break;
@ -872,9 +1011,7 @@ translate(struct line *deck, char *formal, char *actual, char *scname, char *sub
/* copy in the last token, which is the model name */ /* copy in the last token, which is the model name */
if(name) { if(name) {
blen = strlen(buffer);
buffer = (char *)trealloc(buffer, (blen+strlen(name)+2)*sizeof(char));
sprintf(buffer + blen, "%s ", name);
bxx_printf(&buffer, "%s ", name);
} }
/* Set s to null string for compatibility with code */ /* Set s to null string for compatibility with code */
/* after switch statement */ /* after switch statement */
@ -911,8 +1048,8 @@ translate(struct line *deck, char *formal, char *actual, char *scname, char *sub
*/ */
ch = *name; /* ch identifies the type of component */ ch = *name; /* ch identifies the type of component */
buffer = (char *)tmalloc((strlen(scname)+strlen(name)+5)*sizeof(char));
sprintf(buffer, "%c.%s.%s ", ch, scname, name);
bxx_rewind(&buffer);
bxx_printf(&buffer, "%c.%s.%s ", ch, scname, name);
tfree(t); tfree(t);
@ -928,19 +1065,15 @@ translate(struct line *deck, char *formal, char *actual, char *scname, char *sub
} }
/* call gettrans and see if netname was used in the invocation */ /* call gettrans and see if netname was used in the invocation */
t = gettrans(name);
t = gettrans(name, NULL);
if (t) { /* the netname was used during the invocation; print it into the buffer */ if (t) { /* the netname was used during the invocation; print it into the buffer */
blen = strlen(buffer);
buffer = (char *)trealloc(buffer, (blen+strlen(t)+2)*sizeof(char));
sprintf(buffer + blen, "%s ", t);
bxx_printf(&buffer, "%s ", t);
} }
else { /* net netname was not used during the invocation; place a else { /* net netname was not used during the invocation; place a
* translated name into the buffer. * translated name into the buffer.
*/ */
blen = strlen(buffer);
buffer = (char *)trealloc(buffer, (blen+strlen(scname)+strlen(name)+3)*sizeof(char));
sprintf(buffer + blen, "%s.%s ", scname, name);
bxx_printf(&buffer, "%s.%s ", scname, name);
} }
tfree(name); tfree(name);
} /* while (nnodes-- . . . . */ } /* while (nnodes-- . . . . */
@ -979,9 +1112,7 @@ translate(struct line *deck, char *formal, char *actual, char *scname, char *sub
} }
/* Write POLY(dim) into buffer */ /* Write POLY(dim) into buffer */
blen = strlen(buffer);
buffer = (char *)trealloc(buffer, (blen+17)*sizeof(char));
sprintf(buffer + blen, "POLY( %d ) ", dim);
bxx_printf(&buffer, "POLY( %d ) ", dim);
} /* if ( (strcmp(next_name, "POLY") == 0) . . . */ } /* if ( (strcmp(next_name, "POLY") == 0) . . . */
@ -1013,9 +1144,7 @@ translate(struct line *deck, char *formal, char *actual, char *scname, char *sub
ch = *name; /* ch is the first char of the token. */ ch = *name; /* ch is the first char 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);
bxx_printf(&buffer, "%c.%s.%s ", ch, scname, name);
/* From Vsense and Urefdes creates V:Urefdes:sense */ /* From Vsense and Urefdes creates V:Urefdes:sense */
} }
else { /* Handle netname */ else { /* Handle netname */
@ -1026,19 +1155,15 @@ translate(struct line *deck, char *formal, char *actual, char *scname, char *sub
#endif #endif
/* call gettrans and see if netname was used in the invocation */ /* call gettrans and see if netname was used in the invocation */
t = gettrans(name);
t = gettrans(name, NULL);
if (t) { /* the netname was used during the invocation; print it into the buffer */ if (t) { /* the netname was used during the invocation; print it into the buffer */
blen = strlen(buffer);
buffer = (char *)trealloc(buffer, (blen+strlen(t)+2)*sizeof(char));
sprintf(buffer + blen, "%s ", t);
bxx_printf(&buffer, "%s ", t);
} }
else { /* net netname was not used during the invocation; place a else { /* net netname was not used during the invocation; place a
* translated name into the buffer. * translated name into the buffer.
*/ */
blen = strlen(buffer);
buffer = (char *)trealloc(buffer, (blen+strlen(scname)+strlen(name)+3)*sizeof(char));
sprintf(buffer + blen, "%s.%s ", scname, name);
bxx_printf(&buffer, "%s.%s ", scname, name);
/* From netname and Urefdes creates Urefdes:netname */ /* From netname and Urefdes creates Urefdes:netname */
} }
} }
@ -1046,9 +1171,7 @@ translate(struct line *deck, char *formal, char *actual, char *scname, char *sub
} /* while (nnodes--. . . . */ } /* while (nnodes--. . . . */
/* Now write out remainder of line (polynomial coeffs) */ /* Now write out remainder of line (polynomial coeffs) */
blen = strlen(buffer);
buffer = (char *)trealloc(buffer, (blen+strlen(s)+strlen(scname)+1000)*sizeof(char));
finishLine(buffer + blen, s, scname);
finishLine(&buffer, s, scname);
s = ""; s = "";
break; break;
@ -1069,12 +1192,12 @@ translate(struct line *deck, char *formal, char *actual, char *scname, char *sub
*/ */
ch = *name; ch = *name;
bxx_rewind(&buffer);
if ( ch != 'x' ) { if ( ch != 'x' ) {
buffer = (char *)tmalloc((strlen(scname)+strlen(name)+5)*sizeof(char));
sprintf(buffer, "%c.%s.%s ", ch, scname, name);
bxx_printf(&buffer, "%c.%s.%s ", ch, scname, name);
} else { } else {
buffer = (char *)tmalloc((strlen(scname)+strlen(name)+3)*sizeof(char));
sprintf(buffer, "%s.%s ", scname, name);
bxx_printf(&buffer, "%s.%s ", scname, name);
} }
tfree(nametofree); tfree(nametofree);
@ -1091,19 +1214,15 @@ translate(struct line *deck, char *formal, char *actual, char *scname, char *sub
} }
/* call gettrans and see if netname was used in the invocation */ /* call gettrans and see if netname was used in the invocation */
t = gettrans(name);
t = gettrans(name, NULL);
if (t) { /* the netname was used during the invocation; print it into the buffer */ if (t) { /* the netname was used during the invocation; print it into the buffer */
blen = strlen(buffer);
buffer = (char *)trealloc(buffer, (blen+strlen(t)+2)*sizeof(char));
sprintf(buffer + blen, "%s ", t);
bxx_printf(&buffer, "%s ", t);
} }
else { /* net netname was not used during the invocation; place a else { /* net netname was not used during the invocation; place a
* translated name into the buffer. * translated name into the buffer.
*/ */
blen = strlen(buffer);
buffer = (char *)trealloc(buffer, (blen+strlen(scname)+strlen(name)+3)*sizeof(char));
sprintf(buffer + blen, "%s.%s ", scname, name);
bxx_printf(&buffer, "%s.%s ", scname, name);
} }
tfree(name); tfree(name);
} /* while (nnodes-- . . . . */ } /* while (nnodes-- . . . . */
@ -1123,13 +1242,9 @@ translate(struct line *deck, char *formal, char *actual, char *scname, char *sub
ch = *name; ch = *name;
if ( ch != 'x' ) { if ( ch != 'x' ) {
blen = strlen(buffer);
buffer = (char *)trealloc(buffer, (blen+strlen(scname)+strlen(name)+5)*sizeof(char));
sprintf(buffer + blen, "%c.%s.%s ", ch, scname, name);
bxx_printf(&buffer, "%c.%s.%s ", ch, scname, name);
} else { } else {
blen = strlen(buffer);
buffer = (char *)trealloc(buffer, (blen+strlen(scname)+strlen(name)+2)*sizeof(char));
sprintf(buffer + blen, "%s ", scname);
bxx_printf(&buffer, "%s ", scname);
} }
tfree(t); tfree(t);
@ -1140,25 +1255,20 @@ translate(struct line *deck, char *formal, char *actual, char *scname, char *sub
* We also scan through the line for v(something) and * We also scan through the line for v(something) and
* i(something)... * i(something)...
*/ */
blen = strlen(buffer);
buffer = (char *)trealloc(buffer, (blen+strlen(s)+strlen(scname)+1000)*sizeof(char));
finishLine(buffer + blen, s, scname);
finishLine(&buffer, s, scname);
s = ""; s = "";
} /* switch(c->li_line . . . . */ } /* switch(c->li_line . . . . */
blen = strlen(buffer);
buffer = (char *)trealloc(buffer, (blen+strlen(s)+1)*sizeof(char));
strcat(buffer, s);
bxx_printf(&buffer, "%s", s);
tfree(c->li_line); tfree(c->li_line);
c->li_line = copy(buffer);
c->li_line = copy(bxx_buffer(&buffer));
#ifdef TRACE #ifdef TRACE
/* SDB debug statement */ /* SDB debug statement */
printf("In translate, translated line = %s \n", c->li_line); printf("In translate, translated line = %s \n", c->li_line);
#endif #endif
tfree(buffer);
} /* for (c = deck . . . . */ } /* for (c = deck . . . . */
rtn = 1; rtn = 1;
quit: quit:
@ -1168,6 +1278,8 @@ quit:
FREE(table[i].t_old); FREE(table[i].t_old);
FREE(table[i].t_new); FREE(table[i].t_new);
} }
bxx_free(&buffer);
return rtn; return rtn;
} }
@ -1179,11 +1291,10 @@ quit:
* Changes made by SDB on 4.29.2003. * Changes made by SDB on 4.29.2003.
*-------------------------------------------------------------------*/ *-------------------------------------------------------------------*/
static void static void
finishLine(char *dst, char *src, char *scname)
finishLine(struct bxx_buffer *t, char *src, char *scname)
{ {
char buf[4 * BSIZE_SP], which;
char *buf, *buf_end, which;
char *s; char *s;
int i;
int lastwasalpha; int lastwasalpha;
lastwasalpha = 0; lastwasalpha = 0;
@ -1195,37 +1306,36 @@ finishLine(char *dst, char *src, char *scname)
(*src != 'i') && (*src != 'I')) || (*src != 'i') && (*src != 'I')) ||
lastwasalpha) { lastwasalpha) {
lastwasalpha = isalpha(*src); lastwasalpha = isalpha(*src);
*dst++ = *src++;
bxx_putc(t, *src++);
continue; continue;
} }
for (s = src + 1; *s && isspace(*s); s++) for (s = src + 1; *s && isspace(*s); s++)
; ;
if (!*s || (*s != '(')) { if (!*s || (*s != '(')) {
lastwasalpha = isalpha(*src); lastwasalpha = isalpha(*src);
*dst++ = *src++;
bxx_putc(t, *src++);
continue; continue;
} }
lastwasalpha = 0; lastwasalpha = 0;
which = *dst++ = *src;
bxx_putc(t, which = *src);
src = s; src = s;
*dst++ = *src++;
bxx_putc(t, *src++);
while (isspace(*src)) while (isspace(*src))
src++; src++;
for (i = 0; *src && !isspace(*src) && *src != ',' && (*src != ')');
i++)
for (buf = src; *src && !isspace(*src) && *src != ',' && (*src != ')');
)
{ {
buf[i] = *src++;
src++;
} }
buf[i] = '\0';
buf_end = src;
if ((which == 'v') || (which == 'V')) if ((which == 'v') || (which == 'V'))
s = gettrans(buf);
s = gettrans(buf, buf_end);
else else
s = NULL; s = NULL;
if (s) { if (s) {
while (*s)
*dst++ = *s++;
bxx_put_cstring(t, s);
} }
else { /* just a normal netname . . . . */ else { /* just a normal netname . . . . */
/* /*
@ -1233,17 +1343,15 @@ finishLine(char *dst, char *src, char *scname)
*/ */
if ((which == 'i' || which == 'I') && if ((which == 'i' || which == 'I') &&
(buf[0] == 'v' || buf[0] == 'V')) { (buf[0] == 'v' || buf[0] == 'V')) {
*dst++ = buf[0];
*dst++ = '.';
bxx_putc(t, buf[0]);
bxx_putc(t, '.');
/*i = 1; */ /*i = 1; */
} /* else { } /* else {
i = 0; i = 0;
} */ } */
for (s = scname; *s; )
*dst++ = *s++;
*dst++ = '.';
for (s = buf/* + i*/; *s; )
*dst++ = *s++;
bxx_put_cstring(t, scname);
bxx_putc(t, '.');
bxx_put_substring(t, buf, buf_end);
} }
/* translate the reference node, as in the "2" in "v(4,2)" */ /* translate the reference node, as in the "2" in "v(4,2)" */
@ -1253,27 +1361,20 @@ finishLine(char *dst, char *src, char *scname)
src++; src++;
} }
if (*src && *src != ')') { if (*src && *src != ')') {
for (i = 0; *src && !isspace(*src) && (*src != ')'); i++)
buf[i] = *src++;
buf[i] = '\0';
s = gettrans(buf);
*dst++ = ',';
for (buf = src; *src && !isspace(*src) && (*src != ')'); )
src++;
s = gettrans(buf, buf_end = src);
bxx_putc(t, ',');
if (s) { if (s) {
while (*s)
*dst++ = *s++;
bxx_put_cstring(t, s);
} else { } else {
for (s = scname; *s; )
*dst++ = *s++;
*dst++ = '.';
for (s = buf; *s; )
*dst++ = *s++;
bxx_put_cstring(t, scname);
bxx_putc(t, '.');
bxx_put_substring(t, buf, buf_end);
} }
} }
} }
} }
*dst = '\0'; /* va, append in each case '\0' */
return;
} }
/*------------------------------------------------------------------------------* /*------------------------------------------------------------------------------*
@ -1310,31 +1411,47 @@ settrans(char *formal, char *actual, char *subname)
return 0; return 0;
} }
/* compare a substring, with a '\0' terminated string
* the substring itself is required to be free of a '\0'
*/
int
eq_substr(const char* str, const char *end, const char *cstring)
{
while(str < end)
if(*str++ != *cstring++)
return 0;
return (*cstring == '\0');
}
/*------------------------------------------------------------------------------* /*------------------------------------------------------------------------------*
* gettrans returns the name of the top level net if it is in the list, * gettrans returns the name of the top level net if it is in the list,
* otherwise it returns NULL. * otherwise it returns NULL.
*------------------------------------------------------------------------------*/ *------------------------------------------------------------------------------*/
static char * static char *
gettrans(char *name)
gettrans(const char *name, const char *name_end)
{ {
int i; int i;
if(!name_end)
name_end = strchr(name, '\0');
#ifdef XSPICE #ifdef XSPICE
/* gtri - wbk - 2/27/91 - don't translate the reserved word 'null' */ /* gtri - wbk - 2/27/91 - don't translate the reserved word 'null' */
if (eq(name, "null"))
return (name);
if (eq_substr(name, name_end, "null"))
return ("null");
/* gtri - end */ /* gtri - end */
#endif #endif
/* Added by H.Tanaka to translate global nodes */ /* Added by H.Tanaka to translate global nodes */
for(i=0;i<numgnode;i++) for(i=0;i<numgnode;i++)
if(eq(node[i],name)) return (name);
if(eq_substr(name, name_end, node[i]))
return (node[i]);
if (eq(name, "0"))
return (name);
if (eq_substr(name, name_end, "0"))
return ("0");
for (i = 0; table[i].t_old; i++) for (i = 0; table[i].t_old; i++)
if (eq(table[i].t_old, name))
if (eq_substr(name, name_end, table[i].t_old))
return (table[i].t_new); return (table[i].t_new);
return (NULL); return (NULL);
} }

1
src/include/ngspice.h

@ -169,6 +169,7 @@ struct timeb timebegin;
#define open _open #define open _open
#define write _write #define write _write
#define strcasecmp _stricmp #define strcasecmp _stricmp
#define inline _inline
#endif #endif
#ifndef HAVE_RANDOM #ifndef HAVE_RANDOM

Loading…
Cancel
Save