From 826401f6a42f3e5ba18f8d9a6e141caa4cc51d52 Mon Sep 17 00:00:00 2001 From: Brian Taylor Date: Tue, 13 Feb 2024 16:10:28 -0800 Subject: [PATCH 1/8] Add error detection and reporting for invalid infix expressions. --- src/frontend/logicexp.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/src/frontend/logicexp.c b/src/frontend/logicexp.c index 18ea46c9d..ba8d6afc5 100644 --- a/src/frontend/logicexp.c +++ b/src/frontend/logicexp.c @@ -729,7 +729,7 @@ static char *makestr(int c) static int infix_to_postfix(char* infix, DSTRING * postfix_p) { struct Stack stack; - int ltok; + int ltok, last_tok = -1; LEXER lx; NAME_ENTRY nlist = NULL, entry = NULL; int status = 0; @@ -739,6 +739,18 @@ static int infix_to_postfix(char* infix, DSTRING * postfix_p) nlist = add_name_entry("first", NULL); ds_clear(postfix_p); while ( ( ltok = lexer_scan(lx) ) != 0 ) { // start while ltok loop + if (ltok == LEX_ID && last_tok == LEX_ID) { + fprintf(stderr, "ERROR no gate operator between two identifiers\n"); + status = 1; + goto err_return; + } + if (lex_gate_op(ltok) && lex_gate_op(last_tok)) { + fprintf(stderr, "ERROR two consecutive gate operators\n"); + status = 1; + goto err_return; + } + + last_tok = ltok; if (ltok == LEX_ID) { ds_cat_printf(postfix_p, " %s", lx->lexer_buf); } else if (ltok == '(') { @@ -769,6 +781,11 @@ static int infix_to_postfix(char* infix, DSTRING * postfix_p) } entry = add_name_entry(tokstr, nlist); if (push(&stack, entry->name)) goto err_return; + } else { + fprintf(stderr, "ERROR unexpected infix token %d \'%s\'\n", + ltok, lx->lexer_buf); + status = 1; + goto err_return; } } // end while ltok loop while (stack.top != -1) { @@ -1049,6 +1066,12 @@ static BOOL bstmt_postfix(void) retval = FALSE; goto bail_out; } + if (lookahead != '{') { + printf("ERROR in bstmt_postfix \'{\' was expected\n"); + aerror("bstmt_postfix: syntax error"); + retval = FALSE; + goto bail_out; + } rest = parse_lexer->lexer_line + parse_lexer->lexer_pos; right_bracket = strstr(rest, "}"); From 8788ce35046fa1369809ea75efa5e0d7692b06b5 Mon Sep 17 00:00:00 2001 From: Brian Taylor Date: Tue, 13 Feb 2024 21:21:39 -0800 Subject: [PATCH 2/8] Add check for a trailing } in a logicexp statement. --- src/frontend/logicexp.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/frontend/logicexp.c b/src/frontend/logicexp.c index ba8d6afc5..36550e1fc 100644 --- a/src/frontend/logicexp.c +++ b/src/frontend/logicexp.c @@ -1075,6 +1075,12 @@ static BOOL bstmt_postfix(void) rest = parse_lexer->lexer_line + parse_lexer->lexer_pos; right_bracket = strstr(rest, "}"); + if (!right_bracket) { + printf("ERROR in bstmt_postfix \'}\' was not found\n"); + aerror("bstmt_postfix: syntax error"); + retval = FALSE; + goto bail_out; + } ds_clear(&infix); ds_cat_mem(&infix, rest, right_bracket - rest); if (infix_to_postfix(ds_get_buf(&infix), &postfix)) { From 4c983e9133c5f8c2c5e5c232aa789605e221d3d3 Mon Sep 17 00:00:00 2001 From: Brian Taylor Date: Sun, 18 Feb 2024 13:45:59 -0800 Subject: [PATCH 3/8] Remove old dead code. --- src/frontend/logicexp.c | 55 ----------------------------------------- 1 file changed, 55 deletions(-) diff --git a/src/frontend/logicexp.c b/src/frontend/logicexp.c index 36550e1fc..f4a73fa5e 100644 --- a/src/frontend/logicexp.c +++ b/src/frontend/logicexp.c @@ -892,59 +892,6 @@ err_return: /* End of infix to posfix */ -/* Start parse table */ -typedef struct table_line *TLINE; -struct table_line { - char *line; - int depth; /* expression nesting depth, outermost depth == 1 */ - TLINE next; -}; - -typedef struct parse_table *PTABLE; -struct parse_table { - TLINE first; - TLINE last; - unsigned int entry_count; -}; - -static PTABLE parse_tab = NULL; - -static PTABLE new_parse_table(void) -{ - PTABLE pt; - pt = TMALLOC(struct parse_table, 1); - pt->first = pt->last = NULL; - pt->entry_count = 0; - return pt; -} - -static void delete_parse_table(PTABLE pt) -{ - TLINE t, next; - if (!pt) - return; - next = pt->first; - while (next) { - t = next; - tfree(t->line); - next = t->next; - tfree(t); - } - tfree(pt); -} - -static void delete_parse_tables(void) -{ - delete_parse_table(parse_tab); - parse_tab = NULL; -} - -static void init_parse_tables(void) -{ - parse_tab = new_parse_table(); -} -/* End parse table */ - /* Start of logicexp parser */ static void aerror(char *s); static BOOL amatch(int t); @@ -958,7 +905,6 @@ static void cleanup_parser(void) { delete_lexer(parse_lexer); parse_lexer = NULL; - delete_parse_tables(); } static char *get_inst_name(void) @@ -1147,7 +1093,6 @@ static BOOL bparse(char *line, BOOL new_lexer) lookahead = lex_scan(); // ':' lookahead = lex_scan(); while (lookahead != '\0') { - init_parse_tables(); ds_clear(&stmt); ds_cat_str(&stmt, parse_lexer->lexer_buf); if (!bstmt_postfix()) { From a5f99a4953ea946583e39c8316cdbf9972714826 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Fri, 23 Feb 2024 14:12:49 +0100 Subject: [PATCH 4/8] Make PSP103_nqs standard, as it is used by the Open PDK from IHP --- src/spinit.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/spinit.in b/src/spinit.in index f1ca1c285..f9bfde40e 100644 --- a/src/spinit.in +++ b/src/spinit.in @@ -36,7 +36,7 @@ if $?osdi_enabled osdi @pkglibdir@/BSIMBULK107.osdi osdi @pkglibdir@/BSIMCMG.osdi osdi @pkglibdir@/HICUMl0-2.0.osdi - osdi @pkglibdir@/psp103.osdi + osdi @pkglibdir@/psp103_nqs.osdi osdi @pkglibdir@/r2_cmc.osdi osdi @pkglibdir@/vbic_4T_et_cf.osdi From da51e1bddf3f32d620ce94a9af768fa21d07a6f4 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Wed, 28 Feb 2024 10:06:31 +0100 Subject: [PATCH 5/8] Don't use printf(".."), but fprintf(stdout, "..."), thus send an end-of-line also when redirected to file. --- src/frontend/device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/frontend/device.c b/src/frontend/device.c index b6af27493..d9b21dec5 100644 --- a/src/frontend/device.c +++ b/src/frontend/device.c @@ -854,7 +854,7 @@ listparam(wordlist *p, dgen *dg) else fprintf(cp_out, "%*.*s", LEFT_WIDTH, LEFT_WIDTH, " "); k = dgen_for_n(dg, count, printvals_old, (plist + i), j); - printf("\n"); + fprintf(cp_out,"\n"); j += 1; } while (k > 0); } else { From f5c0a1420cd747a568a19797dcadd6e6f10892d8 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Sat, 9 Mar 2024 23:41:34 +0100 Subject: [PATCH 6/8] Upon a warning on a model issue, ngspice should not bail out, even if strict_error is set, as typically the simulation will run and foreign models often have additional unsupported, but less important parameters. It shall however, exit if the simulation is interrupted due to an error and strict_errorhandling is set. --- src/frontend/inp.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/frontend/inp.c b/src/frontend/inp.c index 3a1a22300..d59695a18 100644 --- a/src/frontend/inp.c +++ b/src/frontend/inp.c @@ -1447,17 +1447,20 @@ inp_dodeck( else if (dd->linenum_orig == 0) { fprintf(stderr, "Error on line:\n %s\n%s\n", dd->line, dd->error); + if (ft_stricterror) + controlled_exit(EXIT_BAD); have_err = TRUE; return 1; } else { fprintf(stderr, "Error on line %d or its substitute:\n %s\n%s\n", dd->linenum_orig, dd->line, dd->error); + if (ft_stricterror) + controlled_exit(EXIT_BAD); have_err = TRUE; return 1; } - if (ft_stricterror) - controlled_exit(EXIT_BAD); + } else { fprintf(stderr, "%s\n", p); } @@ -1941,6 +1944,8 @@ com_source(wordlist *wl) Infile_Path = ngdirname(firstfile); if (inp_spsource(fp, FALSE, tempfile ? NULL : wl->wl_word, FALSE) != 0) { fprintf(stderr, " Simulation interrupted due to error!\n\n"); + if (ft_stricterror) + controlled_exit(EXIT_FAILURE); } } From 2dab26212aae08699e03107c161227b9fa299a83 Mon Sep 17 00:00:00 2001 From: dwarning Date: Sun, 10 Mar 2024 09:47:17 +0100 Subject: [PATCH 7/8] introduce diode breakdown voltage parameter alias vb --- src/spicelib/devices/dio/dio.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/spicelib/devices/dio/dio.c b/src/spicelib/devices/dio/dio.c index 663af176c..947230e5a 100644 --- a/src/spicelib/devices/dio/dio.c +++ b/src/spicelib/devices/dio/dio.c @@ -104,6 +104,7 @@ IFparm DIOmPTable[] = { /* model parameters */ IOP( "fc", DIO_MOD_FC, IF_REAL, "Forward bias junction fit parameter"), IOP( "fcs", DIO_MOD_FCS, IF_REAL, "Forward bias sidewall junction fit parameter"), IOP( "bv", DIO_MOD_BV, IF_REAL, "Reverse breakdown voltage"), + IOPR( "vb", DIO_MOD_BV, IF_REAL, "Reverse breakdown voltage"), IOP( "ibv", DIO_MOD_IBV, IF_REAL, "Current at reverse breakdown voltage"), IOPR( "ib", DIO_MOD_IBV, IF_REAL, "Current at reverse breakdown voltage"), IOP( "tcv", DIO_MOD_TCV, IF_REAL, "Reverse breakdown voltage temperature coefficient"), From adb38ecb17daf5d55a8d713c3e7e0f7e52588d15 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Sun, 10 Mar 2024 21:58:56 +0100 Subject: [PATCH 8/8] Upon error, bail out when strict_error is set. --- src/frontend/inpcom.c | 22 ++++++++++++++++++++++ src/main.c | 6 ++++-- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/frontend/inpcom.c b/src/frontend/inpcom.c index 8f96eee84..f55771b7b 100644 --- a/src/frontend/inpcom.c +++ b/src/frontend/inpcom.c @@ -1115,6 +1115,8 @@ struct card *inp_readall(FILE *fp, const char *dir_name, if (inp_poly_2g6_compat(working)) { inp_rem_levels(root); line_free_x(cc, TRUE); + if (ft_stricterror) + controlled_exit(EXIT_BAD); return NULL; } #else @@ -1393,6 +1395,8 @@ struct inp_read_t inp_read( FILE *fp, int call_depth, const char *dir_name, if (!y_resolved) { fprintf(cp_err, "Error: Could not find include file %s\n", y); + if (ft_stricterror) + controlled_exit(EXIT_FAILURE); rv.line_number = line_number; rv.cc = NULL; return rv; @@ -5849,6 +5853,8 @@ static void inp_compat(struct card *card) (firstno && !secondno)) { fprintf(stderr, "Error: Missing token in %s\n", curr_line); + if (ft_stricterror) + controlled_exit(EXIT_FAILURE); break; } else if (!firstno && !secondno) @@ -6060,6 +6066,8 @@ static void inp_compat(struct card *card) if ((!firstno && secondno) || (firstno && !secondno)) { fprintf(stderr, "Error: Missing token in %s\n", curr_line); + if (ft_stricterror) + controlled_exit(EXIT_BAD); break; } else if (!firstno && !secondno) @@ -8080,6 +8088,8 @@ static int inp_vdmos_model(struct card *deck) " in VDMOS instance line with thermal model\n" " %s\n", card->line); fprintf(stderr, "No circuit loaded!\n"); + if (ft_stricterror) + controlled_exit(EXIT_BAD); return 1; } /* next token is the model name of instance */ @@ -8101,6 +8111,8 @@ static int inp_vdmos_model(struct card *deck) " %s\n", card->line); fprintf(stderr, "No circuit loaded!\n"); tfree(instmodname); + if (ft_stricterror) + controlled_exit(EXIT_BAD); return 1; } } @@ -9134,6 +9146,8 @@ static int inp_poly_2g6_compat(struct card* deck) { if (!curr_line) { fprintf(stderr, "Error: bad syntax of line\n %s\n", thisline); fprintf(stderr, "No circuit loaded!\n"); + if (ft_stricterror) + controlled_exit(EXIT_BAD); return 1; } /* exclude all of the following fourth tokens */ @@ -9171,6 +9185,8 @@ static int inp_poly_2g6_compat(struct card* deck) { if (!curr_line) { fprintf(stderr, "Error: not enough parameters in line\n %s\n", thisline); fprintf(stderr, "No circuit loaded!\n"); + if (ft_stricterror) + controlled_exit(EXIT_BAD); return 1; } /* The next token may be a simple text token or an expression @@ -9184,6 +9200,8 @@ static int inp_poly_2g6_compat(struct card* deck) { if (!curr_line) { fprintf(stderr, "Error: not enough parameters in line\n %s\n", thisline); fprintf(stderr, "No circuit loaded!\n"); + if (ft_stricterror) + controlled_exit(EXIT_BAD); return 1; } if (*curr_line == '\0') @@ -9195,6 +9213,8 @@ static int inp_poly_2g6_compat(struct card* deck) { if (!curr_line) { fprintf(stderr, "Error: not enough parameters in line\n %s\n", thisline); fprintf(stderr, "No circuit loaded!\n"); + if (ft_stricterror) + controlled_exit(EXIT_BAD); return 1; } /* The next token may be a simple text token or an expression @@ -9208,6 +9228,8 @@ static int inp_poly_2g6_compat(struct card* deck) { if (!curr_line) { fprintf(stderr, "Error: not enough parameters in line\n %s\n", thisline); fprintf(stderr, "No circuit loaded!\n"); + if (ft_stricterror) + controlled_exit(EXIT_BAD); return 1; } if (*curr_line == '\0') diff --git a/src/main.c b/src/main.c index 0dc5db052..6b3f2cf36 100644 --- a/src/main.c +++ b/src/main.c @@ -1461,8 +1461,8 @@ int main(int argc, char **argv) /* Copy the input file name for becoming another file search path */ if (inp_spsource(tempfile, FALSE, dname, FALSE) != 0) { fprintf(stderr, " Simulation interrupted due to error!\n\n"); - if (oflag && !cp_getvar("interactive", CP_BOOL, NULL, 0)) - exit(EXIT_BAD); + if (ft_stricterror || (oflag && !cp_getvar("interactive", CP_BOOL, NULL, 0))) + sp_shutdown(EXIT_BAD); } tfree(dname); gotone = TRUE; @@ -1477,6 +1477,8 @@ int main(int argc, char **argv) if (!gotone && ft_batchmode) { if (inp_spsource(circuit_file, FALSE, NULL, FALSE) != 0) { fprintf(stderr, " Simulation interrupted due to error!\n\n"); + if (ft_stricterror) + sp_shutdown(EXIT_BAD); } }