From 96bb0dd9417619595fac26eb641dd928c3357ef6 Mon Sep 17 00:00:00 2001 From: rlar Date: Sun, 23 Apr 2017 18:37:06 +0200 Subject: [PATCH] inpcom.c, introduce inp_add_levels(), add scope to decks --- src/frontend/inpcom.c | 126 ++++++++++++++++++++++++++++++++++ src/include/ngspice/inpdefs.h | 12 ++++ 2 files changed, 138 insertions(+) diff --git a/src/frontend/inpcom.c b/src/frontend/inpcom.c index a1a5a537b..87b039a23 100644 --- a/src/frontend/inpcom.c +++ b/src/frontend/inpcom.c @@ -156,6 +156,11 @@ static char *inp_spawn_brace(char *s); static char *inp_pathresolve(const char *name); static char *inp_pathresolve_at(char *name, char *dir); static char *search_plain_identifier(char *str, const char *identifier); + +static struct nscope *inp_add_levels(struct card *deck); +static struct card_assoc *find_subckt(struct nscope *scope, const char *name); +static void inp_rem_levels(struct nscope *root); + void tprint(struct card *deck); static struct card *pspice_compat(struct card *newcard); static void pspice_compat_a(struct card *oldcard); @@ -188,6 +193,7 @@ static struct card *insert_new_line( x->line = line; x->linenum = linenum; x->linenum_orig = linenum_orig; + x->level = card ? card->level : NULL; if (card) card->nextcard = x; @@ -431,6 +437,7 @@ static void inp_stitch_continuation_lines(struct card *working) else { prev->actualLine = insert_new_line(NULL, s, prev->linenum, 0); + prev->actualLine->level = prev->level; prev->actualLine->nextcard = working; } working = prev->nextcard; @@ -557,6 +564,7 @@ static COMPATMODE_T ngspice_compat_mode(void) start preparation of input deck for numparam ... debug printout to debug-out.txt + remove the 'level' entries from each card *-------------------------------------------------------------------------*/ struct card *inp_readall(FILE *fp, char *dir_name, bool comfile, bool intfile, @@ -602,6 +610,8 @@ struct card *inp_readall(FILE *fp, char *dir_name, bool comfile, bool intfile, pspice_compat_a(working); } + struct nscope *root = inp_add_levels(working); + inp_fix_for_numparam(subckt_w_params, working); inp_remove_excess_ws(working); @@ -723,6 +733,7 @@ struct card *inp_readall(FILE *fp, char *dir_name, bool comfile, bool intfile, "Warning: Cannot open file debug-out.txt for saving " "debug info\n"); } + inp_rem_levels(root); } return cc; @@ -8162,3 +8173,118 @@ static char inp_get_elem_ident(char *type) else return 'a'; } + + +static struct card_assoc *find_subckt_1( + struct nscope *scope, const char *name) +{ + struct card_assoc *p = scope->subckts; + for (; p; p = p->next) + if (eq(name, p->name)) + break; + return p; +} + + +static struct card_assoc *find_subckt(struct nscope *scope, const char *name) +{ + for (; scope; scope = scope->next) { + struct card_assoc *p = find_subckt_1(scope, name); + if (p) + return p; + } + return NULL; +} + + +static void add_subckt(struct nscope *scope, struct card *subckt_line) +{ + char *n = skip_ws(skip_non_ws(subckt_line->line)); + char *name = copy_substring(n, skip_non_ws(n)); + if (find_subckt_1(scope, name)) { + fprintf(stderr, "redefinition of .subckt %s\n", name); + controlled_exit(1); + } + struct card_assoc *entry = TMALLOC(struct card_assoc, 1); + entry->name = name; + entry->line = subckt_line; + entry->next = scope->subckts; + scope->subckts = entry; +} + + +/* scan through deck and add level information to all struct card + * depending on nested subcircuits */ +static struct nscope *inp_add_levels(struct card *deck) +{ + struct card *card; + int skip_control = 0; + + struct nscope *root = TMALLOC(struct nscope, 1); + root->next = NULL; + root->subckts = NULL; + + struct nscope *lvl = root; + + for (card = deck; card; card = card->nextcard) { + + char *curr_line = card->line; + + /* exclude any command inside .control ... .endc */ + if (ciprefix(".control", curr_line)) { + skip_control++; + continue; + } + else if (ciprefix(".endc", curr_line)) { + skip_control--; + continue; + } + else if (skip_control > 0) { + continue; + } + + if (*curr_line == '.') { + if (ciprefix(".subckt", curr_line)) { + add_subckt(lvl, card); + struct nscope *scope = TMALLOC(struct nscope, 1); + // lvl->name = ..., or just point to the deck + scope->next = lvl; + scope->subckts = NULL; + lvl = card->level = scope; + } + else if (ciprefix(".ends", curr_line)) { + if (lvl == root) { + fprintf(stderr, ".subckt/.ends not balanced\n"); + controlled_exit(1); + } + card->level = lvl; + lvl = lvl->next; + } + else { + card->level = lvl; + } + } + else { + card->level = lvl; + } + } + + if (lvl != root) + fprintf(stderr, "nesting error\n"); + + return root; +} + +/* remove the level and subckts entries */ +static void inp_rem_levels(struct nscope *root) +{ + struct card_assoc *p = root->subckts; + while (p) { + inp_rem_levels(p->line->level); + tfree(p->name); + struct card_assoc *pn = p->next; + tfree(p); + p = pn; + } + tfree(root); +} diff --git a/src/include/ngspice/inpdefs.h b/src/include/ngspice/inpdefs.h index e46c82d3b..b57746a41 100644 --- a/src/include/ngspice/inpdefs.h +++ b/src/include/ngspice/inpdefs.h @@ -60,6 +60,17 @@ struct INPtables{ GENmodel *defZmod; }; +struct nscope { + struct nscope *next; + struct card_assoc *subckts; +}; + +struct card_assoc { + const char *name; + struct card *line; + struct card_assoc *next; +}; + struct card { int linenum; int linenum_orig; @@ -67,6 +78,7 @@ struct card { char *error; struct card *nextcard; struct card *actualLine; + struct nscope *level; }; /* structure used to save models in after they are read during pass 1 */