2003-07-16 Vera Albrecht <albrecht@danalyse.de>

* frontend/{device.c,parse.c,vectors.c,com_compose.c} :
	More memory leaks closed in utility commands and functions.
This commit is contained in:
stefanjones 2003-07-16 15:37:25 +00:00
parent 88239474a8
commit b4e84d4b47
5 changed files with 89 additions and 25 deletions

View File

@ -1,3 +1,8 @@
2003-07-16 Vera Albrecht <albrecht@danalyse.de>
* frontend/{device.c,parse.c,vectors.c,com_compose.c} :
More memory leaks closed in utility commands and functions.
2003-07-16 Stefan Jones <stefan.jones@multigig.com> 2003-07-16 Stefan Jones <stefan.jones@multigig.com>
* src/frontend/{com_compose.c,cpitf.c,device.c,subckt.c,vectors.c} * src/frontend/{com_compose.c,cpitf.c,device.c,subckt.c,vectors.c}

View File

@ -118,7 +118,7 @@ com_compose(wordlist *wl)
bool realflag = TRUE; bool realflag = TRUE;
int dims[MAXDIMS]; int dims[MAXDIMS];
struct dvec *result, *vecs = NULL, *v, *lv = NULL; struct dvec *result, *vecs = NULL, *v, *lv = NULL;
struct pnode *pn, *first_pn; struct pnode *pn, *first_pn=NULL;
bool reverse = FALSE; bool reverse = FALSE;
resname = cp_unquote(wl->wl_word); resname = cp_unquote(wl->wl_word);

View File

@ -235,16 +235,17 @@ all_show(wordlist *wl, int mode)
int int
printstr(dgen *dg, char *name) printstr(dgen *dg, char *name)
{ {
/* va: ' ' is no flag for %s; \? avoids trigraph warning */
if (*name == 'n') { if (*name == 'n') {
if (dg->instance) if (dg->instance)
printf(" % *.*s", DEV_WIDTH, DEV_WIDTH, dg->instance->GENname); printf(" %*.*s", DEV_WIDTH, DEV_WIDTH, dg->instance->GENname);
else else
printf(" %*s", DEV_WIDTH, "<???????>"); printf(" %*s", DEV_WIDTH, "<\?\?\?\?\?\?\?>");
} else if (*name == 'm') { } else if (*name == 'm') {
if (dg->model) if (dg->model)
printf(" % *.*s", DEV_WIDTH, DEV_WIDTH, dg->model->GENmodName); printf(" %*.*s", DEV_WIDTH, DEV_WIDTH, dg->model->GENmodName);
else else
printf(" %*s", DEV_WIDTH, "<???????>"); printf(" %*s", DEV_WIDTH, "<\?\?\?\?\?\?\?>");
} else } else
printf(" %*s", DEV_WIDTH, "<error>"); printf(" %*s", DEV_WIDTH, "<error>");
@ -400,6 +401,7 @@ printvals(dgen *dg, IFparm *p, int i)
} }
if (p->dataType & IF_VECTOR) { if (p->dataType & IF_VECTOR) {
/* va: ' ' is no flag for %s */
switch ((p->dataType & IF_VARTYPES) & ~IF_VECTOR) { switch ((p->dataType & IF_VARTYPES) & ~IF_VECTOR) {
case IF_FLAG: case IF_FLAG:
printf(" % *d", DEV_WIDTH, val.v.vec.iVec[i]); printf(" % *d", DEV_WIDTH, val.v.vec.iVec[i]);
@ -417,13 +419,13 @@ printvals(dgen *dg, IFparm *p, int i)
printf(" % *.6g", DEV_WIDTH, val.v.vec.cVec[i / 2].imag); printf(" % *.6g", DEV_WIDTH, val.v.vec.cVec[i / 2].imag);
break; break;
case IF_STRING: case IF_STRING:
printf(" % *.*s", DEV_WIDTH, DEV_WIDTH, val.v.vec.sVec[i]); printf(" %*.*s", DEV_WIDTH, DEV_WIDTH, val.v.vec.sVec[i]);
break; break;
case IF_INSTANCE: case IF_INSTANCE:
printf(" % *.*s", DEV_WIDTH, DEV_WIDTH, val.v.vec.uVec[i]); printf(" %*.*s", DEV_WIDTH, DEV_WIDTH, val.v.vec.uVec[i]);
break; break;
default: default:
printf(" % *.*s", DEV_WIDTH, DEV_WIDTH, " ******** "); printf(" %*.*s", DEV_WIDTH, DEV_WIDTH, " ******** ");
} }
} else { } else {
switch ((p->dataType & IF_VARTYPES) & ~IF_VECTOR) { switch ((p->dataType & IF_VARTYPES) & ~IF_VECTOR) {
@ -443,13 +445,13 @@ printvals(dgen *dg, IFparm *p, int i)
printf(" % *.6g", DEV_WIDTH, val.cValue.imag); printf(" % *.6g", DEV_WIDTH, val.cValue.imag);
break; break;
case IF_STRING: case IF_STRING:
printf(" % *.*s", DEV_WIDTH, DEV_WIDTH, val.sValue); printf(" %*.*s", DEV_WIDTH, DEV_WIDTH, val.sValue);
break; break;
case IF_INSTANCE: case IF_INSTANCE:
printf(" % *.*s", DEV_WIDTH, DEV_WIDTH, val.uValue); printf(" %*.*s", DEV_WIDTH, DEV_WIDTH, val.uValue);
break; break;
default: default:
printf(" % *.*s", DEV_WIDTH, DEV_WIDTH, " ******** "); printf(" %*.*s", DEV_WIDTH, DEV_WIDTH, " ******** ");
} }
} }

View File

@ -27,6 +27,7 @@ static struct pnode * mkunode(int op, struct pnode *arg);
static struct pnode * mkfnode(char *func, struct pnode *arg); static struct pnode * mkfnode(char *func, struct pnode *arg);
static struct pnode * mknnode(double number); static struct pnode * mknnode(double number);
static struct pnode * mksnode(char *string); static struct pnode * mksnode(char *string);
static void print_elem(struct element *elem); /* va: for debugging */
static int lasttoken = END, lasttype; static int lasttoken = END, lasttype;
@ -115,7 +116,8 @@ checkvalid(struct pnode *pn)
/* Everything else is a string or a number. Quoted strings are kept in /* Everything else is a string or a number. Quoted strings are kept in
* the form "string", and the lexer strips off the quotes... * the form "string", and the lexer strips off the quotes...
*/ */
/* va: the structure returned is static, e_string is a copy
(in case of e_token==VALUE,e_type==STRING) */
static struct element * static struct element *
lexer(void) lexer(void)
{ {
@ -496,6 +498,19 @@ parse(void)
goto err; goto err;
if (!(pn = mkfnode(stack[sp].e_string, lpn))) if (!(pn = mkfnode(stack[sp].e_string, lpn)))
return (NULL); return (NULL);
/* va: avoid memory leakage:
in case of variablenames (i.e. i(vd)) mkfnode makes in
reality a snode, the old lpn (and its plotless vector) is
then a memory leak */
if (pn->pn_func==NULL && pn->pn_value!=NULL) /* a snode */
{
if (lpn->pn_value && lpn->pn_value->v_plot==NULL)
{
tfree(lpn->pn_value->v_name);
tfree(lpn->pn_value);
}
free_pnode(lpn);
}
} else { /* node op node */ } else { /* node op node */
lpn = makepnode(&stack[sp]); lpn = makepnode(&stack[sp]);
rpn = makepnode(&stack[st]); rpn = makepnode(&stack[st]);
@ -542,6 +557,28 @@ makepnode(struct element *elem)
} }
} }
static void print_elem(struct element *elem)
{
printf("e_token = %d", elem->e_token);
if (elem->e_token == VALUE) {
printf(", e_type = %d", elem->e_type);
switch (elem->e_type) {
case STRING:
printf(", e_string = %s(%p)", elem->e_string,elem->e_string);
break;
case NUM:
printf(", e_double = %g", elem->e_double); break;
case PNODE:
printf(", e_pnode = %p", elem->e_pnode); break;
default:
break;
}
}
printf("\n");
}
/* Some auxiliary functions for building the parse tree. */ /* Some auxiliary functions for building the parse tree. */
static static
@ -810,6 +847,12 @@ mksnode(char *string)
end = nv; end = nv;
} }
p->pn_value = newv; p->pn_value = newv;
/* va: tfree v in case of @xxx[par], because vec_get created a new vec and
nobody will free it elsewhere */
if (v && v->v_name && *v->v_name=='@' && isreal(v) && v->v_realdata) {
vec_free(v);
}
return (p); return (p);
} }
@ -822,9 +865,14 @@ free_pnode(struct pnode *t)
free_pnode(t->pn_left); free_pnode(t->pn_left);
free_pnode(t->pn_right); free_pnode(t->pn_right);
free_pnode(t->pn_next); free_pnode(t->pn_next);
tfree(t->pn_name); tfree(t->pn_name); /* va: it is a copy() of original string, can be free'd */
if(t->pn_value) /* va: tfree struct func, allocated within parser */
vec_free(t->pn_value); if (t->pn_func!=NULL) {
tfree(t->pn_func->fu_name); /* va: name is a copy of original string */
tfree(t->pn_func); /* va: t->pn_func->fu_func must not tfree'd */
}
if (t->pn_value)
vec_free(t->pn_value); /* patch by Stefan Jones */
tfree(t); tfree(t);
} }

View File

@ -354,11 +354,9 @@ vec_get(char *word)
d = newv; d = newv;
if (!d) { if (!d) {
fprintf(cp_err, fprintf(cp_err,
"Error: plot wildcard (name %s) matches nothing\n", "Error: plot wildcard (name %s) matches nothing\n",
word); word);
tfree(wd); /* MW. I don't want core leaks here */
/* MW. I don't want core leaks here */
tfree(wd);
return (NULL); return (NULL);
} }
} }
@ -367,13 +365,12 @@ vec_get(char *word)
/* This is a special quantity... */ /* This is a special quantity... */
if (ft_nutmeg) { if (ft_nutmeg) {
fprintf(cp_err, fprintf(cp_err,
"Error: circuit parameters only available with spice\n"); "Error: circuit parameters only available with spice\n");
tfree(wd); /* MW. Memory leak fixed again */
tfree(wd); /* MW. Memory leak fixed again */ return (NULL); /* va: use NULL */
return (FALSE);
} }
whole=copy(word); whole=copy(word);
name = ++word; name = ++word;
for (param = name; *param && (*param != '['); param++) for (param = name; *param && (*param != '['); param++)
; ;
@ -411,10 +408,11 @@ vec_get(char *word)
d->v_length = 1; d->v_length = 1;
*d->v_realdata = vv->va_real; *d->v_realdata = vv->va_real;
tfree(vv->va_name);
tfree(vv); /* va: tfree vv->va_name and vv (avoid memory leakages) */
tfree(wd); tfree(wd);
vec_new(d); vec_new(d);
tfree(whole); tfree(whole);
tfree(wd);
return (d); return (d);
} }
@ -517,9 +515,11 @@ plot_alloc(char *name)
} while (tp); } while (tp);
pl->pl_typename = copy(buf); pl->pl_typename = copy(buf);
cp_addkword(CT_PLOT, buf); cp_addkword(CT_PLOT, buf);
/* va: create a new, empty keyword tree for class CT_VECTOR, s=old tree */
s = cp_kwswitch(CT_VECTOR, (char *) NULL); s = cp_kwswitch(CT_VECTOR, (char *) NULL);
cp_addkword(CT_VECTOR, "all"); cp_addkword(CT_VECTOR, "all");
pl->pl_ccom = cp_kwswitch(CT_VECTOR, s); pl->pl_ccom = cp_kwswitch(CT_VECTOR, s);
/* va: keyword tree is old tree again, new tree is linked to pl->pl_ccom */
return (pl); return (pl);
} }
@ -692,6 +692,8 @@ vec_basename(struct dvec *v)
/* Make a plot the current one. This gets called by cp_usrset() when one /* Make a plot the current one. This gets called by cp_usrset() when one
* does a 'set curplot = name'. * does a 'set curplot = name'.
* va: ATTENTION: has unlinked old keyword-class-tree from keywords[CT_VECTOR]
* (potentially memory leak)
*/ */
void void
@ -715,8 +717,15 @@ plot_setcur(char *name)
fprintf(cp_err, "Error: no such plot named %s\n", name); fprintf(cp_err, "Error: no such plot named %s\n", name);
return; return;
} }
/* va: we skip cp_kwswitch, because it confuses the keyword-tree management for
* repeated op-commands. When however cp_kwswitch is necessary for other
* reasons, we should hold the original keyword table pointer in an
* permanent variable, since it will lost here, and can never tfree'd.
if (plot_cur) if (plot_cur)
{
plot_cur->pl_ccom = cp_kwswitch(CT_VECTOR, pl->pl_ccom); plot_cur->pl_ccom = cp_kwswitch(CT_VECTOR, pl->pl_ccom);
}
*/
plot_cur = pl; plot_cur = pl;
return; return;
} }