Applied first patch from Steven Borley that fixes memory leaks and errors while reading input decks.
This commit is contained in:
parent
08deeb54f5
commit
609f57ba00
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue