diff --git a/src/frontend/numparam/numparam.h b/src/frontend/numparam/numparam.h index d9258787d..f296eb3eb 100644 --- a/src/frontend/numparam/numparam.h +++ b/src/frontend/numparam/numparam.h @@ -6,6 +6,7 @@ #include "numpaif.h" #include "ngspice/hash.h" +#include "ngspice/inpdefs.h" /***** numparam internals ********/ @@ -35,6 +36,7 @@ typedef struct entry_s { double vl; /* float value if defined */ int ivl; /* int value or string buffer index */ char *sbbase; /* string buffer base address if any */ + struct nscope *levelinfo; } entry_t; @@ -66,5 +68,5 @@ bool nupa_subcktcall(dico_t *, const char *s, const char *x, char *inst_name); void nupa_subcktexit(dico_t *); entry_t *entrynb(dico_t *dico, char *s); -entry_t *attrib(dico_t *, NGHASHPTR htable, char *t, char op); +entry_t *attrib(dico_t *, NGHASHPTR htable, char *t, char op, struct nscope *level); void del_attrib(void *); diff --git a/src/frontend/numparam/spicenum.c b/src/frontend/numparam/spicenum.c index 9d9a69f11..c7881af4f 100644 --- a/src/frontend/numparam/spicenum.c +++ b/src/frontend/numparam/spicenum.c @@ -489,7 +489,7 @@ nupa_add_param(char *param_name, double value) htable_p = dico->symbols[dico->stack_depth]; - entry = attrib(dico, htable_p, param_name, 'N'); + entry = attrib(dico, htable_p, param_name, 'N', NULL); if (entry) { entry->vl = value; entry->tp = NUPA_REAL; @@ -508,7 +508,7 @@ nupa_add_inst_param(char *param_name, double value) if (!(dico->inst_symbols)) dico->inst_symbols = nghash_init(NGHASH_MIN_SIZE); - entry = attrib(dico, dico->inst_symbols, param_name, 'N'); + entry = attrib(dico, dico->inst_symbols, param_name, 'N', NULL); if (entry) { entry->vl = value; entry->tp = NUPA_REAL; diff --git a/src/frontend/numparam/xpressn.c b/src/frontend/numparam/xpressn.c index 6c5d6072d..1bdac3f3c 100644 --- a/src/frontend/numparam/xpressn.c +++ b/src/frontend/numparam/xpressn.c @@ -392,7 +392,7 @@ fetchnumentry(dico_t *dico, char *s, bool *perr) /******* writing dictionary entries *********/ entry_t * -attrib(dico_t *dico, NGHASHPTR htable_p, char *t, char op) +attrib(dico_t *dico, NGHASHPTR htable_p, char *t, char op, struct nscope *levelinfo) { /* seek or attribute dico entry number for string t. Option op='N' : force a new entry, if tos>level and old is valid. @@ -411,6 +411,7 @@ attrib(dico_t *dico, NGHASHPTR htable_p, char *t, char op) entry->symbol = copy(t); entry->tp = NUPA_UNKNOWN; /* signal Unknown */ entry->level = dico->stack_depth; + entry->levelinfo = levelinfo; nghash_insert(htable_p, t, entry); } @@ -441,7 +442,8 @@ nupa_define(dico_t *dico, nupa_type tpe, /* type marker */ double z, /* float value if any */ int w, /* integer value if any */ - char *base) /* string pointer if any */ + char *base, /* string pointer if any */ + struct nscope *level) /* level info */ { /*define t as real or integer, opcode= 'N' impose a new item under local conditions. @@ -462,7 +464,7 @@ nupa_define(dico_t *dico, htable_p = dico->symbols[dico->stack_depth]; - entry = attrib(dico, htable_p, t, op); + entry = attrib(dico, htable_p, t, op, level); if (!entry) return message(dico, " Symbol table overflow\n"); @@ -484,9 +486,33 @@ nupa_define(dico_t *dico, warn = message(dico, "%s:%d overwritten.\n", t, entry->level); } else { - /* error message for redefinition of subcircuits */ - if (0) - message(dico, "subckt %s is already used,\n cannot be redefined\n", t); + /* FIXME: better do this recursively in a new function */ + /* No new entry defined, but previous entry with same name returned + from function attrib(), compare levels, if not equal, o.k. (for now) */ +#if 0 + unsigned short newlevel[NESTINGDEPTH]; + unsigned short oldlevel[NESTINGDEPTH]; + int i; + for (i = 0; i < NESTINGDEPTH; i++) { + newlevel[i] = level[i]; + oldlevel[i] = entry->levelinfo[i]; + } + /* top level */ + if ((newlevel[0] > 0) && (oldlevel[0] > 0) + && (newlevel[1] == 0) && (oldlevel[1] == 0)) + fprintf(stderr, "Warning: %s is already used,\n cannot be redefined\n", t); + /* second level */ + else if ((newlevel[0] > 0) && (oldlevel[0] == newlevel[0]) + && (newlevel[1] > 0) && (oldlevel[1] > 1) + && (newlevel[2] == 0) && (oldlevel[2] == 0)) + fprintf(stderr, "Warning: %s is already used,\n cannot be redefined\n", t); + /* third level */ + else if ((newlevel[0] > 0) && (oldlevel[0] == newlevel[0]) + && (newlevel[1] > 0) && (oldlevel[1] == newlevel[1]) + && (newlevel[2] > 0) && (oldlevel[2] > 1) + && (newlevel[3] == 0) && (oldlevel[3] == 0)) + fprintf(stderr, "Warning: subckt %s is already used,\n cannot be redefined\n", t); +#endif } return 0; @@ -501,6 +527,7 @@ defsubckt(dico_t *dico, struct card *card) { const char *s = card->line; int w = card->linenum; + struct nscope *level = card->level; bool err; @@ -524,7 +551,7 @@ defsubckt(dico_t *dico, struct card *card) SPICE_DSTRING ustr; /* temp user string */ spice_dstring_init(&ustr); pscopy(&ustr, s, s_end); - err = nupa_define(dico, spice_dstring_value(&ustr), ' ', NUPA_SUBCKT, 0.0, w, NULL); + err = nupa_define(dico, spice_dstring_value(&ustr), ' ', NUPA_SUBCKT, 0.0, w, NULL, level); spice_dstring_free(&ustr); } else { err = message(dico, "Subcircuit or Model without name.\n"); @@ -1356,7 +1383,7 @@ nupa_assignment(dico_t *dico, const char *s, char mode) } error = nupa_define(dico, spice_dstring_value(&tstr), mode /* was ' ' */ , - dtype, rval, wval, NULL); + dtype, rval, wval, NULL, NULL); if (error) break; diff --git a/src/include/ngspice/inpdefs.h b/src/include/ngspice/inpdefs.h index 4053a3525..4a34f7a97 100644 --- a/src/include/ngspice/inpdefs.h +++ b/src/include/ngspice/inpdefs.h @@ -16,6 +16,7 @@ Modified: 2000 AlansFixes typedef struct INPtables INPtables; typedef struct INPmodel INPmodel; +#define NESTINGDEPTH 10 struct INPtab { char *t_ent;