Applied first patch from Steven Borley that fixes memory leaks and errors while reading input decks.

This commit is contained in:
pnenzi 2001-06-05 18:00:28 +00:00
parent 08deeb54f5
commit 609f57ba00
3 changed files with 83 additions and 23 deletions

View File

@ -3,6 +3,11 @@ Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
**********/
/*
* SJB 22 May 2001
* Corrected freeing of memory in ft_cpinit()
*/
#include "ngspice.h"
#include "cpdefs.h"
#include "ftedefs.h"
@ -211,6 +216,7 @@ ft_cpinit(void)
s++;
for (r = buf; *s && !isspace(*s); r++, s++)
*r = *s;
tfree(copys); /* sjb - it's safe to free this here */
(void) strcpy(r, DIR_PATHSEP);
(void) strcat(r, "spinit");
if ((fp = fopen(buf, "r"))) {
@ -236,7 +242,8 @@ ft_cpinit(void)
}
tcap_init( );
tfree(copys);/*DG Avoid memory leak*/
/* tfree(copys);*/ /*DG Avoid memory leak*/
/* SJB - must not free here as cp_tildexpande() can return NULL */
return;
}

View File

@ -3,6 +3,12 @@ Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Wayne A. Christopher
**********/
/*
* SJB 22 May 2001
* Fixed memory leaks accociated with freeing memory used by lines in the input deck
* in inp_spsource(). New line_free() routine added to help with this.
*/
/*
* Stuff for dealing with spice input decks and command scripts, and
* the listing routines.
@ -243,6 +249,25 @@ top2:
return;
}
/*
* Free memory used by a line.
* If recure is TRUE then recursivly free all lines linked via the li_next field.
* If recurse is FALSE free only this line.
* All lines linked via the li_actual field are always recursivly freed.
* SJB - 22nd May 2001
*/
void
line_free(struct line * deck, bool recurse) {
if(!deck)
return;
tfree(deck->li_line);
tfree(deck->li_error);
if(recurse)
line_free(deck->li_next,TRUE);
line_free(deck->li_actual,TRUE);
tfree(deck);
}
/* The routine to source a spice input deck. We read the deck in, take
* out the front-end commands, and create a CKT structure. Also we
@ -312,8 +337,9 @@ inp_spsource(FILE *fp, bool comfile, char *filename)
else
cp_evloop(dd->li_line);
}
tfree(dd->li_line);
tfree(dd);
line_free(dd,FALSE); /* SJB - free this line's memory */
/* tfree(dd->li_line);
tfree(dd); */
}
} else {
for (dd = deck->li_next; dd; dd = ld->li_next) {
@ -332,8 +358,9 @@ inp_spsource(FILE *fp, bool comfile, char *filename)
if (ciprefix(".control", dd->li_line)) {
ld->li_next = dd->li_next;
tfree(dd->li_line);
tfree(dd);
line_free(dd,FALSE); /* SJB - free this line's memory */
/* tfree(dd->li_line);
tfree(dd); */
if (commands)
fprintf(cp_err,
"Warning: redundant .control card\n");
@ -341,8 +368,9 @@ inp_spsource(FILE *fp, bool comfile, char *filename)
commands = TRUE;
} else if (ciprefix(".endc", dd->li_line)) {
ld->li_next = dd->li_next;
tfree(dd->li_line);
tfree(dd);
line_free(dd,FALSE); /* SJB - free this line's memory */
/* tfree(dd->li_line);
tfree(dd); */
if (commands)
commands = FALSE;
else
@ -358,16 +386,20 @@ inp_spsource(FILE *fp, bool comfile, char *filename)
controls = wl;
if (prefix("*#", dd->li_line))
wl->wl_word = copy(dd->li_line + 2);
else
else {
wl->wl_word = dd->li_line;
dd->li_line = 0; /* SJB - prevent line_free() freeing the string (now pointed at by wl->wl_word) */
}
ld->li_next = dd->li_next;
tfree(dd);
line_free(dd,FALSE); /* SJB - free this line's memory */
/* tfree(dd); */
} else if (!*dd->li_line) {
/* So blank lines in com files don't get considered as
* circuits. */
ld->li_next = dd->li_next;
tfree(dd->li_line);
tfree(dd);
line_free(dd,FALSE); /* SJB - free this line's memory */
/* tfree(dd->li_line);
tfree(dd); */
} else {
inp_casefix(s);
inp_casefix(dd->li_line);
@ -389,8 +421,9 @@ inp_spsource(FILE *fp, bool comfile, char *filename)
if (!eq(s, ".op") && !eq(s, ".tf")) {
ld->li_next = dd->li_next;
tfree(dd->li_line);
tfree(dd);
line_free(dd,FALSE); /* SJB - free this line's memory */
/* tfree(dd->li_line);
tfree(dd); */
} else
ld = dd;
} else
@ -406,6 +439,7 @@ inp_spsource(FILE *fp, bool comfile, char *filename)
* commands. */
if (!cp_getvar("nosubckt", VT_BOOL, (char *) &nosubckts))
deck->li_next = inp_subcktexpand(deck->li_next);
line_free(deck->li_actual,FALSE); /* SJB - free memory used by old li_actual (if any) */
deck->li_actual = realdeck;
inp_dodeck(deck, tt, wl_first, FALSE, options, filename);
}

View File

@ -6,6 +6,13 @@ Author: 1985 Wayne A. Christopher
/*
* For dealing with spice input decks and command scripts
*/
/*
* SJB 22 May 2001
* Fixed memory leaks in inp_readall() when first(?) line of input begins with a '@'.
* Fixed memory leaks in inp_readall() when .include lines have errors
* Fixed crash where a NULL pointer gets freed in inp_readall()
*/
#include <config.h>
#include "ngspice.h"
@ -117,8 +124,10 @@ inp_readall(FILE *fp, struct line **data)
FILE *newfp;
while ((buffer = readline(fp))) {
if (*buffer == '@')
if (*buffer == '@') {
tfree(buffer); /* was allocated by readline() */
break;
}
for (s = buffer; *s && (*s != '\n'); s++)
;
if (!*s) {
@ -132,24 +141,34 @@ inp_readall(FILE *fp, struct line **data)
while (isspace(*s))
s++;
if (!*s) {
fprintf(cp_err,
"Error: .include filename missing\n");
fprintf(cp_err, "Error: .include filename missing\n");
tfree(buffer); /* was allocated by readline() */
continue;
}
for (t = s; *t && !isspace(*t); t++)
;
*t = '\0';
if (*s == '~')
{
copys=cp_tildexpand(s); /*DG*/
/*s = cp_tildexpand(s); very bad the last reference is los: memory leak*/
strcpy(s,copys);
tfree(copys);
}
if (*s == '~') {
copys = cp_tildexpand(s); /* allocates memory, but can also return NULL */
if(copys != NULL) {
s = copys; /* reuse s, but remember, buffer still points to allocated memory */
}
}
if (!(newfp = inp_pathopen(s, "r"))) {
perror(s);
if(copys) {
tfree(copys); /* allocated by the cp_tildexpand() above */
}
tfree(buffer); /* allocated by readline() above */
continue;
}
if(copys) {
tfree(copys); /* allocated by the cp_tildexpand() above */
}
inp_readall(newfp, &newcard);
(void) fclose(newfp);