new compatibility handling with struct compat newcompat:

simplify the compatibility handling, better readability
make it easily extendable
add new flag 'ki' for KiCad compatibility
This commit is contained in:
Holger Vogt 2020-07-25 22:11:27 +02:00
parent 9defcae963
commit c112279555
5 changed files with 60 additions and 76 deletions

View File

@ -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 <file name> (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:");

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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)