cp_enqvar() returns freshly malloced variables as well

as variables owned by somebody else, e.g. from ft_curckt->ci_vars.
The new function parameter tbfreed notifies the caller if the
variable is malloced here and may be freed safely.
This commit is contained in:
Holger Vogt 2018-10-07 14:52:52 +02:00
parent 6df684e22a
commit d636f7899b
3 changed files with 32 additions and 16 deletions

View File

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

View File

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

View File

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