From c112279555a97c8a5b7ff5d8f66d0f4789c000fc Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Sat, 25 Jul 2020 22:11:27 +0200 Subject: [PATCH] new compatibility handling with struct compat newcompat: simplify the compatibility handling, better readability make it easily extendable add new flag 'ki' for KiCad compatibility --- src/frontend/inpcom.c | 103 ++++++++++++++----------------- src/frontend/numparam/spicenum.c | 3 +- src/frontend/numparam/xpressn.c | 2 +- src/include/ngspice/compatmode.h | 24 ++++--- src/spicelib/parser/ptfuncs.c | 4 +- 5 files changed, 60 insertions(+), 76 deletions(-) diff --git a/src/frontend/inpcom.c b/src/frontend/inpcom.c index b8c855509..9b1dcff4a 100644 --- a/src/frontend/inpcom.c +++ b/src/frontend/inpcom.c @@ -101,8 +101,6 @@ struct func_temper extern void line_free_x(struct card *deck, bool recurse); -COMPATMODE_T inp_compat_mode; - /* Collect information for dynamic allocation of numparam arrays */ /* number of lines in input deck */ int dynmaxline; /* inpcom.c 1529 */ @@ -523,37 +521,46 @@ char *find_back_assignment(const char *p, const char *start) /* Set a compatibility flag. Currently available are flags for: -- ngspice (standard) -- a commercial simulator -- Spice3 -- all compatibility stuff +- LTSPICE, HSPICE, Spice3, PSPICE, KiCad */ -static COMPATMODE_T ngspice_compat_mode(void) +struct compat newcompat; +static void new_compat_mode(void) { char behaviour[80]; - if (cp_getvar("ngbehavior", CP_STRING, behaviour, sizeof(behaviour))) { - if (strcasecmp(behaviour, "all") == 0) - return COMPATMODE_ALL; - if (strcasecmp(behaviour, "hs") == 0) - return COMPATMODE_HS; - if (strcasecmp(behaviour, "ps") == 0) - return COMPATMODE_PS; - if (strcasecmp(behaviour, "lt") == 0) - return COMPATMODE_LT; - if (strcasecmp(behaviour, "ltps") == 0) - return COMPATMODE_LTPS; - if (strcasecmp(behaviour, "psa") == 0) - return COMPATMODE_PSA; - if (strcasecmp(behaviour, "lta") == 0) - return COMPATMODE_LTA; - if (strcasecmp(behaviour, "ltpsa") == 0) - return COMPATMODE_LTPSA; - if (strcasecmp(behaviour, "spice3") == 0) - return COMPATMODE_SPICE3; + if (strstr(behaviour, "hs")) + newcompat.hs = TRUE; + else + newcompat.hs = FALSE; + } + if (cp_getvar("ngbehavior", CP_STRING, behaviour, sizeof(behaviour))) { + if (strstr(behaviour, "ps")) + newcompat.ps = TRUE; + else + newcompat.ps = FALSE; + } + if (cp_getvar("ngbehavior", CP_STRING, behaviour, sizeof(behaviour))) { + if (strstr(behaviour, "lt")) + newcompat.lt = TRUE; + else + newcompat.lt = FALSE; + } + if (cp_getvar("ngbehavior", CP_STRING, behaviour, sizeof(behaviour))) { + if (strstr(behaviour, "ki")) + newcompat.ki = TRUE; + else + newcompat.ki = FALSE; + } + if (cp_getvar("ngbehavior", CP_STRING, behaviour, sizeof(behaviour))) { + if (strstr(behaviour, "a")) + newcompat.a = TRUE; + else + newcompat.a = FALSE; + } + if (newcompat.hs && newcompat.ps) { + fprintf(stderr, "Warning: hs and ps compatibility are mutually exclusive, switch to ps!\n"); + newcompat.hs = FALSE; } - - return COMPATMODE_ALL; } /*------------------------------------------------------------------------- @@ -600,7 +607,8 @@ struct card *inp_readall(FILE *fp, const char *dir_name, struct inp_read_t rv; num_libraries = 0; - inp_compat_mode = ngspice_compat_mode(); + /* set the members of the compatibility structure */ + new_compat_mode(); rv = inp_read(fp, 0, dir_name, comfile, intfile); cc = rv.cc; @@ -631,14 +639,10 @@ struct card *inp_readall(FILE *fp, const char *dir_name, /* some syntax checks, including title line */ inp_check_syntax(cc); - if (inp_compat_mode == COMPATMODE_LTA) + if (newcompat.lt && newcompat.a) ltspice_compat_a(working); - else if (inp_compat_mode == COMPATMODE_PSA) + if (newcompat.ps && newcompat.a) pspice_compat_a(working); - else if (inp_compat_mode == COMPATMODE_LTPSA) { - ltspice_compat_a(working); - pspice_compat_a(working); - } struct nscope *root = inp_add_levels(working); @@ -689,7 +693,7 @@ struct card *inp_readall(FILE *fp, const char *dir_name, inp_poly_err(working); #endif bool expr_w_temper = FALSE; - if (inp_compat_mode != COMPATMODE_SPICE3) { + if (!newcompat.s3) { /* Do all the compatibility stuff here */ working = cc->nextcard; inp_meas_current(working); @@ -914,10 +918,7 @@ struct inp_read_t inp_read( FILE *fp, int call_depth, const char *dir_name, /* new style .lib entries handling is in expand_section_references() */ if (ciprefix(".lib", buffer)) - if (inp_compat_mode == COMPATMODE_PS || - inp_compat_mode == COMPATMODE_PSA || - inp_compat_mode == COMPATMODE_LTPS || - inp_compat_mode == COMPATMODE_LTPSA) { + if (newcompat.lt || newcompat.ps) { /* compatibility mode, * this is neither a libray section definition nor a * reference interpret as old style .lib (no lib @@ -997,14 +998,10 @@ struct inp_read_t inp_read( FILE *fp, int call_depth, const char *dir_name, } if (newcard) { - if (inp_compat_mode == COMPATMODE_LT) + if (newcompat.lt && !newcompat.a) newcard = ltspice_compat(newcard); - else if (inp_compat_mode == COMPATMODE_PS) + if (newcompat.ps && !newcompat.a) newcard = pspice_compat(newcard); - else if (inp_compat_mode == COMPATMODE_LTPS) { - newcard = ltspice_compat(newcard); - newcard = pspice_compat(newcard); - } int line_number_inc = 1; end->nextcard = newcard; @@ -1209,9 +1206,7 @@ struct inp_read_t inp_read( FILE *fp, int call_depth, const char *dir_name, insert_new_line( cc, copy("* gnd is not set to 0 automatically "), 1, 0); - if (inp_compat_mode == COMPATMODE_ALL || - inp_compat_mode == COMPATMODE_HS || - inp_compat_mode == COMPATMODE_NATIVE) { + if (!newcompat.lt && !newcompat.ps && !newcompat.s3) { /* process all library section references */ expand_section_references(cc, dir_name); } @@ -2506,9 +2501,7 @@ static void inp_stripcomments_line(char *s, bool cs) break; } /* outside of .control section, and not in PS mode */ - else if (!cs && (c == '$') && inp_compat_mode != COMPATMODE_PS && - inp_compat_mode != COMPATMODE_LTPS && - inp_compat_mode != COMPATMODE_LTPSA) { + else if (!cs && (c == '$') && !newcompat.ps) { /* The character before '&' has to be ',' or ' ' or tab. A valid numerical expression directly before '$' is not yet supported. */ @@ -2779,11 +2772,7 @@ static void inp_fix_for_numparam( inp_change_quotes(c->line); - if ((inp_compat_mode == COMPATMODE_ALL) || - (inp_compat_mode == COMPATMODE_PS) || - (inp_compat_mode == COMPATMODE_PSA) || - (inp_compat_mode == COMPATMODE_LTPS) || - (inp_compat_mode == COMPATMODE_LTPSA)) + if (!newcompat.hs && !newcompat.s3) if (ciprefix(".subckt", c->line) || ciprefix("x", c->line)) { /* remove params: */ char *str_ptr = strstr(c->line, "params:"); diff --git a/src/frontend/numparam/spicenum.c b/src/frontend/numparam/spicenum.c index 4ea618bef..7ea060f0c 100644 --- a/src/frontend/numparam/spicenum.c +++ b/src/frontend/numparam/spicenum.c @@ -182,8 +182,7 @@ findsubname(dico_t *dico, DSTRINGPTR dstr_p) char *t; entry_t *entry; /* check for known subckt name */ - if (inp_compat_mode == COMPATMODE_PS || inp_compat_mode == COMPATMODE_PSA - || inp_compat_mode == COMPATMODE_LTPS || inp_compat_mode == COMPATMODE_LTPSA) + if (newcompat.ps) for (t = p; alfanumps(*t); t++) ; else diff --git a/src/frontend/numparam/xpressn.c b/src/frontend/numparam/xpressn.c index df503fa0c..f3379b5a7 100644 --- a/src/frontend/numparam/xpressn.c +++ b/src/frontend/numparam/xpressn.c @@ -253,7 +253,7 @@ initdico(dico_t *dico) dico->inst_symbols = NULL; /* instance qualified are lazily allocated */ - if (inp_compat_mode == COMPATMODE_HS) + if (newcompat.hs) dico->hs_compatibility = 1; else dico->hs_compatibility = 0; diff --git a/src/include/ngspice/compatmode.h b/src/include/ngspice/compatmode.h index d9eff348f..5ba1fb5ff 100644 --- a/src/include/ngspice/compatmode.h +++ b/src/include/ngspice/compatmode.h @@ -3,19 +3,17 @@ #include "ngspice/config.h" -typedef enum { - COMPATMODE_NATIVE = 0, - COMPATMODE_HS = 1, - COMPATMODE_SPICE3 = 2, - COMPATMODE_ALL = 3, - COMPATMODE_PS = 4, - COMPATMODE_PSA = 5, - COMPATMODE_LT = 6, - COMPATMODE_LTA = 7, - COMPATMODE_LTPS = 8, - COMPATMODE_LTPSA = 9 -} COMPATMODE_T ; +struct compat +{ + bool hs; + bool s3; + bool all; + bool ps; + bool lt; + bool ki; + bool a; +}; -extern COMPATMODE_T inp_compat_mode; +extern struct compat newcompat; #endif diff --git a/src/spicelib/parser/ptfuncs.c b/src/spicelib/parser/ptfuncs.c index 9e0011057..4c376daa5 100644 --- a/src/spicelib/parser/ptfuncs.c +++ b/src/spicelib/parser/ptfuncs.c @@ -77,9 +77,7 @@ double PTpwr(double arg1, double arg2) { /* if PSPICE device is evaluated */ - if (arg1 == 0.0 && arg2 < 0.0 && - (inp_compat_mode == COMPATMODE_PS || inp_compat_mode == COMPATMODE_PSA - || inp_compat_mode == COMPATMODE_LTPS || inp_compat_mode == COMPATMODE_LTPSA)) + if (arg1 == 0.0 && arg2 < 0.0 && newcompat.ps) arg1 += PTfudge_factor; if (arg1 < 0.0)