inpcom.c, introduce inp_add_levels(), add scope to decks

This commit is contained in:
rlar 2017-04-23 18:37:06 +02:00 committed by Holger Vogt
parent d901665517
commit 96bb0dd941
2 changed files with 138 additions and 0 deletions

View File

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

View File

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