diff --git a/src/frontend/dotcards.c b/src/frontend/dotcards.c index 2e3fd5ad2..29b3eea01 100644 --- a/src/frontend/dotcards.c +++ b/src/frontend/dotcards.c @@ -57,7 +57,7 @@ void ft_dotsaves(void) { wordlist *iline, *wl = NULL; - char *s, *fr; + char *s; if (!ft_curckt) /* Shouldn't happen. */ return; @@ -66,8 +66,7 @@ ft_dotsaves(void) if (ciprefix(".save", iline->wl_word)) { s = iline->wl_word; /* skip .save */ - fr = gettok(&s); - tfree(fr); + gettok_nc(&s); wl = wl_append(wl, gettoks(s)); } @@ -112,7 +111,7 @@ ft_savedotargs(void) isaplot = 0; if (isaplot || ciprefix(".print", s)) { - (void) gettok(&s); + gettok_nc(&s); name = gettok(&s); if ((w = gettoks(s)) == NULL) { @@ -138,8 +137,8 @@ ft_savedotargs(void) com_save2(w, name); } } else if (ciprefix(".four", s)) { - (void) gettok(&s); - (void) gettok(&s); + gettok_nc(&s); + gettok_nc(&s); if ((w = gettoks(s)) == NULL) { fprintf(cp_err, "Warning: no nodes given: %s\n", iline->wl_word); } else { diff --git a/src/frontend/inp.c b/src/frontend/inp.c index 320ecec21..a4df90136 100644 --- a/src/frontend/inp.c +++ b/src/frontend/inp.c @@ -1456,8 +1456,7 @@ inp_parse_temper(struct line *card) if (prefix(".model", curr_line)) { struct pt_temper *modtlistnew = NULL; /* remove '.model' */ - str_ptr = gettok(&curr_line); - tfree(str_ptr); + gettok_nc(&curr_line); devmodname = gettok(&curr_line); beg_tstr = curr_line; while ((end_tstr = beg_tstr = strstr(beg_tstr, "temper")) != NULL) { diff --git a/src/frontend/inpcom.c b/src/frontend/inpcom.c index 349ddcf82..4575de5e9 100644 --- a/src/frontend/inpcom.c +++ b/src/frontend/inpcom.c @@ -5295,14 +5295,14 @@ replace_token(char *string, char *token, int wherereplace, int total) /* get total number of tokens */ while (*actstring) { - txfree(gettok(&actstring)); + gettok_nc(&actstring); count++; } /* If total number of tokens correct */ if (count == total) { actstring = string; for (i = 1; i < wherereplace; i++) - txfree(gettok(&actstring)); + gettok_nc(&actstring); /* If token to be replaced at right position */ if (ciprefix(token, actstring)) { actstring[0] = ' '; @@ -5776,9 +5776,9 @@ inp_poly_err(struct line *card) if ((ciprefix("e", curr_line)) || (ciprefix("g", curr_line)) || (ciprefix("f", curr_line)) || (ciprefix("h", curr_line))) { - txfree(gettok(&curr_line)); - txfree(gettok(&curr_line)); - txfree(gettok(&curr_line)); + gettok_nc(&curr_line); + gettok_nc(&curr_line); + gettok_nc(&curr_line); if (ciprefix("poly", curr_line)) { fprintf(stderr, "\nError: XSPICE is required to run the 'poly' option in line %d\n", @@ -6037,7 +6037,7 @@ inp_fix_temper_in_param(struct line *deck) /* if we have inserted into a .param line, convert to .func */ if (prefix(".param", new_str)) { char *new_tmp_str = new_str; - txfree(gettok(&new_tmp_str)); + gettok_nc(&new_tmp_str); funcname = gettok_char(&new_tmp_str, '=', FALSE, FALSE); funcbody = copy(new_tmp_str + 1); *funcs_tail_ptr = diff --git a/src/frontend/measure.c b/src/frontend/measure.c index 3567cecb9..5b7d99416 100644 --- a/src/frontend/measure.c +++ b/src/frontend/measure.c @@ -264,7 +264,7 @@ do_measure( for (meas_card = ft_curckt->ci_meas; meas_card != NULL; meas_card = meas_card->li_next) { line = meas_card->li_line; - txfree(gettok(&line)); /* discard .meas */ + gettok_nc(&line); /* discard .meas */ an_type = gettok(&line); resname = gettok(&line); @@ -359,7 +359,7 @@ do_measure( for (meas_card = ft_curckt->ci_meas; meas_card != NULL; meas_card = meas_card->li_next) { line = meas_card->li_line; - txfree(gettok(&line)); /* discard .meas */ + gettok_nc(&line); /* discard .meas */ an_type = gettok(&line); resname = gettok(&line); @@ -466,7 +466,7 @@ measure_parse_line(char *line) char *extra_item; /* extra item */ wl = NULL; - txfree(gettok(&line)); + gettok_nc(&line); do { item = gettok(&line); if (!(item)) diff --git a/src/frontend/options.c b/src/frontend/options.c index 7fea1a7a7..a9e831fa3 100644 --- a/src/frontend/options.c +++ b/src/frontend/options.c @@ -170,7 +170,7 @@ inp_getoptsc(char *in_line, struct line *com_options) /* option -> .options */ /* skip option */ - gettok(&in_line); + gettok_nc(&in_line); line = tprintf(".options %s", in_line); next = TMALLOC(struct line, 1); diff --git a/src/frontend/rawfile.c b/src/frontend/rawfile.c index 312ab1dd4..2394e8153 100644 --- a/src/frontend/rawfile.c +++ b/src/frontend/rawfile.c @@ -474,7 +474,7 @@ raw_read(char *name) { (void) fgets(buf, BSIZE_SP, fp); s = buf; } - (void) gettok(&s); /* The strchr field. */ + gettok_nc(&s); /* The strchr field. */ if ((t = gettok(&s)) != NULL) { v->v_name = t; } else { diff --git a/src/frontend/subckt.c b/src/frontend/subckt.c index 75129c648..bc74035ae 100644 --- a/src/frontend/subckt.c +++ b/src/frontend/subckt.c @@ -150,7 +150,7 @@ collect_global_nodes(struct line *c) for (; c; c = c->li_next) if (ciprefix(".global", c->li_line)) { char *s = c->li_line; - txfree(gettok(&s)); + gettok_nc(&s); while (*s) { char *t = skip_non_ws(s); global_nodes[num_global_nodes++] = copy_substring(s, t); @@ -270,7 +270,7 @@ inp_subcktexpand(struct line *deck) { if (ciprefix(model, c->li_line)) { char *s = c->li_line; - txfree(gettok(&s)); /* discard the model keyword */ + gettok_nc(&s); /* discard the model keyword */ modnames = wl_cons(gettok(&s), modnames); } /* model name finding routine */ } @@ -482,7 +482,7 @@ doit(struct line *deck, wordlist *modnames) { sss = TMALLOC(struct subs, 1); - txfree(gettok(&s)); + gettok_nc(&s); sss->su_name = gettok(&s); sss->su_args = copy(s); @@ -615,7 +615,7 @@ doit(struct line *deck, wordlist *modnames) { /* prepend the translated model names to the list `modnames' */ modnames = modtranslate(su_deck, scname, modnames); - txfree(gettok(&t)); /* Throw out the subcircuit refdes */ + gettok_nc(&t); /* Throw out the subcircuit refdes */ /* now invoke translate, which handles the remainder of the * translation. @@ -1516,7 +1516,7 @@ numnodes(char *name, struct subs *subs, wordlist const *modnames) i = 0; s = buf; gotit = 0; - txfree(gettok(&s)); /* Skip component name */ + gettok_nc(&s); /* Skip component name */ while ((i < n) && (*s) && !gotit) { t = gettok_node(&s); /* get nodenames . . . */ for (wl = modnames; wl; wl = wl->wl_next) @@ -1543,7 +1543,7 @@ numnodes(char *name, struct subs *subs, wordlist const *modnames) return (n); for (s = buf, i = 0; *s && (i < 4); i++) - txfree(gettok(&s)); + gettok_nc(&s); if (i == 3) return (3); @@ -1622,7 +1622,7 @@ modtranslate(struct line *c, char *subname, wordlist *new_modnames) #endif /* swallow ".model" */ - txfree(gettok(&t)); + gettok_nc(&t); model_name = gettok(&t); diff --git a/src/include/ngspice/ngspice.h b/src/include/ngspice/ngspice.h index 086b214cf..bcbf32377 100644 --- a/src/include/ngspice/ngspice.h +++ b/src/include/ngspice/ngspice.h @@ -241,6 +241,7 @@ extern double x_atanh(double); extern char *gettok_noparens(char **s); extern char *gettok_node(char **s); extern char *gettok_iv(char **s); +extern int gettok_nc(char **s); extern int get_l_paren(char **s); extern int get_r_paren(char **s); diff --git a/src/misc/string.c b/src/misc/string.c index 3ea96097b..9c872bf70 100644 --- a/src/misc/string.c +++ b/src/misc/string.c @@ -306,6 +306,40 @@ gettok(char **s) return ( token ) ; } + +/*-------------------------------------------------------------------------* +* gettok_nc skips over whitespaces and the next token in s, but does not +* use TMALLOC or not return anything * but 1 for empty s and 0 if o.k. . +* It replaces constructs like txfree(gettok(&actstring)) by +* gettok_nc(&actstring). This is derived from the original gettok version. +* It does not "do the right thing" when +* you have parens or commas anywhere in the nodelist. +*-------------------------------------------------------------------------*/ +int +gettok_nc(char **s) +{ + char c; + int paren; + + paren = 0; + *s = skip_ws(*s); + if (!**s) + return (1); + while ((c = **s) != '\0' && !isspace_c(c)) { + if (c == '(') + paren += 1; + else if (c == ')') + paren -= 1; + else if (c == ',' && paren < 1) + break; + (*s)++; + } + while (isspace_c(**s) || **s == ',') + (*s)++; + return (0); +} + + /*-------------------------------------------------------------------------* * gettok skips over whitespaces or '=' and returns the next token found, * if the token is something like i(xxx), v(yyy), or v(xxx,yyy)