inpcom.c, add function inp_rem_unused_models()

This commit is contained in:
h_vogt 2016-05-01 21:18:40 +02:00 committed by rlar
parent 89c29a646d
commit e77f9451a4
2 changed files with 186 additions and 0 deletions

View File

@ -148,7 +148,10 @@ static char *search_plain_identifier(char *str, const char *identifier);
void tprint(struct line *deck, int numb);
static struct nscope *inp_add_levels(struct line *deck);
static char inp_get_elem_ident(char *type);
static void inp_rem_unused_models(struct nscope *root, struct line *deck);
static struct line_assoc *find_subckt(struct nscope *scope, const char *name);
static struct modellist *find_model(struct nscope *scope, const char *name);
struct inp_read_t
{ struct line *cc;
@ -556,6 +559,7 @@ inp_readall(FILE *fp, char *dir_name, bool comfile, bool intfile, bool *expr_w_t
inp_remove_excess_ws(working);
comment_out_unused_subckt_models(working);
inp_rem_unused_models(root, working);
subckt_params_to_param(working);
@ -6535,6 +6539,38 @@ add_subckt(struct nscope *scope, struct line *subckt_line)
}
/* linked list of models, includes use info */
struct modellist
{
struct line *model;
char *modelname;
bool used;
char elemb;
struct modellist *next;
};
static struct modellist *
find_model_1(struct nscope *scope, const char *name) {
struct modellist *p = scope->models;
for (; p; p = p->next)
if (model_name_match(name, p->modelname))
break;
return p;
}
static struct modellist *
find_model(struct nscope *scope, const char *name) {
for(; scope; scope = scope->next) {
struct modellist *p = find_model_1(scope, name);
if (p)
return p;
}
return NULL;
}
/* scan through deck and add level information to all struct line
* depending on nested subcircuits */
static struct nscope *
@ -6546,6 +6582,7 @@ inp_add_levels(struct line *deck)
struct nscope *root = TMALLOC(struct nscope, 1);
root->next = NULL;
root->subckts = NULL;
root->models = NULL;
struct nscope *lvl = root;
@ -6574,6 +6611,7 @@ inp_add_levels(struct line *deck)
// lvl->name = ..., or just point to the deck
lvl->next = card->level;
lvl->subckts = NULL;
lvl->models = NULL;
}
else if (ciprefix(".ends", curr_line)) {
if (lvl == root) {
@ -6656,3 +6694,148 @@ inp_get_elem_ident(char *type)
else
return 'a';
}
static void
rem_unused_xxx(struct nscope *level)
{
struct modellist *m = level->models;
while (m) {
struct modellist *next_m = m->next;
if (!m->used)
m->model->li_line[0] = '*';
tfree(m->modelname);
tfree(m);
m = next_m;
}
level->models = NULL;
struct line_assoc *p = level->subckts;
for (; p; p = p->next)
rem_unused_xxx(p->line->li_next->level);
}
static void
mark_all_binned(struct nscope *scope, char *name)
{
struct modellist *p = scope->models;
for (; p; p = p->next)
if (model_name_match(name, p->modelname))
p->used = TRUE;
}
static void
inp_rem_unused_models(struct nscope *root, struct line *deck)
{
struct line *card;
int skip_control = 0;
/* create a list of .model */
for (card = deck; card; card = card->li_next) {
char *curr_line = card->li_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 == '*')
continue;
if (ciprefix(".model", curr_line)) {
struct modellist *modl_new;
modl_new = TMALLOC(struct modellist, 1);
char *model_type = get_model_type(curr_line);
modl_new->elemb = inp_get_elem_ident(model_type);
modl_new->modelname = get_subckt_model_name(curr_line);
modl_new->model = card;
modl_new->used = FALSE;
modl_new->next = card->level->models;
card->level->models = modl_new;
tfree(model_type);
}
}
/* scan through all element lines that require or may need a model */
for (card = deck; card; card = card->li_next) {
char *curr_line = card->li_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;
}
switch (*curr_line)
{
case '*':
case '.':
case 'v':
case 'i':
case 'b':
case 'x':
case 'e':
case 'h':
case 'g':
case 'f':
case 'k':
case 't':
continue;
break;
default:
break;
}
/* check if correct model name */
int num_terminals = get_number_terminals(curr_line);
/* num_terminals may be 0 for a elements */
if ((num_terminals != 0) || (*curr_line == 'a')) {
char *elem_model_name;
if (*curr_line == 'a')
elem_model_name = get_adevice_model_name(curr_line);
else
elem_model_name = get_model_name(curr_line, num_terminals);
/* ignore certain cases, for example
* C5 node1 node2 42.0
*/
if (is_a_modelname(elem_model_name)) {
struct modellist *m = find_model(card->level, elem_model_name);
if (m) {
if (*curr_line != m->elemb)
fprintf(stderr, "warning, model type mismatch\n");
mark_all_binned(m->model->level, elem_model_name);
} else {
fprintf(stderr, "warning, can't find model %s\n", elem_model_name);
}
}
tfree(elem_model_name);
}
}
// disable unused .model lines, and free the models assoc lists
rem_unused_xxx(root);
}

View File

@ -61,9 +61,12 @@ struct INPtables{
GENmodel *defZmod;
};
struct modellist;
struct nscope {
struct nscope *next;
struct line_assoc *subckts;
struct modellist *models;
};
struct line_assoc {