From b4e84d4b47db82a5a28f248ef0bf850df84949e0 Mon Sep 17 00:00:00 2001 From: stefanjones Date: Wed, 16 Jul 2003 15:37:25 +0000 Subject: [PATCH] 2003-07-16 Vera Albrecht * frontend/{device.c,parse.c,vectors.c,com_compose.c} : More memory leaks closed in utility commands and functions. --- ChangeLog | 5 ++++ src/frontend/com_compose.c | 2 +- src/frontend/device.c | 22 ++++++++------- src/frontend/parse.c | 56 +++++++++++++++++++++++++++++++++++--- src/frontend/vectors.c | 29 +++++++++++++------- 5 files changed, 89 insertions(+), 25 deletions(-) diff --git a/ChangeLog b/ChangeLog index 88fb1fdbe..7be8e2f92 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2003-07-16 Vera Albrecht + + * frontend/{device.c,parse.c,vectors.c,com_compose.c} : + More memory leaks closed in utility commands and functions. + 2003-07-16 Stefan Jones * src/frontend/{com_compose.c,cpitf.c,device.c,subckt.c,vectors.c} diff --git a/src/frontend/com_compose.c b/src/frontend/com_compose.c index 18ee66785..f179c2ec5 100644 --- a/src/frontend/com_compose.c +++ b/src/frontend/com_compose.c @@ -118,7 +118,7 @@ com_compose(wordlist *wl) bool realflag = TRUE; int dims[MAXDIMS]; struct dvec *result, *vecs = NULL, *v, *lv = NULL; - struct pnode *pn, *first_pn; + struct pnode *pn, *first_pn=NULL; bool reverse = FALSE; resname = cp_unquote(wl->wl_word); diff --git a/src/frontend/device.c b/src/frontend/device.c index 1da120ba5..952b4b5cf 100644 --- a/src/frontend/device.c +++ b/src/frontend/device.c @@ -235,16 +235,17 @@ all_show(wordlist *wl, int mode) int printstr(dgen *dg, char *name) { + /* va: ' ' is no flag for %s; \? avoids trigraph warning */ if (*name == 'n') { if (dg->instance) - printf(" % *.*s", DEV_WIDTH, DEV_WIDTH, dg->instance->GENname); + printf(" %*.*s", DEV_WIDTH, DEV_WIDTH, dg->instance->GENname); else - printf(" %*s", DEV_WIDTH, ""); + printf(" %*s", DEV_WIDTH, "<\?\?\?\?\?\?\?>"); } else if (*name == 'm') { if (dg->model) - printf(" % *.*s", DEV_WIDTH, DEV_WIDTH, dg->model->GENmodName); + printf(" %*.*s", DEV_WIDTH, DEV_WIDTH, dg->model->GENmodName); else - printf(" %*s", DEV_WIDTH, ""); + printf(" %*s", DEV_WIDTH, "<\?\?\?\?\?\?\?>"); } else printf(" %*s", DEV_WIDTH, ""); @@ -400,6 +401,7 @@ printvals(dgen *dg, IFparm *p, int i) } if (p->dataType & IF_VECTOR) { + /* va: ' ' is no flag for %s */ switch ((p->dataType & IF_VARTYPES) & ~IF_VECTOR) { case IF_FLAG: 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); break; 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; 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; default: - printf(" % *.*s", DEV_WIDTH, DEV_WIDTH, " ******** "); + printf(" %*.*s", DEV_WIDTH, DEV_WIDTH, " ******** "); } } else { 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); break; case IF_STRING: - printf(" % *.*s", DEV_WIDTH, DEV_WIDTH, val.sValue); + printf(" %*.*s", DEV_WIDTH, DEV_WIDTH, val.sValue); break; case IF_INSTANCE: - printf(" % *.*s", DEV_WIDTH, DEV_WIDTH, val.uValue); + printf(" %*.*s", DEV_WIDTH, DEV_WIDTH, val.uValue); break; default: - printf(" % *.*s", DEV_WIDTH, DEV_WIDTH, " ******** "); + printf(" %*.*s", DEV_WIDTH, DEV_WIDTH, " ******** "); } } diff --git a/src/frontend/parse.c b/src/frontend/parse.c index 664829c72..21b8fb016 100644 --- a/src/frontend/parse.c +++ b/src/frontend/parse.c @@ -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 * mknnode(double number); static struct pnode * mksnode(char *string); +static void print_elem(struct element *elem); /* va: for debugging */ 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 * 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 * lexer(void) { @@ -496,6 +498,19 @@ parse(void) goto err; if (!(pn = mkfnode(stack[sp].e_string, lpn))) 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 */ lpn = makepnode(&stack[sp]); 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. */ static @@ -810,6 +847,12 @@ mksnode(char *string) end = nv; } 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); } @@ -822,9 +865,14 @@ free_pnode(struct pnode *t) free_pnode(t->pn_left); free_pnode(t->pn_right); free_pnode(t->pn_next); - tfree(t->pn_name); - if(t->pn_value) - vec_free(t->pn_value); + tfree(t->pn_name); /* va: it is a copy() of original string, can be free'd */ + /* va: tfree struct func, allocated within parser */ + 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); } diff --git a/src/frontend/vectors.c b/src/frontend/vectors.c index f16341f4a..60558ecf4 100644 --- a/src/frontend/vectors.c +++ b/src/frontend/vectors.c @@ -354,11 +354,9 @@ vec_get(char *word) d = newv; if (!d) { fprintf(cp_err, - "Error: plot wildcard (name %s) matches nothing\n", + "Error: plot wildcard (name %s) matches nothing\n", word); - - /* MW. I don't want core leaks here */ - tfree(wd); + tfree(wd); /* MW. I don't want core leaks here */ return (NULL); } } @@ -367,13 +365,12 @@ vec_get(char *word) /* This is a special quantity... */ if (ft_nutmeg) { fprintf(cp_err, - "Error: circuit parameters only available with spice\n"); - - tfree(wd); /* MW. Memory leak fixed again */ - return (FALSE); + "Error: circuit parameters only available with spice\n"); + tfree(wd); /* MW. Memory leak fixed again */ + return (NULL); /* va: use NULL */ } - whole=copy(word); + whole=copy(word); name = ++word; for (param = name; *param && (*param != '['); param++) ; @@ -411,10 +408,11 @@ vec_get(char *word) d->v_length = 1; *d->v_realdata = vv->va_real; + tfree(vv->va_name); + tfree(vv); /* va: tfree vv->va_name and vv (avoid memory leakages) */ tfree(wd); vec_new(d); tfree(whole); - tfree(wd); return (d); } @@ -517,9 +515,11 @@ plot_alloc(char *name) } while (tp); pl->pl_typename = copy(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); cp_addkword(CT_VECTOR, "all"); 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); } @@ -692,6 +692,8 @@ vec_basename(struct dvec *v) /* Make a plot the current one. This gets called by cp_usrset() when one * does a 'set curplot = name'. + * va: ATTENTION: has unlinked old keyword-class-tree from keywords[CT_VECTOR] + * (potentially memory leak) */ void @@ -715,8 +717,15 @@ plot_setcur(char *name) fprintf(cp_err, "Error: no such plot named %s\n", name); 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) + { plot_cur->pl_ccom = cp_kwswitch(CT_VECTOR, pl->pl_ccom); + } +*/ plot_cur = pl; return; }