diff --git a/src/frontend/com_set.c b/src/frontend/com_set.c index 4b8d22869..d0d233b48 100644 --- a/src/frontend/com_set.c +++ b/src/frontend/com_set.c @@ -6,6 +6,8 @@ #include "variable.h" #include "com_set.h" +static wordlist* readifile(wordlist*); + /* The set command. * @@ -35,7 +37,14 @@ void com_set(wordlist *wl) return; } - struct variable *oldvar; + /* Handle special case input redirection. The file contents is + * converted to a list that can be handled by cp_setparse(). */ + { + const wordlist * const ww = wl->wl_next; + if (ww && eq(ww->wl_word, "<")) { + wl = readifile(wl); + } + } struct variable *vars = cp_setparse(wl); @@ -62,7 +71,7 @@ void com_set(wordlist *wl) s = NULL; } cp_vset(vars->va_name, vars->va_type, s); - oldvar = vars; + struct variable * const oldvar = vars; vars = vars->va_next; /* Free allocations associated with the current variable */ @@ -73,4 +82,58 @@ void com_set(wordlist *wl) /* don't free oldvar->va_list! This structure is used furthermore! */ txfree(oldvar); } +} /* end of function com_set */ + + + +/* read a file from cp_in, add the tokens to a wordlist and + create an input for a string list like set ccc = ( 3 5 7 ). + Comment lines in input file (starting with '*') are ignored. */ +static wordlist* +readifile(wordlist* win) +{ + /* max file size */ + char intoken[4096]; + /* save start address */ + wordlist* tw = win; + char *tmpstr; + + /* delete wordlist from '<' on */ + wl_free(win->wl_next); + wl_append_word(&win, &win, copy("=")); + wl_append_word(&win, &win, copy("(")); + /* read a line. If it starts with '*', ignore it */ + while (fgets(intoken, sizeof intoken, cp_in) != NULL) { + if (intoken[0] == '*') { /* skip comment lines */ + continue; + } + char *instr = intoken; + /* get all tokens, ignoring '\n' + and add to string list */ + while ((tmpstr = gettok(&instr)) != NULL) { + wl_append_word(&win, &win, tmpstr); + } + } + wl_append_word(&win, &win, copy(")")); + /* close and reset cp_in + (was opened in streams.c:84) */ + cp_ioreset(); + return tw; +#if 0 + size_t retval = fread(intoken, 1, 4096, cp_in); + intoken[retval] = '\0'; + char* delstr; + char* instr = delstr = copy(intoken); + /* get all tokens, ignoring '\n' + and add to string list */ + while ((tmpstr = gettok(&instr)) != NULL) { + wl_append_word(&win, &win, tmpstr); + } + tfree(delstr); + wl_append_word(&win, &win, copy(")")); + /* close and reset cp_in + (was opened in streams.c:84) */ + cp_ioreset(); + return tw; +#endif } diff --git a/src/frontend/streams.c b/src/frontend/streams.c index 8906fd33c..8558220b1 100644 --- a/src/frontend/streams.c +++ b/src/frontend/streams.c @@ -82,16 +82,20 @@ cp_redirect(wordlist *wl) #endif fp = fopen(fname, "r"); - tfree(fname); - if (!fp) { perror(fname); + tfree(fname); goto error; } - + + tfree(fname); cp_in = fp; - wl_delete_slice(beg, w); + /* special case for set command: + keep i/o information (handled in com_set.c) */ + wordlist* bw = beg->wl_prev->wl_prev; + if (!(bw && cieq(bw->wl_word, "set"))) + wl_delete_slice(beg, w); } else if (*w->wl_word == cp_gt) { diff --git a/src/xspice/icm/table/mada/eno2.c b/src/xspice/icm/table/mada/eno2.c index e36adeda0..1adb003e0 100644 --- a/src/xspice/icm/table/mada/eno2.c +++ b/src/xspice/icm/table/mada/eno2.c @@ -72,6 +72,9 @@ sf_eno2_close (sf_eno2 pnt) { int i2; + if (!pnt) + return; + sf_eno_close (pnt->jnt); for (i2 = 0; i2 < pnt->n2; i2++) sf_eno_close (pnt->ent[i2]); diff --git a/src/xspice/icm/table/mada/eno3.c b/src/xspice/icm/table/mada/eno3.c index 81b7e7e93..2942f142c 100644 --- a/src/xspice/icm/table/mada/eno3.c +++ b/src/xspice/icm/table/mada/eno3.c @@ -78,6 +78,9 @@ sf_eno3_close(sf_eno3 pnt) { int i2, i3; + if (!pnt) + return; + sf_eno2_close (pnt->jnt); for (i3 = 0; i3 < pnt->n3; i3++) { for (i2 = 0; i2 < pnt->n2; i2++) diff --git a/src/xspice/icm/table/table2D/cfunc.mod b/src/xspice/icm/table/table2D/cfunc.mod index 7a474232b..df8d363a9 100644 --- a/src/xspice/icm/table/table2D/cfunc.mod +++ b/src/xspice/icm/table/table2D/cfunc.mod @@ -298,6 +298,8 @@ cm_table2D_callback(ARGS, Mif_Callback_Reason_t reason) case MIF_CB_DESTROY: { int i; Local_Data_t *loc = STATIC_VAR (locdata); + if (!loc) + break; free(loc->state); for (i = 0; i < loc->iy; i++) free(loc->table[i]); @@ -306,6 +308,7 @@ cm_table2D_callback(ARGS, Mif_Callback_Reason_t reason) free(loc->ycol); sf_eno2_close (loc->newtable); free(loc); + STATIC_VAR (locdata) = loc = NULL; break; } } @@ -428,8 +431,9 @@ cm_table2D(ARGS) /* structure holding parms, inputs, outputs, etc. */ struct stat st; if (!loc->state->fp || fstat(fileno(loc->state->fp), &st)) { cm_message_printf("cannot open file %s", PARAM(file)); - loc->state->atend = 1; - loc->init_err = 1; + free(loc->state); + free(loc); + STATIC_VAR (locdata) = loc = NULL; return; } /* get file length */ @@ -441,8 +445,9 @@ cm_table2D(ARGS) /* structure holding parms, inputs, outputs, etc. */ cThisLine = calloc(lFileLen + 1, sizeof(char)); if (cFile == NULL || cThisLine == NULL) { cm_message_printf("Insufficient memory to read file %s", PARAM(file)); - loc->state->atend = 1; - loc->init_err = 1; + free(loc->state); + free(loc); + STATIC_VAR (locdata) = loc = NULL; if(cFile) free(cFile); if(cThisLine) free(cThisLine); return; @@ -627,7 +632,7 @@ cm_table2D(ARGS) /* structure holding parms, inputs, outputs, etc. */ loc = STATIC_VAR (locdata); /* return immediately if there was an initialization error */ - if (loc->init_err == 1) + if (!loc || loc->init_err == 1) return; /* get input x, y, diff --git a/src/xspice/icm/table/table3D/cfunc.mod b/src/xspice/icm/table/table3D/cfunc.mod index 3d12cb388..9fe1cf5b1 100644 --- a/src/xspice/icm/table/table3D/cfunc.mod +++ b/src/xspice/icm/table/table3D/cfunc.mod @@ -304,6 +304,8 @@ cm_table3D_callback(ARGS, Mif_Callback_Reason_t reason) case MIF_CB_DESTROY: { int i, j; Local_Data_t *loc = STATIC_VAR (locdata); + if (!loc) + break; free(loc->state); for (i = 0; i < loc->iz; i++) { @@ -317,6 +319,7 @@ cm_table3D_callback(ARGS, Mif_Callback_Reason_t reason) free(loc->zcol); sf_eno3_close (loc->newtable); free(loc); + STATIC_VAR (locdata) = loc = NULL; break; } } @@ -442,8 +445,9 @@ cm_table3D(ARGS) /* structure holding parms, inputs, outputs, etc. */ struct stat st; if (!loc->state->fp || fstat(fileno(loc->state->fp), &st)) { cm_message_printf("cannot open file %s", PARAM(file)); - loc->state->atend = 1; - loc->init_err = 1; + free(loc->state); + free(loc); + STATIC_VAR (locdata) = loc = NULL; return; } /* get file length */ @@ -455,8 +459,9 @@ cm_table3D(ARGS) /* structure holding parms, inputs, outputs, etc. */ cThisLine = calloc(lFileLen + 1, sizeof(char)); if (cFile == NULL || cThisLine == NULL) { cm_message_printf("Insufficient memory to read file %s", PARAM(file)); - loc->state->atend = 1; - loc->init_err = 1; + free(loc->state); + free(loc); + STATIC_VAR (locdata) = loc = NULL; if(cFile) free(cFile); if(cThisLine) free(cThisLine); return; @@ -668,7 +673,7 @@ cm_table3D(ARGS) /* structure holding parms, inputs, outputs, etc. */ loc = STATIC_VAR (locdata); /* return immediately if there was an initialization error */ - if (loc->init_err == 1) + if (!loc || loc->init_err == 1) return; /* get input x, y, z;