diff --git a/ChangeLog b/ChangeLog index 49c862769..149cd9de8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,6 @@ +2011-02-13 Robert Larice + part 1, whitespace and indentation, nothing else + 2011-02-13 Robert Larice undo the last commit, with the sole purpose to seperate it into two commits diff --git a/src/frontend/numparam/mystring.c b/src/frontend/numparam/mystring.c index d9fcb4f70..56bbf3b1f 100644 --- a/src/frontend/numparam/mystring.c +++ b/src/frontend/numparam/mystring.c @@ -1,6 +1,6 @@ /* mystring.c Copyright (C) 2002 Georg Post * - * This file is part of Numparam, see: readme.txt + * This file is part of Numparam, see: readme.txt * Free software under the terms of the GNU Lesser General Public License * $Id$ */ @@ -27,87 +27,89 @@ bool ci_prefix (register char *p, register char *s) { - while (*p) + while (*p) { - if ((isupper (*p) ? tolower (*p) : *p) != - (isupper (*s) ? tolower (*s) : *s)) - return (0); - p++; - s++; + if ((isupper (*p) ? tolower (*p) : *p) != + (isupper (*s) ? tolower (*s) : *s)) + return (0); + p++; + s++; } - return (1); + return (1); } void wc (char c) { - fputc (c, stdout); + fputc (c, stdout); } void wln (void) { - wc ('\n'); + wc ('\n'); } void ws (char *s) { - int k = 0; + int k = 0; - while (s[k] != 0) + while (s[k] != 0) { - wc (s[k]); - k++; + wc (s[k]); + k++; } } void wi (long i) { - SPICE_DSTRING s ; - spice_dstring_init(&s) ; - nadd (&s, i); - ws ( spice_dstring_value(&s)) ; - spice_dstring_free(&s) ; + SPICE_DSTRING s ; + spice_dstring_init(&s) ; + nadd (&s, i); + ws ( spice_dstring_value(&s)) ; + spice_dstring_free(&s) ; } void rs ( SPICE_DSTRINGPTR dstr_p) -{ /* basic line input, limit= 80 chars */ - char c; +{ + /* basic line input, limit= 80 chars */ + char c; - - spice_dstring_reinit(dstr_p) ; - do + spice_dstring_reinit(dstr_p) ; + do { - c = fgetc (stdin); - cadd (dstr_p, c); + c = fgetc (stdin); + cadd (dstr_p, c); } - while (!((c == Cr) || (c == '\n'))); - /* return i */ ; + while (!((c == Cr) || (c == '\n'))); + /* return i */ ; } char rc (void) { - int ls; - char val ; - char *s_p ; - SPICE_DSTRING dstr ; - - spice_dstring_init(&dstr) ; - rs (&dstr); - ls = spice_dstring_length (&dstr); - if (ls > 0){ - s_p = spice_dstring_value(&dstr) ; - val = s_p[ls - 1] ; - } else { - val = 0 ; - } - spice_dstring_free(&dstr) ; - return val ; + int ls; + char val ; + char *s_p ; + SPICE_DSTRING dstr ; + spice_dstring_init(&dstr) ; + rs (&dstr); + ls = spice_dstring_length (&dstr); + if (ls > 0) + { + s_p = spice_dstring_value(&dstr) ; + val = s_p[ls - 1] ; + } + else + { + val = 0 ; + } + spice_dstring_free(&dstr) ; + return val ; } /******* Strings ************ @@ -131,31 +133,31 @@ void sfix ( SPICE_DSTRINGPTR dstr_p, int len) /* suppose s is allocated and filled with non-zero stuff */ { - /* This function will now eliminate the max field. The length of - * the string is going to be i-1 and a null is going to be added - * at the ith position to be compatible with old codel. Also no - * null characters will be present in the string leading up to the - * NULL so this will make it a valid string. */ - int j; - char *s ; + /* This function will now eliminate the max field. The length of + * the string is going to be i-1 and a null is going to be added + * at the ith position to be compatible with old codel. Also no + * null characters will be present in the string leading up to the + * NULL so this will make it a valid string. */ + int j; + char *s ; - spice_dstring_setlength( dstr_p, len ) ; - s = spice_dstring_value( dstr_p ) ; - for (j = 0; j < len; j++) /* eliminate null characters ! */ - if (s[j] == 0) - s[j] = 1; + spice_dstring_setlength( dstr_p, len ) ; + s = spice_dstring_value( dstr_p ) ; + for (j = 0; j < len; j++) /* eliminate null characters ! */ + if (s[j] == 0) + s[j] = 1; } int length (char *s) { - int lg = 0; + int lg = 0; - while (s[lg]) - lg++; + while (s[lg]) + lg++; - return lg; + return lg; } /* ----------------------------------------------------------------- @@ -164,8 +166,8 @@ length (char *s) bool sadd ( SPICE_DSTRINGPTR dstr_p, char *t) { - spice_dstring_append( dstr_p, t, -1 ) ; - return 1 ; + spice_dstring_append( dstr_p, t, -1 ) ; + return 1 ; } /* ----------------------------------------------------------------- @@ -174,11 +176,11 @@ sadd ( SPICE_DSTRINGPTR dstr_p, char *t) bool cadd ( SPICE_DSTRINGPTR dstr_p, char c) { - char tmp_str[2] ; - tmp_str[0] = c ; - tmp_str[1] = 0 ; - spice_dstring_append( dstr_p, tmp_str, -1 ) ; - return 1 ; + char tmp_str[2] ; + tmp_str[0] = c ; + tmp_str[1] = 0 ; + spice_dstring_append( dstr_p, tmp_str, -1 ) ; + return 1 ; } /* ----------------------------------------------------------------- @@ -187,17 +189,17 @@ cadd ( SPICE_DSTRINGPTR dstr_p, char c) bool cins ( SPICE_DSTRINGPTR dstr_p, char c) { - int i ; - int ls ; - char *s_p ; - - ls = spice_dstring_length(dstr_p) ; - spice_dstring_setlength(dstr_p,ls+2) ; /* make sure we have space for char + EOS */ - s_p = spice_dstring_value(dstr_p) ; - for (i = ls + 1; i >= 0; i--) - s_p[i + 1] = s_p[i]; - s_p[0] = c; - return 1 ; + int i ; + int ls ; + char *s_p ; + + ls = spice_dstring_length(dstr_p) ; + spice_dstring_setlength(dstr_p,ls+2) ; /* make sure we have space for char + EOS */ + s_p = spice_dstring_value(dstr_p) ; + for (i = ls + 1; i >= 0; i--) + s_p[i + 1] = s_p[i]; + s_p[0] = c; + return 1 ; } /* ----------------------------------------------------------------- @@ -206,21 +208,21 @@ cins ( SPICE_DSTRINGPTR dstr_p, char c) bool sins ( SPICE_DSTRINGPTR dstr_p, char *t) { - int i ; - int ls ; - int lt ; - char *s_p ; - - ls = spice_dstring_length(dstr_p) ; - lt = length (t) ; - spice_dstring_setlength(dstr_p,ls+lt+1) ; /* make sure we have space for string + EOS */ - s_p = spice_dstring_value(dstr_p) ; - for (i = ls + 1; i >= 0; i--) - s_p[i + lt] = s_p[i]; + int i ; + int ls ; + int lt ; + char *s_p ; - for (i = 0; i < lt; i++) - s_p[i] = t[i]; - return 1 ; + ls = spice_dstring_length(dstr_p) ; + lt = length (t) ; + spice_dstring_setlength(dstr_p,ls+lt+1) ; /* make sure we have space for string + EOS */ + s_p = spice_dstring_value(dstr_p) ; + for (i = ls + 1; i >= 0; i--) + s_p[i + lt] = s_p[i]; + + for (i = 0; i < lt; i++) + s_p[i] = t[i]; + return 1 ; } @@ -231,23 +233,23 @@ cpos (char c, char *s) * No longer! Now position is C-based to make life easier. */ { - int i = 0; - while ((s[i] != c) && (s[i] != 0)) - i++; + int i = 0; + while ((s[i] != c) && (s[i] != 0)) + i++; - if (s[i] == c) - return i ; - else - return -1 ; + if (s[i] == c) + return i ; + else + return -1 ; } char upcase (char c) { - if ((c >= 'a') && (c <= 'z')) - return c + 'A' - 'a'; - else - return c; + if ((c >= 'a') && (c <= 'z')) + return c + 'A' - 'a'; + else + return c; } /* ----------------------------------------------------------------- @@ -257,21 +259,21 @@ upcase (char c) bool scopyd(SPICE_DSTRINGPTR s, SPICE_DSTRINGPTR t) /* returns success flag */ { - spice_dstring_reinit( s ) ; - spice_dstring_append( s, spice_dstring_value(t), -1 ) ; - return 1 ; /* Dstrings expand to any length */ + spice_dstring_reinit( s ) ; + spice_dstring_append( s, spice_dstring_value(t), -1 ) ; + return 1 ; /* Dstrings expand to any length */ } /* ----------------------------------------------------------------- - * Create copy of the string in the dynamic string. Dynamic strings + * Create copy of the string in the dynamic string. Dynamic strings * are always NULLterminated. * ----------------------------------------------------------------- */ bool scopys(SPICE_DSTRINGPTR s, char *t) /* returns success flag */ { - spice_dstring_reinit( s ) ; - spice_dstring_append( s, t, -1 ) ; - return 1 ; /* Dstrings expand to any length */ + spice_dstring_reinit( s ) ; + spice_dstring_append( s, t, -1 ) ; + return 1 ; /* Dstrings expand to any length */ } /* ----------------------------------------------------------------- @@ -281,16 +283,17 @@ scopys(SPICE_DSTRINGPTR s, char *t) /* returns success flag */ bool scopy_up (SPICE_DSTRINGPTR dstr_p, char *str) /* returns success flag */ { - char up[2] ; /* short string */ - char *ptr ; /* position in string */ + char up[2] ; /* short string */ + char *ptr ; /* position in string */ - spice_dstring_reinit( dstr_p ) ; - up[1] = 0 ; - for( ptr = str ; ptr && *ptr ; ptr++ ){ - up[0] = upcase ( *ptr ); - spice_dstring_append( dstr_p, up, 1 ) ; - } - return 1 ; /* Dstrings expand to any length */ + spice_dstring_reinit( dstr_p ) ; + up[1] = 0 ; + for( ptr = str ; ptr && *ptr ; ptr++ ) + { + up[0] = upcase ( *ptr ); + spice_dstring_append( dstr_p, up, 1 ) ; + } + return 1 ; /* Dstrings expand to any length */ } /* ----------------------------------------------------------------- @@ -300,27 +303,28 @@ scopy_up (SPICE_DSTRINGPTR dstr_p, char *str) /* returns success flag */ bool scopy_lower (SPICE_DSTRINGPTR dstr_p, char *str) /* returns success flag */ { - char low[2] ; /* short string */ - char *ptr ; /* position in string */ + char low[2] ; /* short string */ + char *ptr ; /* position in string */ - spice_dstring_reinit( dstr_p ) ; - low[1] = 0 ; - for( ptr = str ; ptr && *ptr ; ptr++ ){ - low[0] = lowcase ( *ptr ); - spice_dstring_append( dstr_p, low, 1 ) ; - } - return 1 ; /* Dstrings expand to any length */ + spice_dstring_reinit( dstr_p ) ; + low[1] = 0 ; + for( ptr = str ; ptr && *ptr ; ptr++ ) + { + low[0] = lowcase ( *ptr ); + spice_dstring_append( dstr_p, low, 1 ) ; + } + return 1 ; /* Dstrings expand to any length */ } bool ccopy ( SPICE_DSTRINGPTR dstr_p, char c) /* returns success flag */ { - char *s_p ; /* current string */ + char *s_p ; /* current string */ - sfix ( dstr_p, 1); - s_p = spice_dstring_value(dstr_p) ; - s_p[0] = c ; - return 1 ; + sfix ( dstr_p, 1); + s_p = spice_dstring_value(dstr_p) ; + s_p[0] = c ; + return 1 ; } char * @@ -330,333 +334,345 @@ pscopy (SPICE_DSTRINGPTR dstr_p, char *t, int start, int leng) * character of the original dstring because resetting string will wipe * out first character. */ { - int i; /* counter */ - int stop ; /* stop value */ - char *s_p ; /* value of dynamic string */ + int i; /* counter */ + int stop ; /* stop value */ + char *s_p ; /* value of dynamic string */ - stop = length(t) ; + stop = length(t) ; - if (start < stop) { /* nothing! */ - if ((start + leng - 1) > stop) { + if (start < stop) /* nothing! */ + { + if ((start + leng - 1) > stop) + { // leng = stop - start + 1; - leng = stop - start ; + leng = stop - start ; + } + _spice_dstring_setlength(dstr_p,leng) ; + s_p = spice_dstring_value(dstr_p) ; + for (i = 0; i < leng; i++) + s_p[i] = t[start + i]; + s_p[leng] = '\0' ; } - _spice_dstring_setlength(dstr_p,leng) ; - s_p = spice_dstring_value(dstr_p) ; - for (i = 0; i < leng; i++) - s_p[i] = t[start + i]; - s_p[leng] = '\0' ; - } else { - s_p = spice_dstring_reinit(dstr_p) ; - } - return s_p ; + else + { + s_p = spice_dstring_reinit(dstr_p) ; + } + return s_p ; } char * pscopy_up (SPICE_DSTRINGPTR dstr_p, char *t, int start, int leng) /* partial string copy to upper case, with C convention for start. */ { - int i; /* counter */ - int stop ; /* stop value */ - char *s_p ; /* value of dynamic string */ + int i; /* counter */ + int stop ; /* stop value */ + char *s_p ; /* value of dynamic string */ - stop = length(t) ; + stop = length(t) ; - if (start < stop) { /* nothing! */ - if ((start + leng - 1) > stop) { + if (start < stop) /* nothing! */ + { + if ((start + leng - 1) > stop) + { // leng = stop - start + 1; - leng = stop - start ; + leng = stop - start ; + } + _spice_dstring_setlength(dstr_p,leng) ; + s_p = spice_dstring_value(dstr_p) ; + for (i = 0; i < leng; i++) + s_p[i] = upcase ( t[start + i] ) ; + s_p[leng] = '\0' ; } - _spice_dstring_setlength(dstr_p,leng) ; - s_p = spice_dstring_value(dstr_p) ; - for (i = 0; i < leng; i++) - s_p[i] = upcase ( t[start + i] ) ; - s_p[leng] = '\0' ; - } else { - s_p = spice_dstring_reinit(dstr_p) ; - } - return s_p ; + else + { + s_p = spice_dstring_reinit(dstr_p) ; + } + return s_p ; } int ord (char c) { - return (c & 0xff); + return (c & 0xff); } /* strip high byte */ int pred (int i) { - return (--i); + return (--i); } int succ (int i) { - return (++i); + return (++i); } bool nadd ( SPICE_DSTRINGPTR dstr_p, long n) /* append a decimal integer to a string */ { - int d[25]; - int j, k ; - char sg; /* the sign */ - char load_str[2] ; /* used to load dstring */ - k = 0; + int d[25]; + int j, k ; + char sg; /* the sign */ + char load_str[2] ; /* used to load dstring */ + k = 0; - if (n < 0) + if (n < 0) { - n = -n; - sg = '-'; + n = -n; + sg = '-'; } - else - sg = '+'; + else + sg = '+'; - while (n > 0) + while (n > 0) { - d[k] = n % 10; - k++; - n = n / 10; + d[k] = n % 10; + k++; + n = n / 10; } - if (k == 0) - cadd (dstr_p, '0'); - else { - load_str[1] = 0 ; - if (sg == '-') - { - load_str[0] = sg ; - spice_dstring_append( dstr_p, load_str, 1 ) ; - } - for (j = k - 1; j >= 0; j--) { - load_str[0] = d[j] + '0'; - spice_dstring_append( dstr_p, load_str, 1 ) ; - } + if (k == 0) + cadd (dstr_p, '0'); + else + { + load_str[1] = 0 ; + if (sg == '-') + { + load_str[0] = sg ; + spice_dstring_append( dstr_p, load_str, 1 ) ; + } + for (j = k - 1; j >= 0; j--) + { + load_str[0] = d[j] + '0'; + spice_dstring_append( dstr_p, load_str, 1 ) ; + } } - return 1 ; + return 1 ; } bool naddll (SPICE_DSTRINGPTR dstr_p, long long n) /* append a decimal integer (but a long long) to a string */ { - int d[25]; - int j, k ; - char sg; /* the sign */ - char load_str[2] ; /* used to load dstring */ - k = 0; + int d[25]; + int j, k ; + char sg; /* the sign */ + char load_str[2] ; /* used to load dstring */ + k = 0; - if (n < 0) + if (n < 0) { - n = -n; - sg = '-'; + n = -n; + sg = '-'; } - else - sg = '+'; + else + sg = '+'; - while (n > 0) + while (n > 0) { - d[k] = n % 10; - k++; - n = n / 10; + d[k] = n % 10; + k++; + n = n / 10; } - if (k == 0) - cadd (dstr_p, '0'); - else { - load_str[1] = 0 ; - if (sg == '-') - { - load_str[0] = sg ; - spice_dstring_append( dstr_p, load_str, 1 ) ; - } - for (j = k - 1; j >= 0; j--) { - load_str[0] = d[j] + '0'; - spice_dstring_append( dstr_p, load_str, 1 ) ; - } + if (k == 0) + cadd (dstr_p, '0'); + else + { + load_str[1] = 0 ; + if (sg == '-') + { + load_str[0] = sg ; + spice_dstring_append( dstr_p, load_str, 1 ) ; + } + for (j = k - 1; j >= 0; j--) + { + load_str[0] = d[j] + '0'; + spice_dstring_append( dstr_p, load_str, 1 ) ; + } } - return 1 ; + return 1 ; } void stri (long n, SPICE_DSTRINGPTR dstr_p) /* convert integer to string */ { - spice_dstring_reinit( dstr_p ) ; - nadd (dstr_p, n) ; + spice_dstring_reinit( dstr_p ) ; + nadd (dstr_p, n) ; } void rawcopy (void *a, void *b, int la, int lb) /* dirty binary copy */ { - int j, n; - if (lb < la) - n = lb; - else - n = la; + int j, n; + if (lb < la) + n = lb; + else + n = la; - for (j = 0; j < n; j++) - ((char *) a)[j] = ((char *) b)[j]; + for (j = 0; j < n; j++) + ((char *) a)[j] = ((char *) b)[j]; } int scompare (char *a, char *b) { - unsigned short j = 0; - int k = 0; - while ((a[j] == b[j]) && (a[j] != 0) && (b[j] != 0)) - j++; + unsigned short j = 0; + int k = 0; + while ((a[j] == b[j]) && (a[j] != 0) && (b[j] != 0)) + j++; - if (a[j] < b[j]) - k = -1; - else if (a[j] > b[j]) - k = 1; + if (a[j] < b[j]) + k = -1; + else if (a[j] > b[j]) + k = 1; - return k; + return k; } bool steq (char *a, char *b) /* string a==b test */ { - unsigned short j = 0; - while ((a[j] == b[j]) && (a[j] != 0) && (b[j] != 0)) - j++; + unsigned short j = 0; + while ((a[j] == b[j]) && (a[j] != 0) && (b[j] != 0)) + j++; - return ((a[j] == 0) && (b[j] == 0)) /* string equality test */ ; + return ((a[j] == 0) && (b[j] == 0)) /* string equality test */ ; } bool stne (char *s, char *t) { - return scompare (s, t) != 0; + return scompare (s, t) != 0; } int hi (long w) { - return (w & 0xff00) >> 8; + return (w & 0xff00) >> 8; } int lo (long w) { - return (w & 0xff); + return (w & 0xff); } char lowcase (char c) { - if ((c >= 'A') && (c <= 'Z')) - return (char) (c - 'A' + 'a'); - else - return c; + if ((c >= 'A') && (c <= 'Z')) + return (char) (c - 'A' + 'a'); + else + return c; } bool alfa (char c) { - return ((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z')) || c == '_' - || c == '[' || c == ']'; + return ((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z')) || c == '_' + || c == '[' || c == ']'; } bool num (char c) { - return (c >= '0') && (c <= '9'); + return (c >= '0') && (c <= '9'); } bool alfanum (char c) { - return alfa (c) || ((c >= '0') && (c <= '9')); + return alfa (c) || ((c >= '0') && (c <= '9')); } int freadstr (FILE * f, SPICE_DSTRINGPTR dstr_p) -/* read a line from a file. +/* read a line from a file. was BUG: long lines truncated without warning, ctrl chars are dumped. Bug no more as we can only run out of memory. Removed max argument. */ { - char c; - char str_load[2] ; - int len = 0 ; + char c; + char str_load[2] ; + int len = 0 ; - str_load[0] = 0 ; - str_load[1] = 0 ; - spice_dstring_reinit(dstr_p) ; - do + str_load[0] = 0 ; + str_load[1] = 0 ; + spice_dstring_reinit(dstr_p) ; + do { - c = fgetc (f); /* tab is the only control char accepted */ - if (((c >= ' ') || (c < 0) || (c == Tab))) - { - str_load[0] = c; - spice_dstring_append( dstr_p, str_load, 1 ) ; - } + c = fgetc (f); /* tab is the only control char accepted */ + if (((c >= ' ') || (c < 0) || (c == Tab))) + { + str_load[0] = c; + spice_dstring_append( dstr_p, str_load, 1 ) ; + } } - while (!(feof (f) || (c == '\n'))); + while (!(feof (f) || (c == '\n'))); - return len ; + return len ; } char freadc (FILE * f) { - return fgetc (f); + return fgetc (f); } long freadi (FILE * f) /* reads next integer, but returns 0 if none found. */ { - long z = 0; - bool minus = 0; - char c; + long z = 0; + bool minus = 0; + char c; - do + do { - c = fgetc (f); + c = fgetc (f); } - while (!(feof (f) || !((c > 0) && (c <= ' ')))); /* skip space */ + while (!(feof (f) || !((c > 0) && (c <= ' ')))); /* skip space */ - if (c == '-') + if (c == '-') { - minus = 1; - c = fgetc (f); + minus = 1; + c = fgetc (f); } - while (num (c)) + while (num (c)) { - z = 10 * z + c - '0'; - c = fgetc (f); + z = 10 * z + c - '0'; + c = fgetc (f); } - ungetc (c, f); /* re-push character lookahead */ + ungetc (c, f); /* re-push character lookahead */ - if (minus) - z = -z; + if (minus) + z = -z; - return z; + return z; } char * stupcase (char *s) { - int i = 0; + int i = 0; - while (s[i] != 0) + while (s[i] != 0) { - s[i] = upcase (s[i]); - i++; + s[i] = upcase (s[i]); + i++; } - return s; + return s; } /***** pointer tricks: app won't use naked malloc(), free() ****/ @@ -664,25 +680,26 @@ stupcase (char *s) void dispose (void *p) { - if (p != NULL) - free (p); + if (p != NULL) + free (p); } void * new (long sz) { - void *p; - if (sz <= 0) - return NULL; - else + void *p; + if (sz <= 0) + return NULL; + else { - p = tmalloc (sz); - if (p == NULL) - { /* fatal error */ - ws (" new() failure. Program halted.\n"); - controlled_exit(EXIT_FAILURE); - } - return p; + p = tmalloc (sz); + if (p == NULL) + { + /* fatal error */ + ws (" new() failure. Program halted.\n"); + controlled_exit(EXIT_FAILURE); + } + return p; } } @@ -691,184 +708,186 @@ new (long sz) double sqr (double x) { - return x * x; + return x * x; } double absf (double x) { - if (x < 0.0) - return -x; - else - return x; + if (x < 0.0) + return -x; + else + return x; } long absi (long i) { - if (i >= 0) - return (i); - else - return (-i); + if (i >= 0) + return (i); + else + return (-i); } void strif (long i, int f, SPICE_DSTRINGPTR dstr_p) /* formatting like str(i:f,s) in Turbo Pascal */ { - int j, k ; - char cs; - char t[32]; - char load_str[2] ; /* load dstring */ - k = 0; + int j, k ; + char cs; + char t[32]; + char load_str[2] ; /* load dstring */ + k = 0; - if (i < 0) + if (i < 0) { - i = -i; - cs = '-'; + i = -i; + cs = '-'; } - else + else { - cs = ' '; + cs = ' '; } - while (i > 0) + while (i > 0) { - j = (int) (i % 10); - i = (long) (i / 10); - t[k] = (char)('0' + j); - k++; + j = (int) (i % 10); + i = (long) (i / 10); + t[k] = (char)('0' + j); + k++; } - if (k == 0) + if (k == 0) { - t[k] = '0'; - k++; + t[k] = '0'; + k++; } - if (cs == '-') - t[k] = cs; - else - k--; + if (cs == '-') + t[k] = cs; + else + k--; - /* now the string is in 0...k in reverse order */ - for (j = 1; j <= k; j++) - t[k + j] = t[k - j]; /* mirror image */ + /* now the string is in 0...k in reverse order */ + for (j = 1; j <= k; j++) + t[k + j] = t[k - j]; /* mirror image */ - t[2 * k + 1] = 0; /* null termination */ - load_str[1] = 0 ; /* not really needed */ - spice_dstring_reinit(dstr_p) ; + t[2 * k + 1] = 0; /* null termination */ + load_str[1] = 0 ; /* not really needed */ + spice_dstring_reinit(dstr_p) ; - if ((f > k) && (f < 40)) - { /* reasonable format */ - for (j = k + 2; j <= f; j++) - { - load_str[0] = ' '; - spice_dstring_append( dstr_p, load_str, 1 ) ; - } + if ((f > k) && (f < 40)) + { + /* reasonable format */ + for (j = k + 2; j <= f; j++) + { + load_str[0] = ' '; + spice_dstring_append( dstr_p, load_str, 1 ) ; + } } - for (j = 0; j <= k + 1; j++){ - load_str[0] = t[k + j]; /* shift t down */ - spice_dstring_append( dstr_p, load_str, 1 ) ; - } + for (j = 0; j <= k + 1; j++) + { + load_str[0] = t[k + j]; /* shift t down */ + spice_dstring_append( dstr_p, load_str, 1 ) ; + } } bool odd (long x) { - return (x & 1); + return (x & 1); } static bool match (char *s, char *t, int n, int tstart, bool testcase) { -/* returns 0 if ( tstart is out of range. But n may be 0 ? */ -/* 1 if s matches t[tstart...tstart+n] */ - int i, j, lt; - bool ok; - char a, b; - i = 0; - j = tstart; - lt = length (t); - ok = (tstart < lt); + /* returns 0 if ( tstart is out of range. But n may be 0 ? */ + /* 1 if s matches t[tstart...tstart+n] */ + int i, j, lt; + bool ok; + char a, b; + i = 0; + j = tstart; + lt = length (t); + ok = (tstart < lt); - while (ok && (i < n)) + while (ok && (i < n)) { - a = s[i]; - b = t[j]; - if (!testcase) - { - a = upcase (a); - b = upcase (b); - } - ok = (j < lt) && (a == b); - i++; - j++; + a = s[i]; + b = t[j]; + if (!testcase) + { + a = upcase (a); + b = upcase (b); + } + ok = (j < lt) && (a == b); + i++; + j++; } - return ok; + return ok; } int posi (char *sub, char *s, int opt) /* find position of substring in s */ { - /* opt=0: like Turbo Pascal */ - /* opt=1: like Turbo Pascal Pos, but case insensitive */ - /* opt=2: position in space separated wordlist for scanners */ - int a, b, k, j; - bool ok, tstcase; - SPICE_DSTRING tstr ; + /* opt=0: like Turbo Pascal */ + /* opt=1: like Turbo Pascal Pos, but case insensitive */ + /* opt=2: position in space separated wordlist for scanners */ + int a, b, k, j; + bool ok, tstcase; + SPICE_DSTRING tstr ; - ok = 0; - spice_dstring_init(&tstr) ; - tstcase = (opt == 0); + ok = 0; + spice_dstring_init(&tstr) ; + tstcase = (opt == 0); - if (opt <= 1) - scopys (&tstr, sub); - else + if (opt <= 1) + scopys (&tstr, sub); + else { - cadd (&tstr, ' '); - sadd (&tstr, sub); - cadd (&tstr, ' '); + cadd (&tstr, ' '); + sadd (&tstr, sub); + cadd (&tstr, ' '); } - a = spice_dstring_length(&tstr) ; - b = (int) (length (s) - a); - k = 0; - j = 1; + a = spice_dstring_length(&tstr) ; + b = (int) (length (s) - a); + k = 0; + j = 1; - if (a > 0) /* ;} else { return 0 */ - while ((k <= b) && (!ok)) - { - ok = match ( spice_dstring_value(&tstr), s, a, k, tstcase); /* we must start at k=0 ! */ - k++; - if (s[k] == ' ') - j++; /* word counter */ ; - } + if (a > 0) /* ;} else { return 0 */ + while ((k <= b) && (!ok)) + { + ok = match ( spice_dstring_value(&tstr), s, a, k, tstcase); /* we must start at k=0 ! */ + k++; + if (s[k] == ' ') + j++; /* word counter */ ; + } - if (opt == 2) - k = j; + if (opt == 2) + k = j; - if (ok) - return k; - else - return 0; + if (ok) + return k; + else + return 0; } int spos_(char *sub, char *s) /* equivalent to Turbo Pascal pos(). - BUG: counts 1 ... length(s), not from 0 like C + BUG: counts 1 ... length(s), not from 0 like C */ { - char *ptr; + char *ptr; - if ((ptr = strstr (s, sub)) != NULL) - return (int) (strlen (s) - strlen (ptr)); - else - return -1 ; + if ((ptr = strstr (s, sub)) != NULL) + return (int) (strlen (s) - strlen (ptr)); + else + return -1 ; } @@ -876,101 +895,102 @@ void strf (double x, int f1, int f2, SPICE_DSTRINGPTR dstr_p) /* e-format if f2<0, else f2 digits after the point, total width=f1 */ /* if f1=0, also e-format with f2 digits */ -{ /* default f1=17, f2=-1 */ - int dlen ; /* length of digits */ - char *dbuf_p ; /* beginning of sprintf buffer */ - SPICE_DSTRING fmt ; /* format string */ - SPICE_DSTRING dformat ; /* format float */ +{ + /* default f1=17, f2=-1 */ + int dlen ; /* length of digits */ + char *dbuf_p ; /* beginning of sprintf buffer */ + SPICE_DSTRING fmt ; /* format string */ + SPICE_DSTRING dformat ; /* format float */ - spice_dstring_init(&fmt) ; - spice_dstring_init(&dformat) ; - cadd (&fmt, '%'); - if (f1 > 0) + spice_dstring_init(&fmt) ; + spice_dstring_init(&dformat) ; + cadd (&fmt, '%'); + if (f1 > 0) { - nadd (&fmt, f1); /* f1 is the total width */ - if (f2 < 0) - sadd (&fmt, "lE"); /* exponent format */ - else - { - cadd (&fmt, '.'); - nadd (&fmt, f2); - sadd (&fmt, "lg"); - } + nadd (&fmt, f1); /* f1 is the total width */ + if (f2 < 0) + sadd (&fmt, "lE"); /* exponent format */ + else + { + cadd (&fmt, '.'); + nadd (&fmt, f2); + sadd (&fmt, "lg"); + } } - else + else { - cadd (&fmt, '.'); - nadd (&fmt, absi (f2 - 6)); /* note the 6 surplus positions */ - cadd (&fmt, 'e'); + cadd (&fmt, '.'); + nadd (&fmt, absi (f2 - 6)); /* note the 6 surplus positions */ + cadd (&fmt, 'e'); } - dlen = 2 * (f1 + f2) + 1 ; /* be conservative */ - dbuf_p = spice_dstring_setlength(&dformat, dlen) ; - sprintf (dbuf_p, spice_dstring_value(&fmt), x); - scopys( dstr_p, dbuf_p ) ; + dlen = 2 * (f1 + f2) + 1 ; /* be conservative */ + dbuf_p = spice_dstring_setlength(&dformat, dlen) ; + sprintf (dbuf_p, spice_dstring_value(&fmt), x); + scopys( dstr_p, dbuf_p ) ; - spice_dstring_free(&fmt) ; - spice_dstring_free(&dformat) ; + spice_dstring_free(&fmt) ; + spice_dstring_free(&dformat) ; } double rval (char *s, int *err) /* returns err=0 if ok, else length of partial string ? */ { - double r = 0.0; - int n = sscanf (s, "%lG", &r); + double r = 0.0; + int n = sscanf (s, "%lG", &r); - if (n == 1) - (*err) = 0; - else - (*err) = 1; + if (n == 1) + (*err) = 0; + else + (*err) = 1; - return r; + return r; } long ival (char *s, int *err) /* value of s as integer string. error code err= 0 if Ok */ { - int k = 0, digit = 0, ls; - long z = 0; - bool minus = 0, ok = 1; - char c; - ls = length (s); + int k = 0, digit = 0, ls; + long z = 0; + bool minus = 0, ok = 1; + char c; + ls = length (s); - do + do { - c = s[k]; - k++; + c = s[k]; + k++; } - while (!((k >= ls) || !((c > 0) && (c <= ' ')))); /* skip space */ + while (!((k >= ls) || !((c > 0) && (c <= ' ')))); /* skip space */ - if (c == '-') + if (c == '-') { - minus = 1; - c = s[k]; - k++; + minus = 1; + c = s[k]; + k++; } - while (num (c)) + while (num (c)) { - z = 10 * z + c - '0'; - c = s[k]; - k++; - digit++; + z = 10 * z + c - '0'; + c = s[k]; + k++; + digit++; } - if (minus) - z = -z; + if (minus) + z = -z; - ok = (digit > 0) && (c == 0); /* successful end of string */ + ok = (digit > 0) && (c == 0); /* successful end of string */ - if (ok) - (*err) = 0; - else - (*err) = k; /* one beyond error position */ + if (ok) + (*err) = 0; + else + (*err) = k; /* one beyond error position */ - return z; + return z; } #ifndef HAVE_LIBM @@ -979,40 +999,40 @@ long np_round (double x) /* using , it would be simpler: floor(x+0.5), see below */ { - double u; - long z; - int n; + double u; + long z; + int n; // Str (40, s); - SPICE_DSTRING s ; - spice_dstring_init(&s) ; - u = 2e9; - if (x > u) - x = u; - else if (x < -u) - x = -u; + SPICE_DSTRING s ; + spice_dstring_init(&s) ; + u = 2e9; + if (x > u) + x = u; + else if (x < -u) + x = -u; - n = sprintf (s, "%-12.0f", x); - s[n] = 0; - sscanf (s, "%ld", &z); - return z; + n = sprintf (s, "%-12.0f", x); + s[n] = 0; + sscanf (s, "%ld", &z); + return z; } long np_trunc (double x) { - long n = np_round (x); - if ((n > x) && (x >= 0.0)) - n--; - else if ((n < x) && (x < 0.0)) - n++; + long n = np_round (x); + if ((n > x) && (x >= 0.0)) + n--; + else if ((n < x) && (x < 0.0)) + n++; - return n; + return n; } double frac (double x) { - return x - np_trunc (x); + return x - np_trunc (x); } #else /* use floor() and ceil() */ @@ -1020,25 +1040,25 @@ frac (double x) long np_round (double r) { - return (long) floor (r + 0.5); + return (long) floor (r + 0.5); } long np_trunc (double r) { - if (r >= 0.0) - return (long) floor (r); - else - return (long) ceil (r); + if (r >= 0.0) + return (long) floor (r); + else + return (long) ceil (r); } double frac (double x) { - if (x >= 0.0) - return (x - floor (x)); - else - return (x - ceil (x)); + if (x >= 0.0) + return (x - floor (x)); + else + return (x - ceil (x)); } #endif diff --git a/src/frontend/numparam/spicenum.c b/src/frontend/numparam/spicenum.c index b1408187a..dd879537a 100644 --- a/src/frontend/numparam/spicenum.c +++ b/src/frontend/numparam/spicenum.c @@ -1,21 +1,21 @@ /* spicenum.c Copyright (C) 2002 Georg Post * - * This file is part of Numparam, see: readme.txt - * Free software under the terms of the GNU Lesser General Public License + * This file is part of Numparam, see: readme.txt + * Free software under the terms of the GNU Lesser General Public License */ /* number parameter add-on for Spice. - to link with mystring.o, xpressn.o (math formula interpreter), - and with Spice frontend src/lib/fte.a . + to link with mystring.o, xpressn.o (math formula interpreter), + and with Spice frontend src/lib/fte.a . Interface function nupa_signal to tell us about automaton states. Buglist (some are 'features'): - blank lines get category '*' - inserts conditional blanks before or after braces - between .control and .endc, flags all lines as 'category C', dont touch. + blank lines get category '*' + inserts conditional blanks before or after braces + between .control and .endc, flags all lines as 'category C', dont touch. there are reserved magic numbers (1e9 + n) as placeholders - control lines must not contain {} . + control lines must not contain {} . ignores the '.option numparam' line planned to trigger the actions - operation of .include certainly doesnt work + operation of .include certainly doesnt work there are frozen maxima for source and expanded circuit size. Todo: add support for nested .if .elsif .else .endif controls. @@ -59,7 +59,7 @@ extern int dynmaxline; /* inpcom.c:1529 */ In Clean state, a lot of deckcopy operations come in and we overwrite any line pointers, or we start a new set after each sig=0 ? Anyway, we neutralize all & and .param lines (category[] array!) - and we substitute all {} &() and &id placeholders by dummy numbers. + and we substitute all {} &() and &id placeholders by dummy numbers. The placeholders are long long integers 100000000000000+n (15 digits, n small). */ @@ -72,25 +72,25 @@ static long placeholder = 0; static void stripsomespace (SPICE_DSTRINGPTR dstr_p, unsigned char incontrol) { -/* if s starts with one of some markers, strip leading space */ - int i, ls; - char *sstr ; /* string contained in s */ - SPICE_DSTRING markers ; + /* if s starts with one of some markers, strip leading space */ + int i, ls; + char *sstr ; /* string contained in s */ + SPICE_DSTRING markers ; - spice_dstring_init( &markers ) ; - scopys( &markers, "*.&+#$") ; + spice_dstring_init( &markers ) ; + scopys( &markers, "*.&+#$") ; - if (!incontrol) - sadd ( &markers, "xX"); + if (!incontrol) + sadd ( &markers, "xX"); - sstr = spice_dstring_value(dstr_p) ; - ls = spice_dstring_length (dstr_p); - i = 0; - while ((i < ls) && (sstr[i] <= ' ')) - i++; + sstr = spice_dstring_value(dstr_p) ; + ls = spice_dstring_length (dstr_p); + i = 0; + while ((i < ls) && (sstr[i] <= ' ')) + i++; - if ((i > 0) && (i < ls) && (cpos (sstr[i], spice_dstring_value(&markers)) >= 0)) - pscopy (dstr_p, sstr, i, ls); + if ((i > 0) && (i < ls) && (cpos (sstr[i], spice_dstring_value(&markers)) >= 0)) + pscopy (dstr_p, sstr, i, ls); } @@ -98,62 +98,63 @@ static int stripbraces (SPICE_DSTRINGPTR dstr_p) /* puts the funny placeholders. returns the number of {...} substitutions */ { - int n, i, nest, ls, j; - char *s ; /* value of dynamic string */ - char *t_p ; /* value of t dynamic string */ - SPICE_DSTRING tstr ; /* temporary dynamic string */ + int n, i, nest, ls, j; + char *s ; /* value of dynamic string */ + char *t_p ; /* value of t dynamic string */ + SPICE_DSTRING tstr ; /* temporary dynamic string */ - n = 0; - spice_dstring_init( &tstr ) ; - s = spice_dstring_value( dstr_p ) ; - ls = spice_dstring_length (dstr_p); - i = 0; + n = 0; + spice_dstring_init( &tstr ) ; + s = spice_dstring_value( dstr_p ) ; + ls = spice_dstring_length (dstr_p); + i = 0; - while (i < ls) - { - if (s[i] == '{') - { /* something to strip */ - j = i + 1; - nest = 1; - n++; + while (i < ls) + { + if (s[i] == '{') + { + /* something to strip */ + j = i + 1; + nest = 1; + n++; - while ((nest > 0) && (j < ls)) - { - if (s[j] == '{') - nest++; - else if (s[j] == '}') - nest--; - j++; - } - pscopy (&tstr, s, 0, i); - placeholder++; + while ((nest > 0) && (j < ls)) + { + if (s[j] == '{') + nest++; + else if (s[j] == '}') + nest--; + j++; + } + pscopy (&tstr, s, 0, i); + placeholder++; - t_p = spice_dstring_value(&tstr) ; + t_p = spice_dstring_value(&tstr) ; - if (t_p[i - 1] > ' ') - cadd (&tstr, ' '); + if (t_p[i - 1] > ' ') + cadd (&tstr, ' '); - cadd ( &tstr, ' '); - naddll( &tstr, PlaceHold + placeholder); /* placeholder has 15 digits */ - cadd ( &tstr, ' '); - - if (s[j] >= ' ') + cadd ( &tstr, ' '); + naddll( &tstr, PlaceHold + placeholder); /* placeholder has 15 digits */ cadd ( &tstr, ' '); - i = spice_dstring_length (&tstr); - pscopy (dstr_p, s, j, ls); - sadd ( &tstr, s); - scopyd ( dstr_p, &tstr); - s = spice_dstring_value( dstr_p ) ; - ls = spice_dstring_length( dstr_p ) ; - } - else - i++; + if (s[j] >= ' ') + cadd ( &tstr, ' '); - } - dynsubst = placeholder; - spice_dstring_free(&tstr); - return n; + i = spice_dstring_length (&tstr); + pscopy (dstr_p, s, j, ls); + sadd ( &tstr, s); + scopyd ( dstr_p, &tstr); + s = spice_dstring_value( dstr_p ) ; + ls = spice_dstring_length( dstr_p ) ; + } + else + i++; + + } + dynsubst = placeholder; + spice_dstring_free(&tstr); + return n; } static int @@ -162,132 +163,134 @@ findsubname (tdico * dico, SPICE_DSTRINGPTR dstr_p) /* scan a string from the end, skipping non-idents and {expressions} */ /* then truncate s after the last subckt(?) identifier */ { - SPICE_DSTRING name ; /* extract a name */ - char *s ; /* current dstring */ - int h, j, k, nest, ls; - int found ; - h = 0; + SPICE_DSTRING name ; /* extract a name */ + char *s ; /* current dstring */ + int h, j, k, nest, ls; + int found ; + h = 0; - ls = spice_dstring_length (dstr_p) ; - s = spice_dstring_value (dstr_p) ; - k = ls - 1 ; /* now a C - string */ - found = 0; - spice_dstring_init( &name ) ; + ls = spice_dstring_length (dstr_p) ; + s = spice_dstring_value (dstr_p) ; + k = ls - 1 ; /* now a C - string */ + found = 0; + spice_dstring_init( &name ) ; - while ((k >= 0) && (!found)) - { /* skip space, then non-space */ - while ((k >= 0) && (s[k] <= ' ')) - k--; + while ((k >= 0) && (!found)) + { + /* skip space, then non-space */ + while ((k >= 0) && (s[k] <= ' ')) + k--; - h = k + 1; /* at h: space */ - while ((k >= 0) && (s[k] > ' ')) - { + h = k + 1; /* at h: space */ + while ((k >= 0) && (s[k] > ' ')) + { - if (s[k] == '}') - { - nest = 1; - k--; + if (s[k] == '}') + { + nest = 1; + k--; - while ((nest > 0) && (k >= 0)) - { - if (s[k] == '{') - nest--; - else if (s[k] == '}') - nest++; + while ((nest > 0) && (k >= 0)) + { + if (s[k] == '{') + nest--; + else if (s[k] == '}') + nest++; - k--; - } - h = k + 1; /* h points to '{' */ ; - } - else - k--; - } + k--; + } + h = k + 1; /* h points to '{' */ ; + } + else + k--; + } - found = (k >= 0) && alfanum (s[k + 1]); /* suppose an identifier */ - if (found) - { /* check for known subckt name */ - spice_dstring_reinit( &name ) ; - j = k + 1; - while (alfanum (s[j])) - { - cadd ( &name, upcase (s[j])); - j++; - } - found = (getidtype (dico, spice_dstring_value(&name) ) == 'U'); - } + found = (k >= 0) && alfanum (s[k + 1]); /* suppose an identifier */ + if (found) + { + /* check for known subckt name */ + spice_dstring_reinit( &name ) ; + j = k + 1; + while (alfanum (s[j])) + { + cadd ( &name, upcase (s[j])); + j++; + } + found = (getidtype (dico, spice_dstring_value(&name) ) == 'U'); + } } - if (found && (h < ls)) - pscopy (dstr_p, s, 0, h); + if (found && (h < ls)) + pscopy (dstr_p, s, 0, h); - return h; + return h; } static void modernizeex (SPICE_DSTRINGPTR dstr_p) /* old style expressions &(..) and &id --> new style with braces. */ { - int i, state, ls; - char c, d; - char *s ; /* current string */ - SPICE_DSTRING t ; /* temporary dyna string */ + int i, state, ls; + char c, d; + char *s ; /* current string */ + SPICE_DSTRING t ; /* temporary dyna string */ - i = 0; - state = 0; - ls = spice_dstring_length (dstr_p); - s = spice_dstring_value( dstr_p ) ; - spice_dstring_init( &t ) ; + i = 0; + state = 0; + ls = spice_dstring_length (dstr_p); + s = spice_dstring_value( dstr_p ) ; + spice_dstring_init( &t ) ; - while (i < ls) + while (i < ls) { - c = s[i]; - d = s[i + 1]; - if ((!state) && (c == Intro) && (i > 0)) - { - if (d == '(') - { - state = 1; - i++; - c = '{'; - } - else if (alfa (d)) - { - cadd (&t, '{'); - i++; - while (alfanum (s[i])) - { - cadd (&t, s[i]); - i++; - } - c = '}'; - i--; - } - } - else if (state) - { - if (c == '(') - state++; - else if (c == ')') - state--; + c = s[i]; + d = s[i + 1]; + if ((!state) && (c == Intro) && (i > 0)) + { + if (d == '(') + { + state = 1; + i++; + c = '{'; + } + else if (alfa (d)) + { + cadd (&t, '{'); + i++; + while (alfanum (s[i])) + { + cadd (&t, s[i]); + i++; + } + c = '}'; + i--; + } + } + else if (state) + { + if (c == '(') + state++; + else if (c == ')') + state--; - if (!state) /* replace--) by terminator */ - c = '}'; + if (!state) /* replace--) by terminator */ + c = '}'; - } + } - cadd (&t, c); - i++; + cadd (&t, c); + i++; } - scopyd (dstr_p, &t); - spice_dstring_free(&t) ; + scopyd (dstr_p, &t); + spice_dstring_free(&t) ; } static char -transform (tdico * dico, SPICE_DSTRINGPTR dstr_p, unsigned char nostripping, +transform (tdico * dico, SPICE_DSTRINGPTR dstr_p, unsigned char nostripping, SPICE_DSTRINGPTR u_p) /* line s is categorized and crippled down to basic Spice - * returns in u control word following dot, if any - * + * returns in u control word following dot, if any + * * any + line is copied as-is. * any & or .param line is commented-out. * any .subckt line has params section stripped off @@ -306,84 +309,90 @@ transform (tdico * dico, SPICE_DSTRINGPTR dstr_p, unsigned char nostripping, * 'C' control entry line * 'E' control exit line * '.' any other dot line - * 'B' netlist (or .model ?) line that had Braces killed + * 'B' netlist (or .model ?) line that had Braces killed */ { - int k, a, n; - char *s ; /* dstring value of dstr_p */ - char *t ; /* dstring value of tstr */ - char category; - SPICE_DSTRING tstr ; /* temporary string */ + int k, a, n; + char *s ; /* dstring value of dstr_p */ + char *t ; /* dstring value of tstr */ + char category; + SPICE_DSTRING tstr ; /* temporary string */ - spice_dstring_init(&tstr) ; - spice_dstring_reinit(u_p) ; - stripsomespace (dstr_p, nostripping); - modernizeex (dstr_p); /* required for stripbraces count */ + spice_dstring_init(&tstr) ; + spice_dstring_reinit(u_p) ; + stripsomespace (dstr_p, nostripping); + modernizeex (dstr_p); /* required for stripbraces count */ - s = spice_dstring_value(dstr_p) ; - if (s[0] == '.') - { /* check Pspice parameter format */ - scopy_up (&tstr, spice_dstring_value(dstr_p) ) ; - k = 1; + s = spice_dstring_value(dstr_p) ; + if (s[0] == '.') + { + /* check Pspice parameter format */ + scopy_up (&tstr, spice_dstring_value(dstr_p) ) ; + k = 1; - t = spice_dstring_value(&tstr) ; - while (t[k] > ' ') - { - cadd (u_p, t[k]); - k++; - } + t = spice_dstring_value(&tstr) ; + while (t[k] > ' ') + { + cadd (u_p, t[k]); + k++; + } - if (ci_prefix (".PARAM", t) == 1) - { /* comment it out */ - /*s[0]='*'; */ - category = 'P'; - } - else if (ci_prefix (".SUBCKT", t) == 1) - { /* split off any "params" tail */ - a = spos_ ("PARAMS:", t); - if (a >= 0) - pscopy (dstr_p, s, 0, a ); - category = 'S'; - } - else if (ci_prefix (".CONTROL", t) == 1) - category = 'C'; - else if (ci_prefix (".ENDC", t) == 1) - category = 'E'; - else if (ci_prefix (".ENDS", t) == 1) - category = 'U'; - else - { - category = '.'; - n = stripbraces (dstr_p); - if (n > 0) - category = 'B'; /* priority category ! */ - } - } - else if (s[0] == Intro) - { /* private style preprocessor line */ - s[0] = '*'; - category = 'P'; - } - else if (upcase (s[0]) == 'X') - { /* strip actual parameters */ - findsubname (dico, dstr_p) ;/* i= index following last identifier in s */ - category = 'X'; - } - else if (s[0] == '+') /* continuation line */ - category = '+'; - else if (cpos (s[0], "*$#") < 0) - { /* not a comment line! */ - n = stripbraces (dstr_p); - if (n > 0) - category = 'B'; /* line that uses braces */ - else - category = ' '; /* ordinary code line */ - } - else - category = '*'; + if (ci_prefix (".PARAM", t) == 1) + { + /* comment it out */ + /*s[0]='*'; */ + category = 'P'; + } + else if (ci_prefix (".SUBCKT", t) == 1) + { + /* split off any "params" tail */ + a = spos_ ("PARAMS:", t); + if (a >= 0) + pscopy (dstr_p, s, 0, a ); + category = 'S'; + } + else if (ci_prefix (".CONTROL", t) == 1) + category = 'C'; + else if (ci_prefix (".ENDC", t) == 1) + category = 'E'; + else if (ci_prefix (".ENDS", t) == 1) + category = 'U'; + else + { + category = '.'; + n = stripbraces (dstr_p); + if (n > 0) + category = 'B'; /* priority category ! */ + } + } + else if (s[0] == Intro) + { + /* private style preprocessor line */ + s[0] = '*'; + category = 'P'; + } + else if (upcase (s[0]) == 'X') + { + /* strip actual parameters */ + findsubname (dico, dstr_p) ;/* i= index following last identifier in s */ + category = 'X'; + } + else if (s[0] == '+') /* continuation line */ + category = '+'; + else if (cpos (s[0], "*$#") < 0) + { + /* not a comment line! */ + n = stripbraces (dstr_p); + if (n > 0) + category = 'B'; /* line that uses braces */ + else + category = ' '; /* ordinary code line */ + } + else + category = '*'; - spice_dstring_free(&tstr) ; - return category; + spice_dstring_free(&tstr) ; + return category; } /************ core of numparam **************/ @@ -413,120 +422,120 @@ static tdico *dicoS = NULL; static void putlogfile (char c, int num, char *t) { - SPICE_DSTRING fname ; /* file name */ - SPICE_DSTRING u ; /* temp dynamic variable */ - - spice_dstring_init( &fname ) ; - spice_dstring_init( &u ) ; - if (dologfileS) - { - if ((logfileS == NULL)) - { - scopys(&fname, "logfile.") ; - nblogS++; - nadd (&fname, nblogS) ; - logfileS = fopen ( spice_dstring_value(&fname), "w"); - } + SPICE_DSTRING fname ; /* file name */ + SPICE_DSTRING u ; /* temp dynamic variable */ - if ((logfileS != NULL)) - { - cadd (&u, c); - nadd (&u, num); - cadd (&u, ':'); - cadd (&u, ' '); - sadd (&u, t); - cadd (&u, '\n'); - fputs ( spice_dstring_value(&u), logfileS); - } - } - spice_dstring_free(&u) ; - spice_dstring_free(&fname) ; + spice_dstring_init( &fname ) ; + spice_dstring_init( &u ) ; + if (dologfileS) + { + if ((logfileS == NULL)) + { + scopys(&fname, "logfile.") ; + nblogS++; + nadd (&fname, nblogS) ; + logfileS = fopen ( spice_dstring_value(&fname), "w"); + } + + if ((logfileS != NULL)) + { + cadd (&u, c); + nadd (&u, num); + cadd (&u, ':'); + cadd (&u, ' '); + sadd (&u, t); + cadd (&u, '\n'); + fputs ( spice_dstring_value(&u), logfileS); + } + } + spice_dstring_free(&u) ; + spice_dstring_free(&fname) ; } static void nupa_init (char *srcfile) { - int i; - /* init the symbol table and so on, before the first nupa_copy. */ - evalcountS = 0; - linecountS = 0; - incontrolS = 0; - placeholder = 0; - dicoS = (tdico *)new(sizeof(tdico)); - initdico (dicoS); + int i; + /* init the symbol table and so on, before the first nupa_copy. */ + evalcountS = 0; + linecountS = 0; + incontrolS = 0; + placeholder = 0; + dicoS = (tdico *)new(sizeof(tdico)); + initdico (dicoS); - dicoS->dynrefptr = TMALLOC(char*, dynmaxline + 1); - dicoS->dyncategory = TMALLOC(char, dynmaxline + 1); + dicoS->dynrefptr = TMALLOC(char*, dynmaxline + 1); + dicoS->dyncategory = TMALLOC(char, dynmaxline + 1); - for (i = 0; i <= dynmaxline; i++) + for (i = 0; i <= dynmaxline; i++) { - dicoS->dynrefptr[i] = NULL; - dicoS->dyncategory[i] = '?'; + dicoS->dynrefptr[i] = NULL; + dicoS->dyncategory[i] = '?'; } - if (srcfile != NULL) - scopys(&dicoS->srcfile, srcfile ) ; + if (srcfile != NULL) + scopys(&dicoS->srcfile, srcfile ) ; } static void nupa_done (void) { - /* int i; not needed so far, see below */ - char *reply ; /* user reply */ - SPICE_DSTRING rep ; /* dynamic report */ - int dictsize, nerrors; + /* int i; not needed so far, see below */ + char *reply ; /* user reply */ + SPICE_DSTRING rep ; /* dynamic report */ + int dictsize, nerrors; - spice_dstring_init(&rep) ; - if (logfileS != NULL) + spice_dstring_init(&rep) ; + if (logfileS != NULL) { - fclose (logfileS); - logfileS = NULL; + fclose (logfileS); + logfileS = NULL; } - nerrors = dicoS->errcount; - dictsize = donedico (dicoS); - /* We cannot remove dico here because numparam is usedby - the .measure statement, which is invoked only after the - simulation has finished */ - /* - for (i = dynmaxline ; i >= 0; i--) { - dispose ((void *) dico->dynrefptr[i]); - } - dispose ((void *) dico->dynrefptr); - dispose ((void *) dico->dyncategory); - dispose ((void *) dico->dyndat); - dispose ((void *) dico); - dico = NULL; - dispose ((void *) inst_dico->dyndat); - dispose ((void *) inst_dico); - inst_dico = NULL; -*/ - if (nerrors) + nerrors = dicoS->errcount; + dictsize = donedico (dicoS); + /* We cannot remove dico here because numparam is usedby + the .measure statement, which is invoked only after the + simulation has finished */ + /* + for (i = dynmaxline ; i >= 0; i--) { + dispose ((void *) dico->dynrefptr[i]); + } + dispose ((void *) dico->dynrefptr); + dispose ((void *) dico->dyncategory); + dispose ((void *) dico->dyndat); + dispose ((void *) dico); + dico = NULL; + dispose ((void *) inst_dico->dyndat); + dispose ((void *) inst_dico); + inst_dico = NULL; + */ + if (nerrors) { - /* debug: ask if spice run really wanted */ - sadd (&rep, " Copies="); - nadd (&rep, linecountS); - sadd (&rep, " Evals="); - nadd (&rep, evalcountS); - sadd (&rep, " Placeholders="); - nadd (&rep, placeholder); - sadd (&rep, " Symbols="); - nadd (&rep, dictsize); - sadd (&rep, " Errors="); - nadd (&rep, nerrors); - cadd (&rep, '\n'); - ws ( spice_dstring_value(&rep) ) ; - ws ("Numparam expansion errors: Run Spice anyway? y/n ? \n"); - spice_dstring_reinit(&rep) ; - rs (&rep); - reply = spice_dstring_value(&rep) ; - if (upcase (reply[0]) != 'Y') - controlled_exit(EXIT_FAILURE); + /* debug: ask if spice run really wanted */ + sadd (&rep, " Copies="); + nadd (&rep, linecountS); + sadd (&rep, " Evals="); + nadd (&rep, evalcountS); + sadd (&rep, " Placeholders="); + nadd (&rep, placeholder); + sadd (&rep, " Symbols="); + nadd (&rep, dictsize); + sadd (&rep, " Errors="); + nadd (&rep, nerrors); + cadd (&rep, '\n'); + ws ( spice_dstring_value(&rep) ) ; + ws ("Numparam expansion errors: Run Spice anyway? y/n ? \n"); + spice_dstring_reinit(&rep) ; + rs (&rep); + reply = spice_dstring_value(&rep) ; + if (upcase (reply[0]) != 'Y') + controlled_exit(EXIT_FAILURE); } - linecountS = 0; - evalcountS = 0; - placeholder = 0; - /* release symbol table data */ ; + linecountS = 0; + evalcountS = 0; + placeholder = 0; + /* release symbol table data */ ; } /* SJB - Scan the line for subcircuits */ @@ -534,10 +543,10 @@ void nupa_scan (char *s, int linenum, int is_subckt) { - if (is_subckt) - defsubckt (dicoS, s, linenum, 'U'); - else - defsubckt (dicoS, s, linenum, 'O'); + if (is_subckt) + defsubckt (dicoS, s, linenum, 'U'); + else + defsubckt (dicoS, s, linenum, 'O'); } @@ -547,24 +556,24 @@ nupa_scan (char *s, int linenum, int is_subckt) static void dump_symbol_table( tdico *dico_p, NGHASHPTR htable_p, FILE * cp_out) { - char *name; /* current symbol */ - entry *entry_p ; /* current entry */ - NGHASHITER iter ; /* hash iterator - thread safe */ + char *name; /* current symbol */ + entry *entry_p ; /* current entry */ + NGHASHITER iter ; /* hash iterator - thread safe */ - NGHASH_FIRST(&iter) ; - for (entry_p = (entry *) nghash_enumerateRE( htable_p,&iter) ; - entry_p ; - entry_p = (entry *) nghash_enumerateRE( htable_p,&iter)) - { - if (entry_p->tp == 'R') - { - spice_dstring_reinit( & dico_p->lookup_buf ) ; - scopy_lower( & dico_p->lookup_buf, entry_p->symbol ) ; - name = spice_dstring_value( & dico_p->lookup_buf ) ; - fprintf (cp_out, " ---> %s = %g\n", name, entry_p->vl) ; - spice_dstring_free( & dico_p->lookup_buf ) ; - } - } + NGHASH_FIRST(&iter) ; + for (entry_p = (entry *) nghash_enumerateRE( htable_p,&iter) ; + entry_p ; + entry_p = (entry *) nghash_enumerateRE( htable_p,&iter)) + { + if (entry_p->tp == 'R') + { + spice_dstring_reinit( & dico_p->lookup_buf ) ; + scopy_lower( & dico_p->lookup_buf, entry_p->symbol ) ; + name = spice_dstring_value( & dico_p->lookup_buf ) ; + fprintf (cp_out, " ---> %s = %g\n", name, entry_p->vl) ; + spice_dstring_free( & dico_p->lookup_buf ) ; + } + } } /* end dump_symbol_table() */ @@ -574,31 +583,33 @@ dump_symbol_table( tdico *dico_p, NGHASHPTR htable_p, FILE * cp_out) void nupa_list_params (FILE * cp_out) { - int depth ; /* nested subcircit depth */ - tdico *dico_p ; /* local copy for speed */ - NGHASHPTR htable_p ; /* current hash table */ + int depth ; /* nested subcircit depth */ + tdico *dico_p ; /* local copy for speed */ + NGHASHPTR htable_p ; /* current hash table */ - dico_p = dicoS ; - fprintf (cp_out, "\n\n"); + dico_p = dicoS ; + fprintf (cp_out, "\n\n"); - /* ----------------------------------------------------------------- - * Print out the locally defined symbols from highest to lowest priority. - * If there are no parameters, the hash table will not be allocated as - * we use lazy allocation to save memory. - * ----------------------------------------------------------------- */ - for( depth = dico_p->stack_depth ; depth > 0 ; depth-- ){ - htable_p = dico_p->local_symbols[depth] ; - if( htable_p ){ - fprintf (cp_out, " local symbol definitions for:%s\n", dico_p->inst_name[depth]) ; - dump_symbol_table( dico_p, htable_p, cp_out ) ; - } - } + /* ----------------------------------------------------------------- + * Print out the locally defined symbols from highest to lowest priority. + * If there are no parameters, the hash table will not be allocated as + * we use lazy allocation to save memory. + * ----------------------------------------------------------------- */ + for( depth = dico_p->stack_depth ; depth > 0 ; depth-- ) + { + htable_p = dico_p->local_symbols[depth] ; + if( htable_p ) + { + fprintf (cp_out, " local symbol definitions for:%s\n", dico_p->inst_name[depth]) ; + dump_symbol_table( dico_p, htable_p, cp_out ) ; + } + } - /* ----------------------------------------------------------------- - * Finally dump the global symbols. - * ----------------------------------------------------------------- */ - fprintf (cp_out, " global symbol definitions:\n") ; - dump_symbol_table( dico_p, dico_p->global_symbols, cp_out ) ; + /* ----------------------------------------------------------------- + * Finally dump the global symbols. + * ----------------------------------------------------------------- */ + fprintf (cp_out, " global symbol definitions:\n") ; + dump_symbol_table( dico_p, dico_p->global_symbols, cp_out ) ; } /* ----------------------------------------------------------------- @@ -612,106 +623,118 @@ nupa_list_params (FILE * cp_out) double nupa_get_param (char *param_name, int *found) { - int depth ; /* nested subcircit depth */ - char *up_name; /* current parameter upper case */ - entry *entry_p ; /* current entry */ - tdico *dico_p ; /* local copy for speed */ - NGHASHPTR htable_p ; /* current hash table */ - double result = 0; /* parameter value */ + int depth ; /* nested subcircit depth */ + char *up_name; /* current parameter upper case */ + entry *entry_p ; /* current entry */ + tdico *dico_p ; /* local copy for speed */ + NGHASHPTR htable_p ; /* current hash table */ + double result = 0; /* parameter value */ - dico_p = dicoS ; - spice_dstring_reinit( & dico_p->lookup_buf ) ; - scopy_up( & dico_p->lookup_buf, param_name ) ; - up_name = spice_dstring_value( & dico_p->lookup_buf ) ; + dico_p = dicoS ; + spice_dstring_reinit( & dico_p->lookup_buf ) ; + scopy_up( & dico_p->lookup_buf, param_name ) ; + up_name = spice_dstring_value( & dico_p->lookup_buf ) ; - *found = 0; - for( depth = dico_p->stack_depth ; depth > 0 ; depth-- ){ - htable_p = dico_p->local_symbols[depth] ; - if( htable_p ){ - entry_p = (entry *) nghash_find( htable_p, up_name ) ; - if( entry_p ){ - result = entry_p->vl ; - *found = 1; - break ; - } - } - } + *found = 0; + for( depth = dico_p->stack_depth ; depth > 0 ; depth-- ) + { + htable_p = dico_p->local_symbols[depth] ; + if( htable_p ) + { + entry_p = (entry *) nghash_find( htable_p, up_name ) ; + if( entry_p ) + { + result = entry_p->vl ; + *found = 1; + break ; + } + } + } - if(!(*found)){ - /* No luck. Try the global table. */ - entry_p = (entry *) nghash_find( dico_p->global_symbols, up_name ) ; - if( entry_p ){ - result = entry_p->vl ; - *found = 1; - } - } + if(!(*found)) + { + /* No luck. Try the global table. */ + entry_p = (entry *) nghash_find( dico_p->global_symbols, up_name ) ; + if( entry_p ) + { + result = entry_p->vl ; + *found = 1; + } + } - spice_dstring_free( & dico_p->lookup_buf ) ; - return result; + spice_dstring_free( & dico_p->lookup_buf ) ; + return result; } void nupa_add_param (char *param_name, double value) { - char *up_name; /* current parameter upper case */ - entry *entry_p ; /* current entry */ - tdico *dico_p ; /* local copy for speed */ - NGHASHPTR htable_p ; /* hash table of interest */ + char *up_name; /* current parameter upper case */ + entry *entry_p ; /* current entry */ + tdico *dico_p ; /* local copy for speed */ + NGHASHPTR htable_p ; /* hash table of interest */ - dico_p = dicoS ; - /* ----------------------------------------------------------------- - * We use a dynamic string here because most of the time we will - * be using short names and no memory allocation will occur. - * ----------------------------------------------------------------- */ - spice_dstring_reinit( & dico_p->lookup_buf ) ; - scopy_up( & dico_p->lookup_buf, param_name ) ; - up_name = spice_dstring_value( & dico_p->lookup_buf ) ; + dico_p = dicoS ; + /* ----------------------------------------------------------------- + * We use a dynamic string here because most of the time we will + * be using short names and no memory allocation will occur. + * ----------------------------------------------------------------- */ + spice_dstring_reinit( & dico_p->lookup_buf ) ; + scopy_up( & dico_p->lookup_buf, param_name ) ; + up_name = spice_dstring_value( & dico_p->lookup_buf ) ; - if( dico_p->stack_depth > 0 ){ - /* can't be lazy anymore */ - if(!(dico_p->local_symbols[dico_p->stack_depth])){ - dico_p->local_symbols[dico_p->stack_depth] = nghash_init( NGHASH_MIN_SIZE ) ; - } - htable_p = dico_p->local_symbols[dico_p->stack_depth] ; - } else { - /* global symbol */ - htable_p = dico_p->global_symbols ; - } + if( dico_p->stack_depth > 0 ) + { + /* can't be lazy anymore */ + if(!(dico_p->local_symbols[dico_p->stack_depth])) + { + dico_p->local_symbols[dico_p->stack_depth] = nghash_init( NGHASH_MIN_SIZE ) ; + } + htable_p = dico_p->local_symbols[dico_p->stack_depth] ; + } + else + { + /* global symbol */ + htable_p = dico_p->global_symbols ; + } - entry_p = attrib ( dico_p, htable_p, up_name, 'N'); - if( entry_p ){ - entry_p->vl = value; - entry_p->tp = 'R'; - entry_p->ivl = 0; - entry_p->sbbase = NULL; - } - spice_dstring_free( & dico_p->lookup_buf ) ; + entry_p = attrib ( dico_p, htable_p, up_name, 'N'); + if( entry_p ) + { + entry_p->vl = value; + entry_p->tp = 'R'; + entry_p->ivl = 0; + entry_p->sbbase = NULL; + } + spice_dstring_free( & dico_p->lookup_buf ) ; } void nupa_add_inst_param (char *param_name, double value) { - char *up_name; /* current parameter upper case */ - entry *entry_p ; /* current entry */ - tdico *dico_p ; /* local copy for speed */ + char *up_name; /* current parameter upper case */ + entry *entry_p ; /* current entry */ + tdico *dico_p ; /* local copy for speed */ - dico_p = dicoS ; - spice_dstring_reinit( & dico_p->lookup_buf ) ; - scopy_up( & dico_p->lookup_buf, param_name ) ; - up_name = spice_dstring_value( & dico_p->lookup_buf ) ; + dico_p = dicoS ; + spice_dstring_reinit( & dico_p->lookup_buf ) ; + scopy_up( & dico_p->lookup_buf, param_name ) ; + up_name = spice_dstring_value( & dico_p->lookup_buf ) ; - if(!(dico_p->inst_symbols)){ - dico_p->inst_symbols = nghash_init( NGHASH_MIN_SIZE ) ; - } + if(!(dico_p->inst_symbols)) + { + dico_p->inst_symbols = nghash_init( NGHASH_MIN_SIZE ) ; + } - entry_p = attrib ( dico_p, dico_p->inst_symbols, up_name, 'N'); - if( entry_p ){ - entry_p->vl = value; - entry_p->tp = 'R'; - entry_p->ivl = 0; - entry_p->sbbase = NULL; - } - spice_dstring_free( & dico_p->lookup_buf ) ; + entry_p = attrib ( dico_p, dico_p->inst_symbols, up_name, 'N'); + if( entry_p ) + { + entry_p->vl = value; + entry_p->tp = 'R'; + entry_p->ivl = 0; + entry_p->sbbase = NULL; + } + spice_dstring_free( & dico_p->lookup_buf ) ; } /* ----------------------------------------------------------------- @@ -722,99 +745,102 @@ nupa_add_inst_param (char *param_name, double value) void nupa_copy_inst_dico (void) { - entry *entry_p ; /* current entry */ - tdico *dico_p ; /* local copy for speed */ - NGHASHITER iter ; /* hash iterator - thread safe */ + entry *entry_p ; /* current entry */ + tdico *dico_p ; /* local copy for speed */ + NGHASHITER iter ; /* hash iterator - thread safe */ - dico_p = dicoS ; - if( dico_p->inst_symbols ){ - /* We we perform this operation we should be in global scope */ - if( dico_p->stack_depth > 0 ){ - fprintf( stderr, "stack depth should be zero.\n" ) ; - } - NGHASH_FIRST(&iter) ; - for (entry_p = (entry *) nghash_enumerateRE(dico_p->inst_symbols,&iter ) ; - entry_p ; - entry_p = (entry *) nghash_enumerateRE(dico_p->inst_symbols,&iter)){ - nupa_add_param ( entry_p->symbol, entry_p->vl) ; - dico_free_entry( entry_p ) ; - } + dico_p = dicoS ; + if( dico_p->inst_symbols ) + { + /* We we perform this operation we should be in global scope */ + if( dico_p->stack_depth > 0 ) + { + fprintf( stderr, "stack depth should be zero.\n" ) ; + } + NGHASH_FIRST(&iter) ; + for (entry_p = (entry *) nghash_enumerateRE(dico_p->inst_symbols,&iter ) ; + entry_p ; + entry_p = (entry *) nghash_enumerateRE(dico_p->inst_symbols,&iter)) + { + nupa_add_param ( entry_p->symbol, entry_p->vl) ; + dico_free_entry( entry_p ) ; + } - nghash_free( dico_p->inst_symbols, NULL, NULL ) ; - dico_p->inst_symbols = NULL ; - } + nghash_free( dico_p->inst_symbols, NULL, NULL ) ; + dico_p->inst_symbols = NULL ; + } } char * nupa_copy (char *s, int linenum) /* returns a copy (not quite) of s in freshly allocated memory. - linenum, for info only, is the source line number. + linenum, for info only, is the source line number. origin pointer s is kept, memory is freed later in nupa_done. - must abort all Spice if malloc() fails. + must abort all Spice if malloc() fails. :{ called for the first time sequentially for all spice deck lines. :{ then called again for all X invocation lines, top-down for subckts defined at the outer level, but bottom-up for local - subcircuit expansion, but has no effect in that phase. + subcircuit expansion, but has no effect in that phase. we steal a copy of the source line pointer. - comment-out a .param or & line - substitute placeholders for all {..} --> 10-digit numeric values. */ { - char *t; - int ls; - char c, d; - SPICE_DSTRING u ; - SPICE_DSTRING keywd ; + char *t; + int ls; + char c, d; + SPICE_DSTRING u ; + SPICE_DSTRING keywd ; - spice_dstring_init(&u) ; - spice_dstring_init(&keywd) ; - ls = length (s); + spice_dstring_init(&u) ; + spice_dstring_init(&keywd) ; + ls = length (s); - while ((ls > 0) && (s[ls - 1] <= ' ')) - ls--; + while ((ls > 0) && (s[ls - 1] <= ' ')) + ls--; - pscopy (&u, s, 0, ls); /* strip trailing space, CrLf and so on */ - dicoS->srcline = linenum; + pscopy (&u, s, 0, ls); /* strip trailing space, CrLf and so on */ + dicoS->srcline = linenum; - if ((!inexpansionS) && (linenum >= 0) && (linenum <= dynmaxline)) - { - linecountS++; - dicoS->dynrefptr[linenum] = s; - c = transform (dicoS, &u, incontrolS, &keywd); - if (c == 'C') - incontrolS = 1; - else if (c == 'E') - incontrolS = 0; - - if (incontrolS) - c = 'C'; /* force it */ - - d = dicoS->dyncategory[linenum]; /* warning if already some strategic line! */ - - if ((d == 'P') || (d == 'S') || (d == 'X')) - fprintf (stderr, - " Numparam warning: overwriting P,S or X line (linenum == %d).\n", - linenum); - dicoS->dyncategory[linenum] = c; - } /* keep a local copy and mangle the string */ - - ls = spice_dstring_length (&u); - t = strdup ( spice_dstring_value(&u) ); - - if (t == NULL) - { - fputs ("Fatal: String malloc crash in nupa_copy()\n", stderr); - controlled_exit(EXIT_FAILURE); - } - else - { - if (!inexpansionS) + if ((!inexpansionS) && (linenum >= 0) && (linenum <= dynmaxline)) { - putlogfile (dicoS->dyncategory[linenum], linenum, t); - }; - } - spice_dstring_free(&u) ; - return t; + linecountS++; + dicoS->dynrefptr[linenum] = s; + c = transform (dicoS, &u, incontrolS, &keywd); + if (c == 'C') + incontrolS = 1; + else if (c == 'E') + incontrolS = 0; + + if (incontrolS) + c = 'C'; /* force it */ + + d = dicoS->dyncategory[linenum]; /* warning if already some strategic line! */ + + if ((d == 'P') || (d == 'S') || (d == 'X')) + fprintf (stderr, + " Numparam warning: overwriting P,S or X line (linenum == %d).\n", + linenum); + dicoS->dyncategory[linenum] = c; + } /* keep a local copy and mangle the string */ + + ls = spice_dstring_length (&u); + t = strdup ( spice_dstring_value(&u) ); + + if (t == NULL) + { + fputs ("Fatal: String malloc crash in nupa_copy()\n", stderr); + controlled_exit(EXIT_FAILURE); + } + else + { + if (!inexpansionS) + { + putlogfile (dicoS->dyncategory[linenum], linenum, t); + }; + } + spice_dstring_free(&u) ; + return t; } int @@ -826,63 +852,65 @@ nupa_eval (char *s, int linenum, int orig_linenum) All the X lines are preserved (commented out) in the expanded circuit. */ { - int idef; /* subckt definition line */ - char c, keep, *ptr; - SPICE_DSTRING subname ; /* dynamic string for subcircuit name */ - bool err = 1; + int idef; /* subckt definition line */ + char c, keep, *ptr; + SPICE_DSTRING subname ; /* dynamic string for subcircuit name */ + bool err = 1; - spice_dstring_init(&subname) ; - dicoS->srcline = linenum; - dicoS->oldline = orig_linenum; - c = dicoS->dyncategory[linenum]; + spice_dstring_init(&subname) ; + dicoS->srcline = linenum; + dicoS->oldline = orig_linenum; + c = dicoS->dyncategory[linenum]; #ifdef TRACE_NUMPARAMS - fprintf (stderr, "** SJB - in nupa_eval()\n"); - fprintf (stderr, "** SJB - processing line %3d: %s\n", linenum, s); - fprintf (stderr, "** SJB - category '%c'\n", c); + fprintf (stderr, "** SJB - in nupa_eval()\n"); + fprintf (stderr, "** SJB - processing line %3d: %s\n", linenum, s); + fprintf (stderr, "** SJB - category '%c'\n", c); #endif /* TRACE_NUMPARAMS */ - if (c == 'P') { /* evaluate parameters */ + if (c == 'P') /* evaluate parameters */ + { // err = nupa_substitute (dico, dico->dynrefptr[linenum], s, 0); - nupa_assignment (dicoS, dicoS->dynrefptr[linenum], 'N'); - } - else if (c == 'B') /* substitute braces line */ - err = nupa_substitute (dicoS, dicoS->dynrefptr[linenum], s, 0); - else if (c == 'X') - { /* compute args of subcircuit, if required */ - ptr = s; - while (!isspace (*ptr)) - ptr++; - keep = *ptr; - *ptr = '\0'; - nupa_inst_name = strdup (s); - *nupa_inst_name = 'x'; - *ptr = keep; - - strtoupper(nupa_inst_name); - - idef = findsubckt (dicoS, s, &subname); - if (idef > 0) - nupa_subcktcall (dicoS, dicoS->dynrefptr[idef], dicoS->dynrefptr[linenum], 0); - else - putlogfile ('?', linenum, " illegal subckt call."); + nupa_assignment (dicoS, dicoS->dynrefptr[linenum], 'N'); } - else if (c == 'U') /* release local symbols = parameters */ - nupa_subcktexit (dicoS); + else if (c == 'B') /* substitute braces line */ + err = nupa_substitute (dicoS, dicoS->dynrefptr[linenum], s, 0); + else if (c == 'X') + { + /* compute args of subcircuit, if required */ + ptr = s; + while (!isspace (*ptr)) + ptr++; + keep = *ptr; + *ptr = '\0'; + nupa_inst_name = strdup (s); + *nupa_inst_name = 'x'; + *ptr = keep; - putlogfile ('e', linenum, s); - evalcountS++; + strtoupper(nupa_inst_name); + + idef = findsubckt (dicoS, s, &subname); + if (idef > 0) + nupa_subcktcall (dicoS, dicoS->dynrefptr[idef], dicoS->dynrefptr[linenum], 0); + else + putlogfile ('?', linenum, " illegal subckt call."); + } + else if (c == 'U') /* release local symbols = parameters */ + nupa_subcktexit (dicoS); + + putlogfile ('e', linenum, s); + evalcountS++; #ifdef TRACE_NUMPARAMS - fprintf (stderr, "** SJB - leaving nupa_eval(): %s %d\n", s, err); - ws ("** SJB - --> "); - ws (s); - wln (); - ws ("** SJB - leaving nupa_eval()"); - wln (); - wln (); + fprintf (stderr, "** SJB - leaving nupa_eval(): %s %d\n", s, err); + ws ("** SJB - --> "); + ws (s); + wln (); + ws ("** SJB - leaving nupa_eval()"); + wln (); + wln (); #endif /* TRACE_NUMPARAMS */ - if (err) - return 0; - else - return 1; + if (err) + return 0; + else + return 1; } int @@ -890,28 +918,28 @@ nupa_signal (int sig, char *info) /* warning: deckcopy may come inside a recursion ! substart no! */ /* info is context-dependent string data */ { - putlogfile ('!', sig, " Nupa Signal"); - if (sig == NUPADECKCOPY) + putlogfile ('!', sig, " Nupa Signal"); + if (sig == NUPADECKCOPY) { - if (firstsignalS) - { - nupa_init (info); - firstsignalS = 0; - } + if (firstsignalS) + { + nupa_init (info); + firstsignalS = 0; + } } - else if (sig == NUPASUBSTART) - inexpansionS = 1; - else if (sig == NUPASUBDONE) + else if (sig == NUPASUBSTART) + inexpansionS = 1; + else if (sig == NUPASUBDONE) { - inexpansionS = 0; - nupa_inst_name = NULL; + inexpansionS = 0; + nupa_inst_name = NULL; } - else if (sig == NUPAEVALDONE) + else if (sig == NUPAEVALDONE) { - nupa_done (); - firstsignalS = 1; + nupa_done (); + firstsignalS = 1; } - return 1; + return 1; } #ifdef USING_NUPATEST @@ -919,14 +947,14 @@ nupa_signal (int sig, char *info) tdico * nupa_fetchinstance (void) { - return dico; + return dico; } #endif /* USING_NUPATEST */ void dump_symbols( tdico *dico_p ) { - NG_IGNORE(dico_p); + NG_IGNORE(dico_p); - fprintf (stderr, "Symbol table\n"); - nupa_list_params ( stderr ) ; + fprintf (stderr, "Symbol table\n"); + nupa_list_params ( stderr ) ; } diff --git a/src/frontend/numparam/xpressn.c b/src/frontend/numparam/xpressn.c index 373f7d62b..947f893e5 100644 --- a/src/frontend/numparam/xpressn.c +++ b/src/frontend/numparam/xpressn.c @@ -1,5 +1,5 @@ /* xpressn.c Copyright (C) 2002 Georg Post - + This file is part of Numparam, see: readme.txt Free software under the terms of the GNU Lesser General Public License $Id$ @@ -39,39 +39,39 @@ extern unsigned int dynLlen; static double ternary_fcn (int conditional, double if_value, double else_value) { - if (conditional) - return if_value; - else - return else_value; + if (conditional) + return if_value; + else + return else_value; } static double agauss (double nominal_val, double abs_variation, double sigma) { - double stdvar; - stdvar=abs_variation/sigma; - return (nominal_val+stdvar*gauss0()); + double stdvar; + stdvar=abs_variation/sigma; + return (nominal_val+stdvar*gauss0()); } static double gauss (double nominal_val, double rel_variation, double sigma) { - double stdvar; - stdvar=nominal_val * rel_variation / sigma; - return (nominal_val + stdvar * gauss0()); + double stdvar; + stdvar=nominal_val * rel_variation / sigma; + return (nominal_val + stdvar * gauss0()); } static double unif (double nominal_val, double rel_variation) { - return (nominal_val + nominal_val * rel_variation * drand()); + return (nominal_val + nominal_val * rel_variation * drand()); } static double aunif (double nominal_val, double abs_variation) { - return (nominal_val + abs_variation * drand()); + return (nominal_val + abs_variation * drand()); } static double @@ -84,21 +84,22 @@ static void initkeys (void) /* the list of reserved words */ { - spice_dstring_init(&keyS) ; - scopy_up (&keyS, - "and or not div mod if else end while macro funct defined" - " include for to downto is var"); - scopy_up (&fmathS, - "sqr sqrt sin cos exp ln arctan abs pow pwr max min int log sinh cosh" - " tanh ternary_fcn v agauss sgn gauss unif aunif limit"); + spice_dstring_init(&keyS) ; + scopy_up (&keyS, + "and or not div mod if else end while macro funct defined" + " include for to downto is var"); + scopy_up (&fmathS, + "sqr sqrt sin cos exp ln arctan abs pow pwr max min int log sinh cosh" + " tanh ternary_fcn v agauss sgn gauss unif aunif limit"); } static double mathfunction (int f, double z, double x) /* the list of built-in functions. Patch 'fmath', here and near line 888 to get more ...*/ { - double y; - switch (f) { + double y; + switch (f) + { case 1: y = x * x; break; @@ -147,57 +148,57 @@ mathfunction (int f, double z, double x) case 16: y = cosh (x); break; - case 17: + case 17: y=sinh(x)/cosh(x); break; case 21: if (x>0) y=1.; else if (x == 0) y=0.; - else y = -1.; + else y = -1.; break; default: y = x; break; } - return y; + return y; } static bool message (tdico * dic, char *s) /* record 'dic' should know about source file and line */ { - char *srcfile ; /* src file name */ - SPICE_DSTRING t ; /* temp dstring */ + char *srcfile ; /* src file name */ + SPICE_DSTRING t ; /* temp dstring */ - spice_dstring_init(&t) ; - dic->errcount++; - srcfile = spice_dstring_value( &(dic->srcfile) ) ; - if ((srcfile != NULL) && srcfile[0]) - { - scopyd(&t, &(dic->srcfile)) ; - cadd (&t, ':'); - } - if (dic->srcline >= 0) - { - sadd (&t, "Original line no.: "); - nadd (&t, dic->oldline); - sadd (&t, ", new internal line no.: "); - nadd (&t, dic->srcline); - sadd (&t, ":\n"); - } - sadd (&t, s); - cadd (&t, '\n'); - fputs ( spice_dstring_value(&t), stderr); - spice_dstring_free(&t) ; + spice_dstring_init(&t) ; + dic->errcount++; + srcfile = spice_dstring_value( &(dic->srcfile) ) ; + if ((srcfile != NULL) && srcfile[0]) + { + scopyd(&t, &(dic->srcfile)) ; + cadd (&t, ':'); + } + if (dic->srcline >= 0) + { + sadd (&t, "Original line no.: "); + nadd (&t, dic->oldline); + sadd (&t, ", new internal line no.: "); + nadd (&t, dic->srcline); + sadd (&t, ":\n"); + } + sadd (&t, s); + cadd (&t, '\n'); + fputs ( spice_dstring_value(&t), stderr); + spice_dstring_free(&t) ; - return 1 /* error! */ ; + return 1 /* error! */ ; } void debugwarn (tdico * d, char *s) { - message (d, s); - d->errcount--; + message (d, s); + d->errcount--; } @@ -206,40 +207,41 @@ debugwarn (tdico * d, char *s) void initdico (tdico * dico) { - int asize ; /* default allocation size */ - COMPATMODE_T compat_mode; + int asize ; /* default allocation size */ + COMPATMODE_T compat_mode; - spice_dstring_init( &(dico->option) ) ; - spice_dstring_init( &(dico->srcfile) ) ; - - dico->srcline = -1; - dico->errcount = 0; + spice_dstring_init( &(dico->option) ) ; + spice_dstring_init( &(dico->srcfile) ) ; - dico->global_symbols = nghash_init( NGHASH_MIN_SIZE ) ; - nghash_unique( dico->global_symbols, TRUE ) ; /* no rewrite of global symbols */ - spice_dstring_init( &(dico->lookup_buf) ) ; - - dico->stack_depth = 0 ; /* top of the stack */ - asize = dico->symbol_stack_alloc = 10 ;/* expected stack depth - no longer limited */ - asize++ ; /* account for zero */ - dico->local_symbols = TMALLOC(NGHASHPTR, asize) ; - dico->inst_name = TMALLOC(char*, asize) ; - dico->inst_symbols = NULL ; /* instance qualified are lazily allocated */ + dico->srcline = -1; + dico->errcount = 0; - initkeys (); + dico->global_symbols = nghash_init( NGHASH_MIN_SIZE ) ; + nghash_unique( dico->global_symbols, TRUE ) ; /* no rewrite of global symbols */ + spice_dstring_init( &(dico->lookup_buf) ) ; - compat_mode = ngspice_compat_mode() ; + dico->stack_depth = 0 ; /* top of the stack */ + asize = dico->symbol_stack_alloc = 10 ;/* expected stack depth - no longer limited */ + asize++ ; /* account for zero */ + dico->local_symbols = TMALLOC(NGHASHPTR, asize) ; + dico->inst_name = TMALLOC(char*, asize) ; + dico->inst_symbols = NULL ; /* instance qualified are lazily allocated */ - if( compat_mode == COMPATMODE_HSPICE ) - dico->hspice_compatibility = 1 ; - else - dico->hspice_compatibility = 0 ; + initkeys (); + + compat_mode = ngspice_compat_mode() ; + + if( compat_mode == COMPATMODE_HSPICE ) + dico->hspice_compatibility = 1 ; + else + dico->hspice_compatibility = 0 ; } void dico_free_entry( entry *entry_p ) { - if( entry_p->symbol ){ - txfree(entry_p->symbol ) ; + if( entry_p->symbol ) + { + txfree(entry_p->symbol ) ; } txfree(entry_p) ; } /* end dico_free_entry() */ @@ -259,74 +261,76 @@ static void dicostack (tdico * dico, char op) /* push or pop operation for nested subcircuit locals */ { - int asize ; /* allocation size */ - char *inst_name ; /* name of subcircuit instance */ - char *param_p ; /* qualified inst parameter name */ - entry *entry_p ; /* current entry */ - NGHASHPTR htable_p ; /* current hash table */ - NGHASHITER iter ; /* hash iterator - thread safe */ + int asize ; /* allocation size */ + char *inst_name ; /* name of subcircuit instance */ + char *param_p ; /* qualified inst parameter name */ + entry *entry_p ; /* current entry */ + NGHASHPTR htable_p ; /* current hash table */ + NGHASHITER iter ; /* hash iterator - thread safe */ - if (op == Push) - { - dico->stack_depth++; - if ( dico->stack_depth > dico->symbol_stack_alloc ){ - /* Just double the stack alloc */ - dico->symbol_stack_alloc *= 2 ; - asize = dico->symbol_stack_alloc + 1 ; /* account for zero */ - dico->local_symbols = TREALLOC(NGHASHPTR, dico->local_symbols, asize) ; - dico->inst_name = TREALLOC(char*, dico->inst_name, asize) ; - } - /* lazy allocation - don't allocate space if we can help it */ - dico->local_symbols[dico->stack_depth] = NULL ; - dico->inst_name[dico->stack_depth] = nupa_inst_name ; - } - else if (op == Pop) - { - if (dico->stack_depth > 0) - { - /* ----------------------------------------------------------------- - * Keep instance parameters around by transferring current local - * scope variables to an instance qualified hash table. - * ----------------------------------------------------------------- */ - inst_name = dico->inst_name[dico->stack_depth] ; - htable_p = dico->local_symbols[dico->stack_depth] ; - if( htable_p ){ - SPICE_DSTRING param_name ; /* build a qualified name */ - spice_dstring_init(¶m_name) ; + if (op == Push) + { + dico->stack_depth++; + if ( dico->stack_depth > dico->symbol_stack_alloc ) + { + /* Just double the stack alloc */ + dico->symbol_stack_alloc *= 2 ; + asize = dico->symbol_stack_alloc + 1 ; /* account for zero */ + dico->local_symbols = TREALLOC(NGHASHPTR, dico->local_symbols, asize) ; + dico->inst_name = TREALLOC(char*, dico->inst_name, asize) ; + } + /* lazy allocation - don't allocate space if we can help it */ + dico->local_symbols[dico->stack_depth] = NULL ; + dico->inst_name[dico->stack_depth] = nupa_inst_name ; + } + else if (op == Pop) + { + if (dico->stack_depth > 0) + { + /* ----------------------------------------------------------------- + * Keep instance parameters around by transferring current local + * scope variables to an instance qualified hash table. + * ----------------------------------------------------------------- */ + inst_name = dico->inst_name[dico->stack_depth] ; + htable_p = dico->local_symbols[dico->stack_depth] ; + if( htable_p ) + { + SPICE_DSTRING param_name ; /* build a qualified name */ + spice_dstring_init(¶m_name) ; - NGHASH_FIRST(&iter) ; - for (entry_p = (entry *) nghash_enumerateRE( htable_p,&iter ) ; - entry_p ; - entry_p = (entry *) nghash_enumerateRE( htable_p,&iter)) - { - spice_dstring_reinit(¶m_name) ; - param_p = spice_dstring_print( ¶m_name, "%s.%s", - inst_name, - entry_p->symbol ) ; - nupa_add_inst_param (param_p, entry_p->vl); - dico_free_entry( entry_p ) ; - } - nghash_free( htable_p, NULL, NULL ) ; - spice_dstring_free(¶m_name) ; - } - tfree (inst_name); + NGHASH_FIRST(&iter) ; + for (entry_p = (entry *) nghash_enumerateRE( htable_p,&iter ) ; + entry_p ; + entry_p = (entry *) nghash_enumerateRE( htable_p,&iter)) + { + spice_dstring_reinit(¶m_name) ; + param_p = spice_dstring_print( ¶m_name, "%s.%s", + inst_name, + entry_p->symbol ) ; + nupa_add_inst_param (param_p, entry_p->vl); + dico_free_entry( entry_p ) ; + } + nghash_free( htable_p, NULL, NULL ) ; + spice_dstring_free(¶m_name) ; + } + tfree (inst_name); - dico->inst_name[dico->stack_depth] = NULL ; - dico->local_symbols[dico->stack_depth] = NULL ; - dico->stack_depth--; - } - else - { - message (dico, " Subckt Stack underflow."); - } - } + dico->inst_name[dico->stack_depth] = NULL ; + dico->local_symbols[dico->stack_depth] = NULL ; + dico->stack_depth--; + } + else + { + message (dico, " Subckt Stack underflow."); + } + } } int donedico (tdico * dico) { - int sze = nghash_get_size( dico->global_symbols ) ; - return sze; + int sze = nghash_get_size( dico->global_symbols ) ; + return sze; } /* ----------------------------------------------------------------- @@ -337,23 +341,26 @@ donedico (tdico * dico) static entry * entrynb ( tdico *d, char *s) { - int depth ; /* stack depth */ - entry *entry_p ; /* search hash table */ - NGHASHPTR htable_p ; /* hash table */ + int depth ; /* stack depth */ + entry *entry_p ; /* search hash table */ + NGHASHPTR htable_p ; /* hash table */ - /* look at the current scope and then backup the stack */ - for( depth = d->stack_depth ; depth > 0 ; depth-- ){ - htable_p = d->local_symbols[depth] ; - if( htable_p ){ - entry_p = (entry *) nghash_find( htable_p, s ) ; - if( entry_p ){ - return( entry_p ) ; - } + /* look at the current scope and then backup the stack */ + for( depth = d->stack_depth ; depth > 0 ; depth-- ) + { + htable_p = d->local_symbols[depth] ; + if( htable_p ) + { + entry_p = (entry *) nghash_find( htable_p, s ) ; + if( entry_p ) + { + return( entry_p ) ; + } + } } - } - /* No local symbols - try the global table */ - entry_p = (entry *) nghash_find( d->global_symbols, s ) ; - return( entry_p ) ; + /* No local symbols - try the global table */ + entry_p = (entry *) nghash_find( d->global_symbols, s ) ; + return( entry_p ) ; } /* end entrynb() */ @@ -361,52 +368,53 @@ char getidtype (tdico * d, char *s) /* test if identifier s is known. Answer its type, or '?' if not in table */ { - entry *entry_p ; /* hash table entry */ - char itp = '?'; /* assume unknown */ + entry *entry_p ; /* hash table entry */ + char itp = '?'; /* assume unknown */ - entry_p = entrynb( d, s ) ; - if( entry_p ) - itp = entry_p->tp ; + entry_p = entrynb( d, s ) ; + if( entry_p ) + itp = entry_p->tp ; - return (itp) ; + return (itp) ; } static double fetchnumentry (tdico * dico, char *t, bool *perr) { - bool err = *perr; - double u; - entry *entry_p ; /* hash table entry */ - SPICE_DSTRING s ; /* dynamic string */ + bool err = *perr; + double u; + entry *entry_p ; /* hash table entry */ + SPICE_DSTRING s ; /* dynamic string */ - spice_dstring_init(&s) ; - entry_p = entrynb (dico, t); /* no keyword */ - /*dbg -- if ( k<=0 ) { ws("Dico num lookup fails. ") ;} */ + spice_dstring_init(&s) ; + entry_p = entrynb (dico, t); /* no keyword */ + /*dbg -- if ( k<=0 ) { ws("Dico num lookup fails. ") ;} */ - while ( entry_p && (entry_p->tp == 'P') ){ - entry_p = entry_p->pointer ; - } + while ( entry_p && (entry_p->tp == 'P') ) + { + entry_p = entry_p->pointer ; + } - if ( entry_p ) - if (entry_p->tp != 'R') - entry_p = NULL ; + if ( entry_p ) + if (entry_p->tp != 'R') + entry_p = NULL ; - if ( entry_p ) - u = entry_p->vl ; - else - { - u = 0.0; - scopys(&s, "Undefined number [") ; - sadd (&s, t); - cadd (&s, ']'); - err = message (dico, spice_dstring_value(&s) ) ; - } + if ( entry_p ) + u = entry_p->vl ; + else + { + u = 0.0; + scopys(&s, "Undefined number [") ; + sadd (&s, t); + cadd (&s, ']'); + err = message (dico, spice_dstring_value(&s) ) ; + } - *perr = err; + *perr = err; - spice_dstring_free(&s) ; + spice_dstring_free(&s) ; - return u; + return u; } /******* writing dictionary entries *********/ @@ -414,115 +422,119 @@ fetchnumentry (tdico * dico, char *t, bool *perr) entry * attrib (tdico *dico_p, NGHASHPTR htable_p, char *t, char op) { -/* seek or attribute dico entry number for string t. - Option op='N' : force a new entry, if tos>level and old is valid. -*/ - entry *entry_p ; /* symbol table entry */ + /* seek or attribute dico entry number for string t. + Option op='N' : force a new entry, if tos>level and old is valid. + */ + entry *entry_p ; /* symbol table entry */ - entry_p = (entry *) nghash_find( htable_p, t ) ; - if ( entry_p && (op == 'N') - && ( entry_p->level < dico_p->stack_depth) && ( entry_p->tp != '?')) - { - entry_p = NULL ; - } + entry_p = (entry *) nghash_find( htable_p, t ) ; + if ( entry_p && (op == 'N') + && ( entry_p->level < dico_p->stack_depth) && ( entry_p->tp != '?')) + { + entry_p = NULL ; + } - if (!(entry_p)) - { - entry_p = TMALLOC(entry, 1) ; - entry_p->symbol = strdup( t ) ; - entry_p->tp = '?'; /* signal Unknown */ - entry_p->level = dico_p->stack_depth ; - nghash_insert( htable_p, t, entry_p ) ; - } - return entry_p ; + if (!(entry_p)) + { + entry_p = TMALLOC(entry, 1) ; + entry_p->symbol = strdup( t ) ; + entry_p->tp = '?'; /* signal Unknown */ + entry_p->level = dico_p->stack_depth ; + nghash_insert( htable_p, t, entry_p ) ; + } + return entry_p ; } static bool -define (tdico * dico, +define (tdico * dico, char *t, /* identifier to define */ char op, /* option */ char tpe, /* type marker */ double z, /* float value if any */ int w, /* integer value if any */ - entry *pval, /* pointer value if any */ + entry *pval, /* pointer value if any */ char *base) /* string pointer if any */ { -/*define t as real or integer, - opcode= 'N' impose a new item under local conditions. - check for pointers, too, in full macrolanguage version: - Call with 'N','P',0.0, ksymbol ... for VAR parameter passing. - Overwrite warning, beware: During 1st pass (macro definition), - we already make symbol entries which are dummy globals ! - we mark each id with its subckt level, and warn if write at higher one. -*/ - char c; - bool err, warn; - entry *entry_p ; /* spice table entry */ - SPICE_DSTRING vartemp ; /* vairable temp */ - NGHASHPTR htable_p ; /* hash table */ + /*define t as real or integer, + opcode= 'N' impose a new item under local conditions. + check for pointers, too, in full macrolanguage version: + Call with 'N','P',0.0, ksymbol ... for VAR parameter passing. + Overwrite warning, beware: During 1st pass (macro definition), + we already make symbol entries which are dummy globals ! + we mark each id with its subckt level, and warn if write at higher one. + */ + char c; + bool err, warn; + entry *entry_p ; /* spice table entry */ + SPICE_DSTRING vartemp ; /* vairable temp */ + NGHASHPTR htable_p ; /* hash table */ - NG_IGNORE(pval); + NG_IGNORE(pval); - spice_dstring_init(&vartemp) ; + spice_dstring_init(&vartemp) ; - if( dico->stack_depth > 0 ){ - /* can't be lazy anymore */ - if(!(dico->local_symbols[dico->stack_depth])){ - dico->local_symbols[dico->stack_depth] = nghash_init( NGHASH_MIN_SIZE ) ; - } - htable_p = dico->local_symbols[dico->stack_depth] ; - } else { - /* global symbol */ - htable_p = dico->global_symbols ; - } - entry_p = attrib (dico, htable_p, t, op); - err = 0; - if (!(entry_p)) - err = message (dico, " Symbol table overflow"); - else - { - if ( entry_p->tp == 'P') - entry_p = entry_p->pointer ; /* pointer indirection */ + if( dico->stack_depth > 0 ) + { + /* can't be lazy anymore */ + if(!(dico->local_symbols[dico->stack_depth])) + { + dico->local_symbols[dico->stack_depth] = nghash_init( NGHASH_MIN_SIZE ) ; + } + htable_p = dico->local_symbols[dico->stack_depth] ; + } + else + { + /* global symbol */ + htable_p = dico->global_symbols ; + } + entry_p = attrib (dico, htable_p, t, op); + err = 0; + if (!(entry_p)) + err = message (dico, " Symbol table overflow"); + else + { + if ( entry_p->tp == 'P') + entry_p = entry_p->pointer ; /* pointer indirection */ - if (entry_p) - c = entry_p->tp ; - else - c = ' '; + if (entry_p) + c = entry_p->tp ; + else + c = ' '; - if ((c == 'R') || (c == 'S') || (c == '?')) - { - entry_p->vl = z; - entry_p->tp = tpe; - entry_p->ivl = w ; - entry_p->sbbase = base ; - /* if ( (c !='?') && (i<= dico->stack[dico->tos]) ) { */ - if (c == '?') - entry_p->level = dico->stack_depth ; /* promote! */ + if ((c == 'R') || (c == 'S') || (c == '?')) + { + entry_p->vl = z; + entry_p->tp = tpe; + entry_p->ivl = w ; + entry_p->sbbase = base ; + /* if ( (c !='?') && (i<= dico->stack[dico->tos]) ) { */ + if (c == '?') + entry_p->level = dico->stack_depth ; /* promote! */ - if ( entry_p->level < dico->stack_depth) - { - /* warn about re-write to a global scope! */ - scopys(&vartemp, t) ; - cadd (&vartemp, ':'); - nadd (&vartemp, entry_p->level); - sadd (&vartemp, " overwritten."); - warn = message (dico, spice_dstring_value(&vartemp)); - } - } - else - { - scopys( &vartemp, t) ; - sadd ( &vartemp, ": cannot redefine"); - /* suppress error message, resulting from multiple definition of - symbols (devices) in .model lines with same name, but in different subcircuits. - Subcircuit expansion is o.k., we have to deal with this numparam - behaviour later. (H. Vogt 090426) - */ - /*err = message (dico, v);*/ - } - } - spice_dstring_free(&vartemp) ; - return err; + if ( entry_p->level < dico->stack_depth) + { + /* warn about re-write to a global scope! */ + scopys(&vartemp, t) ; + cadd (&vartemp, ':'); + nadd (&vartemp, entry_p->level); + sadd (&vartemp, " overwritten."); + warn = message (dico, spice_dstring_value(&vartemp)); + } + } + else + { + scopys( &vartemp, t) ; + sadd ( &vartemp, ": cannot redefine"); + /* suppress error message, resulting from multiple definition of + symbols (devices) in .model lines with same name, but in different subcircuits. + Subcircuit expansion is o.k., we have to deal with this numparam + behaviour later. (H. Vogt 090426) + */ + /*err = message (dico, v);*/ + } + } + spice_dstring_free(&vartemp) ; + return err; } bool @@ -531,37 +543,37 @@ defsubckt (tdico * dico, char *s, int w, char categ) to enter subcircuit (categ=U) and model (categ=O) names */ { - SPICE_DSTRING ustr ; /* temp user string */ - bool err; - int i, j, ls; - ls = length (s); - i = 0; + SPICE_DSTRING ustr ; /* temp user string */ + bool err; + int i, j, ls; + ls = length (s); + i = 0; - while ((i < ls) && (s[i] != '.')) - i++; /* skip 1st dotword */ + while ((i < ls) && (s[i] != '.')) + i++; /* skip 1st dotword */ - while ((i < ls) && (s[i] > ' ')) - i++; + while ((i < ls) && (s[i] > ' ')) + i++; - while ((i < ls) && (s[i] <= ' ')) - i++; /* skip blank */ + while ((i < ls) && (s[i] <= ' ')) + i++; /* skip blank */ - j = i; + j = i; - while ((j < ls) && (s[j] > ' ')) - j++; + while ((j < ls) && (s[j] > ' ')) + j++; - if ((j > i)) - { - spice_dstring_init(&ustr) ; - pscopy_up ( &ustr, s, i, j - i) ; - err = define (dico, spice_dstring_value(&ustr), ' ', categ, 0.0, w, NULL, NULL); - spice_dstring_free(&ustr) ; - } - else - err = message (dico, "Subcircuit or Model without name."); + if ((j > i)) + { + spice_dstring_init(&ustr) ; + pscopy_up ( &ustr, s, i, j - i) ; + err = define (dico, spice_dstring_value(&ustr), ' ', categ, 0.0, w, NULL, NULL); + spice_dstring_free(&ustr) ; + } + else + err = message (dico, "Subcircuit or Model without name."); - return err; + return err; } int @@ -570,86 +582,87 @@ findsubckt (tdico * dico, char *s, SPICE_DSTRINGPTR subname) returns 0 if not found, else the stored definition line number value and the name in string subname */ { - entry *entry_p ; /* symbol table entry */ - SPICE_DSTRING ustr ; /* u= subckt name is last token in string s */ - int j, k; - int line ; /* stored line number */ - spice_dstring_init(&ustr) ; - k = length (s); + entry *entry_p ; /* symbol table entry */ + SPICE_DSTRING ustr ; /* u= subckt name is last token in string s */ + int j, k; + int line ; /* stored line number */ + spice_dstring_init(&ustr) ; + k = length (s); - while ((k >= 0) && (s[k] <= ' ')) - k--; + while ((k >= 0) && (s[k] <= ' ')) + k--; - j = k; + j = k; - while ((k >= 0) && (s[k] > ' ')) - k--; + while ((k >= 0) && (s[k] > ' ')) + k--; - pscopy_up ( &ustr, s, k + 1, j - k) ; - entry_p = entrynb (dico, spice_dstring_value(&ustr) ) ; + pscopy_up ( &ustr, s, k + 1, j - k) ; + entry_p = entrynb (dico, spice_dstring_value(&ustr) ) ; - if ((entry_p) && ( entry_p->tp == 'U')) - { - line = entry_p->ivl; - scopyd ( subname, &ustr ) ; - } - else - { - line = 0; - spice_dstring_reinit(subname); - message (dico, "Cannot find subcircuit."); - } + if ((entry_p) && ( entry_p->tp == 'U')) + { + line = entry_p->ivl; + scopyd ( subname, &ustr ) ; + } + else + { + line = 0; + spice_dstring_reinit(subname); + message (dico, "Cannot find subcircuit."); + } - return line ; + return line ; } #if 0 /* unused, from the full macro language... */ static int deffuma ( /* define function or macro entry. */ - tdico * dico, char *t, char tpe, unsigned short bufstart, - unsigned char *pjumped, bool *perr) + tdico * dico, char *t, char tpe, unsigned short bufstart, + unsigned char *pjumped, bool *perr) { - unsigned char jumped = *pjumped; - bool err = *perr; -/* if not jumped, define new function or macro, returns index to buffferstart - if jumped, return index to existing function -*/ - int i, j; - Strbig (Llen, v); - i = attrib (dico, t, ' '); - j = 0; - if (i <= 0) + unsigned char jumped = *pjumped; + bool err = *perr; + /* if not jumped, define new function or macro, returns index to buffferstart + if jumped, return index to existing function + */ + int i, j; + Strbig (Llen, v); + i = attrib (dico, t, ' '); + j = 0; + if (i <= 0) { - err = message (dico, " Symbol table overflow"); + err = message (dico, " Symbol table overflow"); } - else + else { - if (dico->dat[i].tp != '?') - { /* old item! */ - if (jumped) + if (dico->dat[i].tp != '?') + { + /* old item! */ + if (jumped) { - j = dico->dat[i].ivl; + j = dico->dat[i].ivl; } - else + else { - scopy (v, t); - sadd (v, " already defined"); - err = message (dico, v); + scopy (v, t); + sadd (v, " already defined"); + err = message (dico, v); } } - else + else { - dico->dat[i].tp = tpe; - dico->nfms++; - j = dico->nfms; - dico->dat[i].ivl = j; - dico->fms[j].start = bufstart; + dico->dat[i].tp = tpe; + dico->nfms++; + j = dico->nfms; + dico->dat[i].ivl = j; + dico->fms[j].start = bufstart; /* =ibf->bufaddr = start addr in buffer */ ; } } - *pjumped = jumped; - *perr = err; - return j; + *pjumped = jumped; + *perr = err; + return j; } #endif @@ -658,254 +671,269 @@ deffuma ( /* define function or macro entry. */ static unsigned char keyword ( SPICE_DSTRINGPTR keys_p, SPICE_DSTRINGPTR tstr_p) { -/* return 0 if t not found in list keys, else the ordinal number */ - unsigned char i, j, k; - int lt, lk; - bool ok; - char *t ; - char *keys ; - lt = spice_dstring_length(tstr_p) ; - t = spice_dstring_value(tstr_p) ; - lk = spice_dstring_length (keys_p); - keys = spice_dstring_value(keys_p); - k = 0; - j = 0; + /* return 0 if t not found in list keys, else the ordinal number */ + unsigned char i, j, k; + int lt, lk; + bool ok; + char *t ; + char *keys ; + lt = spice_dstring_length(tstr_p) ; + t = spice_dstring_value(tstr_p) ; + lk = spice_dstring_length (keys_p); + keys = spice_dstring_value(keys_p); + k = 0; + j = 0; - do { - j++; - i = 0; - ok = 1; + do + { + j++; + i = 0; + ok = 1; - do { - i++; - k++; - ok = (k <= lk) && (t[i - 1] == keys[k - 1]); - } while (!((!ok) || (i >= lt))); - - if (ok) - ok = (k == lk) || (keys[k] <= ' '); - - if (!ok && (k < lk)) /* skip to next item */ - while ((k <= lk) && (keys[k - 1] > ' ')) + do + { + i++; k++; - } while (!(ok || (k >= lk))); + ok = (k <= lk) && (t[i - 1] == keys[k - 1]); + } + while (!((!ok) || (i >= lt))); - if (ok) - return j; - else - return 0; + if (ok) + ok = (k == lk) || (keys[k] <= ' '); + + if (!ok && (k < lk)) /* skip to next item */ + while ((k <= lk) && (keys[k - 1] > ' ')) + k++; + } + while (!(ok || (k >= lk))); + + if (ok) + return j; + else + return 0; } static double parseunit (double x, char *s) /* the Spice suffixes */ { - double u = 0; - SPICE_DSTRING t ; - bool isunit; - isunit = 1; - spice_dstring_init(&t) ; + double u = 0; + SPICE_DSTRING t ; + bool isunit; + isunit = 1; + spice_dstring_init(&t) ; - pscopy (&t, s, 0, 3); + pscopy (&t, s, 0, 3); - if (steq ( spice_dstring_value(&t), "MEG")) - u = 1e6; - else if (s[0] == 'G') - u = 1e9; - else if (s[0] == 'K') - u = 1e3; - else if (s[0] == 'M') - u = 0.001; - else if (s[0] == 'U') - u = 1e-6; - else if (s[0] == 'N') - u = 1e-9; - else if (s[0] == 'P') - u = 1e-12; - else if (s[0] == 'F') - u = 1e-15; - else - isunit = 0; + if (steq ( spice_dstring_value(&t), "MEG")) + u = 1e6; + else if (s[0] == 'G') + u = 1e9; + else if (s[0] == 'K') + u = 1e3; + else if (s[0] == 'M') + u = 0.001; + else if (s[0] == 'U') + u = 1e-6; + else if (s[0] == 'N') + u = 1e-9; + else if (s[0] == 'P') + u = 1e-12; + else if (s[0] == 'F') + u = 1e-15; + else + isunit = 0; - if (isunit) - x = x * u; + if (isunit) + x = x * u; - spice_dstring_free(&t) ; + spice_dstring_free(&t) ; - return x; + return x; } static int fetchid (char *s, SPICE_DSTRINGPTR t, int ls, int i) /* copy next identifier from s into t, advance and return scan index i */ { - char c; - bool ok; - c = s[i - 1]; + char c; + bool ok; + c = s[i - 1]; - while ((!alfa (c)) && (i < ls)) + while ((!alfa (c)) && (i < ls)) { - i++; - c = s[i - 1]; + i++; + c = s[i - 1]; } - spice_dstring_reinit(t) ; - cadd (t, upcase (c)); + spice_dstring_reinit(t) ; + cadd (t, upcase (c)); - do { - i++; - if (i <= ls) - c = s[i - 1]; - else - c = Nul; + do + { + i++; + if (i <= ls) + c = s[i - 1]; + else + c = Nul; - c = upcase (c); - ok = alfanum (c) || c == '.'; + c = upcase (c); + ok = alfanum (c) || c == '.'; - if (ok) - cadd (t, c); + if (ok) + cadd (t, c); - } while (ok); - return i /* return updated i */ ; + } + while (ok); + return i /* return updated i */ ; } static double exists (tdico * d, char *s, int *pi, bool *perror) /* check if s in simboltable 'defined': expect (ident) and return 0 or 1 */ { - bool error = *perror; - int i = *pi; - double x; - int ls; - char c; - bool ok; - SPICE_DSTRING t ; + bool error = *perror; + int i = *pi; + double x; + int ls; + char c; + bool ok; + SPICE_DSTRING t ; - ls = length (s); - spice_dstring_init(&t) ; - x = 0.0; + ls = length (s); + spice_dstring_init(&t) ; + x = 0.0; - do { - i++; - if (i > ls) - c = Nul; - else - c = s[i - 1]; - - ok = (c == '('); - } while (!(ok || (c == Nul))); - - if (ok) + do { - i = fetchid (s, &t, ls, i); - i--; - if (entrynb(d, spice_dstring_value(&t))) - x = 1.0; + i++; + if (i > ls) + c = Nul; + else + c = s[i - 1]; - do { - i++; - - if (i > ls) - c = Nul; - else - c = s[i - 1]; - - ok = (c == ')'); - } while (!(ok || (c == Nul))); + ok = (c == '('); } - if (!ok) - error = message (d, " Defined() syntax"); + while (!(ok || (c == Nul))); -/* keep pointer on last closing ")" */ + if (ok) + { + i = fetchid (s, &t, ls, i); + i--; + if (entrynb(d, spice_dstring_value(&t))) + x = 1.0; - *perror = error; - *pi = i; - spice_dstring_free(&t) ; - return x; + do + { + i++; + + if (i > ls) + c = Nul; + else + c = s[i - 1]; + + ok = (c == ')'); + } + while (!(ok || (c == Nul))); + } + if (!ok) + error = message (d, " Defined() syntax"); + + /* keep pointer on last closing ")" */ + + *perror = error; + *pi = i; + spice_dstring_free(&t) ; + return x; } static double fetchnumber (tdico * dico, char *s, int ls, int *pi, bool *perror) /* parse a Spice number in string s */ { - bool error = *perror; - int i = *pi; - int k, err; - char d; - char *t ; - SPICE_DSTRING tstr ; - SPICE_DSTRING vstr ; - double u; - spice_dstring_init(&tstr) ; - spice_dstring_init(&vstr) ; - k = i; + bool error = *perror; + int i = *pi; + int k, err; + char d; + char *t ; + SPICE_DSTRING tstr ; + SPICE_DSTRING vstr ; + double u; + spice_dstring_init(&tstr) ; + spice_dstring_init(&vstr) ; + k = i; - do { - k++; - if (k > ls) - d = (char)(0); - else - d = s[k - 1]; - } while (!(!((d == '.') || ((d >= '0') && (d <= '9'))))); - - if ((d == 'e') || (d == 'E')) - { /* exponent follows */ - k++; - d = s[k - 1]; - - if ((d == '+') || (d == '-')) + do + { k++; - - do { - k++; - if (k > ls) - d = (char)(0); - else - d = s[k - 1]; - } while (!(!((d >= '0') && (d <= '9')))); + if (k > ls) + d = (char)(0); + else + d = s[k - 1]; } + while (!(!((d == '.') || ((d >= '0') && (d <= '9'))))); - pscopy (&tstr, s, i-1, k - i) ; - - t = spice_dstring_value(&tstr) ; - if (t[0] == '.') - cins ( &tstr, '0'); - else if (t[length (t) - 1] == '.') - cadd (&tstr, '0'); - - t = spice_dstring_value(&tstr) ; - u = rval (t, &err); /* extract real value from string here */ - - if (err != 0) + if ((d == 'e') || (d == 'E')) { - scopys(&vstr, "Number format error: ") ; - sadd (&vstr, t); - error = message (dico, spice_dstring_value(&vstr)) ; - } - else - { - spice_dstring_reinit(&tstr); - while (alfa (d)) + /* exponent follows */ + k++; + d = s[k - 1]; + + if ((d == '+') || (d == '-')) + k++; + + do { - cadd (&tstr, upcase (d)); - k++; + k++; + if (k > ls) + d = (char)(0); + else + d = s[k - 1]; + } + while (!(!((d >= '0') && (d <= '9')))); + } - if (k > ls) - d = Nul; - else - d = s[k - 1]; + pscopy (&tstr, s, i-1, k - i) ; + + t = spice_dstring_value(&tstr) ; + if (t[0] == '.') + cins ( &tstr, '0'); + else if (t[length (t) - 1] == '.') + cadd (&tstr, '0'); + + t = spice_dstring_value(&tstr) ; + u = rval (t, &err); /* extract real value from string here */ + + if (err != 0) + { + scopys(&vstr, "Number format error: ") ; + sadd (&vstr, t); + error = message (dico, spice_dstring_value(&vstr)) ; + } + else + { + spice_dstring_reinit(&tstr); + while (alfa (d)) + { + cadd (&tstr, upcase (d)); + k++; + + if (k > ls) + d = Nul; + else + d = s[k - 1]; } - t = spice_dstring_value(&tstr) ; - u = parseunit (u, t); + t = spice_dstring_value(&tstr) ; + u = parseunit (u, t); } - i = k - 1; - *perror = error; - *pi = i; - spice_dstring_free(&tstr) ; - spice_dstring_free(&vstr) ; - return u; + i = k - 1; + *perror = error; + *pi = i; + spice_dstring_free(&tstr) ; + spice_dstring_free(&vstr) ; + return u; } static char @@ -918,108 +946,108 @@ fetchoperator (tdico * dico, each operator has: one-char alias, precedence level, new interpreter state. */ { - int i = *pi; - unsigned char state = *pstate; - unsigned char level = *plevel; - bool error = *perror; - char c, d; - SPICE_DSTRING vstr ; - c = s[i - 1]; - spice_dstring_init(&vstr) ; + int i = *pi; + unsigned char state = *pstate; + unsigned char level = *plevel; + bool error = *perror; + char c, d; + SPICE_DSTRING vstr ; + c = s[i - 1]; + spice_dstring_init(&vstr) ; - if (i < ls) - d = s[i]; - else - d = Nul; + if (i < ls) + d = s[i]; + else + d = Nul; - if ((c == '!') && (d == '=')) + if ((c == '!') && (d == '=')) { - c = '#'; - i++; + c = '#'; + i++; } - else if ((c == '<') && (d == '>')) + else if ((c == '<') && (d == '>')) { - c = '#'; - i++; + c = '#'; + i++; } - else if ((c == '<') && (d == '=')) + else if ((c == '<') && (d == '=')) { - c = 'L'; - i++; + c = 'L'; + i++; } - else if ((c == '>') && (d == '=')) + else if ((c == '>') && (d == '=')) { - c = 'G'; - i++; + c = 'G'; + i++; } - else if ((c == '*') && (d == '*')) + else if ((c == '*') && (d == '*')) { - c = '^'; - i++; + c = '^'; + i++; } - else if ((c == '=') && (d == '=')) + else if ((c == '=') && (d == '=')) { - i++; + i++; } - else if ((c == '&') && (d == '&')) + else if ((c == '&') && (d == '&')) { - i++; + i++; } - else if ((c == '|') && (d == '|')) + else if ((c == '|') && (d == '|')) { - i++; + i++; } - if ((c == '+') || (c == '-')) + if ((c == '+') || (c == '-')) { - state = 2; /* pending operator */ - level = 4; + state = 2; /* pending operator */ + level = 4; } - else if ((c == '*') || (c == '/') || (c == '%') || (c == '\\')) + else if ((c == '*') || (c == '/') || (c == '%') || (c == '\\')) { - state = 2; - level = 3; + state = 2; + level = 3; } - else if (c == '^') + else if (c == '^') { - state = 2; - level = 2; + state = 2; + level = 2; } - else if (cpos (c, "=<>#GL") >= 0) + else if (cpos (c, "=<>#GL") >= 0) { - state = 2; - level = 5; + state = 2; + level = 5; } - else if (c == '&') + else if (c == '&') { - state = 2; - level = 6; + state = 2; + level = 6; } - else if (c == '|') + else if (c == '|') { - state = 2; - level = 7; + state = 2; + level = 7; } - else if (c == '!') + else if (c == '!') { - state = 3; + state = 3; } - else + else { - state = 0; - if (c > ' ') + state = 0; + if (c > ' ') { - spice_dstring_append(&vstr, "Syntax error: letter [", -1 ); - cadd (&vstr, c); - cadd (&vstr, ']'); - error = message (dico, spice_dstring_value(&vstr) ); + spice_dstring_append(&vstr, "Syntax error: letter [", -1 ); + cadd (&vstr, c); + cadd (&vstr, ']'); + error = message (dico, spice_dstring_value(&vstr) ); } } - *pi = i; - *pstate = state; - *plevel = level; - *perror = error; - spice_dstring_free(&vstr) ; - return c; + *pi = i; + *pstate = state; + *plevel = level; + *perror = error; + spice_dstring_free(&vstr) ; + return c; } static char @@ -1029,504 +1057,516 @@ opfunctkey (tdico * dico, bool *perror) /* handle operator and built-in keywords */ { - unsigned char state = *pstate; - unsigned char level = *plevel; - bool error = *perror; -/*if kw operator keyword, c=token*/ - switch (kw) - { /* & | ~ DIV MOD Defined */ + unsigned char state = *pstate; + unsigned char level = *plevel; + bool error = *perror; + /*if kw operator keyword, c=token*/ + switch (kw) + { + /* & | ~ DIV MOD Defined */ case 1: - c = '&'; - state = 2; - level = 6; - break; + c = '&'; + state = 2; + level = 6; + break; case 2: - c = '|'; - state = 2; - level = 7; - break; + c = '|'; + state = 2; + level = 7; + break; case 3: - c = '!'; - state = 3; - level = 1; - break; + c = '!'; + state = 3; + level = 1; + break; case 4: - c = '\\'; - state = 2; - level = 3; - break; + c = '\\'; + state = 2; + level = 3; + break; case 5: - c = '%'; - state = 2; - level = 3; - break; + c = '%'; + state = 2; + level = 3; + break; case Defd: - c = '?'; - state = 1; - level = 0; - break; + c = '?'; + state = 1; + level = 0; + break; default: - state = 0; - error = message (dico, " Unexpected Keyword"); - break; + state = 0; + error = message (dico, " Unexpected Keyword"); + break; } /* case */ - *pstate = state; - *plevel = level; - *perror = error; - return c; + *pstate = state; + *plevel = level; + *perror = error; + return c; } static double operate (char op, double x, double y) { -/* execute operator op on a pair of reals */ -/* bug: x:=x op y or simply x:=y for empty op? No error signalling! */ - double u = 1.0; - double z = 0.0; - double epsi = 1e-30; - double t; - switch (op) + /* execute operator op on a pair of reals */ + /* bug: x:=x op y or simply x:=y for empty op? No error signalling! */ + double u = 1.0; + double z = 0.0; + double epsi = 1e-30; + double t; + switch (op) { case ' ': - x = y; /* problem here: do type conversions ?! */ ; - break; + x = y; /* problem here: do type conversions ?! */ ; + break; case '+': - x = x + y; - break; + x = x + y; + break; case '-': - x = x - y; - break; + x = x - y; + break; case '*': - x = x * y; - break; + x = x * y; + break; case '/': - if (absf (y) > epsi) + if (absf (y) > epsi) x = x / y; - break; + break; case '^': /* power */ - t = absf (x); - if (t < epsi) - x = z; - else - x = exp (y * ln (t)); - break; + t = absf (x); + if (t < epsi) + x = z; + else + x = exp (y * ln (t)); + break; case '&': /* && */ - if (y < x) - x = y; /*=Min*/ ; - break; + if (y < x) + x = y; /*=Min*/ ; + break; case '|': /* || */ - if (y > x) - x = y; /*=Max*/ ; - break; + if (y > x) + x = y; /*=Max*/ ; + break; case '=': - if (x == y) - x = u; - else - x = z; - break; + if (x == y) + x = u; + else + x = z; + break; case '#': /* <> */ - if (x != y) - x = u; - else - x = z; - break; + if (x != y) + x = u; + else + x = z; + break; case '>': - if (x > y) - x = u; - else - x = z; - break; + if (x > y) + x = u; + else + x = z; + break; case '<': - if (x < y) - x = u; - else - x = z; - break; + if (x < y) + x = u; + else + x = z; + break; case 'G': /* >= */ - if (x >= y) - x = u; - else - x = z; - break; + if (x >= y) + x = u; + else + x = z; + break; case 'L': /* <= */ - if (x <= y) - x = u; - else - x = z; - break; + if (x <= y) + x = u; + else + x = z; + break; case '!': /* ! */ - if (y == z) - x = u; - else - x = z; - break; + if (y == z) + x = u; + else + x = z; + break; case '%': /* % */ - t = np_trunc (x / y); - x = x - y * t; - break; + t = np_trunc (x / y); + x = x - y * t; + break; case '\\': /* / */ - x = np_trunc (absf (x / y)); - break; + x = np_trunc (absf (x / y)); + break; } /* case */ - return x; + return x; } static double formula (tdico * dico, char *s, bool *perror) { -/* Expression parser. - s is a formula with parentheses and math ops +-* / ... - State machine and an array of accumulators handle operator precedence. - Parentheses handled by recursion. - Empty expression is forbidden: must find at least 1 atom. - Syntax error if no toggle between binoperator && (unop/state1) ! - States : 1=atom, 2=binOp, 3=unOp, 4= stop-codon. - Allowed transitions: 1->2->(3,1) and 3->(3,1). -*/ - typedef enum {nprece=9} _nnprece; /* maximal nb of precedence levels */ - bool error = *perror; - bool negate = 0; - unsigned char state, oldstate, topop, ustack, level, kw, fu; - double u = 0.0, v, w = 0.0; - double accu[nprece + 1]; - char oper[nprece + 1]; - char uop[nprece + 1]; - int i, k, ls, natom, arg2, arg3; - char c, d; - bool ok; - SPICE_DSTRING tstr ; + /* Expression parser. + s is a formula with parentheses and math ops +-* / ... + State machine and an array of accumulators handle operator precedence. + Parentheses handled by recursion. + Empty expression is forbidden: must find at least 1 atom. + Syntax error if no toggle between binoperator && (unop/state1) ! + States : 1=atom, 2=binOp, 3=unOp, 4= stop-codon. + Allowed transitions: 1->2->(3,1) and 3->(3,1). + */ + typedef enum {nprece=9} _nnprece; /* maximal nb of precedence levels */ + bool error = *perror; + bool negate = 0; + unsigned char state, oldstate, topop, ustack, level, kw, fu; + double u = 0.0, v, w = 0.0; + double accu[nprece + 1]; + char oper[nprece + 1]; + char uop[nprece + 1]; + int i, k, ls, natom, arg2, arg3; + char c, d; + bool ok; + SPICE_DSTRING tstr ; - spice_dstring_init(&tstr) ; - for (i = 0; i <= nprece; i++) + spice_dstring_init(&tstr) ; + for (i = 0; i <= nprece; i++) { - accu[i] = 0.0; - oper[i] = ' '; + accu[i] = 0.0; + oper[i] = ' '; } - i = 0; - ls = length (s); + i = 0; + ls = length (s); - while ((ls > 0) && (s[ls - 1] <= ' ')) - ls--; /* clean s */ + while ((ls > 0) && (s[ls - 1] <= ' ')) + ls--; /* clean s */ - state = 0; - natom = 0; - ustack = 0; - topop = 0; - oldstate = 0; - fu = 0; - error = 0; - level = 0; + state = 0; + natom = 0; + ustack = 0; + topop = 0; + oldstate = 0; + fu = 0; + error = 0; + level = 0; - while ((i < ls) && (!error)) + while ((i < ls) && (!error)) { - i++; - c = s[i - 1]; - if (c == '(') - { /* sub-formula or math function */ - level = 1; - /* new: must support multi-arg functions */ - k = i; - arg2 = 0; - v = 1.0; - arg3 = 0; + i++; + c = s[i - 1]; + if (c == '(') + { + /* sub-formula or math function */ + level = 1; + /* new: must support multi-arg functions */ + k = i; + arg2 = 0; + v = 1.0; + arg3 = 0; - do { - k++; - if (k > ls) - d = (char)(0); - else - d = s[k - 1]; + do + { + k++; + if (k > ls) + d = (char)(0); + else + d = s[k - 1]; - if (d == '(') - level++; - else if (d == ')') - level--; + if (d == '(') + level++; + else if (d == ')') + level--; - if ((d == ',') && (level == 1)) + if ((d == ',') && (level == 1)) { - if (arg2 == 0) - arg2 = k; - else - arg3 = k; /* kludge for more than 2 args (ternary expression) */ + if (arg2 == 0) + arg2 = k; + else + arg3 = k; /* kludge for more than 2 args (ternary expression) */ } /* comma list? */ ; } - while (!((k > ls) || ((d == ')') && (level <= 0)))); + while (!((k > ls) || ((d == ')') && (level <= 0)))); - if (k > ls) + if (k > ls) { - error = message (dico, "Closing \")\" not found."); - natom++; /* shut up other error message */ ; + error = message (dico, "Closing \")\" not found."); + natom++; /* shut up other error message */ ; } - else + else { - if (arg2 > i) + if (arg2 > i) { - pscopy (&tstr, s, i, arg2 - i - 1); - v = formula (dico, spice_dstring_value(&tstr), &error); - i = arg2; + pscopy (&tstr, s, i, arg2 - i - 1); + v = formula (dico, spice_dstring_value(&tstr), &error); + i = arg2; } - if (arg3 > i) + if (arg3 > i) { - pscopy (&tstr, s, i, arg3 - i - 1); - w = formula (dico, spice_dstring_value(&tstr), &error); - i = arg3; + pscopy (&tstr, s, i, arg3 - i - 1); + w = formula (dico, spice_dstring_value(&tstr), &error); + i = arg3; } - pscopy (&tstr, s, i, k - i - 1); - u = formula (dico, spice_dstring_value(&tstr), &error); - state = 1; /* atom */ - if (fu > 0) + pscopy (&tstr, s, i, k - i - 1); + u = formula (dico, spice_dstring_value(&tstr), &error); + state = 1; /* atom */ + if (fu > 0) { - if ((fu == 18)) - u = ternary_fcn ((int) v, w, u); - else if ((fu == 20)) - u = agauss (v, w, u); - else if ((fu == 22)) - u = gauss (v, w, u); - else if ((fu == 23)) - u = unif (v, u); - else if ((fu == 24)) - u = aunif (v, u); - else if ((fu == 25)) - u = limit (v, u); - else - u = mathfunction (fu, v, u); + if ((fu == 18)) + u = ternary_fcn ((int) v, w, u); + else if ((fu == 20)) + u = agauss (v, w, u); + else if ((fu == 22)) + u = gauss (v, w, u); + else if ((fu == 23)) + u = unif (v, u); + else if ((fu == 24)) + u = aunif (v, u); + else if ((fu == 25)) + u = limit (v, u); + else + u = mathfunction (fu, v, u); } } - i = k; - fu = 0; + i = k; + fu = 0; } - else if (alfa (c)) + else if (alfa (c)) { - i = fetchid (s, &tstr, ls, i); /* user id, but sort out keywords */ - state = 1; - i--; - kw = keyword (&keyS, &tstr); /* debug ws('[',kw,']'); */ - if (kw == 0) + i = fetchid (s, &tstr, ls, i); /* user id, but sort out keywords */ + state = 1; + i--; + kw = keyword (&keyS, &tstr); /* debug ws('[',kw,']'); */ + if (kw == 0) { - fu = keyword (&fmathS, &tstr); /* numeric function? */ - if (fu == 0) - u = fetchnumentry (dico, spice_dstring_value(&tstr), &error); - else - state = 0; /* state==0 means: ignore for the moment */ + fu = keyword (&fmathS, &tstr); /* numeric function? */ + if (fu == 0) + u = fetchnumentry (dico, spice_dstring_value(&tstr), &error); + else + state = 0; /* state==0 means: ignore for the moment */ } - else - c = opfunctkey (dico, kw, c, &state, &level, &error); + else + c = opfunctkey (dico, kw, c, &state, &level, &error); - if (kw == Defd) - u = exists (dico, s, &i, &error); + if (kw == Defd) + u = exists (dico, s, &i, &error); } - else if (((c == '.') || ((c >= '0') && (c <= '9')))) + else if (((c == '.') || ((c >= '0') && (c <= '9')))) { - u = fetchnumber (dico, s, ls, &i, &error); - if (negate) + u = fetchnumber (dico, s, ls, &i, &error); + if (negate) { - u = -1 * u; - negate = 0; + u = -1 * u; + negate = 0; } - state = 1; + state = 1; } - else - c = fetchoperator (dico, s, ls, &i, &state, &level, &error); - /* may change c to some other operator char! */ - /* control chars <' ' ignored */ + else + c = fetchoperator (dico, s, ls, &i, &state, &level, &error); + /* may change c to some other operator char! */ + /* control chars <' ' ignored */ - ok = (oldstate == 0) || (state == 0) || - ((oldstate == 1) && (state == 2)) || ((oldstate != 1) - && (state != 2)); - if (oldstate == 2 && state == 2 && c == '-') + ok = (oldstate == 0) || (state == 0) || + ((oldstate == 1) && (state == 2)) || ((oldstate != 1) + && (state != 2)); + if (oldstate == 2 && state == 2 && c == '-') { - ok = 1; - negate = 1; - continue; + ok = 1; + negate = 1; + continue; } - if (!ok) - error = message (dico, " Misplaced operator"); + if (!ok) + error = message (dico, " Misplaced operator"); - if (state == 3) - { /* push unary operator */ - ustack++; - uop[ustack] = c; + if (state == 3) + { + /* push unary operator */ + ustack++; + uop[ustack] = c; } - else if (state == 1) - { /* atom pending */ - natom++; - if (i >= ls) + else if (state == 1) + { + /* atom pending */ + natom++; + if (i >= ls) { - state = 4; - level = topop; + state = 4; + level = topop; } /* close all ops below */ - for (k = ustack; k >= 1; k--) - u = operate (uop[k], u, u); + for (k = ustack; k >= 1; k--) + u = operate (uop[k], u, u); - ustack = 0; - accu[0] = u; /* done: all pending unary operators */ ; + ustack = 0; + accu[0] = u; /* done: all pending unary operators */ ; } - if ((state == 2) || (state == 4)) + if ((state == 2) || (state == 4)) { - /* do pending binaries of priority Upto "level" */ - for (k = 1; k <= level; k++) - { /* not yet speed optimized! */ - accu[k] = operate (oper[k], accu[k], accu[k - 1]); - accu[k - 1] = 0.0; - oper[k] = ' '; /* reset intermediates */ ; + /* do pending binaries of priority Upto "level" */ + for (k = 1; k <= level; k++) + { + /* not yet speed optimized! */ + accu[k] = operate (oper[k], accu[k], accu[k - 1]); + accu[k - 1] = 0.0; + oper[k] = ' '; /* reset intermediates */ ; } - oper[level] = c; + oper[level] = c; - if (level > topop) - topop = level; + if (level > topop) + topop = level; } - if ((state > 0)) + if ((state > 0)) { - oldstate = state; + oldstate = state; } } /* while */ ; - if ((natom == 0) || (oldstate != 4)) + if ((natom == 0) || (oldstate != 4)) { - spice_dstring_reinit(&tstr) ; - sadd( &tstr, " Expression err: "); - sadd (&tstr, s); - error = message (dico, spice_dstring_value(&tstr)); + spice_dstring_reinit(&tstr) ; + sadd( &tstr, " Expression err: "); + sadd (&tstr, s); + error = message (dico, spice_dstring_value(&tstr)); } - if (negate == 1) + if (negate == 1) { - error = - message (dico, - " Problem with formula eval -- wrongly determined negation!"); + error = + message (dico, + " Problem with formula eval -- wrongly determined negation!"); } - *perror = error; + *perror = error; - spice_dstring_free(&tstr) ; + spice_dstring_free(&tstr) ; - if (error) - return 1.0; - else - return accu[topop]; + if (error) + return 1.0; + else + return accu[topop]; } /* formula */ static char fmttype (double x) { -/* I=integer, P=fixedpoint, F=floatpoint */ -/* find out the "natural" type of format for number x */ - double ax, dx; - int rx; - bool isint, astronomic; - ax = absf (x); - isint = 0; - astronomic = 0; + /* I=integer, P=fixedpoint, F=floatpoint */ + /* find out the "natural" type of format for number x */ + double ax, dx; + int rx; + bool isint, astronomic; + ax = absf (x); + isint = 0; + astronomic = 0; - if (ax < 1e-39) /* smaller then 1e-39 is 0 */ - isint = 1; /* and seen as an integer */ - else if (ax < 64000) - { /* detect integers */ - rx = np_round (x); - dx = (x - rx) / ax; - isint = (absf (dx) < 1e-06); + if (ax < 1e-39) /* smaller then 1e-39 is 0 */ + isint = 1; /* and seen as an integer */ + else if (ax < 64000) + { + /* detect integers */ + rx = np_round (x); + dx = (x - rx) / ax; + isint = (absf (dx) < 1e-06); } - if (!isint) - astronomic = (ax >= 1e+06) || (ax < 0.01); /* astronomic for 10 digits */ + if (!isint) + astronomic = (ax >= 1e+06) || (ax < 0.01); /* astronomic for 10 digits */ - if (isint) - return 'I'; - else if (astronomic) - return 'F'; - else - return 'P'; + if (isint) + return 'I'; + else if (astronomic) + return 'F'; + else + return 'P'; } static bool evaluate (tdico * dico, SPICE_DSTRINGPTR qstr_p, char *t, unsigned char mode) { -/* transform t to result q. mode 0: expression, mode 1: simple variable */ - double u = 0.0; - int j, lq; - char dt, fmt; - entry *entry_p ; - bool numeric, done, nolookup; - bool err; - SPICE_DSTRING vstr ; + /* transform t to result q. mode 0: expression, mode 1: simple variable */ + double u = 0.0; + int j, lq; + char dt, fmt; + entry *entry_p ; + bool numeric, done, nolookup; + bool err; + SPICE_DSTRING vstr ; - spice_dstring_init(&vstr) ; - spice_dstring_reinit(qstr_p) ; - numeric = 0; - err = 0; + spice_dstring_init(&vstr) ; + spice_dstring_reinit(qstr_p) ; + numeric = 0; + err = 0; - if (mode == 1) - { /* string? */ - stupcase (t); - entry_p = entrynb (dico, t); - nolookup = (!(entry_p)); - while ((entry_p) && (entry_p->tp == 'P')){ - entry_p = entry_p->pointer ; /* follow pointer chain */ - } - - /* pointer chain */ - if (entry_p) - dt = entry_p->tp; - else - dt = ' '; - - /* data type: Real or String */ - if (dt == 'R') - { - u = entry_p->vl; - numeric = 1; - } - else if (dt == 'S') - { /* suppose source text "..." at */ - j = entry_p->ivl; - lq = 0; - do { - j++; - lq++; - dt = /* ibf->bf[j]; */ entry_p->sbbase[j]; - - if (cpos ('3', spice_dstring_value(&dico->option)) <= 0) - dt = upcase (dt); /* spice-2 */ - - done = (dt == '\"') || (dt < ' ') || (lq > 99); - - if (!done) - cadd (qstr_p, dt); - } while (!(done)); - } - - if (!(entry_p)) - { - spice_dstring_reinit(&vstr) ; - cadd (&vstr, '\"'); - sadd (&vstr, t); - sadd (&vstr, "\" not evaluated. "); - - if (nolookup) - sadd (&vstr, "Lookup failure."); - - err = message (dico, spice_dstring_value(&vstr)); - } - } - else + if (mode == 1) { - u = formula (dico, t, &err); - numeric = 1; - } - if (numeric) - { - fmt = fmttype (u); - if (fmt == 'I') - stri (np_round (u), qstr_p); - else + /* string? */ + stupcase (t); + entry_p = entrynb (dico, t); + nolookup = (!(entry_p)); + while ((entry_p) && (entry_p->tp == 'P')) { - strf (u, 17, 10, qstr_p); + entry_p = entry_p->pointer ; /* follow pointer chain */ + } + + /* pointer chain */ + if (entry_p) + dt = entry_p->tp; + else + dt = ' '; + + /* data type: Real or String */ + if (dt == 'R') + { + u = entry_p->vl; + numeric = 1; + } + else if (dt == 'S') + { + /* suppose source text "..." at */ + j = entry_p->ivl; + lq = 0; + do + { + j++; + lq++; + dt = /* ibf->bf[j]; */ entry_p->sbbase[j]; + + if (cpos ('3', spice_dstring_value(&dico->option)) <= 0) + dt = upcase (dt); /* spice-2 */ + + done = (dt == '\"') || (dt < ' ') || (lq > 99); + + if (!done) + cadd (qstr_p, dt); + } + while (!(done)); + } + + if (!(entry_p)) + { + spice_dstring_reinit(&vstr) ; + cadd (&vstr, '\"'); + sadd (&vstr, t); + sadd (&vstr, "\" not evaluated. "); + + if (nolookup) + sadd (&vstr, "Lookup failure."); + + err = message (dico, spice_dstring_value(&vstr)); } } - spice_dstring_free(&vstr) ; - return err; + else + { + u = formula (dico, t, &err); + numeric = 1; + } + if (numeric) + { + fmt = fmttype (u); + if (fmt == 'I') + stri (np_round (u), qstr_p); + else + { + strf (u, 17, 10, qstr_p); + } + } + spice_dstring_free(&vstr) ; + return err; } #if 0 @@ -1534,169 +1574,178 @@ static bool scanline (tdico * dico, char *s, char *r, bool err) /* scan host code line s for macro substitution. r=result line */ { - int i, k, ls, level, nd, nnest; - bool spice3; - char c, d; - Strbig (Llen, q); - Strbig (Llen, t); - Str (20, u); - spice3 = cpos ('3', dico->option) > 0; /* we had -3 on the command line */ - i = 0; - ls = length (s); - scopy (r, ""); - err = 0; - pscopy (u, s, 1, 3); - if ((ls > 7) && steq (u, "**&")) - { /* special Comment **&AC #... */ - pscopy (r, s, 1, 7); - i = 7; - } - while ((i < ls) && (!err)) + int i, k, ls, level, nd, nnest; + bool spice3; + char c, d; + Strbig (Llen, q); + Strbig (Llen, t); + Str (20, u); + spice3 = cpos ('3', dico->option) > 0; /* we had -3 on the command line */ + i = 0; + ls = length (s); + scopy (r, ""); + err = 0; + pscopy (u, s, 1, 3); + if ((ls > 7) && steq (u, "**&")) { - i++; - c = s[i - 1]; - if (c == Pspice) - { /* try pspice expression syntax */ - k = i; - nnest = 1; - do - { - k++; - d = s[k - 1]; - if (d == '{') - { - nnest++; - } - else if (d == '}') - { - nnest--; - } - } - while (!((nnest == 0) || (d == 0))); - if (d == 0) - { - err = message (dico, "Closing \"}\" not found."); - } - else - { - pscopy (t, s, i + 1, k - i - 1); - if( dico->hspice_compatibility && (strcasecmp(t,"LAST")==0) ) { - strcpy(q,"last") ; - err=0; - } else - err = evaluate (dico, q, t, 0); - } - i = k; - if (!err) - { /* insert number */ - sadd (r, q); - } - else - { - err = message (dico, s); - } - } - else if (c == Intro) + /* special Comment **&AC #... */ + pscopy (r, s, 1, 7); + i = 7; + } + while ((i < ls) && (!err)) + { + i++; + c = s[i - 1]; + if (c == Pspice) { - Inc (i); - while ((i < ls) && (s[i - 1] <= ' ')) - i++; - k = i; - if (s[k - 1] == '(') - { /* sub-formula */ - level = 1; - do - { - k++; - if (k > ls) - { - d = chr (0); - } - else - { - d = s[k - 1]; - } - if (d == '(') - { - level++; - } - else if (d == ')') - { - level--; - } - } - while (!((k > ls) || ((d == ')') && (level <= 0)))); - if (k > ls) - { - err = message (dico, "Closing \")\" not found."); - } - else - { - pscopy (t, s, i + 1, k - i - 1); - err = evaluate (dico, q, t, 0); - } - i = k; - } - else - { /* simple identifier may also be string */ - do - { - k++; - if (k > ls) - { - d = chr (0); - } - else - { - d = s[k - 1]; - } - } - while (!((k > ls) || (d <= ' '))); - pscopy (t, s, i, k - i); - err = evaluate (dico, q, t, 1); - i = k - 1; - } - if (!err) - { /* insert the number */ - sadd (r, q); - } - else + /* try pspice expression syntax */ + k = i; + nnest = 1; + do { - message (dico, s); + k++; + d = s[k - 1]; + if (d == '{') + { + nnest++; + } + else if (d == '}') + { + nnest--; + } + } + while (!((nnest == 0) || (d == 0))); + if (d == 0) + { + err = message (dico, "Closing \"}\" not found."); + } + else + { + pscopy (t, s, i + 1, k - i - 1); + if( dico->hspice_compatibility && (strcasecmp(t,"LAST")==0) ) + { + strcpy(q,"last") ; + err=0; + } + else + err = evaluate (dico, q, t, 0); + } + i = k; + if (!err) + { + /* insert number */ + sadd (r, q); + } + else + { + err = message (dico, s); } } - else if (c == Nodekey) - { /* follows: a node keyword */ - do + else if (c == Intro) + { + Inc (i); + while ((i < ls) && (s[i - 1] <= ' ')) + i++; + k = i; + if (s[k - 1] == '(') { - i++; + /* sub-formula */ + level = 1; + do + { + k++; + if (k > ls) + { + d = chr (0); + } + else + { + d = s[k - 1]; + } + if (d == '(') + { + level++; + } + else if (d == ')') + { + level--; + } + } + while (!((k > ls) || ((d == ')') && (level <= 0)))); + if (k > ls) + { + err = message (dico, "Closing \")\" not found."); + } + else + { + pscopy (t, s, i + 1, k - i - 1); + err = evaluate (dico, q, t, 0); + } + i = k; } - while (!(s[i - 1] > ' ')); - k = i; - do + else { - k++; + /* simple identifier may also be string */ + do + { + k++; + if (k > ls) + { + d = chr (0); + } + else + { + d = s[k - 1]; + } + } + while (!((k > ls) || (d <= ' '))); + pscopy (t, s, i, k - i); + err = evaluate (dico, q, t, 1); + i = k - 1; } - while (!((k > ls) || !alfanum (s[k - 1]))); - pscopy (q, s, i, k - i); - nd = parsenode (Addr (dico->nodetab), q); - if (!spice3) + if (!err) { - stri (nd, q); + /* insert the number */ + sadd (r, q); + } + else + { + message (dico, s); + } + } + else if (c == Nodekey) + { + /* follows: a node keyword */ + do + { + i++; + } + while (!(s[i - 1] > ' ')); + k = i; + do + { + k++; + } + while (!((k > ls) || !alfanum (s[k - 1]))); + pscopy (q, s, i, k - i); + nd = parsenode (Addr (dico->nodetab), q); + if (!spice3) + { + stri (nd, q); } /* substitute by number */ - sadd (r, q); - i = k - 1; + sadd (r, q); + i = k - 1; } - else + else { - if (!spice3) + if (!spice3) { - c = upcase (c); + c = upcase (c); } - cadd (r, c); /* c<>Intro */ ; + cadd (r, c); /* c<>Intro */ ; } } /* while */ - return err; + return err; } #endif @@ -1708,154 +1757,166 @@ compactfloatnb (SPICE_DSTRINGPTR vstr_p) /* erase superfluous 000 digit streams before E */ /* bug: truncating, no rounding */ { - int n, k, m, lex, lem; - char *expov ; - char *expnv ; - char *v_p ; - SPICE_DSTRING expo_str ; - SPICE_DSTRING expn_str ; + int n, k, m, lex, lem; + char *expov ; + char *expnv ; + char *v_p ; + SPICE_DSTRING expo_str ; + SPICE_DSTRING expn_str ; - spice_dstring_init(&expo_str) ; - spice_dstring_init(&expn_str) ; - n = cpos ('E', spice_dstring_value(vstr_p)) ; /* if too long, try to delete digits */ - if (n<0) n = cpos ('e', spice_dstring_value(vstr_p)); + spice_dstring_init(&expo_str) ; + spice_dstring_init(&expn_str) ; + n = cpos ('E', spice_dstring_value(vstr_p)) ; /* if too long, try to delete digits */ + if (n<0) n = cpos ('e', spice_dstring_value(vstr_p)); - if (n >= 0) { - pscopy (&expo_str, spice_dstring_value(vstr_p), n, - spice_dstring_length(vstr_p)); - lex = spice_dstring_length (&expo_str) ; - if (lex > 4) { /* exponent only 2 digits */ - pscopy (&expn_str, spice_dstring_value(&expo_str), 1, 4); - expnv = spice_dstring_value(&expn_str) ; - if (atoi(expnv) < -99){ - spice_dstring_reinit(&expo_str) ; - sadd(&expo_str, "e-099"); /* brutal */ - } - if (atoi(expnv) > +99){ - spice_dstring_reinit(&expo_str) ; - sadd(&expo_str, "e+099"); - } - expov = spice_dstring_value(&expo_str) ; - expov[2] = expov[3]; - expov[3] = expov[4]; - expov[4] = '\0'; - spice_dstring_setlength(&expo_str,4) ; - lex = 4; + if (n >= 0) + { + pscopy (&expo_str, spice_dstring_value(vstr_p), n, + spice_dstring_length(vstr_p)); + lex = spice_dstring_length (&expo_str) ; + if (lex > 4) /* exponent only 2 digits */ + { + pscopy (&expn_str, spice_dstring_value(&expo_str), 1, 4); + expnv = spice_dstring_value(&expn_str) ; + if (atoi(expnv) < -99) + { + spice_dstring_reinit(&expo_str) ; + sadd(&expo_str, "e-099"); /* brutal */ + } + if (atoi(expnv) > +99) + { + spice_dstring_reinit(&expo_str) ; + sadd(&expo_str, "e+099"); + } + expov = spice_dstring_value(&expo_str) ; + expov[2] = expov[3]; + expov[3] = expov[4]; + expov[4] = '\0'; + spice_dstring_setlength(&expo_str,4) ; + lex = 4; + } + k = n ; /* mantissa is 0...k */ + + m = MAX_STRING_INSERT; + v_p = spice_dstring_value(vstr_p) ; + while (v_p[m] != ' ') + m--; + m++; + while ((v_p[k] == '0') && (v_p[k - 1] == '0')) + k--; + + lem = k - m; + + if ((lem + lex) > ACT_CHARACTS) + lem = ACT_CHARACTS - lex; + + pscopy (vstr_p, spice_dstring_value(vstr_p), m, lem); + if (cpos('.', spice_dstring_value(vstr_p)) >= 0) + { + while (lem < ACT_CHARACTS - 4) + { + cadd(vstr_p, '0'); + lem++; + } + } + else + { + cadd(vstr_p, '.'); + lem++; + while (lem < ACT_CHARACTS - 4) + { + cadd(vstr_p, '0'); + lem++; + } + } + sadd (vstr_p, spice_dstring_value(&expo_str) ); } - k = n ; /* mantissa is 0...k */ + else + { + m = 0; + v_p = spice_dstring_value(vstr_p) ; + while (v_p[m] == ' ') + m++; - m = MAX_STRING_INSERT; - v_p = spice_dstring_value(vstr_p) ; - while (v_p[m] != ' ') - m--; - m++; - while ((v_p[k] == '0') && (v_p[k - 1] == '0')) - k--; - - lem = k - m; - - if ((lem + lex) > ACT_CHARACTS) - lem = ACT_CHARACTS - lex; - - pscopy (vstr_p, spice_dstring_value(vstr_p), m, lem); - if (cpos('.', spice_dstring_value(vstr_p)) >= 0) { - while (lem < ACT_CHARACTS - 4) { - cadd(vstr_p, '0'); - lem++; - } - } else { - cadd(vstr_p, '.'); - lem++; - while (lem < ACT_CHARACTS - 4) { - cadd(vstr_p, '0'); - lem++; - } + lem = spice_dstring_length(vstr_p) - m; + if (lem > ACT_CHARACTS) lem = ACT_CHARACTS; + pscopy (vstr_p, spice_dstring_value(vstr_p), m, lem); } - sadd (vstr_p, spice_dstring_value(&expo_str) ); - } else { - m = 0; - v_p = spice_dstring_value(vstr_p) ; - while (v_p[m] == ' ') - m++; - - lem = spice_dstring_length(vstr_p) - m; - if (lem > ACT_CHARACTS) lem = ACT_CHARACTS; - pscopy (vstr_p, spice_dstring_value(vstr_p), m, lem); - } } static int insertnumber (tdico * dico, int i, char *s, SPICE_DSTRINGPTR ustr_p) /* insert u in string s in place of the next placeholder number */ { - SPICE_DSTRING vstr ; /* dynamic string */ - SPICE_DSTRING mstr ; /* dynamic string */ - char *v_p ; /* value of vstr dyna string */ - bool found; - int ls, k; - long long accu; - ls = length (s); + SPICE_DSTRING vstr ; /* dynamic string */ + SPICE_DSTRING mstr ; /* dynamic string */ + char *v_p ; /* value of vstr dyna string */ + bool found; + int ls, k; + long long accu; + ls = length (s); - spice_dstring_init(&vstr) ; - spice_dstring_init(&mstr) ; - scopyd (&vstr, ustr_p) ; - compactfloatnb (&vstr) ; + spice_dstring_init(&vstr) ; + spice_dstring_init(&mstr) ; + scopyd (&vstr, ustr_p) ; + compactfloatnb (&vstr) ; - while ( spice_dstring_length (&vstr) < MAX_STRING_INSERT) - cadd (&vstr, ' '); + while ( spice_dstring_length (&vstr) < MAX_STRING_INSERT) + cadd (&vstr, ' '); - if ( spice_dstring_length (&vstr) > MAX_STRING_INSERT) + if ( spice_dstring_length (&vstr) > MAX_STRING_INSERT) { - spice_dstring_append( &mstr, " insertnumber fails: ", -1); - sadd (&mstr, spice_dstring_value(ustr_p)); - message (dico, spice_dstring_value(&mstr)) ; + spice_dstring_append( &mstr, " insertnumber fails: ", -1); + sadd (&mstr, spice_dstring_value(ustr_p)); + message (dico, spice_dstring_value(&mstr)) ; } - found = 0; + found = 0; - while ((!found) && (i < ls)) + while ((!found) && (i < ls)) { - found = (s[i] == '1'); - k = 0; - accu = 0; + found = (s[i] == '1'); + k = 0; + accu = 0; - while (found && (k < 15)) - { /* parse a 15-digit number */ - found = num (s[i + k]); - - if (found) - accu = 10 * accu + s[i + k] - '0'; - - k++; - } - - if (found) + while (found && (k < 15)) { - accu = accu - 100000000000000LL; /* plausibility test */ + found = num (s[i + k]); - found = (accu > 0) && (accu < dynsubst + 1); /* dynsubst numbers have been allocated */ + if (found) + accu = 10 * accu + s[i + k] - '0'; + + k++; } - i++; + + if (found) + { + accu = accu - 100000000000000LL; /* plausibility test */ + + found = (accu > 0) && (accu < dynsubst + 1); /* dynsubst numbers have been allocated */ + } + i++; } - if (found) - { /* substitute at i-1 ongoing */ - i--; - v_p = spice_dstring_value(&vstr) ; - for (k = 0; k < ACT_CHARACTS; k++) - s[i + k] = v_p[k]; - - i = i + MAX_STRING_INSERT; - - } - else + if (found) { - i = ls; - fprintf (stderr, "xpressn.c--insertnumber: i=%d s=%s u=%s\n", i, s, - spice_dstring_value(ustr_p)) ; - message (dico, "insertnumber: missing slot "); + /* substitute at i-1 ongoing */ + i--; + v_p = spice_dstring_value(&vstr) ; + for (k = 0; k < ACT_CHARACTS; k++) + s[i + k] = v_p[k]; + + i = i + MAX_STRING_INSERT; + } - return i; + else + { + i = ls; + fprintf (stderr, "xpressn.c--insertnumber: i=%d s=%s u=%s\n", i, s, + spice_dstring_value(ustr_p)) ; + message (dico, "insertnumber: missing slot "); + } + return i; } bool @@ -1866,154 +1927,167 @@ nupa_substitute (tdico * dico, char *s, char *r, bool err) bug: wont flag overflow! */ { - int i, k, ls, level, nnest, ir; - char c, d; - SPICE_DSTRING qstr ; /* temp result dynamic string */ - SPICE_DSTRING tstr ; /* temp dynamic string */ + int i, k, ls, level, nnest, ir; + char c, d; + SPICE_DSTRING qstr ; /* temp result dynamic string */ + SPICE_DSTRING tstr ; /* temp dynamic string */ - spice_dstring_init(&qstr) ; - spice_dstring_init(&tstr) ; - i = 0; - ls = length (s); - err = 0; - ir = 0; + spice_dstring_init(&qstr) ; + spice_dstring_init(&tstr) ; + i = 0; + ls = length (s); + err = 0; + ir = 0; - while ((i < ls) && (!err)) + while ((i < ls) && (!err)) { - i++; - c = s[i - 1]; + i++; + c = s[i - 1]; - if (c == Pspice) - { /* try pspice expression syntax */ - k = i; - nnest = 1; - do { - k++; - d = s[k - 1]; - if (d == '{') - nnest++; - else if (d == '}') - nnest--; - } while (!((nnest == 0) || (d == 0))); - - if (d == 0) - err = message (dico, "Closing \"}\" not found."); - else - { - pscopy (&tstr, s, i , k - i - 1); - /* exeption made for .meas */ - if( strcasecmp( spice_dstring_value(&tstr),"LAST")==0) { - spice_dstring_reinit(&qstr) ; - sadd(&qstr,"last") ; - err=0; - } else - err = evaluate (dico, &qstr, spice_dstring_value(&tstr), 0); - } - - i = k; - if (!err) - ir = insertnumber (dico, ir, r, &qstr) ; - else - err = message (dico, "Cannot compute substitute"); - } - else if (c == Intro) + if (c == Pspice) { - /* skip "&&" which may occur in B source */ - if ((i + 1 < ls) && (s[i] == Intro)) { + /* try pspice expression syntax */ + k = i; + nnest = 1; + do + { + k++; + d = s[k - 1]; + if (d == '{') + nnest++; + else if (d == '}') + nnest--; + } + while (!((nnest == 0) || (d == 0))); + + if (d == 0) + err = message (dico, "Closing \"}\" not found."); + else + { + pscopy (&tstr, s, i , k - i - 1); + /* exeption made for .meas */ + if( strcasecmp( spice_dstring_value(&tstr),"LAST")==0) + { + spice_dstring_reinit(&qstr) ; + sadd(&qstr,"last") ; + err=0; + } + else + err = evaluate (dico, &qstr, spice_dstring_value(&tstr), 0); + } + + i = k; + if (!err) + ir = insertnumber (dico, ir, r, &qstr) ; + else + err = message (dico, "Cannot compute substitute"); + } + else if (c == Intro) + { + /* skip "&&" which may occur in B source */ + if ((i + 1 < ls) && (s[i] == Intro)) + { i++; continue; } - i++; - while ((i < ls) && (s[i - 1] <= ' ')) i++; + while ((i < ls) && (s[i - 1] <= ' ')) + i++; - k = i; + k = i; - if (s[k - 1] == '(') - { /* sub-formula */ - level = 1; - do { - k++; - if (k > ls) - d = (char)(0); - else - d = s[k - 1]; - - if (d == '(') - level++; - else if (d == ')') - level--; - } while (!((k > ls) || ((d == ')') && (level <= 0)))); - - if (k > ls) - err = message (dico, "Closing \")\" not found."); - else + if (s[k - 1] == '(') + { + /* sub-formula */ + level = 1; + do { - pscopy (&tstr, s, i, k - i - 1); - err = evaluate (dico, &qstr, spice_dstring_value(&tstr), 0); + k++; + if (k > ls) + d = (char)(0); + else + d = s[k - 1]; + + if (d == '(') + level++; + else if (d == ')') + level--; } - i = k; - } - else - { /* simple identifier may also be string? */ - do { - k++; - if (k > ls) - d = (char)(0); - else - d = s[k - 1]; - } while (!((k > ls) || (d <= ' '))); + while (!((k > ls) || ((d == ')') && (level <= 0)))); - pscopy (&tstr, s, i-1, k - i); - err = evaluate (dico, &qstr, spice_dstring_value(&tstr), 1); - i = k - 1; + if (k > ls) + err = message (dico, "Closing \")\" not found."); + else + { + pscopy (&tstr, s, i, k - i - 1); + err = evaluate (dico, &qstr, spice_dstring_value(&tstr), 0); + } + i = k; + } + else + { + /* simple identifier may also be string? */ + do + { + k++; + if (k > ls) + d = (char)(0); + else + d = s[k - 1]; + } + while (!((k > ls) || (d <= ' '))); + + pscopy (&tstr, s, i-1, k - i); + err = evaluate (dico, &qstr, spice_dstring_value(&tstr), 1); + i = k - 1; } - if (!err) - ir = insertnumber (dico, ir, r, &qstr); - else - message (dico, "Cannot compute &(expression)"); + if (!err) + ir = insertnumber (dico, ir, r, &qstr); + else + message (dico, "Cannot compute &(expression)"); } - } - /* while */ - spice_dstring_free(&qstr) ; - spice_dstring_free(&tstr) ; - return err; + } + /* while */ + spice_dstring_free(&qstr) ; + spice_dstring_free(&tstr) ; + return err; } static unsigned char getword (char *s, SPICE_DSTRINGPTR tstr_p, int after, int *pi) /* isolate a word from s after position "after". return i= last read+1 */ { - int i = *pi; - int ls; - unsigned char key; - char *t_p ; - i = after; - ls = length (s); + int i = *pi; + int ls; + unsigned char key; + char *t_p ; + i = after; + ls = length (s); - do + do { - i++; - } while (!((i >= ls) || alfa (s[i - 1]))); + i++; + } + while (!((i >= ls) || alfa (s[i - 1]))); - spice_dstring_reinit(tstr_p) ; + spice_dstring_reinit(tstr_p) ; - while ((i <= ls) && (alfa (s[i - 1]) || num (s[i - 1]))) + while ((i <= ls) && (alfa (s[i - 1]) || num (s[i - 1]))) { - cadd (tstr_p, upcase (s[i - 1])); - i++; + cadd (tstr_p, upcase (s[i - 1])); + i++; } - t_p = spice_dstring_value(tstr_p) ; - if (t_p[0]) - key = keyword (&keyS, tstr_p); - else - key = 0; + t_p = spice_dstring_value(tstr_p) ; + if (t_p[0]) + key = keyword (&keyS, tstr_p); + else + key = 0; - *pi = i; - return key; + *pi = i; + return key; } static char @@ -2023,81 +2097,89 @@ getexpress (char *s, SPICE_DSTRINGPTR tstr_p, int *pi) returns tpe=='R' if ( numeric, 'S' if ( string only */ { - int i = *pi; - int ia, ls, level; - char c, d, tpe; - bool comment = 0; - ls = length (s); - ia = i + 1; + int i = *pi; + int ia, ls, level; + char c, d, tpe; + bool comment = 0; + ls = length (s); + ia = i + 1; - while ((ia < ls) && (s[ia - 1] <= ' ')) - ia++; /*white space ? */ + while ((ia < ls) && (s[ia - 1] <= ' ')) + ia++; /*white space ? */ - if (s[ia - 1] == '"') - { /* string constant */ - ia++; - i = ia; + if (s[ia - 1] == '"') + { + /* string constant */ + ia++; + i = ia; - while ((i < ls) && (s[i - 1] != '"')) - i++; + while ((i < ls) && (s[i - 1] != '"')) + i++; - tpe = 'S'; + tpe = 'S'; - do { - i++; - } while (!((i > ls) || (s[i - 1] > ' '))); + do + { + i++; + } + while (!((i > ls) || (s[i - 1] > ' '))); } - else + else { - if (s[ia - 1] == '{') - ia++; + if (s[ia - 1] == '{') + ia++; - i = ia - 1; + i = ia - 1; - do { - i++; + do + { + i++; - if (i > ls) - c = ';'; - else - c = s[i - 1]; + if (i > ls) + c = ';'; + else + c = s[i - 1]; - if (c == '(') - { /* sub-formula */ - level = 1; - do { - i++; + if (c == '(') + { + /* sub-formula */ + level = 1; + do + { + i++; - if (i > ls) - d = Nul; - else - d = s[i - 1]; + if (i > ls) + d = Nul; + else + d = s[i - 1]; - if (d == '(') - level++; - else if (d == ')') - level--; - } while (!((i > ls) || ((d == ')') && (level <= 0)))); + if (d == '(') + level++; + else if (d == ')') + level--; + } + while (!((i > ls) || ((d == ')') && (level <= 0)))); } - /* buggy? */ if ((c == '/') || (c == '-')) - comment = (s[i] == c); - } while (!((cpos (c, ",;)}") >= 0) || comment)); /* legal separators */ + /* buggy? */ if ((c == '/') || (c == '-')) + comment = (s[i] == c); + } + while (!((cpos (c, ",;)}") >= 0) || comment)); /* legal separators */ - tpe = 'R'; + tpe = 'R'; } - pscopy (tstr_p, s, ia-1, i - ia); + pscopy (tstr_p, s, ia-1, i - ia); - if (s[i - 1] == '}') - i++; + if (s[i - 1] == '}') + i++; - if (tpe == 'S') - i++; /* beyond quote */ + if (tpe == 'S') + i++; /* beyond quote */ - *pi = i; - return tpe; + *pi = i; + return tpe; } bool @@ -2108,82 +2190,84 @@ nupa_assignment (tdico * dico, char *s, char mode) bug: we cannot rely on the transformed line, must re-parse everything! */ { -/* s has the format: ident = expression; ident= expression ... */ - int i, j, ls; - unsigned char key; - bool error, err; - char dtype; - int wval = 0; - double rval = 0.0; - char *t_p ; /* dstring contents value */ - SPICE_DSTRING tstr ; /* temporary dstring */ - SPICE_DSTRING ustr ; /* temporary dstring */ - spice_dstring_init(&tstr) ; - spice_dstring_init(&ustr) ; - ls = length (s); - error = 0; - i = 0; - j = spos_ ("//", s); /* stop before comment if any */ + /* s has the format: ident = expression; ident= expression ... */ + int i, j, ls; + unsigned char key; + bool error, err; + char dtype; + int wval = 0; + double rval = 0.0; + char *t_p ; /* dstring contents value */ + SPICE_DSTRING tstr ; /* temporary dstring */ + SPICE_DSTRING ustr ; /* temporary dstring */ + spice_dstring_init(&tstr) ; + spice_dstring_init(&ustr) ; + ls = length (s); + error = 0; + i = 0; + j = spos_ ("//", s); /* stop before comment if any */ - if (j >= 0) - ls = j ; - /* bug: doesnt work. need to revise getexpress ... !!! */ - i = 0; + if (j >= 0) + ls = j ; + /* bug: doesnt work. need to revise getexpress ... !!! */ + i = 0; - while ((i < ls) && (s[i] <= ' ')) - i++; - - if (s[i] == Intro) - i++; - - if (s[i] == '.') - { /* skip any dot keyword */ - while (s[i] > ' ') + while ((i < ls) && (s[i] <= ' ')) i++; + + if (s[i] == Intro) + i++; + + if (s[i] == '.') + { + /* skip any dot keyword */ + while (s[i] > ' ') + i++; } - while ((i < ls) && (!error)) + while ((i < ls) && (!error)) { - key = getword (s, &tstr, i, &i); - t_p = spice_dstring_value(&tstr) ; - if ((t_p[0] == 0) || (key > 0)) - error = message (dico, " Identifier expected"); + key = getword (s, &tstr, i, &i); + t_p = spice_dstring_value(&tstr) ; + if ((t_p[0] == 0) || (key > 0)) + error = message (dico, " Identifier expected"); - if (!error) - { /* assignment expressions */ - while ((i <= ls) && (s[i - 1] != '=')) - i++; + if (!error) + { + /* assignment expressions */ + while ((i <= ls) && (s[i - 1] != '=')) + i++; - if (i > ls) - error = message (dico, " = sign expected ."); + if (i > ls) + error = message (dico, " = sign expected ."); - dtype = getexpress (s, &ustr, &i); + dtype = getexpress (s, &ustr, &i); - if (dtype == 'R') + if (dtype == 'R') { - rval = formula (dico, spice_dstring_value(&ustr), &error); - if (error) + rval = formula (dico, spice_dstring_value(&ustr), &error); + if (error) { - message (dico, " Formula() error."); - fprintf (stderr, " %s\n", s); + message (dico, " Formula() error."); + fprintf (stderr, " %s\n", s); } } - else if (dtype == 'S') - wval = i; + else if (dtype == 'S') + wval = i; - err = define (dico, spice_dstring_value(&tstr), mode /* was ' ' */ , - dtype, rval, wval, NULL, NULL); - error = error || err; + err = define (dico, spice_dstring_value(&tstr), mode /* was ' ' */ , + dtype, rval, wval, NULL, NULL); + error = error || err; } - if ((i < ls) && (s[i - 1] != ';')) - error = message (dico, " ; sign expected."); - /* else - i++; */ + if ((i < ls) && (s[i - 1] != ';')) + error = message (dico, " ; sign expected."); + /* else + i++; */ } - spice_dstring_free(&tstr) ; - spice_dstring_free(&ustr) ; - return error; + spice_dstring_free(&tstr) ; + spice_dstring_free(&ustr) ; + return error; } bool @@ -2192,230 +2276,241 @@ nupa_subcktcall (tdico * dico, char *s, char *x, bool err) x= a matching subckt call line, with actual params */ { - int n, m, i, j, k, g, h, narg = 0, ls, nest; - SPICE_DSTRING subname ; - SPICE_DSTRING tstr ; - SPICE_DSTRING ustr ; - SPICE_DSTRING vstr ; - SPICE_DSTRING idlist ; - SPICE_DSTRING parsebuf ; - char *buf, *token; - char *t_p ; - char *u_p ; - bool found; - spice_dstring_init(&subname) ; - spice_dstring_init(&tstr) ; - spice_dstring_init(&ustr) ; - spice_dstring_init(&vstr) ; - spice_dstring_init(&idlist) ; - /* - skip over instance name -- fixes bug where instance 'x1' is - same name as subckt 'x1' - */ - while (*x != ' ') - x++; + int n, m, i, j, k, g, h, narg = 0, ls, nest; + SPICE_DSTRING subname ; + SPICE_DSTRING tstr ; + SPICE_DSTRING ustr ; + SPICE_DSTRING vstr ; + SPICE_DSTRING idlist ; + SPICE_DSTRING parsebuf ; + char *buf, *token; + char *t_p ; + char *u_p ; + bool found; + spice_dstring_init(&subname) ; + spice_dstring_init(&tstr) ; + spice_dstring_init(&ustr) ; + spice_dstring_init(&vstr) ; + spice_dstring_init(&idlist) ; + /* + skip over instance name -- fixes bug where instance 'x1' is + same name as subckt 'x1' + */ + while (*x != ' ') + x++; - /***** first, analyze the subckt definition line */ - n = 0; /* number of parameters if any */ - ls = length (s); - j = spos_ ("//", s); + /***** first, analyze the subckt definition line */ + n = 0; /* number of parameters if any */ + ls = length (s); + j = spos_ ("//", s); - if (j >= 0) - pscopy_up (&tstr, s, 0, j ); - else - scopy_up (&tstr, s); + if (j >= 0) + pscopy_up (&tstr, s, 0, j ); + else + scopy_up (&tstr, s); - j = spos_ ("SUBCKT", spice_dstring_value(&tstr) ) ; + j = spos_ ("SUBCKT", spice_dstring_value(&tstr) ) ; - if (j >= 0) + if (j >= 0) { - j = j + 6; /* fetch its name - skip subckt */ - t_p = spice_dstring_value(&tstr) ; - while ((j < ls) && (t_p[j] <= ' ')) - j++; - - while (t_p[j] != ' ') - { - cadd (&subname, t_p[j]); - j++; - } - } - else - err = message (dico, " ! a subckt line!"); - - i = spos_ ("PARAMS:", spice_dstring_value(&tstr)); - - if (i >= 0) - { - pscopy (&tstr, spice_dstring_value(&tstr), i + 7, spice_dstring_length (&tstr)); - while (j = cpos ('=', spice_dstring_value(&tstr)), j >= 0) - { /* isolate idents to the left of =-signs */ - k = j - 1; - t_p = spice_dstring_value(&tstr) ; - while ((k >= 0) && (t_p[k] <= ' ')) - k--; - - h = k; - - while ((h >= 0) && alfanum (t_p[h])) - h--; - - if (alfa (t_p[h + 1]) && (k > h)) - { /* we have some id */ - for (m = (h + 1); m <= k; m++) - cadd (&idlist, t_p[m]); - - sadd (&idlist, "=$;"); - n++; - } - else - message (dico, "identifier expected."); - - /* It is j+1 to skip over the '=' */ - pscopy (&tstr, spice_dstring_value(&tstr), j+1, spice_dstring_length (&tstr)); - } - } - /***** next, analyze the circuit call line */ - if (!err) - { - narg = 0; - j = spos_ ("//", x); - - if (j >= 0) - pscopy_up ( &tstr, x, 0, j ); - else { - scopy_up (&tstr, x); - j = 0 ; - } - - ls = spice_dstring_length (&tstr); - - spice_dstring_init(&parsebuf) ; - scopyd(&parsebuf, &tstr) ; - buf = spice_dstring_value(&parsebuf) ; - - found = 0; - token = strtok(buf, " "); /* a bit more exact - but not sufficient everytime */ - j = j + (int) strlen(token) + 1; - if (strcmp(token, spice_dstring_value(&subname))) { - while ((token = strtok(NULL, " ")) != NULL) { - if (!strcmp(token, spice_dstring_value(&subname))) { - found = 1; - break; - } - j = j + (int) strlen(token) + 1; - } - } - spice_dstring_free(&parsebuf) ; - - /* make sure that subname followed by space */ - if (found) - { - j = j + spice_dstring_length (&subname) + 1; /* 1st position of arglist: j */ - - t_p = spice_dstring_value(&tstr) ; - while ((j < ls) && ((t_p[j] <= ' ') || (t_p[j] == ','))) + j = j + 6; /* fetch its name - skip subckt */ + t_p = spice_dstring_value(&tstr) ; + while ((j < ls) && (t_p[j] <= ' ')) j++; - while (j < ls) - { /* try to fetch valid arguments */ - k = j; - spice_dstring_reinit(&ustr) ; - if ((t_p[k] == Intro)) - { /* handle historical syntax... */ - if (alfa (t_p[k + 1])) - k++; - else if (t_p[k + 1] == '(') - { /* transform to braces... */ - k++; - t_p[k] = '{'; - g = k; - nest = 1; - while ((nest > 0) && (g < ls)) + while (t_p[j] != ' ') + { + cadd (&subname, t_p[j]); + j++; + } + } + else + err = message (dico, " ! a subckt line!"); + + i = spos_ ("PARAMS:", spice_dstring_value(&tstr)); + + if (i >= 0) + { + pscopy (&tstr, spice_dstring_value(&tstr), i + 7, spice_dstring_length (&tstr)); + while (j = cpos ('=', spice_dstring_value(&tstr)), j >= 0) + { + /* isolate idents to the left of =-signs */ + k = j - 1; + t_p = spice_dstring_value(&tstr) ; + while ((k >= 0) && (t_p[k] <= ' ')) + k--; + + h = k; + + while ((h >= 0) && alfanum (t_p[h])) + h--; + + if (alfa (t_p[h + 1]) && (k > h)) + { + /* we have some id */ + for (m = (h + 1); m <= k; m++) + cadd (&idlist, t_p[m]); + + sadd (&idlist, "=$;"); + n++; + } + else + message (dico, "identifier expected."); + + /* It is j+1 to skip over the '=' */ + pscopy (&tstr, spice_dstring_value(&tstr), j+1, spice_dstring_length (&tstr)); + } + } + /***** next, analyze the circuit call line */ + if (!err) + { + narg = 0; + j = spos_ ("//", x); + + if (j >= 0) + pscopy_up ( &tstr, x, 0, j ); + else + { + scopy_up (&tstr, x); + j = 0 ; + } + + ls = spice_dstring_length (&tstr); + + spice_dstring_init(&parsebuf) ; + scopyd(&parsebuf, &tstr) ; + buf = spice_dstring_value(&parsebuf) ; + + found = 0; + token = strtok(buf, " "); /* a bit more exact - but not sufficient everytime */ + j = j + (int) strlen(token) + 1; + if (strcmp(token, spice_dstring_value(&subname))) + { + while ((token = strtok(NULL, " ")) != NULL) + { + if (!strcmp(token, spice_dstring_value(&subname))) + { + found = 1; + break; + } + j = j + (int) strlen(token) + 1; + } + } + spice_dstring_free(&parsebuf) ; + + /* make sure that subname followed by space */ + if (found) + { + j = j + spice_dstring_length (&subname) + 1; /* 1st position of arglist: j */ + + t_p = spice_dstring_value(&tstr) ; + while ((j < ls) && ((t_p[j] <= ' ') || (t_p[j] == ','))) + j++; + + while (j < ls) + { + /* try to fetch valid arguments */ + k = j; + spice_dstring_reinit(&ustr) ; + if ((t_p[k] == Intro)) + { + /* handle historical syntax... */ + if (alfa (t_p[k + 1])) + k++; + else if (t_p[k + 1] == '(') + { + /* transform to braces... */ + k++; + t_p[k] = '{'; + g = k; + nest = 1; + while ((nest > 0) && (g < ls)) { - g++; - if (t_p[g] == '(') - nest++; - else if (t_p[g] == ')') - nest--; + g++; + if (t_p[g] == '(') + nest++; + else if (t_p[g] == ')') + nest--; } - if ((g < ls) && (nest == 0)) - t_p[g] = '}'; + if ((g < ls) && (nest == 0)) + t_p[g] = '}'; } } - if (alfanum (t_p[k]) || t_p[k] == '.') - { /* number, identifier */ - h = k; - while (t_p[k] > ' ') - k++; + if (alfanum (t_p[k]) || t_p[k] == '.') + { + /* number, identifier */ + h = k; + while (t_p[k] > ' ') + k++; - pscopy (&ustr, spice_dstring_value(&tstr), h, k - h); - j = k; + pscopy (&ustr, spice_dstring_value(&tstr), h, k - h); + j = k; } - else if (t_p[k] == '{') + else if (t_p[k] == '{') { - getexpress ( spice_dstring_value(&tstr), &ustr, &j); - j--; /* confusion: j was in Turbo Pascal convention */ ; + getexpress ( spice_dstring_value(&tstr), &ustr, &j); + j--; /* confusion: j was in Turbo Pascal convention */ ; } - else + else { - j++; - if (t_p[k] > ' ') + j++; + if (t_p[k] > ' ') { - spice_dstring_append(&vstr, "Subckt call, symbol ",-1) ; - cadd (&vstr, t_p[k]); - sadd (&vstr, " not understood"); - message (dico, spice_dstring_value(&vstr) ) ; + spice_dstring_append(&vstr, "Subckt call, symbol ",-1) ; + cadd (&vstr, t_p[k]); + sadd (&vstr, " not understood"); + message (dico, spice_dstring_value(&vstr) ) ; } } - u_p = spice_dstring_value(&ustr) ; - if (u_p[0]) + u_p = spice_dstring_value(&ustr) ; + if (u_p[0]) { - narg++; - k = cpos ('$', spice_dstring_value(&idlist)) ; + narg++; + k = cpos ('$', spice_dstring_value(&idlist)) ; - if (k >= 0) - { /* replace dollar with expression string u */ - pscopy (&vstr, spice_dstring_value(&idlist), 0, k); - sadd ( &vstr, spice_dstring_value(&ustr)) ; - pscopy (&ustr, spice_dstring_value(&idlist), k+1, spice_dstring_length (&idlist)); - scopyd (&idlist, &vstr); - sadd (&idlist, spice_dstring_value(&ustr)); + if (k >= 0) + { + /* replace dollar with expression string u */ + pscopy (&vstr, spice_dstring_value(&idlist), 0, k); + sadd ( &vstr, spice_dstring_value(&ustr)) ; + pscopy (&ustr, spice_dstring_value(&idlist), k+1, spice_dstring_length (&idlist)); + scopyd (&idlist, &vstr); + sadd (&idlist, spice_dstring_value(&ustr)); } } } } - else - message (dico, "Cannot find called subcircuit"); + else + message (dico, "Cannot find called subcircuit"); } - /***** finally, execute the multi-assignment line */ - dicostack (dico, Push); /* create local symbol scope */ - if (narg != n) + /***** finally, execute the multi-assignment line */ + dicostack (dico, Push); /* create local symbol scope */ + if (narg != n) { - scopys(&tstr, " Mismatch: "); - nadd (&tstr, n); - sadd (&tstr, " formal but "); - nadd (&tstr, narg); - sadd (&tstr, " actual params."); - err = message (dico, spice_dstring_value(&tstr)); - message (dico, spice_dstring_value(&idlist)); - /* ;} else { debugwarn(dico, idlist) */ ; + scopys(&tstr, " Mismatch: "); + nadd (&tstr, n); + sadd (&tstr, " formal but "); + nadd (&tstr, narg); + sadd (&tstr, " actual params."); + err = message (dico, spice_dstring_value(&tstr)); + message (dico, spice_dstring_value(&idlist)); + /* ;} else { debugwarn(dico, idlist) */ ; } - err = nupa_assignment (dico, spice_dstring_value(&idlist), 'N'); + err = nupa_assignment (dico, spice_dstring_value(&idlist), 'N'); - spice_dstring_free(&subname) ; - spice_dstring_free(&tstr) ; - spice_dstring_free(&ustr) ; - spice_dstring_free(&vstr) ; - spice_dstring_free(&idlist) ; - return err; + spice_dstring_free(&subname) ; + spice_dstring_free(&tstr) ; + spice_dstring_free(&ustr) ; + spice_dstring_free(&vstr) ; + spice_dstring_free(&idlist) ; + return err; } void nupa_subcktexit (tdico * dico) { - dicostack (dico, Pop); + dicostack (dico, Pop); }