diff options
Diffstat (limited to 'debug.c')
-rw-r--r-- | debug.c | 426 |
1 files changed, 202 insertions, 224 deletions
@@ -40,12 +40,9 @@ extern FILE *output_fp; extern IOBUF *curfile; extern const char *command_file; extern const char *get_spec_varname(Func_ptr fptr); -extern int r_interpret(INSTRUCTION *); extern int zzparse(void); #define read_command() (void) zzparse() -extern int free_instruction(INSTRUCTION *, int *); -extern void destroy_symbol(char *name); extern const char *redir2str(int redirtype); static char *linebuf = NULL; /* used to print a single line of source */ @@ -54,7 +51,7 @@ static size_t linebuf_len; FILE *out_fp; char *dbg_prompt; char *commands_prompt = "> "; /* breakpoint or watchpoint commands list */ -char *eval_prompt = "@> "; /* awk statement(s) */ +char *eval_prompt = "@> "; /* awk statement(s) */ int input_from_tty = FALSE; int input_fd; @@ -176,7 +173,7 @@ static struct { int break_point; /* non-zero (breakpoint number) if stopped at break point */ int watch_point; /* non-zero (watchpoint number) if stopped at watch point */ - int (*check_func)(INSTRUCTION **); /* function to decide when to suspend + int (*check_func)(INSTRUCTION **); /* function to decide when to suspend * awk interpreter and return control * to debugger command interpreter. */ @@ -216,9 +213,9 @@ struct dbg_option { const char *help_txt; }; -#define DEFAULT_HISTFILE "./.dgawk_history" -#define DEFAULT_OPTFILE "./.dgawkrc" -#define DEFAULT_PROMPT "dgawk> " +#define DEFAULT_HISTFILE "./.gawk_history" +#define DEFAULT_OPTFILE "./.gawkrc" +#define DEFAULT_PROMPT "gawk> " #define DEFAULT_LISTSIZE 15 #define DEFAULT_HISTSIZE 100 @@ -234,10 +231,10 @@ static const char *options_file = DEFAULT_OPTFILE; static const char *history_file = DEFAULT_HISTFILE; #endif -/* keep all option variables in one place */ +/* debugger option related variables */ static char *output_file = "/dev/stdout"; /* gawk output redirection */ -char *dgawk_prompt = NULL; /* initialized in interpret */ +char *dgawk_prompt = NULL; /* initialized in interpret */ static int list_size = DEFAULT_LISTSIZE; /* # of lines that 'list' prints */ static int do_trace = FALSE; static int do_save_history = TRUE; @@ -267,7 +264,7 @@ static void save_options(const char *file); /* pager */ jmp_buf pager_quit_tag; -int pager_quit_tag_valid; +int pager_quit_tag_valid = FALSE; static int screen_width = INT_MAX; /* no of columns */ static int screen_height = INT_MAX; /* no of rows */ static int pager_lines_printed = 0; /* no of lines printed so far */ @@ -307,12 +304,13 @@ static struct list_item *add_item(struct list_item *list, int type, NODE *symbol static void delete_item(struct list_item *d); static int breakpoint_triggered(BREAKPOINT *b); static int watchpoint_triggered(struct list_item *w); - static void print_instruction(INSTRUCTION *pc, Func_print print_func, FILE *fp, int in_dump); +static int print_code(INSTRUCTION *pc, void *x); static void next_command(); +static void debug_post_execute(INSTRUCTION *pc); +static int debug_pre_execute(INSTRUCTION **pi); static char *g_readline(const char *prompt); static int prompt_yes_no(const char *, char , int , FILE *); - static struct pf_data { Func_print print_func; int defn; @@ -328,16 +326,13 @@ struct command_source char * (*read_func)(const char *); int (*close_func)(int); int eof_status; /* see push_cmd_src */ - int cmd; /* D_source or 0 */ - char *str; /* sourced file */ + int cmd; /* D_source or 0 */ + char *str; /* sourced file */ struct command_source *next; }; static struct command_source *cmd_src = NULL; -#define get_param_count(f) (f)->lnode->param_cnt -#define get_params(f) (f)->parmlist - #define CHECK_PROG_RUNNING() \ do { \ @@ -490,11 +485,11 @@ source_find(char *src) return s; } - path = find_source(src, &sbuf, &errno_val); + path = find_source(src, & sbuf, & errno_val, FALSE); if (path != NULL) { for (s = srcfiles->next; s != srcfiles; s = s->next) { if ((s->stype == SRC_FILE || s->stype == SRC_INC) - && files_are_same(path, s)) { + && files_are_same(path, s)) { efree(path); return s; } @@ -719,6 +714,8 @@ list: int do_info(CMDARG *arg, int cmd ATTRIBUTE_UNUSED) { + NODE **table; + if (arg == NULL || arg->type != D_argument) return FALSE; @@ -804,7 +801,6 @@ do_info(CMDARG *arg, int cmd ATTRIBUTE_UNUSED) INSTRUCTION *pc; int arg_count, pcount; int i, from, to; - char **pnames; CHECK_PROG_RUNNING(); f = find_frame(cur_frame); @@ -815,8 +811,7 @@ do_info(CMDARG *arg, int cmd ATTRIBUTE_UNUSED) return FALSE; } - pcount = get_param_count(func); /* # of defined params */ - pnames = get_params(func); /* param names */ + pcount = func->param_cnt; /* # of defined params */ pc = (INSTRUCTION *) f->reti; /* Op_func_call instruction */ arg_count = (pc + 1)->expr_count; /* # of arguments supplied */ @@ -836,7 +831,7 @@ do_info(CMDARG *arg, int cmd ATTRIBUTE_UNUSED) r = f->stack[i]; if (r->type == Node_array_ref) r = r->orig_array; - fprintf(out_fp, "%s = ", pnames[i]); + fprintf(out_fp, "%s = ", func->fparms[i].param); print_symbol(r, TRUE); } if (to < from) @@ -848,25 +843,28 @@ do_info(CMDARG *arg, int cmd ATTRIBUTE_UNUSED) break; case A_VARIABLES: + table = variable_list(); initialize_pager(out_fp); if (setjmp(pager_quit_tag) == 0) { gprintf(out_fp, _("All defined variables:\n\n")); - print_vars(gprintf, out_fp); + print_vars(table, gprintf, out_fp); } + efree(table); break; case A_FUNCTIONS: + table = function_list(TRUE); initialize_pager(out_fp); if (setjmp(pager_quit_tag) == 0) { gprintf(out_fp, _("All defined functions:\n\n")); pf_data.print_func = gprintf; pf_data.fp = out_fp; pf_data.defn = TRUE; - (void) foreach_func((int (*)(INSTRUCTION *, void *)) print_function, - FALSE, /* sort */ - &pf_data /* data */ - ); + (void) foreach_func(table, + (int (*)(INSTRUCTION *, void *)) print_function, + &pf_data); } + efree(table); break; case A_DISPLAY: @@ -896,7 +894,7 @@ do_info(CMDARG *arg, int cmd ATTRIBUTE_UNUSED) } gprintf(out_fp, "\n"); } else if (IS_FIELD(d)) - gprintf(out_fp, "%d:\t$%ld\n", d->number, (long) symbol->numbr); + gprintf(out_fp, "%d:\t$%ld\n", d->number, get_number_si(symbol)); else gprintf(out_fp, "%d:\t%s\n", d->number, d->sname); if (d->cndn.code != NULL) @@ -977,6 +975,7 @@ find_param(const char *name, long num, char **pname) { NODE *r = NULL; NODE *f; + char *fparam; if (pname) *pname = NULL; @@ -986,20 +985,18 @@ find_param(const char *name, long num, char **pname) f = find_frame(num); if (f->func_node != NULL) { /* in function */ NODE *func; - char **pnames; int i, pcount; func = f->func_node; - pnames = get_params(func); - pcount = get_param_count(func); - + pcount = func->param_cnt; for (i = 0; i < pcount; i++) { - if (strcmp(name, pnames[i]) == 0) { + fparam = func->fparms[i].param; + if (strcmp(name, fparam) == 0) { r = f->stack[i]; if (r->type == Node_array_ref) r = r->orig_array; if (pname) - *pname = pnames[i]; + *pname = fparam; break; } } @@ -1059,7 +1056,7 @@ print_field(long field_num) static int print_array(volatile NODE *arr, char *arr_name) { - NODE *bucket; + NODE *subs; NODE **list; int i; size_t num_elems = 0; @@ -1067,7 +1064,7 @@ print_array(volatile NODE *arr, char *arr_name) volatile int ret = 0; volatile jmp_buf pager_quit_tag_stack; - if (arr->var_array == NULL || arr->table_size == 0) { + if (array_empty(arr)) { gprintf(out_fp, _("array `%s' is empty\n"), arr_name); return 0; } @@ -1080,12 +1077,12 @@ print_array(volatile NODE *arr, char *arr_name) PUSH_BINDING(pager_quit_tag_stack, pager_quit_tag, pager_quit_tag_valid); if (setjmp(pager_quit_tag) == 0) { for (i = 0; ret == 0 && i < num_elems; i++) { - bucket = list[i]; - r = bucket->ahvalue; + subs = list[i]; + r = *assoc_lookup((NODE *) arr, subs); if (r->type == Node_var_array) ret = print_array(r, r->vname); else { - gprintf(out_fp, "%s[\"%s\"] = ", arr_name, bucket->ahname_str); + gprintf(out_fp, "%s[\"%s\"] = ", arr_name, subs->stptr); valinfo((NODE *) r, gprintf, out_fp); } } @@ -1183,7 +1180,7 @@ do_print_var(CMDARG *arg, int cmd ATTRIBUTE_UNUSED) break; case D_field: - print_field(a->a_node->numbr); + print_field(get_number_si(a->a_node)); break; default: @@ -1215,7 +1212,7 @@ do_set_var(CMDARG *arg, int cmd ATTRIBUTE_UNUSED) switch (r->type) { case Node_var_new: r->type = Node_var; - r->var_value = Nnull_string; + r->var_value = dupnode(Nnull_string); /* fall through */ case Node_var: lhs = &r->var_value; @@ -1255,7 +1252,7 @@ do_set_var(CMDARG *arg, int cmd ATTRIBUTE_UNUSED) else { arg = arg->next; val = arg->a_node; - lhs = assoc_lookup(r, subs, FALSE); + lhs = assoc_lookup(r, subs); unref(*lhs); *lhs = dupnode(val); fprintf(out_fp, "%s[\"%s\"] = ", name, subs->stptr); @@ -1264,12 +1261,10 @@ do_set_var(CMDARG *arg, int cmd ATTRIBUTE_UNUSED) } else { if (value == NULL) { NODE *array; - - getnode(array); - array->type = Node_var_array; - array->var_array = NULL; + array = make_array(); array->vname = estrdup(subs->stptr, subs->stlen); - *assoc_lookup(r, subs, FALSE) = array; + array->parent_array = r; + *assoc_lookup(r, subs) = array; r = array; } else if (value->type != Node_var_array) { d_error(_("attempt to use scalar `%s[\"%s\"]' as array"), @@ -1289,7 +1284,7 @@ do_set_var(CMDARG *arg, int cmd ATTRIBUTE_UNUSED) long field_num; Func_ptr assign = NULL; - field_num = (long) arg->a_node->numbr; + field_num = get_number_si(arg->a_node); assert(field_num >= 0); arg = arg->next; val = arg->a_node; @@ -1306,7 +1301,7 @@ do_set_var(CMDARG *arg, int cmd ATTRIBUTE_UNUSED) break; } return FALSE; -} +} /* find_item --- find an item in the watch/display list */ @@ -1378,14 +1373,18 @@ add_item(struct list_item *list, int type, NODE *symbol, char *pname) d->fcall_count = fcall_count - cur_frame; } - if (type == D_field) { /* field number */ + if (type == D_field) { + /* field number */ d->symbol = symbol; d->flags |= FIELD_NUM; - } else if (type == D_subscript) { /* subscript */ + } else if (type == D_subscript) { + /* subscript */ d->symbol = symbol; d->flags |= SUBSCRIPT; - } else /* array or variable */ + } else { + /* array or variable */ d->symbol = symbol; + } /* add to list */ d->next = list->next; @@ -1430,7 +1429,7 @@ do_add_item(struct list_item *list, CMDARG *arg) for (i = 0; i < count; i++) { arg = arg->next; subs[i] = dupnode(arg->a_node); - (void) force_string(subs[i]); + subs[i] = force_string(subs[i]); } item->subs = subs; item->num_subs = count; @@ -1535,7 +1534,7 @@ display(struct list_item *d) } else if (IS_FIELD(d)) { NODE *r = d->symbol; fprintf(out_fp, "%d: ", d->number); - print_field(r->numbr); + print_field(get_number_si(r)); } else { print_sym: fprintf(out_fp, "%d: %s = ", d->number, d->sname); @@ -1592,13 +1591,12 @@ condition_triggered(struct condition *cndn) return FALSE; /* not triggered */ force_number(r); - di = (r->numbr != 0.0); + di = ! iszero(r); DEREF(r); return di; } - static int find_subscript(struct list_item *item, NODE **ptr) { @@ -1617,7 +1615,8 @@ find_subscript(struct list_item *item, NODE **ptr) else if (i < count - 1) return -1; } - *ptr = r; + if (r != NULL) + *ptr = r; return 0; } @@ -1647,8 +1646,7 @@ cmp_val(struct list_item *w, NODE *old, NODE *new) if (new->type == Node_val) /* 7 */ return TRUE; /* new->type == Node_var_array */ /* 8 */ - if (new->var_array != NULL) - size = new->table_size; + size = new->table_size; if (w->cur_size == size) return FALSE; return TRUE; @@ -1687,7 +1685,7 @@ watchpoint_triggered(struct list_item *w) (void) find_subscript(w, &t2); else if (IS_FIELD(w)) { long field_num; - field_num = (long) w->symbol->numbr; + field_num = get_number_si(w->symbol); t2 = *get_field(field_num, NULL); } else { switch (symbol->type) { @@ -1722,7 +1720,7 @@ watchpoint_triggered(struct list_item *w) w->flags &= ~CUR_IS_ARRAY; w->cur_value = dupnode(t2); } else - w->cur_size = (t2->var_array != NULL) ? t2->table_size : 0; + w->cur_size = (t2->type == Node_var_array) ? t2->table_size : 0; } else if (! t1) { /* 1, 2 */ w->old_value = 0; /* new != NULL */ @@ -1730,7 +1728,7 @@ watchpoint_triggered(struct list_item *w) w->cur_value = dupnode(t2); else { w->flags |= CUR_IS_ARRAY; - w->cur_size = (t2->var_array != NULL) ? t2->table_size : 0; + w->cur_size = (t2->type == Node_var_array) ? t2->table_size : 0; } } else /* if (t1->type == Node_val) */ { /* 4, 5, 6 */ w->old_value = w->cur_value; @@ -1738,7 +1736,7 @@ watchpoint_triggered(struct list_item *w) w->cur_value = 0; else if (t2->type == Node_var_array) { w->flags |= CUR_IS_ARRAY; - w->cur_size = (t2->var_array != NULL) ? t2->table_size : 0; + w->cur_size = t2->table_size; } else w->cur_value = dupnode(t2); } @@ -1764,13 +1762,13 @@ initialize_watch_item(struct list_item *w) w->cur_value = (NODE *) 0; else if (r->type == Node_var_array) { /* it's a sub-array */ w->flags |= CUR_IS_ARRAY; - w->cur_size = (r->var_array != NULL) ? r->table_size : 0; + w->cur_size = r->table_size; } else w->cur_value = dupnode(r); } else if (IS_FIELD(w)) { long field_num; t = w->symbol; - field_num = (long) t->numbr; + field_num = get_number_si(t); r = *get_field(field_num, NULL); w->cur_value = dupnode(r); } else { @@ -1781,7 +1779,7 @@ initialize_watch_item(struct list_item *w) w->cur_value = dupnode(r); } else if (symbol->type == Node_var_array) { w->flags |= CUR_IS_ARRAY; - w->cur_size = (symbol->var_array != NULL) ? symbol->table_size : 0; + w->cur_size = symbol->table_size; } /* else can't happen */ } @@ -1809,7 +1807,7 @@ do_watch(CMDARG *arg, int cmd ATTRIBUTE_UNUSED) fprintf(out_fp, "Watchpoint %d: ", w->number); symbol = w->symbol; -/* FIXME: common code also in print_watch_item */ + /* FIXME: common code also in print_watch_item */ if (IS_SUBSCRIPT(w)) { fprintf(out_fp, "%s", w->sname); for (i = 0; i < w->num_subs; i++) { @@ -1818,7 +1816,7 @@ do_watch(CMDARG *arg, int cmd ATTRIBUTE_UNUSED) } fprintf(out_fp, "\n"); } else if (IS_FIELD(w)) - fprintf(out_fp, "$%ld\n", (long) symbol->numbr); + fprintf(out_fp, "$%ld\n", get_number_si(symbol)); else fprintf(out_fp, "%s\n", w->sname); @@ -1873,19 +1871,17 @@ print_function(INSTRUCTION *pc, void *x) { NODE *func; int i, pcount; - char **pnames; struct pf_data *data = (struct pf_data *) x; int defn = data->defn; Func_print print_func = data->print_func; FILE *fp = data->fp; func = pc->func_body; - pcount = get_param_count(func); - pnames = get_params(func); + pcount = func->param_cnt; - print_func(fp, "%s(", func->lnode->param); + print_func(fp, "%s(", func->vname); for (i = 0; i < pcount; i++) { - print_func(fp, "%s", pnames[i]); + print_func(fp, "%s", func->fparms[i].param); if (i < pcount - 1) print_func(fp, ", "); } @@ -2368,7 +2364,7 @@ func: rp = func->code_ptr; if ((b = set_breakpoint_at(rp, rp->source_line, FALSE)) == NULL) fprintf(out_fp, _("Can't set breakpoint in function `%s'\n"), - func->lnode->param); + func->vname); else if (temporary) b->flags |= BP_TEMP; lineno = b->bpi->source_line; @@ -2495,7 +2491,7 @@ func: } if (! bp_found) fprintf(out_fp, _("No breakpoint(s) at entry to function `%s'\n"), - func->lnode->param); + func->vname); else fprintf(out_fp, "\n"); /* fall through */ @@ -2690,19 +2686,17 @@ do_disable_breakpoint(CMDARG *arg, int cmd ATTRIBUTE_UNUSED) #ifdef HAVE_LIBREADLINE -/* get_parmlist --- list of function params in current context */ +/* get_function --- function definition in current context */ -char ** -get_parmlist() +NODE * +get_function() { NODE *func; if (! prog_running) return NULL; func = find_frame(cur_frame)->func_node; - if (func == NULL) /* in main */ - return NULL; - return func->parmlist; + return func; } /* initialize_readline --- initialize readline */ @@ -2728,10 +2722,19 @@ initialize_readline() #endif -/* interpret --- debugger entry point */ +/* init_debug --- register debugger exec hooks */ + +void +init_debug() +{ + register_exec_hook(debug_pre_execute, debug_post_execute); +} + + +/* debug_prog --- debugger entry point */ int -interpret(INSTRUCTION *pc) +debug_prog(INSTRUCTION *pc) { char *run; @@ -2781,7 +2784,7 @@ interpret(INSTRUCTION *pc) (void) do_run(NULL, 0); } else if (command_file != NULL) { - /* run commands from a file (--command=file or -R file) */ + /* run commands from a file (--debug=file or -D file) */ int fd; fd = open_readfd(command_file); if (fd == INVALID_HANDLE) { @@ -2928,14 +2931,14 @@ do_run(CMDARG *arg ATTRIBUTE_UNUSED, int cmd ATTRIBUTE_UNUSED) prog_running = TRUE; fatal_tag_valid = TRUE; if (setjmp(fatal_tag) == 0) - (void) r_interpret(code_block); + (void) interpret(code_block); fatal_tag_valid = FALSE; prog_running = FALSE; fprintf(out_fp, _("Program exited %s with exit value: %d\n"), - (! exiting && exit_val != EXIT_SUCCESS) ? "abnormally" - : "normally", - exit_val); + (! exiting && exit_val != EXIT_SUCCESS) ? "abnormally" + : "normally", + exit_val); need_restart = TRUE; return FALSE; } @@ -3135,7 +3138,6 @@ do_next(CMDARG *arg, int cmd) static int check_nexti(INSTRUCTION **pi) { - /* make sure not to step inside function calls */ if (fcall_count < stop.fcall_count) { @@ -3224,7 +3226,7 @@ check_return(INSTRUCTION **pi) int do_return(CMDARG *arg, int cmd) { - NODE *func; + NODE *func, *n; CHECK_PROG_RUNNING(); func = find_frame(cur_frame)->func_node; @@ -3241,12 +3243,11 @@ do_return(CMDARG *arg, int cmd) stop.check_func = check_return; - if (arg != NULL && arg->type == D_node) { /* optional return value */ - NODE *n; + if (arg != NULL && arg->type == D_node) /* optional return value */ n = dupnode(arg->a_node); - PUSH(n); - } else - PUSH(Nnull_string); + else + n = dupnode(Nnull_string); + PUSH(n); return TRUE; } @@ -3315,7 +3316,7 @@ do_until(CMDARG *arg, int cmd) s = source_find(arg->a_string); arg = arg->next; if (s == NULL || arg == NULL - || (arg->type != D_int && arg->type != D_func)) + || (arg->type != D_int && arg->type != D_func)) return FALSE; src = s->src; if (arg->type == D_func) @@ -3345,7 +3346,7 @@ func: } } fprintf(out_fp, _("Can't find specified location in function `%s'\n"), - func->lnode->param); + func->vname); /* fall through */ default: return FALSE; @@ -3389,7 +3390,7 @@ print_watch_item(struct list_item *w) } fprintf(out_fp, "\n"); } else if (IS_FIELD(w)) - fprintf(out_fp, "$%ld\n", (long) symbol->numbr); + fprintf(out_fp, "$%ld\n", get_number_si(symbol)); else fprintf(out_fp, "%s\n", w->sname); @@ -3500,10 +3501,10 @@ no_output: read_command(); /* zzparse */ } -/* post_execute --- post_hook in the interpreter */ +/* debug_post_execute --- post_hook in the interpreter */ -void -post_execute(INSTRUCTION *pc) +static void +debug_post_execute(INSTRUCTION *pc) { if (! in_main_context()) return; @@ -3553,13 +3554,13 @@ post_execute(INSTRUCTION *pc) } } -/* pre_execute --- pre_hook, called by the interpreter before execution; +/* debug_pre_execute --- pre_hook, called by the interpreter before execution; * checks if execution needs to be suspended and control * transferred to the debugger. */ -int -pre_execute(INSTRUCTION **pi) +static int +debug_pre_execute(INSTRUCTION **pi) { static int cant_stop = FALSE; NODE *m; @@ -3614,7 +3615,6 @@ pre_execute(INSTRUCTION **pi) return TRUE; case Op_func: - case Op_ext_func: case Op_var_update: return TRUE; @@ -3649,19 +3649,33 @@ pre_execute(INSTRUCTION **pi) /* print_memory --- print a scalar value */ static void -print_memory(NODE *m, char **fparms, Func_print print_func, FILE *fp) +print_memory(NODE *m, NODE *func, Func_print print_func, FILE *fp) { switch (m->type) { case Node_val: if (m == Nnull_string) print_func(fp, "Nnull_string"); - else if ((m->flags & NUMBER) != 0) - print_func(fp, "%g", m->numbr); - else if ((m->flags & STRING) != 0) + else if ((m->flags & NUMBER) != 0) { +#ifdef HAVE_MPFR + if (m->flags & MPFN) + print_func(fp, "%s", mpg_fmt("%R*g", ROUND_MODE, m->mpg_numbr)); + else if (m->flags & MPZN) + print_func(fp, "%s", mpg_fmt("%Zd", m->mpg_i)); + else +#endif + print_func(fp, "%g", m->numbr); + } else if ((m->flags & STRING) != 0) pp_string_fp(print_func, fp, m->stptr, m->stlen, '"', FALSE); - else if ((m->flags & NUMCUR) != 0) - print_func(fp, "%g", m->numbr); - else if ((m->flags & STRCUR) != 0) + else if ((m->flags & NUMCUR) != 0) { +#ifdef HAVE_MPFR + if (m->flags & MPFN) + print_func(fp, "%s", mpg_fmt("%R*g", ROUND_MODE, m->mpg_numbr)); + else if (m->flags & MPZN) + print_func(fp, "%s", mpg_fmt("%Zd", m->mpg_i)); + else +#endif + print_func(fp, "%g", m->numbr); + } else if ((m->flags & STRCUR) != 0) pp_string_fp(print_func, fp, m->stptr, m->stlen, '"', FALSE); else print_func(fp, "-?-"); @@ -3676,8 +3690,8 @@ print_memory(NODE *m, char **fparms, Func_print print_func, FILE *fp) break; case Node_param_list: - assert(fparms != NULL); - print_func(fp, "%s", fparms[m->param_cnt]); + assert(func != NULL); + print_func(fp, "%s", func->fparms[m->param_cnt].param); break; case Node_var: @@ -3696,9 +3710,8 @@ print_memory(NODE *m, char **fparms, Func_print print_func, FILE *fp) static void print_instruction(INSTRUCTION *pc, Func_print print_func, FILE *fp, int in_dump) { - static char **fparms = NULL; int pcount = 0; - NODE *func = NULL; + static NODE *func = NULL; static int noffset = 0; if (noffset == 0) { @@ -3710,25 +3723,17 @@ print_instruction(INSTRUCTION *pc, Func_print print_func, FILE *fp, int in_dump) if (pc->opcode == Op_func) { func = pc->func_body; - fparms = get_params(func); - pcount = get_param_count(func); + pcount = func->param_cnt; if (in_dump) { int j; - print_func(fp, "\n\t# Function: %s (", func->lnode->param); + print_func(fp, "\n\t# Function: %s (", func->vname); for (j = 0; j < pcount; j++) { - print_func(fp, "%s", fparms[j]); + print_func(fp, "%s", func->fparms[j].param); if (j < pcount - 1) print_func(fp, ", "); } print_func(fp, ")\n\n"); } - } else if (pc->opcode == Op_ext_func) { - func = pc->func_body; - fparms = get_params(func); - pcount = get_param_count(func); - if (in_dump) - print_func(fp, "\n\t# Extension function: %s (... %d params ...)\n\n", - func->lnode->param, pcount); } else if (pc->opcode == Op_rule) { if (in_dump) print_func(fp, "\n\t# %s\n\n", ruletab[pc->in_rule]); @@ -3744,12 +3749,8 @@ print_instruction(INSTRUCTION *pc, Func_print print_func, FILE *fp, int in_dump) pc->source_line, pc, opcode2str(pc->opcode)); if (prog_running && ! in_dump) { - /* find params in the current frame */ + /* find Node_func if in function */ func = find_frame(0)->func_node; - if (func != NULL) - fparms = get_params(func); - /* else - fparms = NULL; */ } @@ -3775,10 +3776,6 @@ print_instruction(INSTRUCTION *pc, Func_print print_func, FILE *fp, int in_dump) pc->target_assign, pc->do_reference ? "TRUE" : "FALSE"); break; - case Op_ext_func: - print_func(fp, "[param_cnt = %d]\n", pcount); - break; - case Op_func: print_func(fp, "[param_cnt = %d] [source_file = %s]\n", pcount, pc->source_file ? pc->source_file : "cmd. line"); @@ -3853,7 +3850,7 @@ print_instruction(INSTRUCTION *pc, Func_print print_func, FILE *fp, int in_dump) case Op_arrayfor_incr: print_func(fp, "[array_var = %s] [target_jmp = %p]\n", pc->array_var->type == Node_param_list ? - fparms[pc->array_var->param_cnt] : pc->array_var->vname, + func->fparms[pc->array_var->param_cnt].param : pc->array_var->vname, pc->target_jmp); break; @@ -3888,13 +3885,13 @@ print_instruction(INSTRUCTION *pc, Func_print print_func, FILE *fp, int in_dump) break; case Op_builtin: - { - const char *fname = getfname(pc->builtin); - if (fname == NULL) - print_func(fp, "(extension func) [arg_count = %ld]\n", pc->expr_count); - else - print_func(fp, "%s [arg_count = %ld]\n", fname, pc->expr_count); - } + print_func(fp, "%s [arg_count = %ld]\n", getfname(pc->builtin), + pc->expr_count); + break; + + case Op_ext_builtin: + print_func(fp, "%s [arg_count = %ld]\n", (pc + 1)->func_name, + pc->expr_count); break; case Op_subscript: @@ -3903,7 +3900,7 @@ print_instruction(INSTRUCTION *pc, Func_print print_func, FILE *fp, int in_dump) break; case Op_store_sub: - print_memory(pc->memory, fparms, print_func, fp); + print_memory(pc->memory, func, print_func, fp); print_func(fp, " [sub_count = %ld]\n", pc->expr_count); break; @@ -3946,9 +3943,17 @@ print_instruction(INSTRUCTION *pc, Func_print print_func, FILE *fp, int in_dump) print_func(fp, "[exec_count = %ld]\n", pc->exec_count); break; - case Op_store_var: + case Op_store_var: + print_memory(pc->memory, func, print_func, fp); + if (pc->initval != NULL) { + print_func(fp, " = "); + print_memory(pc->initval, func, print_func, fp); + } + print_func(fp, "\n"); + break; + case Op_push_lhs: - print_memory(pc->memory, fparms, print_func, fp); + print_memory(pc->memory, func, print_func, fp); print_func(fp, " [do_reference = %s]\n", pc->do_reference ? "TRUE" : "FALSE"); break; @@ -3969,7 +3974,7 @@ print_instruction(INSTRUCTION *pc, Func_print print_func, FILE *fp, int in_dump) case Op_quotient_i: case Op_mod_i: case Op_assign_concat: - print_memory(pc->memory, fparms, print_func, fp); + print_memory(pc->memory, func, print_func, fp); /* fall through */ default: print_func(fp, "\n"); @@ -4007,7 +4012,8 @@ int do_dump_instructions(CMDARG *arg, int cmd ATTRIBUTE_UNUSED) { FILE *fp; - + NODE **funcs; + if (arg != NULL && arg->type == D_string) { /* dump to a file */ if ((fp = fopen(arg->a_string, "w")) == NULL) { @@ -4019,25 +4025,27 @@ do_dump_instructions(CMDARG *arg, int cmd ATTRIBUTE_UNUSED) pf_data.fp = fp; pf_data.defn = TRUE; /* in_dump = TRUE */ (void) print_code(code_block, &pf_data); - (void) foreach_func((int (*)(INSTRUCTION *, void *)) print_code, - FALSE, /* sort */ - &pf_data /* data */ - ); + funcs = function_list(TRUE); + (void) foreach_func(funcs, + (int (*)(INSTRUCTION *, void *)) print_code, + &pf_data); + efree(funcs); fclose(fp); return FALSE; } + funcs = function_list(TRUE); initialize_pager(out_fp); if (setjmp(pager_quit_tag) == 0) { pf_data.print_func = gprintf; pf_data.fp = out_fp; pf_data.defn = TRUE; /* in_dump = TRUE */ (void) print_code(code_block, &pf_data); - (void) foreach_func((int (*)(INSTRUCTION *, void *)) print_code, - FALSE, /* sort */ - &pf_data /* data */ - ); + (void) foreach_func(funcs, + (int (*)(INSTRUCTION *, void *)) print_code, + &pf_data); } + efree(funcs); return FALSE; } @@ -4379,7 +4387,7 @@ enlarge_buffer: nchar = serialize_subscript(buf + bl, buflen - bl, wd); else if (IS_FIELD(wd)) nchar = snprintf(buf + bl, buflen - bl, "%d%c%d%c%d%c", - wd->number, FSEP, D_field, FSEP, (int) wd->symbol->numbr, FSEP); + wd->number, FSEP, D_field, FSEP, (int) get_number_si(wd->symbol), FSEP); else nchar = snprintf(buf + bl, buflen - bl, "%d%c%d%c%s%c", wd->number, FSEP, D_variable, FSEP, wd->sname, FSEP); @@ -4946,7 +4954,7 @@ do_print_f(CMDARG *arg, int cmd ATTRIBUTE_UNUSED) { long field_num; r = a->a_node; - field_num = (long) r->numbr; + field_num = get_number_si(r); tmp[i] = *get_field(field_num, NULL); } break; @@ -4959,7 +4967,7 @@ do_print_f(CMDARG *arg, int cmd ATTRIBUTE_UNUSED) goto done; for (; cnt > 0; cnt--) { - NODE *value, *subs; + NODE *value, *subs; a = a->next; subs = a->a_node; value = in_array(r, subs); @@ -4997,7 +5005,7 @@ do_print_f(CMDARG *arg, int cmd ATTRIBUTE_UNUSED) } } - force_string(tmp[0]); + tmp[0] = force_string(tmp[0]); PUSH_BINDING(fatal_tag_stack, fatal_tag, fatal_tag_valid); if (setjmp(fatal_tag) == 0) @@ -5340,35 +5348,6 @@ close_all() set_gawk_output(NULL); /* closes output_fp if not stdout */ } -/* install_params --- install function parameters into the symbol table */ - -static void -install_params(NODE *func) -{ - NODE *np; - - if (func == NULL) - return; - /* function parameters of type Node_param_list */ - np = func->lnode; - for (np = np->rnode; np != NULL; np = np->rnode) - install_symbol(np->param, np); -} - -/* remove_params --- remove function parameters out of the symbol table */ - -static void -remove_params(NODE *func) -{ - NODE *np; - - if (func == NULL) - return; - np = func->lnode; - for (np = np->rnode; np != NULL; np = np->rnode) - remove_symbol(np->param); -} - /* pre_execute_code --- pre_hook for execute_code, called by pre_execute */ static int @@ -5411,22 +5390,25 @@ execute_code(volatile INSTRUCTION *code) volatile NODE *r = NULL; volatile jmp_buf fatal_tag_stack; long save_stack_size; + int save_flags = do_flags; /* We use one global stack for all contexts. * Save # of items in stack; in case of * a fatal error, pop stack until it has that many items. */ + save_stack_size = (stack_ptr - stack_bottom) + 1; + do_flags = FALSE; PUSH_BINDING(fatal_tag_stack, fatal_tag, fatal_tag_valid); if (setjmp(fatal_tag) == 0) { - (void) r_interpret((INSTRUCTION *) code); + (void) interpret((INSTRUCTION *) code); r = POP_SCALAR(); } else /* fatal error */ (void) unwind_stack(save_stack_size); POP_BINDING(fatal_tag_stack, fatal_tag, fatal_tag_valid); - + do_flags = save_flags; if (exit_val != EXIT_SUCCESS) { /* must be EXIT_FATAL? */ exit_val = EXIT_SUCCESS; return NULL; @@ -5445,9 +5427,9 @@ do_eval(CMDARG *arg, int cmd ATTRIBUTE_UNUSED) NODE **sp; INSTRUCTION *eval, *code = NULL; AWK_CONTEXT *ctxt; - char **save_parmlist = NULL; int ecount = 0, pcount = 0; int ret; + int save_flags = do_flags; if (prog_running) { this_frame = find_frame(0); @@ -5459,7 +5441,9 @@ do_eval(CMDARG *arg, int cmd ATTRIBUTE_UNUSED) ctxt->install_func = append_symbol; /* keep track of newly installed globals */ push_context(ctxt); (void) add_srcfile(SRC_CMDLINE, arg->a_string, srcfiles, NULL, NULL); + do_flags = FALSE; ret = parse_program(&code); + do_flags = save_flags; remove_params(this_func); if (ret != 0) { pop_context(); /* switch to prev context */ @@ -5481,9 +5465,7 @@ do_eval(CMDARG *arg, int cmd ATTRIBUTE_UNUSED) } else { /* execute as a part of the current function */ int i; - char **varnames; INSTRUCTION *t; - NODE *np; eval = f->code_ptr; /* Op_func */ eval->source_file = cur_srcfile->src; @@ -5492,9 +5474,8 @@ do_eval(CMDARG *arg, int cmd ATTRIBUTE_UNUSED) t->opcode = Op_stop; /* add or append eval locals to the current frame stack */ - ecount = f->lnode->param_cnt; /* eval local count */ - pcount = this_func->lnode->param_cnt; - save_parmlist = this_func->parmlist; + ecount = f->param_cnt; /* eval local count */ + pcount = this_func->param_cnt; if (ecount > 0) { if (pcount == 0) @@ -5502,26 +5483,22 @@ do_eval(CMDARG *arg, int cmd ATTRIBUTE_UNUSED) else erealloc(this_frame->stack, NODE **, (pcount + ecount) * sizeof(NODE *), "do_eval"); - emalloc(varnames, char **, (pcount + ecount + 1) * sizeof(char *), "do_eval"); - if (pcount > 0) - memcpy(varnames, save_parmlist, pcount * sizeof(char *)); - for (np = f->lnode->rnode, i = 0; np != NULL; np = np->rnode, i++) { - varnames[pcount + i] = np->param; - np->param_cnt += pcount; /* appending eval locals: fixup param_cnt */ - } - varnames[pcount + ecount] = NULL; sp = this_frame->stack + pcount; for (i = 0; i < ecount; i++) { + NODE *np; + + np = f->fparms + i; + np->param_cnt += pcount; /* appending eval locals: fixup param_cnt */ + getnode(r); memset(r, 0, sizeof(NODE)); *sp++ = r; /* local variable */ r->type = Node_var_new; - r->vname = varnames[pcount + i]; + r->vname = np->param; } - this_func->parmlist = varnames; - this_func->lnode->param_cnt += ecount; + this_func->param_cnt += ecount; } } @@ -5561,19 +5538,17 @@ do_eval(CMDARG *arg, int cmd ATTRIBUTE_UNUSED) } /* else restore_frame() will free it */ - efree(this_func->parmlist); - this_func->parmlist = save_parmlist; - this_func->lnode->param_cnt -= ecount; + this_func->param_cnt -= ecount; } /* always destroy symbol "@eval", however destroy all newly installed - * globals only if fatal error in r_interpret (r == NULL). + * globals only if fatal error (execute_code() returing NULL). */ pop_context(); /* switch to prev context */ free_context(ctxt, (ret_val != NULL)); /* free all instructions and optionally symbols */ if (ret_val != NULL) - destroy_symbol("@eval"); /* destroy "@eval" */ + destroy_symbol(f); /* destroy "@eval" */ return FALSE; } @@ -5590,13 +5565,13 @@ an error message: static int invalid_symbol = 0; -void -check_symbol(char *name) +static void +check_symbol(NODE *r) { invalid_symbol++; - d_error(_("No symbol `%s' in current context"), name); + d_error(_("No symbol `%s' in current context"), r->vname); /* install anyway, but keep track of it */ - append_symbol(name); + append_symbol(r); } /* parse_condition --- compile a condition expression */ @@ -5612,6 +5587,7 @@ parse_condition(int type, int num, char *expr) NODE *this_func = NULL; INSTRUCTION *it, *stop, *rule; struct condition *cndn = NULL; + int save_flags = do_flags; if (type == D_break && (b = find_breakpoint(num)) != NULL) { INSTRUCTION *rp; @@ -5635,7 +5611,9 @@ parse_condition(int type, int num, char *expr) ctxt->install_func = check_symbol; push_context(ctxt); (void) add_srcfile(SRC_CMDLINE, expr, srcfiles, NULL, NULL); + do_flags = FALSE; ret = parse_program(&code); + do_flags = save_flags; remove_params(this_func); pop_context(); @@ -5655,8 +5633,8 @@ parse_condition(int type, int num, char *expr) it = rule->firsti; /* Op_K_print_rec */ assert(it->opcode == Op_K_print_rec); - it->opcode = Op_push_i; - it->memory = mk_number((AWKNUM) 1.0, PERM|NUMBER|NUMCUR); + it->opcode = Op_push_i; + it->memory = make_number(1.0); it->nexti = bcalloc(Op_jmp, 1, 0); it->nexti->target_jmp = stop; it->nexti->nexti = rule->lasti; @@ -5664,7 +5642,7 @@ parse_condition(int type, int num, char *expr) it = rule->lasti; /* Op_no_op, target for Op_jmp_false */ assert(it->opcode == Op_no_op); it->opcode = Op_push_i; - it->memory = mk_number((AWKNUM) 0.0, PERM|NUMBER|NUMCUR); + it->memory = make_number(0.0); it->nexti = stop; out: @@ -5744,7 +5722,7 @@ push_cmd_src( cs->str = NULL; cs->next = cmd_src; cmd_src = cs; - + input_fd = fd; input_from_tty = istty; read_a_line = readfunc; |