inpcom.c, use a `rib cage' to store the .subckt lexical scoping of `.func'
This commit is contained in:
parent
777dbede9b
commit
9093ec8fac
|
|
@ -52,14 +52,19 @@ static int num_libraries;
|
|||
static char *subckt_w_params[N_SUBCKT_W_PARAMS];
|
||||
static int num_subckt_w_params;
|
||||
|
||||
static struct function {
|
||||
char *name;
|
||||
char *macro;
|
||||
char *params[N_PARAMS];
|
||||
int num_parameters;
|
||||
} functions[N_FUNCTIONS];
|
||||
struct function_env
|
||||
{
|
||||
struct function_env *up;
|
||||
|
||||
static int num_functions;
|
||||
int num_functions;
|
||||
|
||||
struct function {
|
||||
char *name;
|
||||
char *macro;
|
||||
char *params[N_PARAMS];
|
||||
int num_parameters;
|
||||
} *functions;
|
||||
};
|
||||
|
||||
|
||||
static char *global;
|
||||
|
|
@ -82,10 +87,10 @@ static void inp_stripcomments_line(char *s);
|
|||
static void inp_fix_for_numparam(struct line *deck);
|
||||
static void inp_remove_excess_ws(struct line *deck);
|
||||
static void expand_section_references(struct line *deck, int call_depth, char *dir_name);
|
||||
static void inp_grab_func(struct line *deck);
|
||||
static void inp_grab_func(struct function_env *, struct line *deck);
|
||||
static void inp_fix_inst_calls_for_numparam(struct line *deck);
|
||||
static void inp_expand_macros_in_func(int from);
|
||||
static struct line *inp_expand_macros_in_deck(struct line *deck);
|
||||
static void inp_expand_macros_in_func(struct function_env *);
|
||||
static struct line *inp_expand_macros_in_deck(struct function_env *, struct line *deck);
|
||||
static void inp_fix_param_values(struct line *deck);
|
||||
static void inp_reorder_params(struct line *deck, struct line *list_head, struct line *end);
|
||||
static int inp_split_multi_param_lines(struct line *deck, int line_number);
|
||||
|
|
@ -307,7 +312,6 @@ inp_readall(FILE *fp, int call_depth, char *dir_name, bool comfile, bool intfile
|
|||
if (call_depth == 0) {
|
||||
num_subckt_w_params = 0;
|
||||
num_libraries = 0;
|
||||
num_functions = 0;
|
||||
global = NULL;
|
||||
found_end = FALSE;
|
||||
inp_compat_mode = ngspice_compat_mode();
|
||||
|
|
@ -728,12 +732,8 @@ inp_readall(FILE *fp, int call_depth, char *dir_name, bool comfile, bool intfile
|
|||
|
||||
inp_fix_macro_param_func_paren_io(working);
|
||||
inp_fix_ternary_operator(working);
|
||||
// tprint(working);
|
||||
if (num_functions != 0) {
|
||||
fprintf(stderr, "ERROR, internal error, unexpected num_functions = %d\n", num_functions);
|
||||
controlled_exit(EXIT_FAILURE);
|
||||
}
|
||||
inp_expand_macros_in_deck(working);
|
||||
//tprint(working);
|
||||
inp_expand_macros_in_deck(NULL, working);
|
||||
inp_fix_param_values(working);
|
||||
|
||||
/* get end card as last card in list; end card pntr does not appear to always
|
||||
|
|
@ -2763,25 +2763,26 @@ inp_fix_inst_calls_for_numparam(struct line *deck)
|
|||
|
||||
|
||||
static struct function *
|
||||
new_function(void)
|
||||
new_function(struct function_env *env)
|
||||
{
|
||||
if (num_functions >= N_FUNCTIONS) {
|
||||
if (env->num_functions >= N_FUNCTIONS) {
|
||||
fprintf(stderr, "ERROR, N_FUNCTIONS overflow\n");
|
||||
controlled_exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
return & functions[num_functions++];
|
||||
return & env->functions[env->num_functions++];
|
||||
}
|
||||
|
||||
|
||||
static struct function *
|
||||
find_function(char *name)
|
||||
find_function(struct function_env *env, char *name)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = num_functions; --i >= 0; i++)
|
||||
if (strcmp(functions[i].name, name) == 0)
|
||||
return & functions[i];
|
||||
for (; env; env = env->up)
|
||||
for (i = env->num_functions; --i >= 0; i++)
|
||||
if (strcmp(env->functions[i].name, name) == 0)
|
||||
return & env->functions[i];
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -2801,7 +2802,7 @@ free_function(struct function *fcn)
|
|||
|
||||
|
||||
static void
|
||||
inp_get_func_from_line(char *line)
|
||||
inp_get_func_from_line(struct function_env *env, char *line)
|
||||
{
|
||||
char *ptr, *end;
|
||||
char keep;
|
||||
|
|
@ -2821,9 +2822,9 @@ inp_get_func_from_line(char *line)
|
|||
|
||||
/* see if already encountered this function */
|
||||
/* FIXME, this code is unused, which is probably a bug */
|
||||
function = find_function(line);
|
||||
function = find_function(env, line);
|
||||
|
||||
function = new_function();
|
||||
function = new_function(env);
|
||||
|
||||
function->name = strdup(line);
|
||||
*end = keep;
|
||||
|
|
@ -2868,7 +2869,7 @@ inp_get_func_from_line(char *line)
|
|||
// only grab global functions; skip subckt functions
|
||||
//
|
||||
static void
|
||||
inp_grab_func(struct line *c)
|
||||
inp_grab_func(struct function_env *env, struct line *c)
|
||||
{
|
||||
int nesting = 0;
|
||||
|
||||
|
|
@ -2889,7 +2890,7 @@ inp_grab_func(struct line *c)
|
|||
continue;
|
||||
|
||||
if (ciprefix(".func", c->li_line)) {
|
||||
inp_get_func_from_line(c->li_line);
|
||||
inp_get_func_from_line(env, c->li_line);
|
||||
*c->li_line = '*';
|
||||
}
|
||||
}
|
||||
|
|
@ -2964,7 +2965,7 @@ inp_do_macro_param_replace(struct function *fcn, char *params[])
|
|||
|
||||
|
||||
static char*
|
||||
inp_expand_macro_in_str(char *str)
|
||||
inp_expand_macro_in_str(struct function_env *env, char *str)
|
||||
{
|
||||
struct function *function;
|
||||
char *c;
|
||||
|
|
@ -2989,7 +2990,7 @@ inp_expand_macro_in_str(char *str)
|
|||
|
||||
*open_paren_ptr = '\0';
|
||||
|
||||
function = find_function(fcn_name);
|
||||
function = find_function(env, fcn_name);
|
||||
|
||||
*open_paren_ptr = '(';
|
||||
|
||||
|
|
@ -3043,7 +3044,7 @@ inp_expand_macro_in_str(char *str)
|
|||
break;
|
||||
}
|
||||
params[num_params++] =
|
||||
inp_expand_macro_in_str(copy_substring(beg_parameter, curr_ptr));
|
||||
inp_expand_macro_in_str(env, copy_substring(beg_parameter, curr_ptr));
|
||||
}
|
||||
|
||||
if (function->num_parameters != num_params) {
|
||||
|
|
@ -3085,23 +3086,53 @@ inp_expand_macro_in_str(char *str)
|
|||
|
||||
|
||||
static void
|
||||
inp_expand_macros_in_func(int from)
|
||||
inp_expand_macros_in_func(struct function_env *env)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = from; i < num_functions; i++)
|
||||
functions[i].macro = inp_expand_macro_in_str(functions[i].macro);
|
||||
for (i = 0; i < env->num_functions; i++)
|
||||
env->functions[i].macro = inp_expand_macro_in_str(env, env->functions[i].macro);
|
||||
}
|
||||
|
||||
|
||||
static struct function_env *
|
||||
new_function_env(struct function_env *up)
|
||||
{
|
||||
struct function_env *env = TMALLOC(struct function_env, 1);
|
||||
|
||||
env -> up = up;
|
||||
env -> num_functions = 0;
|
||||
env -> functions = TMALLOC(struct function, N_FUNCTIONS);
|
||||
|
||||
return env;
|
||||
}
|
||||
|
||||
|
||||
static struct function_env *
|
||||
delete_function_env(struct function_env *env)
|
||||
{
|
||||
int i;
|
||||
|
||||
struct function_env *up = env -> up;
|
||||
|
||||
for (i = 0; i < env -> num_functions; i++)
|
||||
free_function(& env -> functions[i]);
|
||||
|
||||
tfree(env -> functions);
|
||||
tfree(env);
|
||||
|
||||
return up;
|
||||
}
|
||||
|
||||
|
||||
static struct line *
|
||||
inp_expand_macros_in_deck(struct line *c)
|
||||
inp_expand_macros_in_deck(struct function_env *env, struct line *c)
|
||||
{
|
||||
int prev_num_functions = num_functions;
|
||||
env = new_function_env(env);
|
||||
|
||||
inp_grab_func(c);
|
||||
inp_grab_func(env, c);
|
||||
|
||||
inp_expand_macros_in_func(prev_num_functions);
|
||||
inp_expand_macros_in_func(env);
|
||||
|
||||
for (; c; c = c->li_next) {
|
||||
|
||||
|
|
@ -3109,25 +3140,17 @@ inp_expand_macros_in_deck(struct line *c)
|
|||
continue;
|
||||
|
||||
if (ciprefix(".subckt", c->li_line)) {
|
||||
int i;
|
||||
|
||||
int prev_num_functions = num_functions;
|
||||
|
||||
c = inp_expand_macros_in_deck(c->li_next);
|
||||
|
||||
for (i = prev_num_functions; i < num_functions; i++)
|
||||
free_function(& functions[i]);
|
||||
num_functions = prev_num_functions;
|
||||
|
||||
c = inp_expand_macros_in_deck(env, c->li_next);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ciprefix(".ends", c->li_line))
|
||||
return c;
|
||||
break;
|
||||
|
||||
c->li_line = inp_expand_macro_in_str(c->li_line);
|
||||
c->li_line = inp_expand_macro_in_str(env, c->li_line);
|
||||
}
|
||||
|
||||
env = delete_function_env(env);
|
||||
return c;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue