diff --git a/ChangeLog b/ChangeLog index 9916f3aec..974fa8ca3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2009-03-22 Holger Vogt + * inpcom.c: readline() now returns /n for an empty line, dynLlen consists of + maximum line length plus some space for parameter substitution and has a + minimum size of 512. + * spicenum.c, xpressn.c, general.h, numparam.h: dynamic memory allocation + also for all string manipultions, Strbig now is a macro using tmalloc, + the macro Strrem deallocates the memory, the size of the arrays is dynLlen. + 2009-03-21 Holger Vogt * inpcom.c, fteinp.h, inpdefs.h: line renumbering of input deck added to the end of fcn inp_readall(). cc->li_line_original now contains diff --git a/src/frontend/inpcom.c b/src/frontend/inpcom.c index 3c54440ca..c072b1ef5 100644 --- a/src/frontend/inpcom.c +++ b/src/frontend/inpcom.c @@ -130,39 +130,39 @@ static void inp_sort_params( struct line *start_card, struct line *end_card, str static char * readline(FILE *fd) { - int c; - int memlen; - char *strptr; - int strlen; + int c; + int memlen; + char *strptr; + int strlen; - strptr = NULL; - strlen = 0; - memlen = STRGROW; - strptr = tmalloc(memlen); - memlen -= 1; /* Save constant -1's in while loop */ - while((c = getc(fd)) != EOF) { - if (strlen == 0 && (c == '\n' || c == ' ')) /* Leading spaces away */ - continue; - strptr[strlen] = c; - strlen++; - if( strlen >= memlen ) { - memlen += STRGROW; - if( !(strptr = trealloc(strptr, memlen + 1))) { - return (NULL); - } - } - if (c == '\n') { - break; - } - } - if (!strlen) { - tfree(strptr); - return (NULL); - } - strptr[strlen] = '\0'; - /* Trim the string */ - strptr = trealloc(strptr, strlen + 1); - return (strptr); + strptr = NULL; + strlen = 0; + memlen = STRGROW; + strptr = tmalloc(memlen); + memlen -= 1; /* Save constant -1's in while loop */ + while((c = getc(fd)) != EOF) { + if (strlen == 0 && (c == '\t' || c == ' ')) /* Leading spaces away */ + continue; + strptr[strlen] = c; + strlen++; + if( strlen >= memlen ) { + memlen += STRGROW; + if( !(strptr = trealloc(strptr, memlen + 1))) { + return (NULL); + } + } + if (c == '\n') { + break; + } + } + if (!strlen) { + tfree(strptr); + return (NULL); + } + strptr[strlen] = '\0'; + /* Trim the string */ + strptr = trealloc(strptr, strlen + 1); + return (strptr); } @@ -997,7 +997,8 @@ inp_readall(FILE *fp, struct line **data, int call_depth, char *dir_name) char *copys=NULL, big_buff2[5000]; char *global_copy = NULL, keep_char; int line_number = 1; /* sjb - renamed to avoid confusion with struct line */ - int line_number_orig = 0; + int line_number_orig = 1, line_number_lib = 1, line_number_inc = 1; + int no_braces = 0; /* number of '{' */ FILE *newfp; #if defined(TRACE) || defined(OUTDECK) FILE *fdo; @@ -1079,6 +1080,7 @@ inp_readall(FILE *fp, struct line **data, int call_depth, char *dir_name) /* If input line is blank, ignore it & continue looping. */ if ( (strcmp(buffer,"\n") == 0) || (strcmp(buffer,"\r\n") == 0) ) { if ( call_depth != 0 || (call_depth == 0 && cc != NULL) ) { + line_number_orig++; continue; } } @@ -1237,13 +1239,13 @@ inp_readall(FILE *fp, struct line **data, int call_depth, char *dir_name) if (newcard) { end->li_next = newcard; /* Renumber the lines */ - line_number_orig = 1; + line_number_inc = 1; for (end = newcard; end && end->li_next; end = end->li_next) { - end->li_linenum = line_number_orig++; - end->li_linenum_orig = line_number++; + end->li_linenum = line_number++; + end->li_linenum_orig = line_number_inc++; } end->li_linenum = line_number++; /* SJB - renumber the last line */ - end->li_linenum_orig = line_number_orig++; /* SJB - renumber the last line */ + end->li_linenum_orig = line_number_inc++; /* SJB - renumber the last line */ } /* Fix the buffer up a bit. */ @@ -1307,7 +1309,8 @@ inp_readall(FILE *fp, struct line **data, int call_depth, char *dir_name) end->li_error = NULL; end->li_actual = NULL; end->li_line = buffer; - end->li_linenum = end->li_linenum_orig = line_number++; + end->li_linenum = line_number++; + end->li_linenum_orig = line_number_orig++; } /* end while ((buffer = readline(fp))) */ if (!end) { /* No stuff here */ @@ -1389,13 +1392,13 @@ inp_readall(FILE *fp, struct line **data, int call_depth, char *dir_name) library_ll_ptr[i][j]->li_next = working; /* renumber lines */ - line_number_orig = 1; + line_number_lib = 1; for ( start_lib = working; !ciprefix(".endl", start_lib->li_line); start_lib = start_lib->li_next ) { start_lib->li_linenum = line_number++; - start_lib->li_linenum_orig = line_number_orig++; + start_lib->li_linenum_orig = line_number_lib++; } start_lib->li_linenum = line_number++; // renumber endl line - start_lib->li_linenum_orig = line_number_orig++; + start_lib->li_linenum_orig = line_number_lib++; break; } } @@ -1424,6 +1427,7 @@ inp_readall(FILE *fp, struct line **data, int call_depth, char *dir_name) end->li_actual = NULL; end->li_line = buffer; end->li_linenum = end->li_linenum_orig = line_number++; + end->li_linenum_orig = line_number_orig++; } } @@ -1531,16 +1535,26 @@ inp_readall(FILE *fp, struct line **data, int call_depth, char *dir_name) *data = cc; /* get max. line length and number of lines in input deck, - * and renumber the lines */ + and renumber the lines, + count the number of '{' per line as an upper estimate of the number + of parameter substitutions in a line*/ dynmaxline = 0; dynLlen = 0; for(tmp_ptr1 = cc; tmp_ptr1 != NULL; tmp_ptr1 = tmp_ptr1->li_next) { + char *s; + int braces_per_line = 0; + /* count number of lines */ dynmaxline++; /* renumber the lines of the processed input deck */ tmp_ptr1->li_linenum = dynmaxline; if (dynLlen < strlen(tmp_ptr1->li_line)) - dynLlen = strlen(tmp_ptr1->li_line); + dynLlen = strlen(tmp_ptr1->li_line); + /* count '{' */ + for (s = tmp_ptr1->li_line; *s; s++) + if (*s == '{') braces_per_line++; + if (no_braces < braces_per_line) no_braces = braces_per_line; } + #if defined(TRACE) || defined(OUTDECK) /*debug: print into file*/ fdo = fopen("debug-out.txt", "w"); @@ -1548,9 +1562,15 @@ inp_readall(FILE *fp, struct line **data, int call_depth, char *dir_name) fprintf(fdo, "%d %d %s\n", tmp_ptr1->li_linenum_orig, tmp_ptr1->li_linenum, tmp_ptr1->li_line); (void) fclose(fdo); - fprintf(stdout, "lLen %d, maxline %d\n", dynLlen, dynmaxline); + fprintf(stdout, "max line length %d, max subst. per line %d, number of lines %d\n", + dynLlen, no_braces, dynmaxline); #endif - + /* max line length increased by maximum number of parameter substitutions per line + times parameter string length (25) */ + dynLlen += no_braces * 25; + /* several times a string of length dynLlen is used for messages, thus give it a + minimum length */ + if (dynLlen < 512) dynLlen = 512; return; } @@ -3026,7 +3046,7 @@ inp_sort_params( struct line *start_card, struct line *end_card, struct line *ca num_terminals = get_number_terminals( curr_line ); - if ( num_terminals == 0 ) { ptr = ptr->li_next; continue; } + if ( num_terminals <= 0 ) { ptr = ptr->li_next; continue; } for ( i = 0; i < num_params; i++ ) { diff --git a/src/frontend/numparam/general.h b/src/frontend/numparam/general.h index 2571bb75f..299899182 100644 --- a/src/frontend/numparam/general.h +++ b/src/frontend/numparam/general.h @@ -12,14 +12,37 @@ #define Hi(x) (((x) >> 8) & 0xff) #define Lo(x) ((x) & 0xff) -#define Strbig(n,a) char a[n+4]={0, (char)Hi(n), (char)Lo(n)} +//#define Strbig(n,a) char a[n+4]={0, (char)Hi(n), (char)Lo(n)} +#define Strbig(n,a) char*(a)=(char*)tmalloc((n+4)*sizeof(char)); \ + (a)[0]=0; (a)[1]=(char)Hi(n); (a)[2]=(char)Lo(n) +#define Strdbig(n,a,b) char*(a); char*(b); \ + (a)=(char*)tmalloc((n+4)*sizeof(char)); \ + (a)[0]=0; (a)[1]=(char)Hi(n); (a)[2]=(char)Lo(n);\ + (b)=(char*)tmalloc((n+4)*sizeof(char)); \ + (b)[0]=0; (b)[1]=(char)Hi(n); (b)[2]=(char)Lo(n) + +#define Strfbig(n,a,b,c,d) char*(a); char*(b); char*(c); char*(d);\ + (a)=(char*)tmalloc((n+4)*sizeof(char)); \ + (a)[0]=0; (a)[1]=(char)Hi(n); (a)[2]=(char)Lo(n);\ + (b)=(char*)tmalloc((n+4)*sizeof(char)); \ + (b)[0]=0; (b)[1]=(char)Hi(n); (b)[2]=(char)Lo(n);\ + (c)=(char*)tmalloc((n+4)*sizeof(char)); \ + (c)[0]=0; (c)[1]=(char)Hi(n); (c)[2]=(char)Lo(n);\ + (d)=(char*)tmalloc((n+4)*sizeof(char)); \ + (d)[0]=0; (d)[1]=(char)Hi(n); (d)[2]=(char)Lo(n) + +#define Strrem(a) tfree(a) +#define Strdrem(a,b) tfree(a); tfree(b) +#define Strfrem(a,b,c,d) tfree(a); tfree(b); tfree(c); tfree(d) + #define Str(n,a) char a[n+3]={0,0,(char)n} /* n<255 ! */ #define Sini(s) sini(s,sizeof(s)-4) /* was 255, then 15000, string maxlen, 40000 to catch really big - macros in .model lines */ -typedef enum {Maxstr=40000} _nMaxstr; + macros in .model lines, now just a big number, a line length + which never should be exceeded, may be removed later*/ +typedef enum {Maxstr=4000000} _nMaxstr; typedef enum {Esc=27} _nEsc; typedef enum {Tab=9} _nTab; typedef enum {Bs=8} _nBs; diff --git a/src/frontend/numparam/numparam.h b/src/frontend/numparam/numparam.h index 114754166..0a50fdd2b 100644 --- a/src/frontend/numparam/numparam.h +++ b/src/frontend/numparam/numparam.h @@ -25,7 +25,7 @@ typedef enum {Defd=15} _nDefd; /* serial numb. of 'defined' keyword. The others .model line, especially when spread over several continuation lines with much white space. Set to 40000 to catch really big macros in .model lines. Will add 100k of memory compared to previous 25004*/ -typedef enum {Llen=40000} _nLlen; +//typedef enum {Llen=40000} _nLlen; typedef char str50 [54]; typedef char str80 [84]; diff --git a/src/frontend/numparam/spicenum.c b/src/frontend/numparam/spicenum.c index 7cb2c648c..45f87ce71 100644 --- a/src/frontend/numparam/spicenum.c +++ b/src/frontend/numparam/spicenum.c @@ -94,7 +94,7 @@ stripbraces (char *s) /* puts the funny placeholders. returns the number of {...} substitutions */ { int n, i, nest, ls, j; - Strbig (Llen, t); + Strbig (dynLlen, t); n = 0; ls = length (s); i = 0; @@ -142,6 +142,7 @@ stripbraces (char *s) ls = length (s); } dynsubst = placeholder; + Strrem(t); return n; } @@ -211,9 +212,10 @@ static void modernizeex (char *s) /* old style expressions &(..) and &id --> new style with braces. */ { - Strbig (Llen, t); +// Strbig (Llen, t); int i, state, ls; char c, d; + Strbig (dynLlen, t); i = 0; state = 0; ls = length (s); @@ -259,6 +261,7 @@ modernizeex (char *s) i++; } scopy (s, t); + Strrem(t); } static char @@ -287,10 +290,10 @@ transform (tdico * dico, char *s, unsigned char nostripping, char *u) * 'B' netlist (or .model ?) line that had Braces killed */ { - Strbig (Llen, t); +// Strbig (Llen, t); char category; int i, k, a, n; - + Strbig (dynLlen, t); stripsomespace (s, nostripping); modernizeex (s); /* required for stripbraces count */ scopy (u, ""); @@ -355,6 +358,7 @@ transform (tdico * dico, char *s, unsigned char nostripping, char *u) else category = '*'; + Strrem(t); return category; } @@ -385,30 +389,31 @@ static tdico *dico = NULL; static void putlogfile (char c, int num, char *t) { - Strbig (Llen, u); - Str (20, fname); - - if (dologfile) - { +// Strbig (Llen, u); + Str (20, fname); + Strbig (dynLlen, u); + if (dologfile) + { if ((logfile == NULL)) - { - scopy (fname, "logfile."); - nblog++; - nadd (fname, nblog); - logfile = fopen (fname, "w"); - } + { + scopy (fname, "logfile."); + nblog++; + nadd (fname, nblog); + logfile = fopen (fname, "w"); + } if ((logfile != NULL)) - { - cadd (u, c); - nadd (u, num); - cadd (u, ':'); - cadd (u, ' '); - sadd (u, t); - cadd (u, '\n'); - fputs (u, logfile); - } - } + { + cadd (u, c); + nadd (u, num); + cadd (u, ':'); + cadd (u, ' '); + sadd (u, t); + cadd (u, '\n'); + fputs (u, logfile); + } + } + Strrem(u); } static void @@ -425,8 +430,8 @@ nupa_init (char *srcfile) initdico (dico); initdico (inst_dico); - dico->dynrefptr = (char**)tmalloc(dynmaxline*sizeof(char*) + 1); - dico->dyncategory = (char*)tmalloc(dynmaxline*sizeof(char) + 1); + dico->dynrefptr = (char**)tmalloc((dynmaxline + 1)*sizeof(char*)); + dico->dyncategory = (char*)tmalloc((dynmaxline + 1)*sizeof(char)); for (i = 0; i <= dynmaxline; i++) { @@ -434,7 +439,7 @@ nupa_init (char *srcfile) dico->dyncategory[i] = '?'; } - sini (dico->srcfile, sizeof (dico->srcfile) - 4); +// sini (dico->srcfile, sizeof (dico->srcfile) - 4); if (srcfile != NULL) scopy (dico->srcfile, srcfile); @@ -617,11 +622,12 @@ nupa_copy (char *s, int linenum) - substitute placeholders for all {..} --> 10-digit numeric values. */ { - Strbig (Llen, u); - Strbig (Llen, keywd); +// Strbig (Llen, u); +// Strbig (Llen, keywd); char *t; int ls; char c, d; + Strdbig (dynLlen, u, keywd); ls = length (s); while ((ls > 0) && (s[ls - 1] <= ' ')) @@ -667,6 +673,7 @@ nupa_copy (char *s, int linenum) putlogfile (dico->dyncategory[linenum], linenum, t); }; } + Strdrem(u, keywd); return t; } diff --git a/src/frontend/numparam/xpressn.c b/src/frontend/numparam/xpressn.c index 7c2f5ef3a..1ef968286 100644 --- a/src/frontend/numparam/xpressn.c +++ b/src/frontend/numparam/xpressn.c @@ -21,6 +21,7 @@ static Str (150, fmath); /* all math functions */ extern char *nupa_inst_name; /* see spicenum.c */ extern long dynsubst; /* see inpcom.c */ +extern int dynLlen; static double ternary_fcn (int conditional, double if_value, double else_value) @@ -119,7 +120,7 @@ static unsigned char message (tdico * dic, char *s) /* record 'dic' should know about source file and line */ { - Strbig (Llen, t); + Strbig (dynLlen, t); dic->errcount++; if ((dic->srcfile != NULL) && dic->srcfile[0]) { @@ -134,6 +135,7 @@ message (tdico * dic, char *s) sadd (t, s); cadd (t, '\n'); fputs (t, stderr); + Strrem(t); return 1 /*error! */ ; } @@ -271,7 +273,7 @@ fetchnumentry (tdico * dico, char *t, unsigned char *perr) unsigned char err = *perr; unsigned short k; double u; - Strbig (Llen, s); + Strbig (dynLlen, s); k = entrynb (dico, t); /*no keyword */ /*dbg -- if ( k<=0 ) { ws("Dico num lookup fails. ") ;} */ @@ -295,6 +297,8 @@ fetchnumentry (tdico * dico, char *t, unsigned char *perr) *perr = err; + Strrem(s); + return u; } @@ -355,7 +359,7 @@ define (tdico * dico, int i; char c; unsigned char err, warn; - Strbig (Llen, v); + Strbig (dynLlen, v); i = attrib (dico, t, op); err = 0; if (i <= 0) @@ -397,6 +401,7 @@ define (tdico * dico, err = message (dico, v); } } + Strrem(v); return err; } @@ -641,7 +646,7 @@ exists (tdico * d, char *s, int *pi, unsigned char *perror) int ls; char c; unsigned char ok; - Strbig (Llen, t); + Strbig (dynLlen, t); ls = length (s); x = 0.0; @@ -680,6 +685,7 @@ exists (tdico * d, char *s, int *pi, unsigned char *perror) *perror = error; *pi = i; + Strrem(t); return x; } @@ -692,8 +698,9 @@ fetchnumber (tdico * dico, char *s, int ls, int *pi, unsigned char *perror) int k, err; char d; Str (20, t); - Strbig (Llen, v); +// Strbig (Llen, v); double u; + Strbig (dynLlen, v); k = i; do { @@ -756,7 +763,7 @@ fetchnumber (tdico * dico, char *s, int ls, int *pi, unsigned char *perror) i = k - 1; *perror = error; *pi = i; - + Strrem(v); return u; } @@ -775,7 +782,7 @@ fetchoperator (tdico * dico, unsigned char level = *plevel; unsigned char error = *perror; char c, d; - Strbig (Llen, v); + Strbig (dynLlen, v); c = s[i - 1]; if (i < ls) @@ -869,6 +876,7 @@ fetchoperator (tdico * dico, *pstate = state; *plevel = level; *perror = error; + Strrem(v); return c; } @@ -1044,8 +1052,9 @@ formula (tdico * dico, char *s, unsigned char *perror) char uop[nprece + 1]; int i, k, ls, natom, arg2, arg3; char c, d; - Strbig (Llen, t); +// Strbig (Llen, t); unsigned char ok; + Strbig (dynLlen, t); for (i = 0; i <= nprece; i++) { @@ -1241,6 +1250,8 @@ formula (tdico * dico, char *s, unsigned char *perror) *perror = error; + Strrem(t); + if (error) return 1.0; else @@ -1288,7 +1299,7 @@ evaluate (tdico * dico, char *q, char *t, unsigned char mode) char dt, fmt; unsigned char numeric, done, nolookup; unsigned char err; - Strbig (Llen, v); + Strbig (dynLlen, v); scopy (q, ""); numeric = 0; err = 0; @@ -1363,6 +1374,7 @@ evaluate (tdico * dico, char *q, char *t, unsigned char mode) strf (u, 17, 10, q); } /* strf() arg 2 doesnt work: always >10 significant digits ! */ ; } + Strrem(v); return err; } @@ -1678,8 +1690,9 @@ nupa_substitute (tdico * dico, char *s, char *r, unsigned char err) { int i, k, ls, level, nnest, ir; char c, d; - Strbig (Llen, q); - Strbig (Llen, t); +// Strbig (Llen, q); +// Strbig (Llen, t); + Strdbig (dynLlen, q, t); i = 0; ls = length (s); err = 0; @@ -1769,7 +1782,9 @@ nupa_substitute (tdico * dico, char *s, char *r, unsigned char err) else message (dico, "Cannot compute &(expression)"); } - } /*while */ + } + /*while */ + Strdrem(q,t); return err; } @@ -1898,14 +1913,15 @@ nupa_assignment (tdico * dico, char *s, char mode) */ { /* s has the format: ident = expression; ident= expression ... */ - Strbig (Llen, t); - Strbig (Llen, u); +// Strbig (Llen, t); +// Strbig (Llen, u); int i, j, ls; unsigned char key; unsigned char error, err; char dtype; int wval = 0; double rval = 0.0; + Strdbig (dynLlen, t, u); ls = length (s); error = 0; i = 0; @@ -1965,6 +1981,7 @@ nupa_assignment (tdico * dico, char *s, char mode) else /* i++ */; } + Strdrem(t,u); return error; } @@ -1975,14 +1992,14 @@ nupa_subcktcall (tdico * dico, char *s, char *x, unsigned char err) */ { int n, m, i, j, k, g, h, narg = 0, ls, nest; - Strbig (Llen, t); - Strbig (Llen, u); - Strbig (Llen, v); - Strbig (Llen, idlist); +// Strbig (Llen, t); +// Strbig (Llen, u); +// Strbig (Llen, v); +// Strbig (Llen, idlist); Str (80, subname); char *buf, *token; unsigned char found; - + Strfbig (dynLlen, t, u, v, idlist); /* skip over instance name -- fixes bug where instance 'x1' is same name as subckt 'x1' @@ -2172,6 +2189,7 @@ nupa_subcktcall (tdico * dico, char *s, char *x, unsigned char err) /* ;} else { debugwarn(dico, idlist) */ ; } err = nupa_assignment (dico, idlist, 'N'); + Strfrem(t,u,v,idlist); return err; }