diff --git a/src/frontend/options.c b/src/frontend/options.c index 4a68fdb52..8db40a0a2 100644 --- a/src/frontend/options.c +++ b/src/frontend/options.c @@ -29,13 +29,16 @@ bool ft_nodesprint = FALSE, ft_optsprint = FALSE, ft_noinitprint = FALSE; bool ft_ngdebug = FALSE, ft_stricterror = FALSE; -/* The user-supplied routine to query the values of variables. This - * recognises the $&varname notation, and also searches the values of - * plot and circuit environment variables. +/* The user-supplied routine to query the address of a variable, if its + * name is given. This recognises the $&varname notation, and also + * searches the address of plot and circuit environment variables. + * tbfreed is set to 1, if the variable is malloced here and may safely + * be freed, and is set to 0 if plot and circuit environment variables + * are returned. */ struct variable * -cp_enqvar(char *word) +cp_enqvar(char *word, int *tbfreed) { struct dvec *d; struct variable *vv; @@ -43,6 +46,7 @@ cp_enqvar(char *word) if (*word == '&') { word++; + *tbfreed = 1; d = vec_get(word); if (!d) @@ -71,9 +75,11 @@ cp_enqvar(char *word) } if (plot_cur) { + *tbfreed = 0; for (vv = plot_cur->pl_env; vv; vv = vv->va_next) if (eq(vv->va_name, word)) return (vv); + *tbfreed = 1; if (eq(word, "curplotname")) return var_alloc_string(copy(word), copy(plot_cur->pl_name), NULL); if (eq(word, "curplottitle")) @@ -91,6 +97,7 @@ cp_enqvar(char *word) } } + *tbfreed = 0; if (ft_curckt) for (vv = ft_curckt->ci_vars; vv; vv = vv->va_next) if (eq(vv->va_name, word)) @@ -106,26 +113,27 @@ struct variable * cp_usrvars(void) { struct variable *v, *tv; + int tbfreed; v = NULL; - if ((tv = cp_enqvar("plots")) != NULL) { + if ((tv = cp_enqvar("plots", &tbfreed)) != NULL) { tv->va_next = v; v = tv; } - if ((tv = cp_enqvar("curplot")) != NULL) { + if ((tv = cp_enqvar("curplot", &tbfreed)) != NULL) { tv->va_next = v; v = tv; } - if ((tv = cp_enqvar("curplottitle")) != NULL) { + if ((tv = cp_enqvar("curplottitle", &tbfreed)) != NULL) { tv->va_next = v; v = tv; } - if ((tv = cp_enqvar("curplotname")) != NULL) { + if ((tv = cp_enqvar("curplotname", &tbfreed)) != NULL) { tv->va_next = v; v = tv; } - if ((tv = cp_enqvar("curplotdate")) != NULL) { + if ((tv = cp_enqvar("curplotdate", &tbfreed)) != NULL) { tv->va_next = v; v = tv; } diff --git a/src/frontend/variable.c b/src/frontend/variable.c index f8365bd00..219663c5a 100644 --- a/src/frontend/variable.c +++ b/src/frontend/variable.c @@ -723,7 +723,7 @@ vareval(char *string) char buf[BSIZE_SP], *s; char *oldstring = copy(string); char *range = NULL; - int i, up, low; + int i, up, low, tbfreed; /* usage of vfree: variable v has to be freed only if created by cp_enqvar()! */ @@ -761,8 +761,11 @@ vareval(char *string) for (v = variables; v; v = v->va_next) if (eq(v->va_name, string)) break; - if (!v) - vfree = v = cp_enqvar(string); + if (!v) { + v = cp_enqvar(string, &tbfreed); + if (tbfreed) + vfree = v; + } wl = wl_cons(copy(v ? "1" : "0"), NULL); free_struct_variable(vfree); tfree(oldstring); @@ -773,8 +776,11 @@ vareval(char *string) for (v = variables; v; v = v->va_next) if (eq(v->va_name, string)) break; - if (!v) - vfree = v = cp_enqvar(string); + if (!v) { + v = cp_enqvar(string, &tbfreed); + if (tbfreed) + vfree = v; + } if (!v) { fprintf(cp_err, "Error: %s: no such variable.\n", string); tfree(oldstring); @@ -813,7 +819,9 @@ vareval(char *string) if (!v) { range = NULL; string = oldstring; - vfree = v = cp_enqvar(string); + v = cp_enqvar(string, &tbfreed); + if (tbfreed) + vfree = v; } if (!v && (s = getenv(string)) != NULL) { wl = wl_cons(copy(s), NULL); diff --git a/src/include/ngspice/cpextern.h b/src/include/ngspice/cpextern.h index 9955f0146..314d6ae5f 100644 --- a/src/include/ngspice/cpextern.h +++ b/src/include/ngspice/cpextern.h @@ -180,7 +180,7 @@ extern void cp_periodic(void); extern void ft_cpinit(void); extern struct comm *cp_coms; extern char *cp_program; -extern struct variable *cp_enqvar(char *word); +extern struct variable *cp_enqvar(char *word, int *tbfreed); extern struct variable *cp_usrvars(void); int cp_usrset(struct variable *var, bool isset); extern void fatal(void);