Browse Source

Applied another bunch of patches sent by CDHW (Charles D.H. Williams). The patches

are aimed to close some leaks in the parser.
pre-master-46
pnenzi 25 years ago
parent
commit
7583d1849e
  1. 23
      src/frontend/com_cdump.c
  2. 1
      src/frontend/com_cdump.h
  3. 117
      src/frontend/control.c
  4. 1
      src/frontend/control.h
  5. 3
      src/frontend/parser/complete.c
  6. 34
      src/frontend/parser/lexical.c
  7. 11
      src/frontend/variable.c
  8. 1
      src/frontend/variable.h

23
src/frontend/com_cdump.c

@ -5,6 +5,7 @@
#include "control.h" #include "control.h"
#include "streams.h" #include "streams.h"
#include "com_cdump.h"
static int indent; static int indent;
@ -39,10 +40,10 @@ dodump(struct control *cc)
fprintf(cp_out, "while "); fprintf(cp_out, "while ");
wl_print(cc->co_cond, cp_out); wl_print(cc->co_cond, cp_out);
putc('\n', cp_out); putc('\n', cp_out);
indent += 8;
indent += TABINDENT;
for (tc = cc->co_children; tc; tc = tc->co_next) for (tc = cc->co_children; tc; tc = tc->co_next)
dodump(tc); dodump(tc);
indent -= 8;
indent -= TABINDENT;
tab(indent); tab(indent);
fprintf(cp_out, "end\n"); fprintf(cp_out, "end\n");
break; break;
@ -50,13 +51,13 @@ dodump(struct control *cc)
tab(indent); tab(indent);
fprintf(cp_out, "repeat "); fprintf(cp_out, "repeat ");
if (cc->co_numtimes != -1) if (cc->co_numtimes != -1)
fprintf(cp_out, "%d\n", cc->co_numtimes);
fprintf(cp_out, "%d (%d left to do)\n", cc->co_numtimes, cc->co_timestodo); /* CDHW */
else else
putc('\n', cp_out); putc('\n', cp_out);
indent += 8;
indent += TABINDENT;
for (tc = cc->co_children; tc; tc = tc->co_next) for (tc = cc->co_children; tc; tc = tc->co_next)
dodump(tc); dodump(tc);
indent -= 8;
indent -= TABINDENT;
tab(indent); tab(indent);
fprintf(cp_out, "end\n"); fprintf(cp_out, "end\n");
break; break;
@ -65,10 +66,10 @@ dodump(struct control *cc)
fprintf(cp_out, "dowhile "); fprintf(cp_out, "dowhile ");
wl_print(cc->co_cond, cp_out); wl_print(cc->co_cond, cp_out);
putc('\n', cp_out); putc('\n', cp_out);
indent += 8;
indent += TABINDENT;
for (tc = cc->co_children; tc; tc = tc->co_next) for (tc = cc->co_children; tc; tc = tc->co_next)
dodump(tc); dodump(tc);
indent -= 8;
indent -= TABINDENT;
tab(indent); tab(indent);
fprintf(cp_out, "end\n"); fprintf(cp_out, "end\n");
break; break;
@ -77,10 +78,10 @@ dodump(struct control *cc)
fprintf(cp_out, "if "); fprintf(cp_out, "if ");
wl_print(cc->co_cond, cp_out); wl_print(cc->co_cond, cp_out);
putc('\n', cp_out); putc('\n', cp_out);
indent += 8;
indent += TABINDENT;
for (tc = cc->co_children; tc; tc = tc->co_next) for (tc = cc->co_children; tc; tc = tc->co_next)
dodump(tc); dodump(tc);
indent -= 8;
indent -= TABINDENT;
tab(indent); tab(indent);
fprintf(cp_out, "end\n"); fprintf(cp_out, "end\n");
break; break;
@ -89,10 +90,10 @@ dodump(struct control *cc)
fprintf(cp_out, "foreach %s ", cc->co_foreachvar); fprintf(cp_out, "foreach %s ", cc->co_foreachvar);
wl_print(cc->co_text, cp_out); wl_print(cc->co_text, cp_out);
putc('\n', cp_out); putc('\n', cp_out);
indent += 8;
indent += TABINDENT;
for (tc = cc->co_children; tc; tc = tc->co_next) for (tc = cc->co_children; tc; tc = tc->co_next)
dodump(tc); dodump(tc);
indent -= 8;
indent -= TABINDENT;
tab(indent); tab(indent);
fprintf(cp_out, "end\n"); fprintf(cp_out, "end\n");
break; break;

1
src/frontend/com_cdump.h

@ -2,5 +2,6 @@
#define _COM_CDUMP_H #define _COM_CDUMP_H
void com_cdump(wordlist *wl); void com_cdump(wordlist *wl);
#define TABINDENT 2 /* CDHW */ /* The orginal value was 8 */
#endif #endif

117
src/frontend/control.c

@ -47,6 +47,14 @@ int stackp = 0;
* blown away every time we return -- probably every time we type * blown away every time we return -- probably every time we type
* source at the keyboard and every time a source returns to keyboard * source at the keyboard and every time a source returns to keyboard
* input is ok though -- use ft_controlreset. */ * input is ok though -- use ft_controlreset. */
/* Notes by CDHW:
* This routine leaked like a sieve because each getcommand() created a
* wordlist that was never freed becuase it might have been added into
* the control structure. I've tackled this by making sure that everything
* put into the cend[stackp] is a copy. This means that wlist can be
* destroyed safely
*/
static char *noredirect[] = { "stop", NULL } ; /* Only one?? */ static char *noredirect[] = { "stop", NULL } ; /* Only one?? */
@ -79,6 +87,37 @@ pwlist(wordlist *wlist, char *name)
} }
/* CDHW defined functions */
static void
pwlist_echo(wlist, name) /*CDHW used to perform function of set echo */
wordlist *wlist;
char *name;
{
wordlist *wl;
if ((!cp_echo)||cp_debug) /* cpdebug prints the same info */
return;
fprintf(cp_err, "%s ", name);
for (wl = wlist; wl; wl = wl->wl_next)
fprintf(cp_err, "%s ", wl->wl_word);
fprintf(cp_err, "\n");
return;
}
/*CDHW Remove control structure and free the memory its hogging CDHW*/
void ctl_free(struct control *ctrl) {
if (!ctrl) return;
wl_free(ctrl->co_cond); ctrl->co_cond = NULL;
tfree(ctrl->co_foreachvar); ctrl->co_foreachvar = NULL;
wl_free(ctrl->co_text); ctrl->co_text = NULL;
ctl_free(ctrl->co_children); ctrl->co_children = NULL;
ctl_free(ctrl->co_elseblock); ctrl->co_elseblock = NULL;
ctl_free(ctrl->co_next); ctrl->co_next = NULL;
tfree(ctrl); ctrl = NULL;
}
/* Note that we only do io redirection when we get to here - we also /* Note that we only do io redirection when we get to here - we also
* postpone some other things until now. */ * postpone some other things until now. */
@ -108,8 +147,10 @@ docommand(wordlist *wlist)
wlist = cp_doglob(wlist); wlist = cp_doglob(wlist);
pwlist(wlist, "After globbing"); pwlist(wlist, "After globbing");
pwlist_echo(wlist, "Becomes >");
if (!wlist || !wlist->wl_word)
if (!wlist || !wlist->wl_word) /*CDHW need to free wlist in second case? CDHW*/
return; return;
/* Now loop through all of the commands given. */ /* Now loop through all of the commands given. */
@ -185,7 +226,7 @@ docommand(wordlist *wlist)
for (wl = wlist->wl_next; wl; wl = wl->wl_next) for (wl = wlist->wl_next; wl; wl = wl->wl_next)
nargs++; nargs++;
if (command->co_stringargs) { if (command->co_stringargs) {
lcom = wl_flatten(wlist->wl_next);
lcom = wl_flatten(wlist->wl_next); /*CDHW lcom will need freeing CDHW*/
(*command->co_func) ((void *)(lcom)); (*command->co_func) ((void *)(lcom));
} else { } else {
if (nargs < command->co_minargs) { if (nargs < command->co_minargs) {
@ -241,10 +282,17 @@ doblock(struct control *bl, int *num)
wordlist *wl; wordlist *wl;
char *i; char *i;
int nn; int nn;
nn = *num + 1 ; /*CDHW this is a guess... CDHW*/
switch (bl->co_type) { switch (bl->co_type) {
case CO_WHILE: case CO_WHILE:
if (!bl->co_children) {
fprintf(cp_err, "Warning: Executing empty 'while' block.\n");
fprintf(cp_err, " (Use a label statement as a no-op to suppress this warning.)\n");
}
while (bl->co_cond && cp_istrue(bl->co_cond)) { while (bl->co_cond && cp_istrue(bl->co_cond)) {
if (!bl->co_children) cp_periodic(); /*CDHW*/
for (ch = bl->co_children; ch; ch = cn) { for (ch = bl->co_children; ch; ch = cn) {
cn = ch->co_next; cn = ch->co_next;
i = doblock(ch, &nn); i = doblock(ch, &nn);
@ -316,10 +364,19 @@ doblock(struct control *bl, int *num)
break; break;
case CO_REPEAT: case CO_REPEAT:
while ((bl->co_numtimes > 0) ||
(bl->co_numtimes == -1)) {
if (bl->co_numtimes != -1)
bl->co_numtimes--;
if (!bl->co_children) {
fprintf(cp_err, "Warning: Executing empty 'repeat' block.\n");
fprintf(cp_err, " (Use a label statement as a no-op to suppress this warning.)\n");
}
if (!bl->co_timestodo) bl->co_timestodo = bl->co_numtimes;
/*...CDHW*/
while ((bl->co_timestodo > 0) ||
(bl->co_timestodo == -1)) {
if (!bl->co_children) cp_periodic(); /*CDHW*/
if (bl->co_timestodo != -1) bl->co_timestodo--;
for (ch = bl->co_children; ch; ch = cn) { for (ch = bl->co_children; ch; ch = cn) {
cn = ch->co_next; cn = ch->co_next;
i = doblock(ch, &nn); i = doblock(ch, &nn);
@ -447,11 +504,12 @@ doblock(struct control *bl, int *num)
case CO_GOTO: case CO_GOTO:
wl = cp_variablesubst(cp_bquote(cp_doglob( wl = cp_variablesubst(cp_bquote(cp_doglob(
wl_copy(bl->co_text))));
wl_copy(bl->co_text)))); /*CDHW Leak ? CDHW*/
return (wl->wl_word); return (wl->wl_word);
case CO_LABEL: case CO_LABEL:
/* Do nothing. */ /* Do nothing. */
cp_periodic(); /*CDHW needed to avoid lock-ups when loop contains only a label CDHW*/
break; break;
case CO_STATEMENT: case CO_STATEMENT:
@ -556,7 +614,9 @@ cp_evloop(char *string)
/* Add this to the control structure list. If cend->co_type is /* Add this to the control structure list. If cend->co_type is
* CO_UNFILLED, the last line was the beginning of a block, * CO_UNFILLED, the last line was the beginning of a block,
* and this is the unfilled first statement. */
* and this is the unfilled first statement.
*/
if (cend[stackp] && (cend[stackp]->co_type != CO_UNFILLED)) { if (cend[stackp] && (cend[stackp]->co_type != CO_UNFILLED)) {
cend[stackp]->co_next = alloc(struct control); cend[stackp]->co_next = alloc(struct control);
ZERO(cend[stackp]->co_next, struct control); ZERO(cend[stackp]->co_next, struct control);
@ -574,7 +634,7 @@ cp_evloop(char *string)
cend[stackp]->co_cond = wlist->wl_next; cend[stackp]->co_cond = wlist->wl_next;
if (!cend[stackp]->co_cond) { if (!cend[stackp]->co_cond) {
fprintf(stderr, fprintf(stderr,
"Error: missing while condition.\n");
"Error: missing while condition, 'false' will be assumed.\n");
} }
newblock; newblock;
} else if (eq(wlist->wl_word, "dowhile")) { } else if (eq(wlist->wl_word, "dowhile")) {
@ -582,7 +642,7 @@ cp_evloop(char *string)
cend[stackp]->co_cond = wlist->wl_next; cend[stackp]->co_cond = wlist->wl_next;
if (!cend[stackp]->co_cond) { if (!cend[stackp]->co_cond) {
fprintf(stderr, fprintf(stderr,
"Error: missing dowhile condition.\n");
"Error: missing dowhile condition, '???' will be assumed.\n");
} }
newblock; newblock;
} else if (eq(wlist->wl_word, "repeat")) { } else if (eq(wlist->wl_word, "repeat")) {
@ -592,10 +652,12 @@ cp_evloop(char *string)
} else { } else {
char *s; char *s;
double *dd; double *dd;
wlist = cp_variablesubst(cp_bquote(
cp_doglob(wl_copy(wlist))));
s = wlist->wl_next->wl_word;
struct wordlist *t; /*CDHW*/
/*CDHW wlist = cp_variablesubst(cp_bquote(cp_doglob(wl_copy(wlist)))); Wrong order? Leak? CDHW*/
t = cp_doglob(cp_bquote(cp_variablesubst(wl_copy(wlist)))); /*CDHW leak from cp_doglob? */
s = t->wl_next->wl_word;
dd = ft_numparse(&s, FALSE); dd = ft_numparse(&s, FALSE);
if (dd) { if (dd) {
if (*dd < 0) { if (*dd < 0) {
@ -607,9 +669,11 @@ cp_evloop(char *string)
} else } else
fprintf(cp_err, fprintf(cp_err,
"Error: bad repeat argument %s\n", "Error: bad repeat argument %s\n",
wlist->wl_next->wl_word);
t->wl_next->wl_word); /* CDHW */
wl_free(t); t = NULL; /* CDHW */
} }
newblock; newblock;
} else if (eq(wlist->wl_word, "if")) { } else if (eq(wlist->wl_word, "if")) {
cend[stackp]->co_type = CO_IF; cend[stackp]->co_type = CO_IF;
cend[stackp]->co_cond = wlist->wl_next; cend[stackp]->co_cond = wlist->wl_next;
@ -618,6 +682,7 @@ cp_evloop(char *string)
"Error: missing if condition.\n"); "Error: missing if condition.\n");
} }
newblock; newblock;
} else if (eq(wlist->wl_word, "foreach")) { } else if (eq(wlist->wl_word, "foreach")) {
cend[stackp]->co_type = CO_FOREACH; cend[stackp]->co_type = CO_FOREACH;
if (wlist->wl_next) { if (wlist->wl_next) {
@ -628,7 +693,7 @@ cp_evloop(char *string)
} else } else
fprintf(stderr, fprintf(stderr,
"Error: missing foreach variable.\n"); "Error: missing foreach variable.\n");
wlist = cp_doglob(wlist);
wlist = cp_doglob(wlist); /*CDHW Possible leak around here? */
cend[stackp]->co_text = wl_copy(wlist); cend[stackp]->co_text = wl_copy(wlist);
newblock; newblock;
} else if (eq(wlist->wl_word, "label")) { } else if (eq(wlist->wl_word, "label")) {
@ -642,6 +707,7 @@ cp_evloop(char *string)
"Warning: ignored extra junk after label.\n"); "Warning: ignored extra junk after label.\n");
} else } else
fprintf(stderr, "Error: missing label.\n"); fprintf(stderr, "Error: missing label.\n");
} else if (eq(wlist->wl_word, "goto")) { } else if (eq(wlist->wl_word, "goto")) {
/* Incidentally, this won't work if the values 1 and 2 ever get /* Incidentally, this won't work if the values 1 and 2 ever get
* to be valid character pointers -- I think it's reasonably * to be valid character pointers -- I think it's reasonably
@ -685,12 +751,12 @@ cp_evloop(char *string)
cend[stackp]->co_prev->co_next = NULL; cend[stackp]->co_prev->co_next = NULL;
x = cend[stackp]; x = cend[stackp];
cend[stackp] = cend[stackp]->co_parent; cend[stackp] = cend[stackp]->co_parent;
tfree(x);
tfree(x); x=NULL;
} else { } else {
x = cend[stackp]; x = cend[stackp];
cend[stackp] = cend[stackp]->co_parent; cend[stackp] = cend[stackp]->co_parent;
cend[stackp]->co_children = NULL; cend[stackp]->co_children = NULL;
tfree(x);
tfree(x); x=NULL;
} }
} else if (eq(wlist->wl_word, "else")) { } else if (eq(wlist->wl_word, "else")) {
if (!cend[stackp]->co_parent || if (!cend[stackp]->co_parent ||
@ -708,25 +774,25 @@ cp_evloop(char *string)
} }
} else { } else {
cend[stackp]->co_type = CO_STATEMENT; cend[stackp]->co_type = CO_STATEMENT;
cend[stackp]->co_text = wlist;
cend[stackp]->co_text = wl_copy(wlist);
} }
if (!cend[stackp]->co_parent) { if (!cend[stackp]->co_parent) {
x = cend[stackp]; x = cend[stackp];
/* We have to toss this do-while loop in here so /* We have to toss this do-while loop in here so
* that gotos at the top level will work. * that gotos at the top level will work.
*/ */
do {
do { nn = 0; /* CDHW */
i = doblock(x, &nn); i = doblock(x, &nn);
switch (*i) { switch (*i) {
case NORMAL: case NORMAL:
break; break;
case BROKEN: case BROKEN:
fprintf(cp_err, fprintf(cp_err,
"Error: break not in loop or too many break levels given\n");
"Error: break not in loop (or too many break levels given)\n");
break; break;
case CONTINUED: case CONTINUED:
fprintf(cp_err, fprintf(cp_err,
"Error: continue not in loop or too many continue levels given\n");
"Error: continue not in loop (or too many continue levels given)\n");
break; break;
default: default:
x = findlabel(i, control[stackp]); x = findlabel(i, control[stackp]);
@ -737,15 +803,18 @@ cp_evloop(char *string)
x = x->co_next; x = x->co_next;
} while (x); } while (x);
} }
wl_free(wlist); wlist = NULL;
if (string) if (string)
return (1); /* The return value is irrelevant. */ return (1); /* The return value is irrelevant. */
} }
wl_free(wlist); wlist = NULL;
} }
/* This blows away the control structures... */ /* This blows away the control structures... */
void void
cp_resetcontrol(void) cp_resetcontrol(void)
{ {
fprintf(cp_err, "Warning: clearing control structures\n");
if (cend[stackp] && cend[stackp]->co_parent) if (cend[stackp] && cend[stackp]->co_parent)
fprintf(cp_err, "Warning: EOF before block terminated\n"); fprintf(cp_err, "Warning: EOF before block terminated\n");
/* We probably should free the control structures... */ /* We probably should free the control structures... */
@ -797,5 +866,3 @@ cp_toplevel(void)
cend[stackp] = cend[stackp]->co_parent; cend[stackp] = cend[stackp]->co_parent;
return; return;
} }

1
src/frontend/control.h

@ -14,6 +14,7 @@ struct control {
wordlist *co_cond; /* if, while, dowhile */ wordlist *co_cond; /* if, while, dowhile */
char *co_foreachvar; /* foreach */ char *co_foreachvar; /* foreach */
int co_numtimes; /* repeat, break & continue levels */ int co_numtimes; /* repeat, break & continue levels */
int co_timestodo; /* the number of times left during a repeat loop */
wordlist *co_text; /* Ordinary text and foreach values. */ wordlist *co_text; /* Ordinary text and foreach values. */
struct control *co_parent; /* If this is inside a block. */ struct control *co_parent; /* If this is inside a block. */
struct control *co_children; /* The contents of this block. */ struct control *co_children; /* The contents of this block. */

3
src/frontend/parser/complete.c

@ -123,6 +123,9 @@ cp_ccom(wordlist *wlist, char *buf, bool esc)
pmatches = ccmatch(buf, &commands); pmatches = ccmatch(buf, &commands);
i = strlen(buf); i = strlen(buf);
} }
tfree(buf); /*CDHW*/
if (!esc) { if (!esc) {
printem(pmatches); printem(pmatches);
wl_free(pmatches); wl_free(pmatches);

34
src/frontend/parser/lexical.c

@ -10,6 +10,7 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
#include <config.h> #include <config.h>
#include "ngspice.h" #include "ngspice.h"
#include "cpdefs.h" #include "cpdefs.h"
#include <errno.h> #include <errno.h>
#ifdef HAVE_UNISTD_H #ifdef HAVE_UNISTD_H
@ -45,6 +46,7 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
static void prompt(void); static void prompt(void);
extern bool cp_echo; /* For CDHW patches: defined in variable.c */
FILE *cp_inp_cur = NULL; FILE *cp_inp_cur = NULL;
int cp_event = 1; int cp_event = 1;
@ -77,6 +79,27 @@ static int numeofs = 0;
bzero(buf, BSIZE_SP); \ bzero(buf, BSIZE_SP); \
i = 0; i = 0;
/* CDHW Debug function */
static void
pwlist_echo(wlist, name) /*CDHW used to perform function of set echo */
wordlist *wlist;
char *name;
{
wordlist *wl;
if ((!cp_echo)||cp_debug) /* cpdebug prints the same info */
return;
fprintf(cp_err, "%s ", name);
for (wl = wlist; wl; wl = wl->wl_next)
fprintf(cp_err, "%s ", wl->wl_word );
fprintf(cp_err, "\n");
return;
}
/* CDHW */
wordlist * wordlist *
cp_lexer(char *string) cp_lexer(char *string)
{ {
@ -86,10 +109,10 @@ cp_lexer(char *string)
char buf[BSIZE_SP], linebuf[BSIZE_SP], d; char buf[BSIZE_SP], linebuf[BSIZE_SP], d;
int paren; int paren;
if (cp_inp_cur == NULL)
if (cp_inp_cur == NULL)
cp_inp_cur = cp_in; cp_inp_cur = cp_in;
if (!string && cp_interactive) {
if (!string && cp_interactive) {/* prompt for string if none is passed */
cp_ccon(TRUE); cp_ccon(TRUE);
prompt(); prompt();
} }
@ -261,6 +284,11 @@ gotchar:
newword; newword;
break; break;
} }
case ';': /*CDHW semicolon inside parentheses is part of expression CDHW*/
if (paren > 0) {
buf[i++]=c;
break;
}
default: default:
/* We have to remember the special case $< /* We have to remember the special case $<
* here * here
@ -280,6 +308,8 @@ gotchar:
} }
} }
done: done:
if (wlist->wl_word) pwlist_echo(wlist,"Command>");
return (wlist); return (wlist);
} }

11
src/frontend/variable.c

@ -28,6 +28,7 @@ bool cp_noglob = TRUE;
bool cp_nonomatch = FALSE; bool cp_nonomatch = FALSE;
bool cp_noclobber = FALSE; bool cp_noclobber = FALSE;
bool cp_ignoreeof = FALSE; bool cp_ignoreeof = FALSE;
bool cp_echo = FALSE; /* CDHW */
struct variable *variables = NULL; struct variable *variables = NULL;
@ -156,6 +157,8 @@ cp_vset(char *varname, char type, char *value)
cp_maxhistlength = v->va_real; cp_maxhistlength = v->va_real;
else if (eq(copyvarname, "noclobber")) else if (eq(copyvarname, "noclobber"))
cp_noclobber = TRUE; cp_noclobber = TRUE;
else if (eq(varname, "echo")) /*CDHW*/
cp_echo = TRUE; /*CDHW*/
else if (eq(copyvarname, "prompt") && (type == VT_STRING)) else if (eq(copyvarname, "prompt") && (type == VT_STRING))
cp_promptstring = copy(v->va_string); cp_promptstring = copy(v->va_string);
else if (eq(copyvarname, "ignoreeof")) else if (eq(copyvarname, "ignoreeof"))
@ -234,7 +237,7 @@ cp_vset(char *varname, char type, char *value)
return; return;
} }
/*CDHW This needs leak checking carefully CDHW*/
struct variable * struct variable *
cp_setparse(wordlist *wl) cp_setparse(wordlist *wl)
{ {
@ -391,6 +394,8 @@ cp_remvar(char *varname)
cp_nonomatch = FALSE; cp_nonomatch = FALSE;
else if (eq(varname, "noclobber")) else if (eq(varname, "noclobber"))
cp_noclobber = FALSE; cp_noclobber = FALSE;
else if (eq(varname, "echo")) /*CDHW*/
cp_echo = FALSE; /*CDHW*/
else if (eq(varname, "prompt")){ else if (eq(varname, "prompt")){
/* cp_promptstring = ""; Memory leak here the last allocated reference wil be lost*/ /* cp_promptstring = ""; Memory leak here the last allocated reference wil be lost*/
if(cp_promptstring) { if(cp_promptstring) {
@ -557,7 +562,7 @@ cp_variablesubst(wordlist *wlist)
{ {
wordlist *wl, *nwl; wordlist *wl, *nwl;
char *s, *t, buf[BSIZE_SP], wbuf[BSIZE_SP], tbuf[BSIZE_SP]; char *s, *t, buf[BSIZE_SP], wbuf[BSIZE_SP], tbuf[BSIZE_SP];
/* MW. tbuf holds curret word after wl_splice() calls free() on it */
/* MW. tbuf holds current word after wl_splice() calls free() on it */
int i; int i;
for (wl = wlist; wl; wl = wl->wl_next) { for (wl = wlist; wl; wl = wl->wl_next) {
@ -591,7 +596,7 @@ cp_variablesubst(wordlist *wlist)
} }
(void) strcpy(tbuf, t); /* MW. Save t*/ (void) strcpy(tbuf, t); /* MW. Save t*/
if (!(wl = wl_splice(wl, nwl)))
if (!(wl = wl_splice(wl, nwl))) /*CDHW this frees wl CDHW*/
return (NULL); return (NULL);
/* This is bad... */ /* This is bad... */
for (wlist = wl; wlist->wl_prev; wlist = wlist->wl_prev) for (wlist = wl; wlist->wl_prev; wlist = wlist->wl_prev)

1
src/frontend/variable.h

@ -42,6 +42,7 @@ extern bool cp_noglob;
extern bool cp_nonomatch; extern bool cp_nonomatch;
extern bool cp_noclobber; extern bool cp_noclobber;
extern bool cp_ignoreeof; extern bool cp_ignoreeof;
extern bool cp_echo;
// extern struct variable *variables; // extern struct variable *variables;
wordlist * cp_varwl(struct variable *var); wordlist * cp_varwl(struct variable *var);

Loading…
Cancel
Save