Dynamic memory allocation for numparam

This commit is contained in:
h_vogt 2009-03-22 21:03:02 +00:00
parent 9b2170953c
commit 624a8a0be0
6 changed files with 175 additions and 99 deletions

View File

@ -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

View File

@ -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++ )
{

View File

@ -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;

View File

@ -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];

View File

@ -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;
}

View File

@ -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;
}