From 3a319212f332e03c10a27d67d712a4784ced8d09 Mon Sep 17 00:00:00 2001 From: h_vogt Date: Sun, 15 Mar 2009 15:08:04 +0000 Subject: [PATCH] numparam dynamic memory allocation, part 1 --- ChangeLog | 5 + src/frontend/inpcom.c | 12 +- src/frontend/numparam/numparam.h | 34 ++- src/frontend/numparam/spicenum.c | 388 ++++++++++-------------- src/frontend/numparam/xpressn.c | 487 ++++++++++++++----------------- 5 files changed, 414 insertions(+), 512 deletions(-) diff --git a/ChangeLog b/ChangeLog index f3b3e1d9d..385521eb7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2009-03-15 Holger Vogt + * cktfinddev.c: some (optical) cleanup + * numparam.h, xpressn.c, spicenum.c, inpcom.c: dynamic memory + allocation for numparam (the easier part) + 2009-03-08 Holger Vogt * dctran.c no printout of 'Initial transient solution' if .options noacct is set diff --git a/src/frontend/inpcom.c b/src/frontend/inpcom.c index 78cb7c312..4aedf993b 100644 --- a/src/frontend/inpcom.c +++ b/src/frontend/inpcom.c @@ -92,9 +92,9 @@ static int num_parameters[1000]; /* Collect information for dynamic allocation of numparam arrays */ /* number of lines in input deck */ -int dynmaxline; /* inpcom.c 1524 */ +int dynmaxline; /* inpcom.c 1529 */ /* max. line length in input deck */ -int dynnLen; /* inpcom.c 1526 */ +int dynLlen; /* inpcom.c 1526 */ /* number of lines in deck after expansion */ int dynMaxckt = 0; /* subckt.c 307 */ /* number of parameter substitutions */ @@ -1524,11 +1524,11 @@ inp_readall(FILE *fp, struct line **data, int call_depth, char *dir_name) /* get max. line length and number of lines in input deck*/ dynmaxline = 0; - dynnLen = 0; + dynLlen = 0; for(tmp_ptr1 = cc; tmp_ptr1 != NULL; tmp_ptr1 = tmp_ptr1->li_next) { dynmaxline++; - if (dynnLen < strlen(tmp_ptr1->li_line)) - dynnLen = strlen(tmp_ptr1->li_line); + if (dynLlen < strlen(tmp_ptr1->li_line)) + dynLlen = strlen(tmp_ptr1->li_line); } #if defined(TRACE) || defined(OUTDECK) /*debug: print into file*/ @@ -1537,7 +1537,7 @@ inp_readall(FILE *fp, struct line **data, int call_depth, char *dir_name) fprintf(fdo, "%s\n", tmp_ptr1->li_line); ; (void) fclose(fdo); - fprintf(stdout, "lLen %d, maxline %d\n", dynnLen, dynmaxline); + fprintf(stdout, "lLen %d, maxline %d\n", dynLlen, dynmaxline); #endif return; diff --git a/src/frontend/numparam/numparam.h b/src/frontend/numparam/numparam.h index 4346a307a..114754166 100644 --- a/src/frontend/numparam/numparam.h +++ b/src/frontend/numparam/numparam.h @@ -17,7 +17,8 @@ typedef enum {Nodekey='#'} _nNodekey; /* Introduces node symbol */ typedef enum {Intro='&'} _nIntro; /* Introduces preprocessor tokens */ typedef enum {Comment='*'} _nComment; /* Spice Comment lines*/ typedef enum {Pspice='{'} _nPspice; /* Pspice expression */ -typedef enum {Maxdico=40000} _nMaxdico; /* Size of symbol table*/ +//typedef enum {Maxdico=40000} _nMaxdico; /* Size of symbol table*/ +typedef enum {Defd=15} _nDefd; /* serial numb. of 'defined' keyword. The others are not used (yet) */ /* Composite line length This used to be 250 characters, but this is too easy to exceed with a @@ -29,8 +30,8 @@ typedef enum {Llen=40000} _nLlen; typedef char str50 [54]; typedef char str80 [84]; -typedef enum {Maxline=70000} _nMaxline; /* Size of initial unexpanded circuit code */ -typedef enum {Maxckt=40000} _nMaxckt; /* Size of expanded circuit code */ +//typedef enum {Maxline=70000} _nMaxline; /* Size of initial unexpanded circuit code */ +//typedef enum {Maxckt=40000} _nMaxckt; /* Size of expanded circuit code */ typedef char * auxtable; /* dummy */ @@ -53,7 +54,8 @@ typedef struct _ttdico { str80 srcfile; /* last piece of source file name */ int srcline; int errcount; - entry dat[Maxdico+1]; +// entry dat[Maxdico+1]; + entry* dyndat; int nbd; /* number of data entries */ fumas fms[101]; int nfms; /* number of functions & macros */ @@ -62,18 +64,20 @@ typedef struct _ttdico { int tos; /* top of stack index for symbol mark/release mechanics */ str80 option; /* one-character translator options */ auxtable nodetab; - char * refptr[Maxline]; /* pointers to source code lines */ - char category[Maxline]; /* category of each line */ +// char * refptr[Maxline]; /* pointers to source code lines */ + char **dynrefptr; +// char category[Maxline]; /* category of each line */ + char *dyncategory; } tdico; void initdico(tdico * dico); - int donedico(tdico * dico); - unsigned char defsubckt( tdico *dico, char * s, int w, char categ); - int findsubckt( tdico *dico, char * s, char * subname); - unsigned char nupa_substitute( tdico *dico, char * s, char * r, unsigned char err); - unsigned char nupa_assignment( tdico *dico, char * s, char mode); - unsigned char nupa_subcktcall( tdico *dico, char * s, char * x, unsigned char err); +int donedico(tdico * dico); +unsigned char defsubckt( tdico *dico, char * s, int w, char categ); +int findsubckt( tdico *dico, char * s, char * subname); +unsigned char nupa_substitute( tdico *dico, char * s, char * r, unsigned char err); +unsigned char nupa_assignment( tdico *dico, char * s, char mode); +unsigned char nupa_subcktcall( tdico *dico, char * s, char * x, unsigned char err); void nupa_subcktexit( tdico *dico); - tdico * nupa_fetchinstance(void); - char getidtype( tdico *d, char * s); - int attrib( tdico *dico, char * t, char op ); +tdico * nupa_fetchinstance(void); +char getidtype( tdico *d, char * s); +int attrib( tdico *dico, char * t, char op ); diff --git a/src/frontend/numparam/spicenum.c b/src/frontend/numparam/spicenum.c index 6a95c9f0b..7cb2c648c 100644 --- a/src/frontend/numparam/spicenum.c +++ b/src/frontend/numparam/spicenum.c @@ -32,7 +32,14 @@ extern void txfree (void *ptr); char *nupa_inst_name; static tdico *inst_dico; -extern long dynsubst; /* inpcom.c */ +/* number of parameter substitutions, available only after the substitution */ +extern long dynsubst; /* spicenum.c:144 */ + +/* number of lines in input deck */ +extern int dynmaxline; /* inpcom.c:1529 */ + +/* max. line length in input deck */ +int dynLlen; /* inpcom.c:1531 */ /* Uncomment this line to allow debug tracing */ /* #define TRACE_NUMPARAMS */ @@ -60,49 +67,11 @@ extern long dynsubst; /* inpcom.c */ #define PlaceHold 1000000000L static long placeholder = 0; -#ifdef NOT_REQUIRED /* SJB - not required as front-end now does stripping */ -static int -stripcomment (char *s) -/* allow end-of-line comments in Spice, like C++ */ -{ - int i, ls; - char c, d; - unsigned char stop; - ls = length (s); - c = ' '; - i = 0; - stop = 0; - - while ((i < ls) && !stop) - { - d = c; - i++; - c = s[i - 1]; - stop = (c == d) && ((c == '/') || (c == '-')); - /* comments after // or -- */ ; - } - if (stop) - { - i = i - 2; /*last valid character before Comment */ - while ((i > 0) && (s[i - 1] <= ' ')) - i--; /*strip blank space */ - - if (i <= 0) - scopy (s, ""); - else - pscopy (s, s, 1, i); - } - else - i = -1; - - return i /* i>=0 if comment stripped at that position */ ; -} -#endif /* NOT_REQUIRED */ static void stripsomespace (char *s, unsigned char incontrol) { -/* iff s starts with one of some markers, strip leading space */ +/* if s starts with one of some markers, strip leading space */ Str (12, markers); int i, ls; scopy (markers, "*.&+#$"); @@ -120,106 +89,60 @@ stripsomespace (char *s, unsigned char incontrol) } -#if 0 /* unused? */ -void -partition (char *t) -/* t is a list val=expr val=expr .... Insert Lf-& before any val= */ -/* the Basic preprocessor doesnt understand multiple cmd/line */ -/* bug: strip trailing spaces */ -{ - Strbig (Llen, u); - int i, lt, state; - char c; - cadd (u, Intro); - state = 0; /* a trivial 3-state machine */ - lt = length (t); - while (t[lt - 1] <= ' ') - lt--; - - for (i = 0; i < lt; i++) - { - c = t[i]; - if (c == '=') - { - state = 1; - } - else if ((state == 1) && (c == ' ')) - { - state = 2; - } - if (state == 2) - { - cadd (u, Lf); - cadd (u, Intro); - state = 0; - } - cadd (u, c); - } - scopy (t, u); - for (i = 0; i < length (t); i++) - { /* kill braces inside */ - if ((t[i] == '{') || (t[i] == '}')) - { - t[i] = ' '; - } - } -} -#endif - static int stripbraces (char *s) /* puts the funny placeholders. returns the number of {...} substitutions */ { - int n, i, nest, ls, j; - Strbig (Llen, t); - n = 0; - ls = length (s); - i = 0; + int n, i, nest, ls, j; + Strbig (Llen, t); + n = 0; + ls = length (s); + i = 0; - while (i < ls) - { + while (i < ls) + { if (s[i] == '{') - { /* something to strip */ - j = i + 1; - nest = 1; - n++; + { /* 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 (t, s, 1, i); - placeholder++; + while ((nest > 0) && (j < ls)) + { + if (s[j] == '{') + nest++; + else if (s[j] == '}') + nest--; + j++; + } + pscopy (t, s, 1, i); + placeholder++; - if (t[i - 1] > ' ') - cadd (t, ' '); + if (t[i - 1] > ' ') + cadd (t, ' '); - cadd (t, ' '); // add extra character to increase number significant digits for evaluated numbers - cadd (t, ' '); - cadd (t, ' '); - cadd (t, ' '); - nadd (t, PlaceHold + placeholder); - cadd (t, ' '); + cadd (t, ' '); /* add extra character to increase number significant digits for evaluated numbers */ + cadd (t, ' '); + cadd (t, ' '); + cadd (t, ' '); + nadd (t, PlaceHold + placeholder); + cadd (t, ' '); - if (s[j] >= ' ') - cadd (t, ' '); + if (s[j] >= ' ') + cadd (t, ' '); - i = length (t); - pscopy (s, s, j + 1, ls); - sadd (t, s); - scopy (s, t); - } + i = length (t); + pscopy (s, s, j + 1, ls); + sadd (t, s); + scopy (s, t); + } else - i++; + i++; ls = length (s); - } - dynsubst = placeholder; - return n; + } + dynsubst = placeholder; + return n; } static int @@ -364,76 +287,75 @@ transform (tdico * dico, char *s, unsigned char nostripping, char *u) * 'B' netlist (or .model ?) line that had Braces killed */ { - Strbig (Llen, t); - char category; - int i, k, a, n; + Strbig (Llen, t); + char category; + int i, k, a, n; - stripsomespace (s, nostripping); - modernizeex (s); /* required for stripbraces count */ - scopy (u, ""); + stripsomespace (s, nostripping); + modernizeex (s); /* required for stripbraces count */ + scopy (u, ""); - if (s[0] == '.') - { /* check Pspice parameter format */ + if (s[0] == '.') + { /* check Pspice parameter format */ scopy_up (t, s); k = 1; while (t[k] > ' ') - { - cadd (u, t[k]); - k++; - } + { + cadd (u, t[k]); + k++; + } if (ci_prefix (".PARAM", t) == 1) - { /* comment it out */ - /*s[0]='*'; */ - category = 'P'; - } + { /* 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 (s, s, 1, a - 1); - - category = 'S'; - } + { /* split off any "params" tail */ + a = spos ("PARAMS:", t); + if (a > 0) + pscopy (s, s, 1, a - 1); + category = 'S'; + } else if (ci_prefix (".CONTROL", t) == 1) - category = 'C'; + category = 'C'; else if (ci_prefix (".ENDC", t) == 1) - category = 'E'; + category = 'E'; else if (ci_prefix (".ENDS", t) == 1) - category = 'U'; + category = 'U'; else - { - category = '.'; - n = stripbraces (s); - if (n > 0) - category = 'B'; /* priority category ! */ - } - } - else if (s[0] == Intro) - { /* private style preprocessor line */ + { + category = '.'; + n = stripbraces (s); + 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 */ + } + else if (upcase (s[0]) == 'X') + { /* strip actual parameters */ i = findsubname (dico, s); /* 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! */ + } + else if (s[0] == '+') /* continuation line */ + category = '+'; + else if (cpos (s[0], "*$#") <= 0) + { /* not a comment line! */ n = stripbraces (s); if (n > 0) - category = 'B'; /* line that uses braces */ + category = 'B'; /* line that uses braces */ else - category = ' '; /* ordinary code line */ - } - else - category = '*'; + category = ' '; /* ordinary code line */ + } + else + category = '*'; - return category; + return category; } /************ core of numparam **************/ @@ -454,8 +376,6 @@ static tdico *dico = NULL; /* already part of dico : */ /* Str(80, srcfile); source file */ -/* Darray(refptr, char *, Maxline) pointers to source code lines */ -/* Darray(category, char, Maxline) category of each line */ /* Open ouput to a log file. @@ -505,12 +425,16 @@ nupa_init (char *srcfile) initdico (dico); initdico (inst_dico); - for (i = 0; i < Maxline; i++) + dico->dynrefptr = (char**)tmalloc(dynmaxline*sizeof(char*) + 1); + dico->dyncategory = (char*)tmalloc(dynmaxline*sizeof(char) + 1); + + for (i = 0; i <= dynmaxline; i++) { - dico->refptr[i] = NULL; - dico->category[i] = '?'; + dico->dynrefptr[i] = NULL; + dico->dyncategory[i] = '?'; } - sini (dico->srcfile, sizeof (dico->srcfile) - 4); + + sini (dico->srcfile, sizeof (dico->srcfile) - 4); if (srcfile != NULL) scopy (dico->srcfile, srcfile); @@ -531,11 +455,14 @@ nupa_done (void) nerrors = dico->errcount; dictsize = donedico (dico); - for (i = Maxline - 1; i >= 0; i--) - dispose ((void *) dico->refptr[i]); - + for (i = dynmaxline ; i >= 0; i--) { + dispose ((void *) dico->dynrefptr[i]); + dispose ((void *) dico->dyncategory[i]); + } dispose ((void *) dico); dico = NULL; + dispose ((void *) inst_dico); + inst_dico = NULL; if (nerrors) { /* debug: ask if spice run really wanted */ @@ -600,42 +527,42 @@ upper_str (char *str) void nupa_list_params (FILE * cp_out) { - char *name; - int i; + char *name; + int i; - fprintf (cp_out, "\n\n"); - for (i = 1; i <= dico->nbd; i++) - { - if (dico->dat[i].tp == 'R') - { - name = lower_str (strdup (dico->dat[i].nom)); - fprintf (cp_out, " ---> %s = %g\n", name, dico->dat[i].vl); - txfree (name); - } - } + fprintf (cp_out, "\n\n"); + for (i = 1; i <= dico->nbd; i++) + { + if (dico->dyndat[i].tp == 'R') + { + name = lower_str (strdup (dico->dyndat[i].nom)); + fprintf (cp_out, " ---> %s = %g\n", name, dico->dyndat[i].vl); + txfree (name); + } + } } double nupa_get_param (char *param_name, int *found) { - char *name = upper_str (strdup (param_name)); - double result = 0; - int i; + char *name = upper_str (strdup (param_name)); + double result = 0; + int i; - *found = 0; + *found = 0; - for (i = 1; i <= dico->nbd + 1; i++) - { - if (strcmp (dico->dat[i].nom, name) == 0) - { - result = dico->dat[i].vl; - *found = 1; - break; - } - } + for (i = 1; i <= dico->nbd + 1; i++) + { + if (strcmp (dico->dyndat[i].nom, name) == 0) + { + result = dico->dyndat[i].vl; + *found = 1; + break; + } + } - txfree (name); - return result; + txfree (name); + return result; } void @@ -644,11 +571,10 @@ nupa_add_param (char *param_name, double value) char *up_name = upper_str (strdup (param_name)); int i = attrib (dico, up_name, 'N'); - dico->dat[i].vl = value; - dico->dat[i].tp = 'R'; - dico->dat[i].ivl = 0; - dico->dat[i].sbbase = NULL; - + dico->dyndat[i].vl = value; + dico->dyndat[i].tp = 'R'; + dico->dyndat[i].ivl = 0; + dico->dyndat[i].sbbase = NULL; txfree (up_name); } @@ -658,10 +584,11 @@ nupa_add_inst_param (char *param_name, double value) char *up_name = upper_str (strdup (param_name)); int i = attrib (inst_dico, up_name, 'N'); - inst_dico->dat[i].vl = value; - inst_dico->dat[i].tp = 'R'; - inst_dico->dat[i].ivl = 0; - inst_dico->dat[i].sbbase = NULL; + inst_dico->dyndat[i].vl = value; + inst_dico->dyndat[i].tp = 'R'; + inst_dico->dyndat[i].ivl = 0; + inst_dico->dyndat[i].sbbase = NULL; + txfree (up_name); } @@ -672,7 +599,7 @@ nupa_copy_inst_dico () int i; for (i = 1; i <= inst_dico->nbd; i++) - nupa_add_param (inst_dico->dat[i].nom, inst_dico->dat[i].vl); + nupa_add_param (inst_dico->dyndat[i].nom, inst_dico->dyndat[i].vl); } char * @@ -703,10 +630,10 @@ nupa_copy (char *s, int linenum) pscopy (u, s, 1, ls); /* strip trailing space, CrLf and so on */ dico->srcline = linenum; - if ((!inexpansion) && (linenum >= 0) && (linenum < Maxline)) + if ((!inexpansion) && (linenum >= 0) && (linenum < dynmaxline)) { linecount++; - dico->refptr[linenum] = s; + dico->dynrefptr[linenum] = s; c = transform (dico, u, incontrol, keywd); if (c == 'C') incontrol = 1; @@ -716,14 +643,13 @@ nupa_copy (char *s, int linenum) if (incontrol) c = 'C'; /* force it */ - d = dico->category[linenum]; /* warning if already some strategic line! */ + d = dico->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); - - dico->category[linenum] = c; + dico->dyncategory[linenum] = c; } /* keep a local copy and mangle the string */ ls = length (u); @@ -738,7 +664,7 @@ nupa_copy (char *s, int linenum) { if (!inexpansion) { - putlogfile (dico->category[linenum], linenum, t); + putlogfile (dico->dyncategory[linenum], linenum, t); }; } return t; @@ -760,16 +686,16 @@ nupa_eval (char *s, int linenum) unsigned char err = 1; dico->srcline = linenum; - c = dico->category[linenum]; + c = dico->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); #endif /* TRACE_NUMPARAMS */ if (c == 'P') /* evaluate parameters */ - nupa_assignment (dico, dico->refptr[linenum], 'N'); + nupa_assignment (dico, dico->dynrefptr[linenum], 'N'); else if (c == 'B') /* substitute braces line */ - err = nupa_substitute (dico, dico->refptr[linenum], s, 0); + err = nupa_substitute (dico, dico->dynrefptr[linenum], s, 0); else if (c == 'X') { /* compute args of subcircuit, if required */ ptr = s; @@ -786,7 +712,7 @@ nupa_eval (char *s, int linenum) idef = findsubckt (dico, s, subname); if (idef > 0) - nupa_subcktcall (dico, dico->refptr[idef], dico->refptr[linenum], 0); + nupa_subcktcall (dico, dico->dynrefptr[idef], dico->dynrefptr[linenum], 0); else putlogfile ('?', linenum, " illegal subckt call."); } diff --git a/src/frontend/numparam/xpressn.c b/src/frontend/numparam/xpressn.c index 4761e0950..7c2f5ef3a 100644 --- a/src/frontend/numparam/xpressn.c +++ b/src/frontend/numparam/xpressn.c @@ -16,11 +16,11 @@ extern double gauss(); /************ keywords ************/ /* SJB - 150 chars is ample for this - see initkeys() */ -static Str (150, keys); /* all my keywords */ -static Str (150, fmath); /* all math functions */ +static Str (150, keys); /* all my keywords */ +static Str (150, fmath); /* all math functions */ extern char *nupa_inst_name; /* see spicenum.c */ -extern long dynsubst; /* see inpcom.c */ +extern long dynsubst; /* see inpcom.c */ static double ternary_fcn (int conditional, double if_value, double else_value) @@ -115,76 +115,57 @@ mathfunction (int f, double z, double x) return y; } -typedef enum {Defd=15} _nDefd; -/* serial numb. of 'defined' keyword. The others are not used (yet) */ - static unsigned char message (tdico * dic, char *s) +static unsigned char +message (tdico * dic, char *s) /* record 'dic' should know about source file and line */ { - Strbig (Llen, t); - dic->errcount++; - if ((dic->srcfile != NULL) && dic->srcfile[0]) - { + Strbig (Llen, t); + dic->errcount++; + if ((dic->srcfile != NULL) && dic->srcfile[0]) + { scopy (t, dic->srcfile); cadd (t, ':'); - } - if (dic->srcline >= 0) - { + } + if (dic->srcline >= 0) + { nadd (t, dic->srcline); sadd (t, ": "); - } - sadd (t, s); - cadd (t, '\n'); - fputs (t, stderr); + } + sadd (t, s); + cadd (t, '\n'); + fputs (t, stderr); - return 1 /*error! */ ; + return 1 /*error! */ ; } void debugwarn (tdico * d, char *s) { - message (d, s); - d->errcount--; + message (d, s); + d->errcount--; } -/************* historical: stubs for nodetable manager ************/ -/* in the full preprocessor version there was a node translator for spice2 */ - -static void -initsymbols (auxtable * n) -{; -} - -static void -donesymbols (auxtable * n) -{; -} - -/* static - int parsenode(auxtable *n, char * s) -{ - return 0; -} -*/ /************ the input text symbol table (dictionary) *************/ void initdico (tdico * dico) { - int i; - dico->nbd = 0; - sini(dico->option,sizeof(dico->option)-4); - sini(dico->srcfile,sizeof(dico->srcfile)-4); - dico->srcline = -1; - dico->errcount = 0; + int i; + dico->nbd = 0; + sini(dico->option,sizeof(dico->option)-4); + sini(dico->srcfile,sizeof(dico->srcfile)-4); + dico->srcline = -1; + dico->errcount = 0; - for (i = 0; i <= Maxdico; i++) - sini (dico->dat[i].nom, 100); + dico->dyndat = (entry*)tmalloc(3 * sizeof(entry)); + + for (i = 0; i < 3; i++) + sini (dico->dyndat[i].nom, 100); - dico->tos = 0; - dico->stack[dico->tos] = 0; /* global data beneath */ - initsymbols (&dico->nodetab); - initkeys (); + dico->tos = 0; + dico->stack[dico->tos] = 0; /* global data beneath */ + initkeys (); } /* local semantics for parameters inside a subckt */ @@ -197,67 +178,58 @@ initdico (tdico * dico) typedef enum {Push='u'} _nPush; typedef enum {Pop='o'} _nPop; - static void - dicostack (tdico * dico, char op) +static void +dicostack (tdico * dico, char op) /* push or pop operation for nested subcircuit locals */ { - char *param_name, *inst_name; - int i, current_stack_size, old_stack_size; + char *param_name, *inst_name; + int i, current_stack_size, old_stack_size; - if (op == Push) - { + if (op == Push) + { if (dico->tos < (20 - 1)) - dico->tos++; + dico->tos++; else - message (dico, " Subckt Stack overflow"); + message (dico, " Subckt Stack overflow"); dico->stack[dico->tos] = dico->nbd; dico->inst_name[dico->tos] = nupa_inst_name; - } - else if (op == Pop) - { - /* obsolete: undefine all data items of level dico->tos - for ( i=dico->nbd; i>0; i--) ) { - c= dico->dat[i].tp; - if ( ((c=='R') || (c=='S')) && (dico->dat[i].level == dico->tos) ) { - dico->dat[i].tp= '?'; - } - } - */ + } + else if (op == Pop) + { if (dico->tos > 0) - { - // keep instance parameters around - current_stack_size = dico->nbd; - old_stack_size = dico->stack[dico->tos]; - inst_name = dico->inst_name[dico->tos]; + { + /* keep instance parameters around */ + current_stack_size = dico->nbd; + old_stack_size = dico->stack[dico->tos]; + inst_name = dico->inst_name[dico->tos]; - for (i = old_stack_size + 1; i <= current_stack_size; i++) - { - param_name = - tmalloc (strlen (inst_name) + strlen (dico->dat[i].nom) + 2); - sprintf (param_name, "%s.%s", inst_name, dico->dat[i].nom); - nupa_add_inst_param (param_name, dico->dat[i].vl); - tfree (param_name); - } - tfree (inst_name); + for (i = old_stack_size + 1; i <= current_stack_size; i++) + { + param_name = + tmalloc (strlen (inst_name) + strlen (dico->dyndat[i].nom) + 2); + sprintf (param_name, "%s.%s", inst_name, dico->dyndat[i].nom); + nupa_add_inst_param (param_name, dico->dyndat[i].vl); + tfree (param_name); + } + tfree (inst_name); - dico->nbd = dico->stack[dico->tos]; /* simply kill all local items */ - dico->tos--; - - } + dico->nbd = dico->stack[dico->tos]; /* simply kill all local items */ + dico->tos--; + } else - { - message (dico, " Subckt Stack underflow."); - } - } + { + message (dico, " Subckt Stack underflow."); + } + } } int donedico (tdico * dico) { - int sze = dico->nbd; - donesymbols (&dico->nodetab); - return sze; + int sze = dico->nbd; + if (dico->dyndat) tfree(dico->dyndat); + return sze; } static int @@ -265,19 +237,19 @@ entrynb (tdico * d, char *s) /* symbol lookup from end to start, for stacked local symbols .*/ /* bug: sometimes we need access to same-name symbol, at lower level? */ { - int i; - unsigned char ok; - ok = 0; - i = d->nbd + 1; + int i; + unsigned char ok; + ok = 0; + i = d->nbd + 1; - while ((!ok) && (i > 1)) - { + while ((!ok) && (i > 1)) + { i--; - ok = steq (d->dat[i].nom, s); - } - if (!ok) + ok = steq (d->dyndat[i].nom, s); + } + if (!ok) return 0; - else + else return i; } @@ -285,46 +257,45 @@ char getidtype (tdico * d, char *s) /* test if identifier s is known. Answer its type, or '?' if not in list */ { - char itp = '?'; /* assume unknown */ - int i = entrynb (d, s); + char itp = '?'; /* assume unknown */ + int i = entrynb (d, s); - if (i > 0) - itp = d->dat[i].tp; - - return itp; + if (i > 0) + itp = d->dyndat[i].tp; + return itp; } static double fetchnumentry (tdico * dico, char *t, unsigned char *perr) { - unsigned char err = *perr; - unsigned short k; - double u; - Strbig (Llen, s); - k = entrynb (dico, t); /*no keyword */ - /*dbg -- if ( k<=0 ) { ws("Dico num lookup fails. ") ;} */ + unsigned char err = *perr; + unsigned short k; + double u; + Strbig (Llen, s); + k = entrynb (dico, t); /*no keyword */ + /*dbg -- if ( k<=0 ) { ws("Dico num lookup fails. ") ;} */ - while ((k > 0) && (dico->dat[k].tp == 'P')) - k = dico->dat[k].ivl; /*pointer chain */ + while ((k > 0) && (dico->dyndat[k].tp == 'P')) + k = dico->dyndat[k].ivl; /*pointer chain */ - if (k > 0) - if (dico->dat[k].tp != 'R') - k = 0; + if (k > 0) + if (dico->dyndat[k].tp != 'R') + k = 0; - if (k > 0) - u = dico->dat[k].vl; - else - { + if (k > 0) + u = dico->dyndat[k].vl; + else + { u = 0.0; scopy (s, "Undefined number ["); sadd (s, t); cadd (s, ']'); err = message (dico, s); - } + } - *perr = err; + *perr = err; - return u; + return u; } /******* writing dictionary entries *********/ @@ -335,46 +306,43 @@ attrib (tdico * dico, 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. */ - int i; - unsigned char ok; - i = dico->nbd + 1; - ok = 0; - while ((!ok) && (i > 1)) - { /*search old */ + int i; + unsigned char ok; + i = dico->nbd + 1; + ok = 0; + while ((!ok) && (i > 1)) + { /*search old */ i--; - ok = steq (dico->dat[i].nom, t); - } + ok = steq (dico->dyndat[i].nom, t); + } - if (ok && (op == 'N') - && (dico->dat[i].level < dico->tos) && (dico->dat[i].tp != '?')) - { + if (ok && (op == 'N') + && (dico->dyndat[i].level < dico->tos) && (dico->dyndat[i].tp != '?')) + { ok = 0; - } + } - if (!ok) - { + if (!ok) + { dico->nbd++; i = dico->nbd; - - if (dico->nbd > Maxdico) - i = 0; - else - { - scopy (dico->dat[i].nom, t); - dico->dat[i].tp = '?'; /*signal Unknown */ - dico->dat[i].level = dico->tos; - } - } - return i; + dico->dyndat = trealloc(dico->dyndat, (i+1) * sizeof(entry)); + sini (dico->dyndat[i].nom, 100); + scopy (dico->dyndat[i].nom, t); + dico->dyndat[i].tp = '?'; /*signal Unknown */ + dico->dyndat[i].level = dico->tos; + } + return i; } static unsigned char -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 */ - char *base) /* string pointer if any */ +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 */ + char *base) /* string pointer if any */ { /*define t as real or integer, opcode= 'N' impose a new item under local conditions. @@ -384,53 +352,52 @@ define (tdico * dico, char *t, /* identifier to define */ we already make symbol entries which are dummy globals ! we mark each id with its subckt level, and warn if write at higher one. */ - int i; - char c; - unsigned char err, warn; - Strbig (Llen, v); - i = attrib (dico, t, op); - err = 0; - if (i <= 0) + int i; + char c; + unsigned char err, warn; + Strbig (Llen, v); + i = attrib (dico, t, op); + err = 0; + if (i <= 0) err = message (dico, " Symbol table overflow"); - else - { - if (dico->dat[i].tp == 'P') - i = dico->dat[i].ivl; /*pointer indirection */ + else + { + if (dico->dyndat[i].tp == 'P') + i = dico->dyndat[i].ivl; /*pointer indirection */ if (i > 0) - c = dico->dat[i].tp; + c = dico->dyndat[i].tp; else - c = ' '; + c = ' '; if ((c == 'R') || (c == 'S') || (c == '?')) - { - dico->dat[i].vl = z; - dico->dat[i].tp = tpe; - dico->dat[i].ivl = w; - dico->dat[i].sbbase = base; - /* if ( (c !='?') && (i<= dico->stack[dico->tos]) ) { */ + { + dico->dyndat[i].vl = z; + dico->dyndat[i].tp = tpe; + dico->dyndat[i].ivl = w; + dico->dyndat[i].sbbase = base; + /* if ( (c !='?') && (i<= dico->stack[dico->tos]) ) { */ + if (c == '?') + dico->dyndat[i].level = dico->tos; /* promote! */ - if (c == '?') - dico->dat[i].level = dico->tos; /* promote! */ - - if (dico->dat[i].level < dico->tos) - { - /* warn about re-write to a global scope! */ - scopy (v, t); - cadd (v, ':'); - nadd (v, dico->dat[i].level); - sadd (v, " overwritten."); - warn = message (dico, v); - } - } + if (dico->dyndat[i].level < dico->tos) + { + /* warn about re-write to a global scope! */ + scopy (v, t); + cadd (v, ':'); + nadd (v, dico->dyndat[i].level); + sadd (v, " overwritten."); + warn = message (dico, v); + } + } else - { - scopy (v, t); - sadd (v, ": cannot redefine"); - err = message (dico, v); - } - } - return err; + { + scopy (v, t); + sadd (v, ": cannot redefine"); + err = message (dico, v); + } + } + return err; } unsigned char @@ -439,35 +406,35 @@ defsubckt (tdico * dico, char *s, int w, char categ) to enter subcircuit (categ=U) and model (categ=O) names */ { - Str (80, u); - unsigned char err; - int i, j, ls; - ls = length (s); - i = 0; + Str (80, u); + unsigned char 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)) - { + if ((j > i)) + { pscopy_up (u, s, i + 1, j - i); err = define (dico, u, ' ', categ, 0.0, w, NULL); - } - else + } + else err = message (dico, "Subcircuit or Model without name."); - return err; + return err; } int @@ -476,34 +443,34 @@ findsubckt (tdico * dico, char *s, char *subname) returns 0 if not found, else the stored definition line number value and the name in string subname */ { - Str (80, u); /* u= subckt name is last token in string s */ - int i, j, k; - k = length (s); + Str (80, u); /* u= subckt name is last token in string s */ + int i, j, k; + 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 (u, s, k + 2, j - k); - i = entrynb (dico, u); + pscopy_up (u, s, k + 2, j - k); + i = entrynb (dico, u); - if ((i > 0) && (dico->dat[i].tp == 'U')) - { - i = dico->dat[i].ivl; + if ((i > 0) && (dico->dyndat[i].tp == 'U')) + { + i = dico->dyndat[i].ivl; scopy (subname, u); - } - else - { + } + else + { i = 0; scopy (subname, ""); message (dico, "Cannot find subcircuit."); - } + } - return i; + return i; } #if 0 /* unused, from the full macro language... */ @@ -562,36 +529,36 @@ static unsigned char keyword (char *keys, char *t) { /* return 0 if t not found in list keys, else the ordinal number */ - unsigned char i, j, k; - int lt, lk; - unsigned char ok; - lt = length (t); - lk = length (keys); - k = 0; - j = 0; + unsigned char i, j, k; + int lt, lk; + unsigned char ok; + lt = length (t); + lk = length (keys); + k = 0; + j = 0; - do { + do { j++; i = 0; ok = 1; - do{ - i++; - k++; - ok = (k <= lk) && (t[i - 1] == keys[k - 1]); - } while (!((!ok) || (i >= lt))); + do { + i++; + k++; + ok = (k <= lk) && (t[i - 1] == keys[k - 1]); + } while (!((!ok) || (i >= lt))); if (ok) - ok = (k == lk) || (keys[k] <= ' '); + ok = (k == lk) || (keys[k] <= ' '); if (!ok && (k < lk)) /*skip to next item */ - while ((k <= lk) && (keys[k - 1] > ' ')) + while ((k <= lk) && (keys[k - 1] > ' ')) k++; - } while (!(ok || (k >= lk))); + } while (!(ok || (k >= lk))); - if (ok) + if (ok) return j; - else + else return 0; } @@ -1331,29 +1298,29 @@ evaluate (tdico * dico, char *q, char *t, unsigned char mode) stupcase (t); k = entrynb (dico, t); nolookup = (k <= 0); - while ((k > 0) && (dico->dat[k].tp == 'P')) - k = dico->dat[k].ivl; + while ((k > 0) && (dico->dyndat[k].tp == 'P')) + k = dico->dyndat[k].ivl; /*pointer chain */ if (k > 0) - dt = dico->dat[k].tp; + dt = dico->dyndat[k].tp; else dt = ' '; /*data type: Real or String */ if (dt == 'R') { - u = dico->dat[k].vl; + u = dico->dyndat[k].vl; numeric = 1; } else if (dt == 'S') { /*suppose source text "..." at */ - j = dico->dat[k].ivl; + j = dico->dyndat[k].ivl; lq = 0; do { j++; lq++; - dt = /*ibf->bf[j]; */ dico->dat[k].sbbase[j]; + dt = /*ibf->bf[j]; */ dico->dyndat[k].sbbase[j]; if (cpos ('3', dico->option) <= 0) dt = upcase (dt); /* spice-2 */