diff --git a/src/frontend/inp.c b/src/frontend/inp.c index d3729a7dc..a4e0c7d68 100644 --- a/src/frontend/inp.c +++ b/src/frontend/inp.c @@ -49,20 +49,24 @@ Author: 1985 Wayne A. Christopher line = NULL; \ } while(0) -static char *upper(register char *string); -static bool doedit(char *filename); + static struct card *com_options = NULL; static struct card *mc_deck = NULL; static struct card *recent_deck = NULL; + static void cktislinear(CKTcircuit *ckt, struct card *deck); +void create_circbyline(char *line); +static bool doedit(char *filename); static void dotifeval(struct card *deck); +static void eval_agauss(struct card *deck, char *fcn); +static wordlist *inp_savecurrents(struct card *deck, struct card *options, + wordlist *wl, wordlist *controls); +void line_free_x(struct card *deck, bool recurse); static void recifeval(struct card *pdeck); +static char *upper(register char *string); + -static wordlist *inp_savecurrents(struct card *deck, struct card *options, wordlist *wl, wordlist *controls); -static void eval_agauss(struct card *deck, char *fcn); -void line_free_x(struct card *deck, bool recurse); -void create_circbyline(char *line); //void inp_source_recent(void); //void inp_mc_free(void); //void inp_remove_recent(void); @@ -641,13 +645,14 @@ inp_spsource(FILE *fp, bool comfile, char *filename, bool intfile) else fprintf(cp_err, "Warning: misplaced .endc card\n"); } else if (commands || prefix("*#", dd->line)) { - /* assemble all commands starting with pre_ after stripping pre_, - to be executed before circuit parsing */ + /* assemble all commands starting with pre_ after stripping + * pre_, to be executed before circuit parsing */ if (ciprefix("pre_", dd->line)) { s = copy(dd->line + 4); pre_controls = wl_cons(s, pre_controls); } - /* assemble all other commands to be executed after circuit parsing */ + /* assemble all other commands to be executed after circuit + * parsing */ else { /* special control lines outside of .control section*/ if (prefix("*#", dd->line)) { @@ -673,14 +678,13 @@ inp_spsource(FILE *fp, bool comfile, char *filename, bool intfile) if (!eq(s, ".plot") && !eq(s, ".print")) inp_casefix(dd->line); if (eq(s, ".width") || - ciprefix(".four", s) || - eq(s, ".plot") || - eq(s, ".print") || - eq(s, ".save") || - eq(s, ".op") || - ciprefix(".meas", s) || - eq(s, ".tf")) - { + ciprefix(".four", s) || + eq(s, ".plot") || + eq(s, ".print") || + eq(s, ".save") || + eq(s, ".op") || + ciprefix(".meas", s) || + eq(s, ".tf")) { wl_append_word(&wl_first, &end, copy(dd->line)); if (!eq(s, ".op") && !eq(s, ".tf") && !ciprefix(".meas", s)) { @@ -782,8 +786,9 @@ inp_spsource(FILE *fp, bool comfile, char *filename, bool intfile) cstoken[0] = gettok_char(&s, '=', FALSE, FALSE); cstoken[1] = gettok_char(&s, '=', TRUE, FALSE); cstoken[2] = gettok(&s); - for (i = 3; --i >= 0;) + for (i = 3; --i >= 0; ) { wlist = wl_cons(cstoken[i], wlist); + } com_let(wlist); wl_free(wlist); } @@ -1599,9 +1604,11 @@ com_source(wordlist *wl) } -void -inp_source(char *file) +void inp_source(char *file) { + /* This wordlist is special in that nothing in it should be freed -- + * the file name word is "borrowed" from the argument to file and + * the wordlist is allocated on the stack. */ static struct wordlist wl = { NULL, NULL, NULL }; wl.wl_word = file; com_source(&wl); @@ -1612,8 +1619,7 @@ inp_source(char *file) for linear elements. If only linear elements are found, ckt->CKTisLinear is set to 1. Return immediately if a first non-linear element is found. */ -static void -cktislinear(CKTcircuit *ckt, struct card *deck) +static void cktislinear(CKTcircuit *ckt, struct card *deck) { struct card *dd; char firstchar; @@ -1646,40 +1652,51 @@ cktislinear(CKTcircuit *ckt, struct card *deck) /* global array for assembling circuit lines entered by fcn circbyline - or receiving array from external caller. Array is created once per ngspice call. - Last line of the array has to get the value NULL */ + * or receiving array from external caller. Array is created whenever + * a new deck is started. Last line of the array has to get the value NULL */ char **circarray; -void -create_circbyline(char *line) +void create_circbyline(char *line) { - static int linec = 0; - static int memlen = 256; - FILE *fp = NULL; - if (!circarray) - circarray = TMALLOC(char*, memlen); - char *p = skip_ws(line); - if (line < p) - memmove(line, p, strlen(p) + 1); - circarray[linec++] = line; - if (linec < memlen) { - if (ciprefix(".end", line) && (line[4] == '\0' || isspace_c(line[4]))) { - circarray[linec] = NULL; - inp_spsource(fp, FALSE, NULL, TRUE); - linec = 0; + static unsigned int linec = 0; + static unsigned int n_elem_alloc = 0; + + /* Ensure up to 2 cards can be added */ + if (n_elem_alloc < linec + 2) { + n_elem_alloc = n_elem_alloc == 0 ? 256 : 2 * n_elem_alloc; + circarray = TREALLOC(char *, circarray, n_elem_alloc); + } + + /* Remove any leading whitespace by shifting */ + char *p_src = skip_ws(line); + if (p_src != line) { + char *p_dst = line; + char ch_cur; + do { + ch_cur = *p_dst++ = *p_src++; } + while (ch_cur != '\0'); } - else { - memlen += memlen; - circarray = TREALLOC(char*, circarray, memlen); + + circarray[linec++] = line; /* add card to deck */ + + /* If the card added ended the deck, send it for processing and + * free the deck. The card allocations themselves will be freed + * elsewhere */ + if (ciprefix(".end", line) && (line[4] == '\0' || isspace_c(line[4]))) { + circarray[linec] = NULL; /* termiante the deck */ + inp_spsource((FILE *) NULL, FALSE, NULL, TRUE); /* process */ + tfree(circarray); /* set to empty */ + linec = 0; + n_elem_alloc = 0; } -} +} /* end of function create_circbyline */ + /* fcn called by command 'circbyline' */ -void -com_circbyline(wordlist *wl) +void com_circbyline(wordlist *wl) { /* undo the automatic wordline creation. wl_flatten allocates memory on the heap for each newline. @@ -1693,8 +1710,7 @@ com_circbyline(wordlist *wl) numparam has evaluated .if('boolean expression') to .if ( 1.000000000e+000 ) or .elseif ( 0.000000000e+000 ). Evaluation is done recursively, starting with .IF, ending with .ENDIF*/ -static void -recifeval(struct card *pdeck) +static void recifeval(struct card *pdeck) { struct card *nd; int iftrue = 0, elseiftrue = 0, elsetrue = 0, iffound = 0, elseiffound = 0, elsefound = 0; @@ -1753,8 +1769,7 @@ recifeval(struct card *pdeck) } /* Scan through all lines of the deck */ -static void -dotifeval(struct card *deck) +static void dotifeval(struct card *deck) { struct card *dd; char *dottoken; @@ -1806,8 +1821,8 @@ dotifeval(struct card *deck) to the model parameters or device instance parameters. */ -static int -inp_parse_temper(struct card *card, struct pt_temper **modtlist_p, struct pt_temper **devtlist_p) +static int inp_parse_temper(struct card *card, struct pt_temper **modtlist_p, + struct pt_temper **devtlist_p) { int error = 0; @@ -1930,8 +1945,8 @@ rem_tlist(struct pt_temper *p) } -void -inp_evaluate_temper(struct circ *circ) + +void inp_evaluate_temper(struct circ *circ) { struct pt_temper *d; double result; @@ -1944,20 +1959,24 @@ inp_evaluate_temper(struct circ *circ) com_alter(d->wl); } + /* Step through the nodes of the linked list at circ->modtlist */ for(d = circ->modtlist; d; d = d->next) { char *name = d->wl->wl_word; INPretrieve(&name, circ->ci_symtab); /* only evaluate models which have been entered into the hash table ckt->MODnameHash */ - if (ft_sim->findModel (circ->ci_ckt, name) == NULL) + if (ft_sim->findModel (circ->ci_ckt, name) == NULL) { continue; + } + IFeval((IFparseTree *) d->pt, 1e-12, &result, NULL, NULL); if (d->wlend->wl_word) tfree(d->wlend->wl_word); d->wlend->wl_word = tprintf("%g", result); com_altermod(d->wl); } -} +} /* end of funtion inp_evaluate_temper */ + /* @@ -1998,10 +2017,12 @@ inp_savecurrents(struct card *deck, struct card *options, wordlist *wl, wordlist break; /* if not found, then add '.save all' */ - if (!p) + if (!p) { p = wl_cons(copy(".save all"), NULL); - else + } + else { p = NULL; + } /* Scan the deck for devices with their terminals. * We currently serve bipolars, resistors, MOS1, capacitors, inductors,