[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [bug-gawk] Gawk debug command 'eval'
From: |
arnold |
Subject: |
Re: [bug-gawk] Gawk debug command 'eval' |
Date: |
Sun, 17 Feb 2019 08:08:47 -0700 |
User-agent: |
Heirloom mailx 12.5 7/5/10 |
Hi.
Lothar Langer <address@hidden> wrote:
> Hi,
>
> i didn't read anything in the 'Gawk User's Guide' that it is not
> possible to evaluate user defined functions with the command 'eval' in
> the debugger.
>
> Example:
>
> function isnumeric(x) {
> return (length(x) && x == x+0)
> }
>
> ...
>
> gawk> eval "print isnumeric(\"hello\")"
> error: `return' not allowed in current context; statement ignored
>
> ... but ...
>
> gawk> eval "print length(\"hello\")"
> 5
>
> ... which is expected ...
>
> My version is:
> GNU Awk 4.2.60, API: 2.0
This turned out to be not so hard to fix. Please apply this patch, rebuild,
and let me know if you find any other problems. I plan to push this to
master soon.
Thanks for the report!
Arnold
------------------------------------------
diff --git a/awk.h b/awk.h
index a8a37f60..e90f83d5 100644
--- a/awk.h
+++ b/awk.h
@@ -664,6 +664,7 @@ typedef enum opcodeval {
Op_K_next,
Op_K_exit,
Op_K_return,
+ Op_K_return_from_eval,
Op_K_delete,
Op_K_delete_loop,
Op_K_getline_redir,
@@ -1402,7 +1403,7 @@ extern unsigned long (*hash)(const char *s, size_t len,
unsigned long hsize, siz
extern void init_env_array(NODE *env_node);
/* awkgram.c */
extern NODE *variable(int location, char *name, NODETYPE type);
-extern int parse_program(INSTRUCTION **pcode);
+extern int parse_program(INSTRUCTION **pcode, bool from_eval);
extern void track_ext_func(const char *name);
extern void dump_funcs(void);
extern void dump_vars(const char *fname);
diff --git a/awkgram.y b/awkgram.y
index 9f2b4d3c..87570dfa 100644
--- a/awkgram.y
+++ b/awkgram.y
@@ -176,6 +176,7 @@ static INSTRUCTION *ip_end;
static INSTRUCTION *ip_endfile;
static INSTRUCTION *ip_beginfile;
INSTRUCTION *main_beginfile;
+static bool called_from_eval = false;
static inline INSTRUCTION *list_create(INSTRUCTION *x);
static inline INSTRUCTION *list_append(INSTRUCTION *l, INSTRUCTION *x);
@@ -1093,6 +1094,9 @@ non_compound_stmt
if (! in_function)
yyerror(_("`return' used outside function context"));
} opt_exp statement_term {
+ if (called_from_eval)
+ $1->opcode = Op_K_return_from_eval;
+
if ($3 == NULL) {
$$ = list_create($1);
(void) list_prepend($$, instruction(Op_push_i));
@@ -2732,10 +2736,12 @@ out:
/* parse_program --- read in the program and convert into a list of
instructions */
int
-parse_program(INSTRUCTION **pcode)
+parse_program(INSTRUCTION **pcode, bool from_eval)
{
int ret;
+ called_from_eval = from_eval;
+
/* pre-create non-local jump targets
* ip_end (Op_no_op) -- used as jump target for `exit'
* outside an END block.
diff --git a/debug.c b/debug.c
index 452b6b6f..19874284 100644
--- a/debug.c
+++ b/debug.c
@@ -5522,7 +5522,7 @@ pre_execute_code(INSTRUCTION **pi)
op2str(ei->opcode));
*pi = ei->nexti;
break;
- case Op_K_return:
+ case Op_K_return_from_eval:
if (ei->nexti != NULL) { /* not an implicit return */
NODE *r;
d_error(_("`return' not allowed in current context;"
@@ -5600,7 +5600,7 @@ do_eval(CMDARG *arg, int cmd ATTRIBUTE_UNUSED)
push_context(ctxt);
the_source = add_srcfile(SRC_CMDLINE, arg->a_string, srcfiles, NULL,
NULL);
do_flags = false;
- ret = parse_program(&code);
+ ret = parse_program(&code, true);
do_flags = save_flags;
remove_params(this_func);
if (ret != 0) {
@@ -5783,7 +5783,7 @@ parse_condition(int type, int num, char *expr)
push_context(ctxt);
(void) add_srcfile(SRC_CMDLINE, expr, srcfiles, NULL, NULL);
do_flags = false;
- ret = parse_program(&code);
+ ret = parse_program(&code, true);
do_flags = save_flags;
remove_params(this_func);
pop_context();
diff --git a/eval.c b/eval.c
index aa78d3e6..4858fa69 100644
--- a/eval.c
+++ b/eval.c
@@ -325,6 +325,7 @@ static struct optypetab {
{ "Op_K_next", "next" },
{ "Op_K_exit", "exit" },
{ "Op_K_return", "return" },
+ { "Op_K_return_from_eval", "return" },
{ "Op_K_delete", "delete" },
{ "Op_K_delete_loop", NULL },
{ "Op_K_getline_redir", "getline" },
diff --git a/interpret.h b/interpret.h
index c16da88f..cc6e02af 100644
--- a/interpret.h
+++ b/interpret.h
@@ -1199,6 +1199,10 @@ match_re:
JUMPTO(ni); /* Op_func */
}
+ case Op_K_return_from_eval:
+ cant_happen();
+ break;
+
case Op_K_return:
m = POP_SCALAR(); /* return value */
diff --git a/main.c b/main.c
index d42d1f43..5800231c 100644
--- a/main.c
+++ b/main.c
@@ -465,7 +465,7 @@ main(int argc, char **argv)
setlocale(LC_NUMERIC, "C");
#endif
/* Read in the program */
- if (parse_program(& code_block) != 0 || dash_v_errs > 0)
+ if (parse_program(& code_block, false) != 0 || dash_v_errs > 0)
exit(EXIT_FAILURE);
if (do_intl)