From 486b74f728fb7496af65cb401e5624cefbe816a8 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Tue, 4 Jul 2023 11:45:27 +0200 Subject: [PATCH 1/4] Prevent a crash if p==NULL (due to buggy input) --- src/spicelib/parser/inpptree.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/spicelib/parser/inpptree.c b/src/spicelib/parser/inpptree.c index 398771048..063bbd5f9 100644 --- a/src/spicelib/parser/inpptree.c +++ b/src/spicelib/parser/inpptree.c @@ -1167,12 +1167,20 @@ INPparseNode *PT_mkfnode(const char *fname, INPparseNode * arg) p->function = funcs[i].funcptr; p->data = NULL; - if(p->funcnum == PTF_PWL) + if (p->funcnum == PTF_PWL) { p = prepare_PTF_PWL(p); + if (p == NULL) { + fprintf(stderr, "Error while parsing function '%s'\n", buf); + if (ft_stricterror) + controlled_exit(EXIT_BAD); + return mkfirst(NULL, arg); + } + } if (p->funcnum == PTF_DDT) p = prepare_PTF_DDT(p); + return (p); } From b63f6e7905da7e26a658699e4e83e0adbe3d9526 Mon Sep 17 00:00:00 2001 From: Brian Taylor Date: Mon, 3 Jul 2023 15:22:38 -0700 Subject: [PATCH 2/4] When Cider models are present, a normal batch mode sp_shutdown (for example, ngspice -b cmosinv.cir) will call com_quit(NULL). This cleans up so that valgrind will find no leaks in Cider devices after sp_shutdown. To disable this feature, set the environment variable CIDER_COM_QUIT="OFF". Even though it really does not matter that Cider memory is cleared just before exit, it makes it cleaner for valgrind checks. --- examples/cider/diode/diode.cir | 4 ++-- src/ciderlib/oned/onedest.c | 4 ++++ src/ciderlib/oned/onemesh.c | 5 +++++ src/ciderlib/support/globals.c | 11 +++++++++++ src/ciderlib/twod/twodest.c | 4 ++++ src/ciderlib/twod/twomesh.c | 4 ++++ src/main.c | 13 +++++++++++++ 7 files changed, 43 insertions(+), 2 deletions(-) diff --git a/examples/cider/diode/diode.cir b/examples/cider/diode/diode.cir index 527de4af9..9a9c436a2 100644 --- a/examples/cider/diode/diode.cir +++ b/examples/cider/diode/diode.cir @@ -30,7 +30,7 @@ D1 1 2 M_PN AREA=100 .op .ac dec 10 100kHz 10gHz .print ac i(Vpp) -.dc Vpp -3.0v 2.0001v 50mv -.print dc i(Vpp) +* .dc Vpp -3.0v 2.0001v 50mv +* .print dc i(Vpp) .END diff --git a/src/ciderlib/oned/onedest.c b/src/ciderlib/oned/onedest.c index 9b1bba8b4..cc19c1acf 100644 --- a/src/ciderlib/oned/onedest.c +++ b/src/ciderlib/oned/onedest.c @@ -85,4 +85,8 @@ ONEdestroy(ONEdevice *pDevice) /* NOT IMPLEMENTED */ FREE(pDevice); + { + extern void CiderLoaded(int); + CiderLoaded(-1); + } } diff --git a/src/ciderlib/oned/onemesh.c b/src/ciderlib/oned/onemesh.c index 78ad614fd..62766e7f0 100644 --- a/src/ciderlib/oned/onemesh.c +++ b/src/ciderlib/oned/onemesh.c @@ -194,6 +194,11 @@ ONEbuildMesh(ONEdevice *pDevice, ONEcoord *pCoord, ONEdomain *pDomain, pDevice->dimBias = numEqn; FREE(nodeArray); + { + extern void CiderLoaded(int); + CiderLoaded(1); + } + /* * ONEprnMesh( pDevice ); */ diff --git a/src/ciderlib/support/globals.c b/src/ciderlib/support/globals.c index 8f98e5e75..2ab5a2acc 100644 --- a/src/ciderlib/support/globals.c +++ b/src/ciderlib/support/globals.c @@ -155,3 +155,14 @@ void GLOBprnGlobals(FILE *file, GLOBvalues *values) return; } + +static int cider_is_loaded = 0; +void CiderLoaded(int val) +{ + cider_is_loaded += val; +} + +int IsCiderLoaded(void) +{ + return cider_is_loaded; +} diff --git a/src/ciderlib/twod/twodest.c b/src/ciderlib/twod/twodest.c index 6294b852d..35c7ecf9a 100644 --- a/src/ciderlib/twod/twodest.c +++ b/src/ciderlib/twod/twodest.c @@ -107,4 +107,8 @@ TWOdestroy(TWOdevice *pDevice) /* NOT IMPLEMENTED */ FREE( pDevice ); + { + extern void CiderLoaded(int); + CiderLoaded(-1); + } } diff --git a/src/ciderlib/twod/twomesh.c b/src/ciderlib/twod/twomesh.c index 161bb0c3c..cbc058346 100644 --- a/src/ciderlib/twod/twomesh.c +++ b/src/ciderlib/twod/twomesh.c @@ -458,6 +458,10 @@ TWObuildMesh(TWOdevice *pDevice, TWOdomain *pDomain, FREE(edgeArrayV); FREE(edgeArrayH); + { + extern void CiderLoaded(int); + CiderLoaded(1); + } /* * TWOprnMesh( pDevice ); */ diff --git a/src/main.c b/src/main.c index 7957cc7f2..70906ca14 100644 --- a/src/main.c +++ b/src/main.c @@ -533,6 +533,19 @@ SIMinit(IFfrontEnd *frontEnd, IFsimulator **simulator) static ATTRIBUTE_NORETURN void sp_shutdown(int exitval) { +#ifdef CIDER + { + extern int IsCiderLoaded(void); + char *cider_quit = getenv("CIDER_COM_QUIT"); + bool cider_com_quit = TRUE; + if (cider_quit && eq(cider_quit, "OFF")) { + cider_com_quit = FALSE; + } + if (cider_com_quit && IsCiderLoaded() > 0) { + com_quit(NULL); + } + } +#endif destroy_ivars(); #ifdef HAS_WINGUI if (exitval == EXIT_BAD) From f3b83fd4e4d4329d481e048ad2eae84dd22d7e22 Mon Sep 17 00:00:00 2001 From: Brian Taylor Date: Mon, 3 Jul 2023 16:19:13 -0700 Subject: [PATCH 3/4] Tidy up sp_shutdown with Cider. --- src/main.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/main.c b/src/main.c index 70906ca14..3c36990cc 100644 --- a/src/main.c +++ b/src/main.c @@ -536,13 +536,16 @@ sp_shutdown(int exitval) #ifdef CIDER { extern int IsCiderLoaded(void); - char *cider_quit = getenv("CIDER_COM_QUIT"); + char *cider_quit_s = NULL; bool cider_com_quit = TRUE; - if (cider_quit && eq(cider_quit, "OFF")) { - cider_com_quit = FALSE; - } - if (cider_com_quit && IsCiderLoaded() > 0) { - com_quit(NULL); + if (exitval != EXIT_BAD) { + cider_quit_s = getenv("CIDER_COM_QUIT"); + if (cider_quit_s && *cider_quit_s && eq(cider_quit_s, "OFF")) { + cider_com_quit = FALSE; + } + if (cider_com_quit && IsCiderLoaded() > 0) { + com_quit(NULL); + } } } #endif From c6edbe44dbf525a27c9da2fa08a75427d898df5a Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Tue, 4 Jul 2023 12:07:41 +0200 Subject: [PATCH 4/4] Move extern declaration to the top, out of any function. Thus remove VC2022 compiler warnings. --- src/ciderlib/oned/onedest.c | 3 ++- src/ciderlib/oned/onemesh.c | 2 +- src/ciderlib/twod/twodest.c | 3 ++- src/ciderlib/twod/twomesh.c | 2 +- src/main.c | 4 +++- 5 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/ciderlib/oned/onedest.c b/src/ciderlib/oned/onedest.c index cc19c1acf..56a544ed2 100644 --- a/src/ciderlib/oned/onedest.c +++ b/src/ciderlib/oned/onedest.c @@ -12,6 +12,8 @@ Author: 1991 David A. Gates, U. C. Berkeley CAD Group #include "onedext.h" #include "oneddefs.h" +extern void CiderLoaded(int); + void ONEdestroy(ONEdevice *pDevice) { @@ -86,7 +88,6 @@ ONEdestroy(ONEdevice *pDevice) FREE(pDevice); { - extern void CiderLoaded(int); CiderLoaded(-1); } } diff --git a/src/ciderlib/oned/onemesh.c b/src/ciderlib/oned/onemesh.c index 62766e7f0..45f8fc911 100644 --- a/src/ciderlib/oned/onemesh.c +++ b/src/ciderlib/oned/onemesh.c @@ -12,6 +12,7 @@ Author: 1987 Kartikeya Mayaram, U. C. Berkeley CAD Group #include "onedext.h" #include "oneddefs.h" +extern void CiderLoaded(int); /* Forward Declarations */ /* static void ONEresetEvalFlag(ONEdevice *); sjb - not used */ @@ -195,7 +196,6 @@ ONEbuildMesh(ONEdevice *pDevice, ONEcoord *pCoord, ONEdomain *pDomain, FREE(nodeArray); { - extern void CiderLoaded(int); CiderLoaded(1); } diff --git a/src/ciderlib/twod/twodest.c b/src/ciderlib/twod/twodest.c index 35c7ecf9a..232c39867 100644 --- a/src/ciderlib/twod/twodest.c +++ b/src/ciderlib/twod/twodest.c @@ -12,6 +12,8 @@ Author: 1991 David A. Gates, U. C. Berkeley CAD Group #include "twoddefs.h" #include "twodext.h" +extern void CiderLoaded(int); + void TWOdestroy(TWOdevice *pDevice) { @@ -108,7 +110,6 @@ TWOdestroy(TWOdevice *pDevice) FREE( pDevice ); { - extern void CiderLoaded(int); CiderLoaded(-1); } } diff --git a/src/ciderlib/twod/twomesh.c b/src/ciderlib/twod/twomesh.c index cbc058346..4eddd4d87 100644 --- a/src/ciderlib/twod/twomesh.c +++ b/src/ciderlib/twod/twomesh.c @@ -19,6 +19,7 @@ Author: 1991 David A. Gates, U. C. Berkeley CAD Group static void doMobCoeffs(TWOelem *, int); static void resetEvalFlag(TWOdevice *pDevice); +extern void CiderLoaded(int); void TWObuildMesh(TWOdevice *pDevice, TWOdomain *pDomain, @@ -459,7 +460,6 @@ TWObuildMesh(TWOdevice *pDevice, TWOdomain *pDomain, FREE(edgeArrayH); { - extern void CiderLoaded(int); CiderLoaded(1); } /* diff --git a/src/main.c b/src/main.c index 3c36990cc..653d3ddcb 100644 --- a/src/main.c +++ b/src/main.c @@ -107,6 +107,8 @@ FILE *flogp = NULL; /* log file ('-o logfile' command line option) */ bool orflag = FALSE; /* global for -o option */ #endif +extern int IsCiderLoaded(void); + FILE *slogp = NULL; /* soa log file ('--soa-log file' command line option) */ /* Frontend and circuit options */ @@ -535,7 +537,7 @@ sp_shutdown(int exitval) { #ifdef CIDER { - extern int IsCiderLoaded(void); + char *cider_quit_s = NULL; bool cider_com_quit = TRUE; if (exitval != EXIT_BAD) {