subckt.c, xpressn.c, spicenum.c, add level information for .subckt entries nupa_scan is totally without level info. This preliminary fix at least lets us decide to issue a warning if subckt have equal names and are on the same level. Still nupa_scan only enters the first entry into its hash table, irrespective of its level.
This commit is contained in:
parent
4d4183384f
commit
6663da9bda
|
|
@ -14,7 +14,7 @@
|
|||
extern char *nupa_copy(char *s, int linenum);
|
||||
extern int nupa_eval(char *s, int linenum, int orig_linenum);
|
||||
extern int nupa_signal(int sig, char *info);
|
||||
extern void nupa_scan(char * s, int linenum, int is_subckt);
|
||||
extern void nupa_scan(char * s, int linenum, int is_subckt, unsigned short level[]);
|
||||
extern void nupa_list_params(FILE *cp_out);
|
||||
extern double nupa_get_param(char *param_name, int *found);
|
||||
extern void nupa_add_param(char *param_name, double value);
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#include "numpaif.h"
|
||||
#include "ngspice/hash.h"
|
||||
#include "ngspice/inpdefs.h"
|
||||
|
||||
/***** numparam internals ********/
|
||||
|
||||
|
|
@ -27,6 +28,7 @@ typedef struct entry_s {
|
|||
int ivl; /* int value or string buffer index */
|
||||
char *sbbase; /* string buffer base address if any */
|
||||
struct entry_s *pointer; /* pointer chain */
|
||||
unsigned short levelinfo[NESTINGDEPTH];
|
||||
} entry_t;
|
||||
|
||||
|
||||
|
|
@ -53,7 +55,7 @@ typedef struct { /* the input scanner data structure */
|
|||
void initdico(dico_t *);
|
||||
int donedico(dico_t *);
|
||||
void dico_free_entry(entry_t *);
|
||||
bool defsubckt(dico_t *, char *s, int w, char categ);
|
||||
bool defsubckt(dico_t *, char *s, int w, char categ, unsigned short level[]);
|
||||
int findsubckt(dico_t *, char *s, SPICE_DSTRINGPTR subname);
|
||||
bool nupa_substitute(dico_t *, char *s, char *r, bool err);
|
||||
bool nupa_assignment(dico_t *, char *s, char mode);
|
||||
|
|
@ -61,5 +63,5 @@ bool nupa_subcktcall(dico_t *, char *s, char *x, bool err);
|
|||
void nupa_subcktexit(dico_t *);
|
||||
dico_t *nupa_fetchinstance(void);
|
||||
char getidtype(dico_t *, char *s);
|
||||
entry_t *attrib(dico_t *, NGHASHPTR htable, char *t, char op);
|
||||
entry_t *attrib(dico_t *, NGHASHPTR htable, char *t, char op, unsigned short level[]);
|
||||
void del_attrib(void *);
|
||||
|
|
|
|||
|
|
@ -533,12 +533,12 @@ nupa_done(void)
|
|||
|
||||
/* SJB - Scan the line for subcircuits */
|
||||
void
|
||||
nupa_scan(char *s, int linenum, int is_subckt)
|
||||
nupa_scan(char *s, int linenum, int is_subckt, unsigned short level[])
|
||||
{
|
||||
if (is_subckt)
|
||||
defsubckt(dicoS, s, linenum, 'U');
|
||||
defsubckt(dicoS, s, linenum, 'U', level);
|
||||
else
|
||||
defsubckt(dicoS, s, linenum, 'O');
|
||||
defsubckt(dicoS, s, linenum, 'O', level);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -661,7 +661,7 @@ nupa_add_param(char *param_name, double value)
|
|||
|
||||
htable_p = dico->symbols[dico->stack_depth];
|
||||
|
||||
entry = attrib(dico, htable_p, up_name, 'N');
|
||||
entry = attrib(dico, htable_p, up_name, 'N', NULL);
|
||||
if (entry) {
|
||||
entry->vl = value;
|
||||
entry->tp = 'R';
|
||||
|
|
@ -688,7 +688,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, up_name, 'N');
|
||||
entry = attrib(dico, dico->inst_symbols, up_name, 'N', NULL);
|
||||
if (entry) {
|
||||
entry->vl = value;
|
||||
entry->tp = 'R';
|
||||
|
|
|
|||
|
|
@ -421,7 +421,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, unsigned short levelinfo[])
|
||||
{
|
||||
/* seek or attribute dico entry number for string t.
|
||||
Option op='N' : force a new entry, if tos>level and old is valid.
|
||||
|
|
@ -436,10 +436,14 @@ attrib(dico_t *dico, NGHASHPTR htable_p, char *t, char op)
|
|||
}
|
||||
|
||||
if (!entry) {
|
||||
int i;
|
||||
entry = TMALLOC(entry_t, 1);
|
||||
entry->symbol = strdup(t);
|
||||
entry->tp = '?'; /* signal Unknown */
|
||||
entry->level = dico->stack_depth;
|
||||
if (levelinfo)
|
||||
for (i = 0; i < NESTINGDEPTH; i++)
|
||||
entry->levelinfo[i] = levelinfo[i];
|
||||
nghash_insert(htable_p, t, entry);
|
||||
}
|
||||
|
||||
|
|
@ -470,7 +474,8 @@ nupa_define(dico_t *dico,
|
|||
char 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 */
|
||||
unsigned short level[]) /* level info */
|
||||
{
|
||||
/*define t as real or integer,
|
||||
opcode= 'N' impose a new item under local conditions.
|
||||
|
|
@ -491,7 +496,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);
|
||||
err = 0;
|
||||
|
||||
if (!entry) {
|
||||
|
|
@ -523,8 +528,31 @@ nupa_define(dico_t *dico,
|
|||
warn = message(dico, "%s:%d overwritten.\n", t, entry->level);
|
||||
|
||||
} else {
|
||||
/* error message for redefinition of symbols */
|
||||
fprintf(stderr, "Warning: %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) */
|
||||
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: %s is already used,\n cannot be redefined\n", t);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -533,7 +561,7 @@ nupa_define(dico_t *dico,
|
|||
|
||||
|
||||
bool
|
||||
defsubckt(dico_t *dico, char *s, int w, char categ)
|
||||
defsubckt(dico_t *dico, char *s, int w, char categ, unsigned short level[])
|
||||
/* called on 1st pass of spice source code,
|
||||
to enter subcircuit (categ=U) and model (categ=O) names
|
||||
*/
|
||||
|
|
@ -562,7 +590,7 @@ defsubckt(dico_t *dico, char *s, int w, char categ)
|
|||
SPICE_DSTRING ustr; /* temp user string */
|
||||
spice_dstring_init(&ustr);
|
||||
pscopy_up(&ustr, s, i, j - i);
|
||||
err = nupa_define(dico, spice_dstring_value(&ustr), ' ', categ, 0.0, w, NULL);
|
||||
err = nupa_define(dico, spice_dstring_value(&ustr), ' ', categ, 0.0, w, NULL, level);
|
||||
spice_dstring_free(&ustr);
|
||||
} else {
|
||||
err = message(dico, "Subcircuit or Model without name.\n");
|
||||
|
|
@ -1533,7 +1561,7 @@ nupa_assignment(dico_t *dico, char *s, char mode)
|
|||
}
|
||||
|
||||
err = nupa_define(dico, spice_dstring_value(&tstr), mode /* was ' ' */ ,
|
||||
dtype, rval, wval, NULL);
|
||||
dtype, rval, wval, NULL, NULL);
|
||||
error = error || err;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -238,7 +238,7 @@ inp_subcktexpand(struct line *deck) {
|
|||
/* get the subckt names from the deck */
|
||||
for (c = deck; c; c = c->li_next) /* first Numparam pass */
|
||||
if (ciprefix(".subckt", c->li_line))
|
||||
nupa_scan(c->li_line, c->li_linenum, TRUE);
|
||||
nupa_scan(c->li_line, c->li_linenum, TRUE, c->level);
|
||||
/* now copy instances */
|
||||
for (c = deck; c; c = c->li_next) /* first Numparam pass */
|
||||
c->li_line = nupa_copy(c->li_line, c->li_linenum);
|
||||
|
|
|
|||
Loading…
Reference in New Issue