diff --git a/src/frontend/inpcom.c b/src/frontend/inpcom.c index a5c90a15c..fe3e296cb 100644 --- a/src/frontend/inpcom.c +++ b/src/frontend/inpcom.c @@ -583,7 +583,12 @@ static struct library *read_a_lib(const char *y, const char *dir_name) lib->habitat = ngdirname(yy); lib->deck = - inp_read(newfp, 1 /*dummy*/, lib->habitat, NULL, FALSE, FALSE).cc; + inp_read(newfp, 1 /*dummy*/, lib->habitat, lib->realpath, FALSE, FALSE).cc; + + struct card* tmpdeck; + int cnumber = 1; + for (tmpdeck = lib->deck; tmpdeck; tmpdeck = tmpdeck->nextcard) + tmpdeck->linenum_orig = cnumber++; fclose(newfp); } @@ -1432,17 +1437,14 @@ static 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; + controlled_exit(EXIT_FAILURE); } newfp = fopen(y_resolved, "r"); if (!newfp) { - fprintf(cp_err, "Error: .include statement failed.\n"); + fprintf(cp_err, "Error: .include statement failed.\n" + "Could not open file\n%s\n", y_resolved); tfree(buffer); /* allocated by readline() above */ controlled_exit(EXIT_FAILURE); } @@ -1465,8 +1467,12 @@ static struct inp_read_t inp_read(FILE* fp, int call_depth, const char* dir_name /* append `buffer' to the (cc, end) chain of decks */ { - end = insert_new_line( - end, copy(buffer), line_number, end->linenum_orig, end->linesource); + if (end) + end = insert_new_line( + end, copy(buffer), line_number, end->linenum_orig, end->linesource); + else + end = insert_new_line( + end, copy(buffer), line_number, 1, file_name); if (!cc) cc = end; @@ -5868,8 +5874,10 @@ static void inp_compat(struct card *card) &cut_line, '}', TRUE, TRUE); /* expression */ if (!expression || !str_ptr) { fprintf(stderr, - "Error: bad syntax in line %d\n %s\n", - card->linenum_orig, card->line); + "Error: bad syntax in line %d\n %s\n" + "from file\n" + " %s\n", + card->linenum_orig, card->line, card->linesource); controlled_exit(EXIT_BAD); } tfree(str_ptr); @@ -6063,8 +6071,11 @@ static void inp_compat(struct card *card) // skip "table" cut_line = skip_ws(cut_line); if (!ciprefix("table", cut_line)) { - fprintf(stderr, "Error: bad syntax in line %d\n %s\n", - card->linenum_orig, card->line); + fprintf(stderr, + "Error: bad syntax in line %d\n %s\n" + "from file\n" + " %s\n", + card->linenum_orig, card->line, card->linesource); controlled_exit(EXIT_BAD); } cut_line += 5; @@ -6075,8 +6086,11 @@ static void inp_compat(struct card *card) str_ptr = gettok_char(&cut_line, '{', FALSE, FALSE); expression = gettok_char(&cut_line, '}', TRUE, TRUE); if (!expression || !str_ptr) { - fprintf(stderr, "Error: bad syntax in line %d\n %s\n", - card->linenum_orig, card->line); + fprintf(stderr, + "Error: bad syntax in line %d\n %s\n" + "from file\n" + " %s\n", + card->linenum_orig, card->line, card->linesource); controlled_exit(EXIT_BAD); } tfree(str_ptr); diff --git a/src/frontend/inpcompat.c b/src/frontend/inpcompat.c index 56d8b48ce..503d190d1 100644 --- a/src/frontend/inpcompat.c +++ b/src/frontend/inpcompat.c @@ -1369,7 +1369,11 @@ struct card *pspice_compat(struct card *oldcard) for (i = 0; i < 6; i++) { stoks[i] = gettok_node(&cut_line); if (!stoks[i]) { - fprintf(stderr, "Error: Bad syntax in line:\n %s\n", card->line); + fprintf(stderr, + "Error: bad syntax in line %d\n %s\n" + "from file\n" + " %s\n", + card->linenum_orig, card->line, card->linesource); good = FALSE; break; } diff --git a/src/include/ngspice/inpdefs.h b/src/include/ngspice/inpdefs.h index 18bc92ca4..36203bc11 100644 --- a/src/include/ngspice/inpdefs.h +++ b/src/include/ngspice/inpdefs.h @@ -97,7 +97,9 @@ struct INPmodel { GENmodel *INPmodfast; /* high speed pointer to model for access */ }; - +// Ugly way to pass line onfo (number and source file) to lower-level error handlers. +extern int Current_parse_line; +extern char* Sourcefile; /* listing types - used for debug listings */ #define LOGICAL 1 diff --git a/src/spicelib/parser/inppas2.c b/src/spicelib/parser/inppas2.c index bfc4b060a..6cc1bfe6a 100644 --- a/src/spicelib/parser/inppas2.c +++ b/src/spicelib/parser/inppas2.c @@ -16,6 +16,9 @@ Author: 1985 Thomas L. Quarles /* gtri - end - wbk - 11/9/90 */ #endif +// Ugly way to pass line info (number and source file) to lower-level error handlers. +int Current_parse_line; +char* Sourcefile; /* uncomment to trace in this file */ /*#define TRACE*/ @@ -41,10 +44,6 @@ void INPpas2(CKTcircuit *ckt, struct card *data, INPtables * tab, TSKtask *task) printf("Entered INPpas2 . . . .\n"); #endif -#ifdef XSPICE - if (!ckt->CKTadevFlag) ckt->CKTadevFlag = 0; -#endif - error = INPgetTok(&groundname, &gname, 1); if (error) data->error = @@ -81,12 +80,16 @@ void INPpas2(CKTcircuit *ckt, struct card *data, INPtables * tab, TSKtask *task) #endif #ifdef HAS_PROGREP - if (linecount > 0) { + if (linecount > 0) { SetAnalyse( "Parse", (int) (1000.*actcount/linecount)); actcount++; } #endif + Current_parse_line = + current->linenum_orig ? current->linenum_orig : current->linenum; + Sourcefile = current->linesource; + c = *(current->line); if(islower_c(c)) c = toupper_c(c); diff --git a/src/spicelib/parser/inpptree-parser.y b/src/spicelib/parser/inpptree-parser.y index 1dde6a591..38e919a5b 100644 --- a/src/spicelib/parser/inpptree-parser.y +++ b/src/spicelib/parser/inpptree-parser.y @@ -5,6 +5,7 @@ #include "ngspice/ngspice.h" #include "ngspice/inpptree.h" + #include "ngspice/inpdefs.h" #include #include @@ -143,5 +144,11 @@ PTerror (YYLTYPE *locp, char **line, struct INPparseNode **retval, void *ckt, ch NG_IGNORE(retval); NG_IGNORE(ckt); - fprintf (stderr, "\n%s: %s, parsing stopped at\n %s\n\n", __func__, s, locp->start); + fprintf (stderr, + "\nYYparse error, %s, in expression: parsing stopped at line %d" + "\n %s in %s\n" + "\nfrom file" + " %s\n\n", + s, Current_parse_line, locp->start, *line, Sourcefile); + controlled_exit(EXIT_BAD); // Unsafe to continue. } diff --git a/src/spicelib/parser/inpptree.c b/src/spicelib/parser/inpptree.c index de97c2468..bc1850154 100644 --- a/src/spicelib/parser/inpptree.c +++ b/src/spicelib/parser/inpptree.c @@ -1029,7 +1029,8 @@ static INPparseNode *prepare_PTF_PWL(INPparseNode *p) int i; if (p->funcnum != PTF_PWL) { - fprintf(stderr, "PWL-INFO: %s, very unexpected\n", __func__); + fprintf(stderr, "PWL-INFO: %s, very unexpected at line %d\nfrom file\n %s\n\n", + __func__, Current_parse_line, Sourcefile); controlled_exit(EXIT_BAD); } @@ -1041,7 +1042,10 @@ static INPparseNode *prepare_PTF_PWL(INPparseNode *p) i++; if (i<2 || (i%1)) { - fprintf(stderr, "Error: PWL(expr, points...) needs an even and >=2 number of constant args\n"); + fprintf(stderr, + "Error: PWL(expr, points...) needs an even and >=2 number " + "of constant args at line %d\nfrom file\n %s\n\n", + Current_parse_line, Sourcefile); controlled_exit(EXIT_BAD); } @@ -1060,10 +1064,13 @@ static INPparseNode *prepare_PTF_PWL(INPparseNode *p) w->right->left->type == PT_CONSTANT) { data->vals[i] = - w->right->left->constant; } else { - fprintf(stderr, "PWL-ERROR: %s, not a constant\n", __func__); - fprintf(stderr, " type = %d\n", w->right->type); - fprintf(stderr, "Error: PWL(expr, points...) only *literal* points are supported\n"); - controlled_exit(EXIT_BAD); + fprintf(stderr, + "Error: PWL(expr, points...) only *literal* points " + "are supported at line %d\nfrom file\n %s\n", + Current_parse_line, Sourcefile); + // In case #671, "Crash when loading an Infineon model: IR4427S", + // a crash occurred after this error. There can be no recovery. + controlled_exit(EXIT_BAD); } #ifdef TRACE @@ -1073,7 +1080,9 @@ static INPparseNode *prepare_PTF_PWL(INPparseNode *p) for (i = 2 ; i < data->n ; i += 2) if(data->vals[i-2] >= data->vals[i]) { - fprintf(stderr, "Error: PWL(expr, points...) the abscissa of points must be ascending\n"); + fprintf(stderr, + "Error: PWL(expr, points...) the abscissa of points " + "must be ascending at line %d\nfrom file\n %s\n", Current_parse_line, Sourcefile); controlled_exit(EXIT_BAD); } @@ -1110,13 +1119,15 @@ INPparseNode *PT_mkfnode(const char *fname, INPparseNode * arg) char buf[128]; if (!fname) { - fprintf(stderr, "Error: bogus function name \n"); - return mkfirst(NULL, arg); + fprintf(stderr, "Error: bogus function name at line %d\nfrom file\n %s\n", + Current_parse_line, Sourcefile); + controlled_exit(EXIT_BAD); } if (!arg) { - fprintf(stderr, "Error: bad function arguments \n"); - return mkfirst(NULL, arg); + fprintf(stderr, "Error: bad function arguments at line %d\nfrom file\n %s\n", + Current_parse_line, Sourcefile); + controlled_exit(EXIT_BAD); } /* Make sure the case is ok. */ @@ -1143,8 +1154,9 @@ INPparseNode *PT_mkfnode(const char *fname, INPparseNode * arg) return mkfirst(p, arg); } - fprintf(stderr, "Error: bogus ternary_fcn form\n"); - return mkfirst(NULL, arg); + fprintf(stderr, "Error: bogus ternary_fcn form at line %d\nfrom file\n %s\n", + Current_parse_line, Sourcefile); + controlled_exit(EXIT_BAD); } /* This is used only to evaluate fcn gauss(a1, a2, a3) in .model files, where @@ -1160,8 +1172,9 @@ INPparseNode *PT_mkfnode(const char *fname, INPparseNode * arg) double a3 = arg3->constant; if (a2 == 0.0 || a3 == 0.0) { - fprintf(stderr, "Error: bogus gauss form\n"); - return mkfirst(NULL, arg); //return mkcon(a1); + fprintf(stderr, "Error: bogus gauss form at line %d\nfrom file\n %s\n", + Current_parse_line, Sourcefile); + controlled_exit(EXIT_BAD); } return mkcon(gauss(a1, a2, a3)); @@ -1176,10 +1189,9 @@ INPparseNode *PT_mkfnode(const char *fname, INPparseNode * arg) break; if (i == NUM_FUNCS) { - fprintf(stderr, "Error: no such function '%s'\n", buf); - if (ft_stricterror) - controlled_exit(EXIT_BAD); - return mkfirst(NULL, arg); + fprintf(stderr, "Error: no such function '%s' at line %d\nfrom file\n %s\n", + buf, Current_parse_line, Sourcefile); + controlled_exit(EXIT_BAD); } p = TMALLOC(INPparseNode, 1); @@ -1196,10 +1208,9 @@ INPparseNode *PT_mkfnode(const char *fname, INPparseNode * arg) 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); + fprintf(stderr, "Error while parsing function '%s' at line %d\nfrom file\n %s\n", + buf, Current_parse_line, Sourcefile); + controlled_exit(EXIT_BAD); } }