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