From 3cf8fe8c41c61343fdec65c8223db0da163d8f52 Mon Sep 17 00:00:00 2001 From: Giles Atkinson <“gatk555@gmail.com”> Date: Fri, 1 Dec 2023 12:06:24 +0000 Subject: [PATCH 01/11] Stop after last data point, preventing read overrun of nscale. --- src/maths/poly/interpolate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/maths/poly/interpolate.c b/src/maths/poly/interpolate.c index a736aa15d..cbcd31bf8 100644 --- a/src/maths/poly/interpolate.c +++ b/src/maths/poly/interpolate.c @@ -133,7 +133,7 @@ ft_interpolate(double *data, double *ndata, double *oscale, int olen, /* Now plot the rest, piece by piece. l is the * last element under consideration. */ - for (++l; l < olen; l++) { + for (++l; l < olen && lastone < nlen - 1; l++) { double out; /* Shift the old stuff by one and get another value. */ From 1adee642245581829a3464ed233a1fe6ceab8971 Mon Sep 17 00:00:00 2001 From: Brian Taylor Date: Fri, 1 Dec 2023 15:54:17 -0800 Subject: [PATCH 02/11] Add scripts for running the paranoia tests in parallel on Linux with valgrind. --- examples/paranoia/README.txt | 26 +++++++++++++++++++++ examples/paranoia/runtests.sh | 39 +++++++++++++++++++++++++++++++ examples/paranoia/textract.py | 44 +++++++++++++++++++++++++++++++++++ 3 files changed, 109 insertions(+) create mode 100644 examples/paranoia/README.txt create mode 100755 examples/paranoia/runtests.sh create mode 100644 examples/paranoia/textract.py diff --git a/examples/paranoia/README.txt b/examples/paranoia/README.txt new file mode 100644 index 000000000..515b742ef --- /dev/null +++ b/examples/paranoia/README.txt @@ -0,0 +1,26 @@ + +To run the paranoia test suite in parallel on Linux with valgrind: + +1. Download the paranoia tests (paranoia.7z) from the ngspice Quality web page. + +2. p7zip -d paranoia.7z +Rename the the unzipped directory to a name without spaces which would +otherwise confuse valgrind. + +3. cd into the renamed unzipped directory. + +4. copy runtests.sh and textract.py from the examples/paranoia directory in +your git repository to the current directory. + +5. If your computer has several cores, you can modify the -j4 in the line + time parallel -j4 bash ::: $2/* +in runtests.sh and increase the number of parallel jobs. + +6. ./runtests.sh +For example: + ./runtests.sh paranoia_test.sh testdir +Note that the test area directory must not exist before you invoke runtests.sh. + +Now relax and drink a cup of coffee. If you don't want to run the tests in +parallel, it will take several cups. + diff --git a/examples/paranoia/runtests.sh b/examples/paranoia/runtests.sh new file mode 100755 index 000000000..69b3973ff --- /dev/null +++ b/examples/paranoia/runtests.sh @@ -0,0 +1,39 @@ +#!/bin/bash + +if test -n "$1" && test -n "$2" ; then + if test -d "$2" || test -e "$2" ; then + echo "$2 already exists, remove it first" + exit 1 + fi +python3 textract.py $1 $2 +else +echo "arg 1 is the paranoia test script" +echo "arg 2 is the test script working directory" +exit 1 +fi + +SECONDS=0 + +time parallel -j4 bash ::: $2/* + +wait +NGSPICE_OK="`ngspice -v | awk '/level/ {print $2;}'` done" + +echo "*******************************************" +echo "vlog files with errors found by valgrind:" +grep -L "ERROR SUMMARY: 0 errors from 0 context" ./*.vlog +echo "*******************************************" +echo "log files with ngspice errors:" +grep -L "$NGSPICE_OK" ./*.log +echo "*******************************************" +echo "log files with convergence issues:" +grep -l "Too many iterations without convergence" ./*.log +echo "*******************************************" +echo "log files with messages containing 'error':" +grep -i -l "error" ./*.log +echo "*******************************************" + +ELAPSED="Elapsed: $(($SECONDS / 3600))hrs $((($SECONDS / 60) % 60))min $(($SECONDS % 60))sec" +echo +echo $ELAPSED + diff --git a/examples/paranoia/textract.py b/examples/paranoia/textract.py new file mode 100644 index 000000000..a81cf6a75 --- /dev/null +++ b/examples/paranoia/textract.py @@ -0,0 +1,44 @@ +import os +import sys + + +testnum = 1 + + +def writeit(cd, cmd, outd): + global testnum + pwd = os.getcwd() + outfname = outd + '/testfile' + str(testnum) + '.sh' + outf = open(outfname, 'w') + testnum = testnum + 1 + outf.write('#!/bin/bash\n') + outf.write('NGSPICE="ngspice -i "\n') + p1 = 'VALGRIND="valgrind --leak-check=full --suppressions=' + p2 = p1 + pwd + '/ignore_shared_libs.supp"\n' + outf.write(p2) + outf.write(cd) + if cmd.endswith('&\n'): + outf.write(cmd[:-2] + '\n') + else: + outf.write(cmd) + os.chmod(outfname, 0o777) + outf.close() + return 0 + + +def main(): + infile = sys.argv[1] + outdir = sys.argv[2] + os.mkdir(outdir) + inp = open(infile, 'r') + for line in inp: + if line.startswith('cd '): + cdname = line + elif line.startswith('$VALGRIND'): + writeit(cdname, line, outdir) + inp.close() + return 0 + + +if __name__ == '__main__': + main() From 90f0680b518749b90712a3d17ead5a9f3b152831 Mon Sep 17 00:00:00 2001 From: dwarning Date: Tue, 5 Dec 2023 10:48:11 +0100 Subject: [PATCH 03/11] allow compile w/o NEWCONV defined --- src/spicelib/devices/bsim3v1/b3v1ld.c | 5 ++++- src/spicelib/devices/bsimsoi/b4soild.c | 3 +++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/spicelib/devices/bsim3v1/b3v1ld.c b/src/spicelib/devices/bsim3v1/b3v1ld.c index 61362a3d0..79629f3eb 100644 --- a/src/spicelib/devices/bsim3v1/b3v1ld.c +++ b/src/spicelib/devices/bsim3v1/b3v1ld.c @@ -121,7 +121,10 @@ double Cgg1, Cgb1, Cgd1, Cbg1, Cbb1, Cbd1, Qac0, Qsub0; double dQac0_dVg, dQac0_dVd, dQac0_dVb, dQsub0_dVg, dQsub0_dVd, dQsub0_dVb; double m = 1.0; - +#ifndef NEWCONV +double tol; +#endif + struct bsim3v1SizeDependParam *pParam; int ByPass, Check, ChargeComputationNeeded = 0, error; diff --git a/src/spicelib/devices/bsimsoi/b4soild.c b/src/spicelib/devices/bsimsoi/b4soild.c index 29e4a7caa..f0379fd3c 100644 --- a/src/spicelib/devices/bsimsoi/b4soild.c +++ b/src/spicelib/devices/bsimsoi/b4soild.c @@ -487,6 +487,9 @@ int B4SOILoadOMP(B4SOIinstance *here, CKTcircuit *ckt) { double eggbcp2, eggdep, agb1, bgb1, agb2, bgb2, agbc2n, agbc2p, bgbc2n, bgbc2p, Vtm00; /* v4.3.1 bugfix for mtrlMod=1 -Tanvir */ double m; +#ifndef NEWCONV + double tol; +#endif #ifndef USE_OMP for (; model != NULL; model = B4SOInextModel(model)) From b0d3b2064162e7746712b092586e549ff5d3e2ad Mon Sep 17 00:00:00 2001 From: dwarning Date: Tue, 5 Dec 2023 17:02:51 +0100 Subject: [PATCH 04/11] hisim2: allow compile w/o NEWCONV defined --- src/spicelib/devices/hisim2/hsm2ld.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/spicelib/devices/hisim2/hsm2ld.c b/src/spicelib/devices/hisim2/hsm2ld.c index cf694177a..d72a8459b 100644 --- a/src/spicelib/devices/hisim2/hsm2ld.c +++ b/src/spicelib/devices/hisim2/hsm2ld.c @@ -853,7 +853,6 @@ tm0 = gtodsecld() ; isConv = 0; } } - } #endif /* NEWCONV */ } } From 5ae5e877d2e0f8464dc23af7d35daa54d007a327 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Fri, 8 Dec 2023 10:30:12 +0100 Subject: [PATCH 05/11] prepare ngspice-42 --- NEWS | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/NEWS b/NEWS index bedb63582..50f5f5101 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,31 @@ +Ngspice-42, Dec 24th, 2023 +============ +- New features: + + New optional matrix solver KLU (select by 'option klu') + + improve error messages (more verbose, user centric) + + Add variable wr_onspace to allow printing the vetor name with + one space delimiter + + Re-write of the code model PWM generator + + Linked list modtab has been enhanced by a hash table + modtabhash + + Add a code model function cm_cexit(const int exitcode). + + PSP103 model pspnqs103va is now standard + + Add Isotel d_process xspice digital model (enable C models). + + OSDI interface allows small signal noise simulation in Verilog-A + compact models compiled by current OpenVAF. + + Add series resistance 1e-4 Ohms to diode model, if RS is not given + + Generate seed numbers from a microseconds clock, not a seconds clock + + Add functions ngSpice_LockRealloc and ngSpice_UnlockRealloc + + Add new code model function cm_irreversible(). + + Add XSPICE code model d_cosim, a generic adaptor for digital cosimulation. + + New interpreter commands strstr, strslice, fopen, fread and fclose. + + Recognise *ng_script_with_params" + + Add a predifined variable 'skywaterpdk' to speed up circuit + loading and parsing. + + Add scripts for running the paranoia tests in parallel on Linux with valgrind. + + + Ngspice-41, Aug 13th, 2023 ============ - New features: From 3b38125afd5dfee2b7661789773becd650c5ad78 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Fri, 8 Dec 2023 10:32:15 +0100 Subject: [PATCH 06/11] =?UTF-8?q?Enable=20measurements=20with=20=3F-sweep?= =?UTF-8?q?=20(v,=20i,=20temp,=20or=20res).=20Improve=20error=20messages.?= =?UTF-8?q?=20Prevent=20crash=20is=20comp=C3=BCdata=20is=20not=20available?= =?UTF-8?q?.=20Add=20to=20examples=20for=20measure=20failures.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/measure/buggy-meas-tran.sp | 2 + src/frontend/com_measure2.c | 63 +++++++++++++++++++++++------ 2 files changed, 53 insertions(+), 12 deletions(-) diff --git a/examples/measure/buggy-meas-tran.sp b/examples/measure/buggy-meas-tran.sp index a2a3906af..36277ebe8 100644 --- a/examples/measure/buggy-meas-tran.sp +++ b/examples/measure/buggy-meas-tran.sp @@ -91,5 +91,7 @@ meas tran tdiff TRIG v(1) VAL=0.5 RISE=1 TARG VAL=0.5 RISE=2 meas tran tdiff TRIG v(1) VAL=0.5 RISE=1 TARG v(1) RISE=2 meas tran tdiff TRIG v(1) VAL= RISE=1 TARG v(1) VAL=0.5 RISE=2 meas tran tdiff TRIG v(1) VAL=0.5 RISE= TARG v(1) VAL=0.5 RISE=2 +meas sp tmax MAX v(2) from=2m to=3m +meas dc ymax MAX v(2) from=2m to=3m .endc .end diff --git a/src/frontend/com_measure2.c b/src/frontend/com_measure2.c index 7033abbec..29dd6e9e6 100644 --- a/src/frontend/com_measure2.c +++ b/src/frontend/com_measure2.c @@ -432,7 +432,10 @@ com_measure_when( value = get_value(meas, d, i); //d->v_compdata[i].cx_real; else value = d->v_realdata[i]; - scaleValue = dScale->v_compdata[i].cx_real; + if (dScale->v_compdata) + scaleValue = dScale->v_compdata[i].cx_real; + else + scaleValue = dScale->v_realdata[i]; } else if (sp_check) { if (d->v_compdata) value = get_value(meas, d, i); //d->v_compdata[i].cx_real; @@ -768,20 +771,38 @@ measure_minMaxAvg( if (ac_check || sp_check) { dScale = vec_get("frequency"); + if (dScale == NULL) { + fprintf(cp_err, "Error: meas %s ...\n", meas->m_analysis); + fprintf(cp_err, " no such scale vector as frequency.\n"); + return MEASUREMENT_FAILURE; + } } else if (tran_check) { dScale = vec_get("time"); + if (dScale == NULL) { + fprintf(cp_err, "Error: meas %s ...\n", meas->m_analysis); + fprintf(cp_err, " no such scale vector as time.\n"); + return MEASUREMENT_FAILURE; + } } else if (dc_check) { dScale = vec_get("v-sweep"); + if (!dScale) { + dScale = vec_get("i-sweep"); + if (!dScale) { + dScale = vec_get("temp-sweep"); + if (!dScale) + dScale = vec_get("res-sweep"); + } + } + if (dScale == NULL) { + fprintf(cp_err, "Error: meas %s ...\n", meas->m_analysis); + fprintf(cp_err, " no such scale vector as v-sweep, i-sweep, temp-sweep, or res-sweep.\n"); + return MEASUREMENT_FAILURE; + } } else { /* error */ fprintf(cp_err, "Error: no such analysis type as %s.\n", meas->m_analysis); return MEASUREMENT_FAILURE; } - if (dScale == NULL) { - fprintf(cp_err, "Error: no such vector as time, frequency or v-sweep.\n"); - return MEASUREMENT_FAILURE; - } - if (dScale->v_realdata == NULL && dScale->v_compdata == NULL) { fprintf(cp_err, "Error: scale vector time, frequency or v-sweep has no data.\n"); return MEASUREMENT_FAILURE; @@ -949,22 +970,40 @@ measure_rms_integral( if (ac_check || sp_check) { xScale = vec_get("frequency"); + if (xScale == NULL) { + fprintf(cp_err, "Error: meas %s ...\n", meas->m_analysis); + fprintf(cp_err, " no such scale vector as frequency.\n"); + return MEASUREMENT_FAILURE; + } } else if (tran_check) { xScale = vec_get("time"); + if (xScale == NULL) { + fprintf(cp_err, "Error: meas %s ...\n", meas->m_analysis); + fprintf(cp_err, " no such scale vector as time.\n"); + return MEASUREMENT_FAILURE; + } } else if (dc_check) { xScale = vec_get("v-sweep"); + if (!xScale) { + xScale = vec_get("i-sweep"); + if (!xScale) { + xScale = vec_get("temp-sweep"); + if (!xScale) + xScale = vec_get("res-sweep"); + } + } + if (xScale == NULL) { + fprintf(cp_err, "Error: meas %s ...\n", meas->m_analysis); + fprintf(cp_err, " no such scale vector as v-sweep, i-sweep, temp-sweep, or res-sweep.\n"); + return MEASUREMENT_FAILURE; + } } else { /* error */ fprintf(cp_err, "Error: no such analysis type as %s.\n", meas->m_analysis); return MEASUREMENT_FAILURE; } - if (xScale == NULL) { - fprintf(cp_err, "Error: no such vector as time, frequency or v-sweep.\n"); - return MEASUREMENT_FAILURE; - } - if (xScale->v_realdata == NULL && xScale->v_compdata == NULL) { - fprintf(cp_err, "Error: scale vector time, frequency or v-sweep has no data.\n"); + fprintf(cp_err, "Error: scale vector time, frequency or ?-sweep has no data.\n"); return MEASUREMENT_FAILURE; } From 88ce328d846cc8622f672ce46a8d8afc3b950f4b Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Fri, 8 Dec 2023 10:40:33 +0100 Subject: [PATCH 07/11] Remove another potential crash if buggy user input --- src/frontend/com_measure2.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/frontend/com_measure2.c b/src/frontend/com_measure2.c index 29dd6e9e6..b36a510ce 100644 --- a/src/frontend/com_measure2.c +++ b/src/frontend/com_measure2.c @@ -691,7 +691,10 @@ measure_at( value = d->v_realdata[i]; // fprintf(cp_err, "Warning: 'meas ac' input vector is real!\n"); } - svalue = dScale->v_compdata[i].cx_real; + if (dScale->v_compdata) + svalue = dScale->v_compdata[i].cx_real; + else + svalue = dScale->v_realdata[i]; //prevent crash in case if buggy input } else if (sp_check) { if (d->v_compdata) value = get_value(meas, d, i); //d->v_compdata[i].cx_real; @@ -804,7 +807,7 @@ measure_minMaxAvg( } if (dScale->v_realdata == NULL && dScale->v_compdata == NULL) { - fprintf(cp_err, "Error: scale vector time, frequency or v-sweep has no data.\n"); + fprintf(cp_err, "Error: scale vector time, frequency or ?-sweep has no data.\n"); return MEASUREMENT_FAILURE; } From 0cdf3f0d28efc0715ca58ec31cf11ac17a966cf2 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Sun, 10 Dec 2023 15:15:44 +0100 Subject: [PATCH 08/11] Don't prescribe a different resistance value if the user has given one > 0. --- src/spicelib/devices/res/resmpar.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/spicelib/devices/res/resmpar.c b/src/spicelib/devices/res/resmpar.c index 8166b6bff..35df4c7ce 100644 --- a/src/spicelib/devices/res/resmpar.c +++ b/src/spicelib/devices/res/resmpar.c @@ -79,7 +79,7 @@ RESmParam(int param, IFvalue *value, GENmodel *inModel) model->RESefGiven = TRUE; break; case RES_MOD_R: - if ( value->rValue > 1e-03 ) { + if ( value->rValue > 0 ) { model->RESres = value->rValue; model->RESresGiven = TRUE; } From a3fef757a5a0afa32eebdfe72e3bda5354a1be6b Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Sun, 10 Dec 2023 15:16:05 +0100 Subject: [PATCH 09/11] typo --- src/spicelib/devices/res/restemp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/spicelib/devices/res/restemp.c b/src/spicelib/devices/res/restemp.c index 993a7795f..0d0a0b61f 100644 --- a/src/spicelib/devices/res/restemp.c +++ b/src/spicelib/devices/res/restemp.c @@ -69,7 +69,7 @@ RESupdate_conduct(RESinstance *here, bool spill_warnings) } else { if (spill_warnings) SPfrontEnd->IFerrorf (ERR_WARNING, - "%s: resistance to low, set to 1 mOhm", here->RESname); + "%s: resistance too low or not given, set to 1 mOhm", here->RESname); here->RESresist = 1e-03; } } From e0ee0bf131dbee8a27d5fdad71284cd7af0de3dc Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Sun, 10 Dec 2023 15:18:17 +0100 Subject: [PATCH 10/11] Don't silently accept wrong user input (missing nodes, values). Check for at leat 4 tokens (name, n1, n2, val/model/...). If the instance has not been set up correctly, bail out, prevent crash. --- src/spicelib/parser/inp2c.c | 29 ++++++++++++++++++++++++----- src/spicelib/parser/inp2l.c | 34 +++++++++++++++++++++++++--------- src/spicelib/parser/inp2r.c | 24 +++++++++++++++++++++--- 3 files changed, 70 insertions(+), 17 deletions(-) diff --git a/src/spicelib/parser/inp2c.c b/src/spicelib/parser/inp2c.c index 7ef15766f..3fc4da4ed 100644 --- a/src/spicelib/parser/inp2c.c +++ b/src/spicelib/parser/inp2c.c @@ -32,7 +32,7 @@ void INP2C(CKTcircuit *ckt, INPtables * tab, struct card *current) int error1; /* secondary error code temporary */ INPmodel *thismodel; /* pointer to model structure describing our model */ GENmodel *mdfast = NULL; /* pointer to the actual model */ - GENinstance *fast; /* pointer to the actual instance */ + GENinstance *fast = NULL;/* pointer to the actual instance */ IFvalue ptemp; /* a value structure to package resistance into */ int waslead; /* flag to indicate that funny unlabeled number was found */ double leadval; /* actual value of unlabeled number */ @@ -49,11 +49,25 @@ void INP2C(CKTcircuit *ckt, INPtables * tab, struct card *current) } } line = current->line; - INPgetNetTok(&line, &name, 1); + + INPgetNetTok(&line, &name, 1); /* Cname */ + if (*line == '\0') { + fprintf(stderr, "\nWarning: '%s' is not a valid capacitor instance line, ignored!\n\n", current->line); + return; + } + INPgetNetTok(&line, &nname1, 1); /* */ + if (*line == '\0') { + fprintf(stderr, "\nWarning: '%s' is not a valid capacitor instance line, ignored!\n\n", current->line); + return; + } + INPgetNetTok(&line, &nname2, 1); /* */ + if (*line == '\0') { + fprintf(stderr, "\nWarning: '%s' is not a valid capacitor instance line, ignored!\n\n", current->line); + return; + } + INPinsert(&name, tab); - INPgetNetTok(&line, &nname1, 1); INPtermInsert(ckt, &nname1, tab, &node1); - INPgetNetTok(&line, &nname2, 1); INPtermInsert(ckt, &nname2, tab, &node2); /* enable reading values like 4u7 */ @@ -109,7 +123,12 @@ void INP2C(CKTcircuit *ckt, INPtables * tab, struct card *current) #endif } } - + + if (!fast || !fast->GENmodPtr) { + fprintf(stderr, "\nWarning: Instance for capacitor '%s' could not be set up properly, ignored!\n\n", current->line); + return; + } + if (error1 == 0) { /* Looks like a number */ ptemp.rValue = val; GCA(INPpName, ("capacitance", &ptemp, ckt, type, fast)); diff --git a/src/spicelib/parser/inp2l.c b/src/spicelib/parser/inp2l.c index da66650f0..adfd885b3 100644 --- a/src/spicelib/parser/inp2l.c +++ b/src/spicelib/parser/inp2l.c @@ -32,7 +32,7 @@ void INP2L(CKTcircuit *ckt, INPtables * tab, struct card *current) int error1; /* secondary error code temporary */ INPmodel *thismodel; /* pointer to model structure describing our model */ GENmodel *mdfast = NULL; /* pointer to the actual model */ - GENinstance *fast; /* pointer to the actual instance */ + GENinstance *fast = NULL;/* pointer to the actual instance */ IFvalue ptemp; /* a value structure to package inductance into */ int waslead; /* flag to indicate that funny unlabeled number was found */ double leadval; /* actual value of unlabeled number */ @@ -49,14 +49,25 @@ void INP2L(CKTcircuit *ckt, INPtables * tab, struct card *current) } } line = current->line; - INPgetNetTok(&line, &name, 1); - INPinsert(&name, tab); - INPgetNetTok(&line, &nname1, 1); - INPtermInsert(ckt, &nname1, tab, &node1); - INPgetNetTok(&line, &nname2, 1); - INPtermInsert(ckt, &nname2, tab, &node2); + INPgetNetTok(&line, &name, 1); /* Lname */ + if (*line == '\0') { + fprintf(stderr, "\nWarning: '%s' is not a valid inductor instance line, ignored!\n\n", current->line); + return; + } + INPgetNetTok(&line, &nname1, 1); /* */ + if (*line == '\0') { + fprintf(stderr, "\nWarning: '%s' is not a valid inductor instance line, ignored!\n\n", current->line); + return; + } + INPgetNetTok(&line, &nname2, 1); /* */ + if (*line == '\0') { + fprintf(stderr, "\nWarning: '%s' is not a valid inductor instance line, ignored!\n\n", current->line); + return; + } -// val = INPevaluate(&line, &error1, 1); + INPinsert(&name, tab); + INPtermInsert(ckt, &nname1, tab, &node1); + INPtermInsert(ckt, &nname2, tab, &node2); /* enable reading values like 4u7 */ if (newcompat.lt) @@ -110,7 +121,12 @@ void INP2L(CKTcircuit *ckt, INPtables * tab, struct card *current) #endif } } - + + if (!fast || !fast->GENmodPtr) { + fprintf(stderr, "\nWarning: Instance for inductor '%s' could not be set up properly, ignored!\n\n", current->line); + return; + } + if (error1 == 0) { /* Looks like a number */ ptemp.rValue = val; GCA(INPpName, ("inductance", &ptemp, ckt, type, fast)); diff --git a/src/spicelib/parser/inp2r.c b/src/spicelib/parser/inp2r.c index 587f940a5..5241b3035 100644 --- a/src/spicelib/parser/inp2r.c +++ b/src/spicelib/parser/inp2r.c @@ -39,7 +39,7 @@ void INP2R(CKTcircuit *ckt, INPtables * tab, struct card *current) int error1; /* secondary error code temporary */ INPmodel *thismodel; /* pointer to model structure describing our model */ GENmodel *mdfast = NULL; /* pointer to the actual model */ - GENinstance *fast; /* pointer to the actual instance */ + GENinstance *fast = NULL; /* pointer to the actual instance */ IFvalue ptemp; /* a value structure to package resistance into */ int waslead; /* flag to indicate that funny unlabeled number was found */ double leadval; /* actual value of unlabeled number */ @@ -59,10 +59,23 @@ void INP2R(CKTcircuit *ckt, INPtables * tab, struct card *current) } line = current->line; INPgetNetTok(&line, &name, 1); /* Rname */ - INPinsert(&name, tab); + if (*line == '\0') { + fprintf(stderr, "\nWarning: '%s' is not a valid resistor instance line, ignored!\n\n", current->line); + return; + } INPgetNetTok(&line, &nname1, 1); /* */ - INPtermInsert(ckt, &nname1, tab, &node1); + if (*line == '\0') { + fprintf(stderr, "\nWarning: '%s' is not a valid resistor instance line, ignored!\n\n", current->line); + return; + } INPgetNetTok(&line, &nname2, 1); /* */ + if (*line == '\0') { + fprintf(stderr, "\nWarning: '%s' is not a valid resistor instance line, ignored!\n\n", current->line); + return; + } + + INPinsert(&name, tab); + INPtermInsert(ckt, &nname1, tab, &node1); INPtermInsert(ckt, &nname2, tab, &node2); /* enable reading values like 4k7 */ @@ -197,6 +210,11 @@ void INP2R(CKTcircuit *ckt, INPtables * tab, struct card *current) } } + if (!fast || !fast->GENmodPtr) { + fprintf(stderr, "\nWarning: Instance for resistor '%s' could not be set up properly, ignored!\n\n", current->line); + return; + } + if (error1 == 0) { /* got a resistance above */ ptemp.rValue = val; GCA(INPpName, ("resistance", &ptemp, ckt, type, fast)); From d0e91f58b3e825787040bc2bebec630702eef0c4 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Sun, 10 Dec 2023 18:01:07 +0100 Subject: [PATCH 11/11] Prevent crash if port number is less than 1. --- src/spicelib/devices/vsrc/vsrctemp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/spicelib/devices/vsrc/vsrctemp.c b/src/spicelib/devices/vsrc/vsrctemp.c index 413e356e9..359e0bdc6 100644 --- a/src/spicelib/devices/vsrc/vsrctemp.c +++ b/src/spicelib/devices/vsrc/vsrctemp.c @@ -76,7 +76,7 @@ VSRCtemp(GENmodel *inModel, CKTcircuit *ckt) if (!here->VSRCportZ0Given) here->VSRCportZ0 = 50.0; - here->VSRCisPort = here->VSRCportZ0 > 0.0; + here->VSRCisPort = here->VSRCportZ0 > 0.0 && here->VSRCportNum > 0; } else here->VSRCisPort = FALSE;