From 8a6b8c4d36f315ed3150ae2221365fb0587dcac4 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Mon, 27 Apr 2020 14:40:01 +0200 Subject: [PATCH] Unify model handling: errors, default models, user supplied models Add variable 'use_default_models' (.spiceinit) to select allowing default models or strictly stop ngspice, if .model declaration is missing. Add member 'warning' to struct card. If member 'error' is flagged, ngspice will stop, if 'warning' is flagged, ngspice continues with warning message and default model. Will be set in inp2x. Here prototype is pushed for JFET model (inp2j.c). --- src/frontend/inp.c | 13 ++++++++++++- src/frontend/inpcom.c | 1 + src/frontend/options.c | 4 ++++ src/frontend/subckt.c | 2 ++ src/include/ngspice/fteext.h | 1 + src/include/ngspice/inpdefs.h | 3 ++- src/spicelib/parser/inp2j.c | 7 ++++++- src/spicelib/parser/inpgmod.c | 5 ++++- 8 files changed, 32 insertions(+), 4 deletions(-) diff --git a/src/frontend/inp.c b/src/frontend/inp.c index bbb7cbac5..73043ca4d 100644 --- a/src/frontend/inp.c +++ b/src/frontend/inp.c @@ -309,6 +309,7 @@ line_free_x(struct card *deck, bool recurse) line_free_x(deck->actualLine, TRUE); tfree(deck->line); tfree(deck->error); + tfree(deck->warning); tfree(deck); if (!recurse) return; @@ -1032,11 +1033,16 @@ inp_dodeck( /* First throw away any old error messages there might be and fix the case of the lines. */ - for (dd = deck; dd; dd = dd->nextcard) + for (dd = deck; dd; dd = dd->nextcard) { if (dd->error) { tfree(dd->error); dd->error = NULL; } + if (dd->warning) { + tfree(dd->warning); + dd->warning = NULL; + } + } if (reuse) { /* re-use existing circuit structure */ @@ -1151,6 +1157,11 @@ inp_dodeck( printf("In inp_dodeck, looking for errors and examining line %s . . . \n", dd->line); #endif + if (dd->warning) { + out_printf("Caution for line %d :\n %s\n%s\n", + dd->linenum_orig, dd->line, dd->warning); + } + if (dd->error) { char *p, *q; #ifdef XSPICE diff --git a/src/frontend/inpcom.c b/src/frontend/inpcom.c index 81372a03b..c4dfdd6b2 100644 --- a/src/frontend/inpcom.c +++ b/src/frontend/inpcom.c @@ -212,6 +212,7 @@ static struct card *insert_new_line( x->nextcard = card ? card->nextcard : NULL; x->error = NULL; + x->warning = NULL; x->actualLine = NULL; x->line = line; x->linenum = linenum; diff --git a/src/frontend/options.c b/src/frontend/options.c index 6ea3a9f37..e92b1ea40 100644 --- a/src/frontend/options.c +++ b/src/frontend/options.c @@ -25,6 +25,7 @@ bool ft_acctprint = FALSE, ft_noacctprint = FALSE, ft_listprint = FALSE; bool ft_nodesprint = FALSE, ft_optsprint = FALSE, ft_noinitprint = FALSE; bool ft_norefprint = FALSE; bool ft_ngdebug = FALSE, ft_stricterror = FALSE; +bool ft_usedefmodel = FALSE; static void setdb(char *str); static struct variable *cp_enqvec_as_var(const char *vec_name, @@ -254,6 +255,7 @@ inp_getoptsc(char *line, struct card *options) next->line = tprintf(".options %s", line); next->linenum = 0; next->error = NULL; + next->warning = NULL; next->actualLine = NULL; /* put new line in front */ @@ -322,6 +324,8 @@ cp_usrset(struct variable *var, bool isset) ft_strictnumparse = isset; } else if (eq(var->va_name, "strict_errorhandling")) { ft_stricterror = isset; + } else if (eq(var->va_name, "use_default_models")) { + ft_usedefmodel = isset; } else if (eq(var->va_name, "rawfileprec")) { if ((var->va_type == CP_BOOL) && (isset == FALSE)) raw_prec = -1; diff --git a/src/frontend/subckt.c b/src/frontend/subckt.c index 179e9abfb..f342b24f1 100644 --- a/src/frontend/subckt.c +++ b/src/frontend/subckt.c @@ -714,6 +714,8 @@ struct card * inp_deckcopy(struct card *deck) { d->line = copy(deck->line); if (deck->error) d->error = copy(deck->error); + if (deck->warning) + d->warning = copy(deck->warning); d->actualLine = inp_deckcopy(deck->actualLine); deck = deck->nextcard; } diff --git a/src/include/ngspice/fteext.h b/src/include/ngspice/fteext.h index 70cea638c..9a085bf9b 100644 --- a/src/include/ngspice/fteext.h +++ b/src/include/ngspice/fteext.h @@ -264,6 +264,7 @@ extern struct card *inp_getopts(struct card *deck); extern struct card *inp_getoptsc(char *line, struct card *options); extern bool ft_ngdebug; extern bool ft_stricterror; +extern bool ft_usedefmodel; /* parse.c */ diff --git a/src/include/ngspice/inpdefs.h b/src/include/ngspice/inpdefs.h index e8d9c864f..4e9f67579 100644 --- a/src/include/ngspice/inpdefs.h +++ b/src/include/ngspice/inpdefs.h @@ -78,7 +78,8 @@ struct card { int linenum; int linenum_orig; char *line; - char *error; + char *error; /* entry causes ngspice to stop */ + char *warning; struct card *nextcard; struct card *actualLine; struct nscope *level; diff --git a/src/spicelib/parser/inp2j.c b/src/spicelib/parser/inp2j.c index 344322639..dd9470c50 100644 --- a/src/spicelib/parser/inp2j.c +++ b/src/spicelib/parser/inp2j.c @@ -34,6 +34,7 @@ void INP2J(CKTcircuit *ckt, INPtables * tab, struct card *current) INPmodel *thismodel; /* pointer to model description for user's model */ GENmodel *mdfast; /* pointer to the actual model */ IFuid uid; /* uid of default model */ + char* errormsg; line = current->line; INPgetNetTok(&line, &name, 1); @@ -46,7 +47,11 @@ void INP2J(CKTcircuit *ckt, INPtables * tab, struct card *current) INPtermInsert(ckt, &nname3, tab, &node3); INPgetNetTok(&line, &model, 1); INPinsert(&model, tab); - current->error = INPgetMod(ckt, model, &thismodel, tab); + errormsg = INPgetMod(ckt, model, &thismodel, tab); + if (ft_usedefmodel) + current->warning = errormsg; + else + current->error = errormsg; if (thismodel != NULL) { if (thismodel->INPmodType != INPtypelook("JFET") && thismodel->INPmodType != INPtypelook("JFET2") diff --git a/src/spicelib/parser/inpgmod.c b/src/spicelib/parser/inpgmod.c index d252b26d6..0330b4225 100644 --- a/src/spicelib/parser/inpgmod.c +++ b/src/spicelib/parser/inpgmod.c @@ -334,7 +334,10 @@ INPgetMod(CKTcircuit *ckt, char *name, INPmodel **model, INPtables *tab) #endif *model = NULL; - return tprintf("Unable to find definition of model %s - default assumed\n", name); + if (ft_usedefmodel) + return tprintf("Unable to find definition of model %s - default assumed\n", name); + else + return tprintf("Unable to find definition of model %s\n", name); }