From 99685d17a16d143b58c0201ef2b88e0033c56c05 Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Fri, 7 Dec 2007 23:58:44 +0000 Subject: [PATCH] --- ase/awk/run.c | 143 ++++++++++++++++++++++++++++-------- ase/configure | 6 +- ase/configure.ac | 2 +- ase/test/awk/Awk.cpp | 4 + ase/test/awk/main-001.awk | 5 ++ ase/test/awk/main-002.awk | 36 +++++++++ ase/test/awk/simple-001.awk | 18 +++++ ase/test/awk/simple-002.awk | 24 ++++++ ase/test/awk/simple-003.awk | 25 +++++++ ase/test/awk/simple-004.awk | 28 +++++++ ase/test/awk/simple-005.awk | 29 ++++++++ ase/test/awk/simple-006.awk | 34 +++++++++ 12 files changed, 319 insertions(+), 35 deletions(-) create mode 100644 ase/test/awk/main-001.awk create mode 100644 ase/test/awk/main-002.awk create mode 100644 ase/test/awk/simple-001.awk create mode 100644 ase/test/awk/simple-002.awk create mode 100644 ase/test/awk/simple-003.awk create mode 100644 ase/test/awk/simple-004.awk create mode 100644 ase/test/awk/simple-005.awk create mode 100644 ase/test/awk/simple-006.awk diff --git a/ase/awk/run.c b/ase/awk/run.c index a447f743..6a6004a6 100644 --- a/ase/awk/run.c +++ b/ase/awk/run.c @@ -171,11 +171,16 @@ static ase_awk_val_t* eval_incpre (ase_awk_run_t* run, ase_awk_nde_t* nde); static ase_awk_val_t* eval_incpst (ase_awk_run_t* run, ase_awk_nde_t* nde); static ase_awk_val_t* eval_cnd (ase_awk_run_t* run, ase_awk_nde_t* nde); +static ase_awk_val_t* eval_afn_intrinsic ( + ase_awk_run_t* run, ase_awk_nde_t* nde, + void(*errhandler)(void*), void* eharg); + static ase_awk_val_t* eval_bfn (ase_awk_run_t* run, ase_awk_nde_t* nde); static ase_awk_val_t* eval_afn (ase_awk_run_t* run, ase_awk_nde_t* nde); static ase_awk_val_t* eval_call ( ase_awk_run_t* run, ase_awk_nde_t* nde, - const ase_char_t* bfn_arg_spec, ase_awk_afn_t* afn); + const ase_char_t* bfn_arg_spec, ase_awk_afn_t* afn, + void(*errhandler)(void*), void* eharg); static int get_reference ( ase_awk_run_t* run, ase_awk_nde_t* nde, ase_awk_val_t*** ref); @@ -661,33 +666,20 @@ int ase_awk_run (ase_awk_t* awk, n = run_main (run, main, runarg); if (n == -1) { - if (run->errnum == ASE_AWK_ENOERR) + /* if no callback is specified, awk's error number + * is updated with the run's error number */ + if (runcbs == ASE_NULL) { - /* an error is returned with no error number set. - * this feature is used by eval_expression to - * abort the evaluation when exit() is executed - * during function evaluation */ - n = 0; - run->errlin = 0; - run->errmsg[0] = ASE_T('\0'); + awk->errnum = run->errnum; + awk->errlin = run->errlin; + + ase_strxcpy ( + awk->errmsg, ASE_COUNTOF(awk->errmsg), + run->errmsg); } else { - /* if no callback is specified, awk's error number - * is updated with the run's error number */ - if (runcbs == ASE_NULL) - { - awk->errnum = run->errnum; - awk->errlin = run->errlin; - - ase_strxcpy ( - awk->errmsg, ASE_COUNTOF(awk->errmsg), - run->errmsg); - } - else - { - ase_awk_seterrnum (awk, ASE_AWK_ERUNTIME); - } + ase_awk_seterrnum (awk, ASE_AWK_ERUNTIME); } } @@ -1188,6 +1180,21 @@ static int set_globals_to_default (ase_awk_run_t* run) return 0; } +struct capture_retval_data_t +{ + ase_awk_run_t* run; + ase_awk_val_t* val; +}; + +static void capture_retval_on_exit (void* arg) +{ + struct capture_retval_data_t* data; + + data = (struct capture_retval_data_t*)arg; + data->val = STACK_RETVAL(data->run); + ase_awk_refupval (data->run, data->val); +} + static int run_main ( ase_awk_run_t* run, const ase_char_t* main, ase_awk_runarg_t* runarg) @@ -1246,6 +1253,7 @@ static int run_main ( if (n == 0 && main != ASE_NULL) { /* run the given function */ + struct capture_retval_data_t crdata; ase_awk_nde_call_t nde; nde.type = ASE_AWK_NDE_AFN; @@ -1259,6 +1267,7 @@ static int run_main ( if (runarg != ASE_NULL) { + if (!(run->awk->option & ASE_AWK_ARGSTOMAIN)) { /* if the option is not set, the arguments @@ -1322,8 +1331,31 @@ static int run_main ( ASE_ASSERT (nrunargs == nde.nargs); } - v = eval_afn (run, (ase_awk_nde_t*)&nde); - if (v == ASE_NULL) n = -1; + crdata.run = run; + crdata.val = ASE_NULL; + v = eval_afn_intrinsic (run, (ase_awk_nde_t*)&nde, + capture_retval_on_exit, &crdata); + if (v == ASE_NULL) + { + if (crdata.val == ASE_NULL) + { + ASE_ASSERT (run->errnum != ASE_AWK_ENOERR); + n = -1; + } + else + { + if (run->errnum == ASE_AWK_ENOERR) + { + if (run->cbs != ASE_NULL && run->cbs->on_return != ASE_NULL) + { + run->cbs->on_return (run, crdata.val, run->cbs->custom_data); + } + } + else n = -1; + + ase_awk_refdownval(run, crdata.val); + } + } else { ase_awk_refupval (run, v); @@ -1411,6 +1443,17 @@ static int run_main ( if (run_block (run, blk) == -1) n = -1; } + if (n == -1 && run->errnum == ASE_AWK_ENOERR) + { + /* an error is returned with no error number set. + * this feature is used by eval_expression to + * abort the evaluation when exit() is executed + * during function evaluation */ + n = 0; + run->errlin = 0; + run->errmsg[0] = ASE_T('\0'); + } + if (n == 0 && (run->awk->tree.chain != ASE_NULL || run->awk->tree.end != ASE_NULL) && @@ -1419,6 +1462,17 @@ static int run_main ( if (run_pattern_blocks (run) == -1) n = -1; } + if (n == -1 && run->errnum == ASE_AWK_ENOERR) + { + /* an error is returned with no error number set. + * this feature is used by eval_expression to + * abort the evaluation when exit() is executed + * during function evaluation */ + n = 0; + run->errlin = 0; + run->errmsg[0] = ASE_T('\0'); + } + /* the first END block is executed if the program is not * explicitly aborted with ase_awk_stop */ for (nde = run->awk->tree.end; @@ -1441,6 +1495,17 @@ static int run_main ( } } + if (n == -1 && run->errnum == ASE_AWK_ENOERR) + { + /* an error is returned with no error number set. + * this feature is used by eval_expression to + * abort the evaluation when exit() is executed + * during function evaluation */ + n = 0; + run->errlin = 0; + run->errmsg[0] = ASE_T('\0'); + } + /* restore stack */ nargs = (ase_size_t)STACK_NARGS(run); ASE_ASSERT (nargs == 0); @@ -2949,7 +3014,7 @@ static ase_awk_val_t* eval_expression (ase_awk_run_t* run, ase_awk_nde_t* nde) if (run->exit_level >= EXIT_GLOBAL) { /* returns ASE_NULL as if an error occurred but - * clears the error number. ase_awk_run will + * clears the error number. run_main will * detect this condition and treat it as a * non-error condition.*/ run->errnum = ASE_AWK_ENOERR; @@ -5228,10 +5293,13 @@ static ase_awk_val_t* eval_bfn (ase_awk_run_t* run, ase_awk_nde_t* nde) return ASE_NULL; } - return eval_call (run, nde, call->what.bfn.arg.spec, ASE_NULL); + return eval_call ( + run, nde, call->what.bfn.arg.spec, + ASE_NULL, ASE_NULL, ASE_NULL); } -static ase_awk_val_t* eval_afn (ase_awk_run_t* run, ase_awk_nde_t* nde) +static ase_awk_val_t* eval_afn_intrinsic ( + ase_awk_run_t* run, ase_awk_nde_t* nde, void(*errhandler)(void*), void* eharg) { ase_awk_nde_call_t* call = (ase_awk_nde_call_t*)nde; ase_awk_afn_t* afn; @@ -5263,9 +5331,13 @@ static ase_awk_val_t* eval_afn (ase_awk_run_t* run, ase_awk_nde_t* nde) return ASE_NULL; } - return eval_call (run, nde, ASE_NULL, afn); + return eval_call (run, nde, ASE_NULL, afn, errhandler, eharg); } +static ase_awk_val_t* eval_afn (ase_awk_run_t* run, ase_awk_nde_t* nde) +{ + return eval_afn_intrinsic (run, nde, ASE_NULL, ASE_NULL); +} /* run->stack_base has not been set for this * stack frame. so the STACK_ARG macro cannot be used as in @@ -5288,7 +5360,8 @@ static ase_awk_val_t* eval_afn (ase_awk_run_t* run, ase_awk_nde_t* nde) static ase_awk_val_t* eval_call ( ase_awk_run_t* run, ase_awk_nde_t* nde, - const ase_char_t* bfn_arg_spec, ase_awk_afn_t* afn) + const ase_char_t* bfn_arg_spec, ase_awk_afn_t* afn, + void(*errhandler)(void*), void* eharg) { ase_awk_nde_call_t* call = (ase_awk_nde_call_t*)nde; ase_size_t saved_stack_top; @@ -5539,6 +5612,14 @@ static ase_awk_val_t* eval_call ( v = STACK_RETVAL(run); if (n == -1) { + if (errhandler != ASE_NULL) + { + /* capture_retval_on_exit takes advantage of + * this handler to retrieve the return value + * when exit() is used to terminate the program. */ + errhandler (eharg); + } + /* if the earlier operations failed and this function * has to return a error, the return value is just * destroyed and replaced by nil */ diff --git a/ase/configure b/ase/configure index 4dd82962..8cf980bf 100755 --- a/ase/configure +++ b/ase/configure @@ -25712,9 +25712,9 @@ _ACEOF fi -# Check whether --enable-mode or --disable-mode was given. -if test "${enable_mode+set}" = set; then - enableval="$enable_mode" +# Check whether --enable-debug or --disable-debug was given. +if test "${enable_debug+set}" = set; then + enableval="$enable_debug" enable_debug_is=$enableval else enable_debug_is=no diff --git a/ase/configure.ac b/ase/configure.ac index 8ae4d31f..5378334d 100644 --- a/ase/configure.ac +++ b/ase/configure.ac @@ -99,7 +99,7 @@ else AC_DEFINE([ASE_CHAR_IS_MCHAR],[],[char is mchar]) fi -AC_ARG_ENABLE([mode], [AC_HELP_STRING([--enable-debug], +AC_ARG_ENABLE([debug], [AC_HELP_STRING([--enable-debug], [build the library in the debug mode (default. no)])], enable_debug_is=$enableval,enable_debug_is=no) if test "$enable_debug_is" = "yes" diff --git a/ase/test/awk/Awk.cpp b/ase/test/awk/Awk.cpp index a15acb4a..0a179fbb 100644 --- a/ase/test/awk/Awk.cpp +++ b/ase/test/awk/Awk.cpp @@ -21,6 +21,10 @@ #include #endif +#if defined(__linux) && defined(_DEBUG) +#include +#endif + class TestAwk: public ASE::StdAwk { public: diff --git a/ase/test/awk/main-001.awk b/ase/test/awk/main-001.awk new file mode 100644 index 00000000..6e486411 --- /dev/null +++ b/ase/test/awk/main-001.awk @@ -0,0 +1,5 @@ +function main() { + x = 0; + y = 0; + return 999; +} diff --git a/ase/test/awk/main-002.awk b/ase/test/awk/main-002.awk new file mode 100644 index 00000000..f729fd84 --- /dev/null +++ b/ase/test/awk/main-002.awk @@ -0,0 +1,36 @@ + + function error() { exit (200); } + function getx() + { + if (x == 2) error(); + return x++; + } + + function gety() { return y++; } + + function main() { + x = 0; + y = 0; + print getx() + gety(); + print getx() + gety(); + print getx() + gety(); + print getx() + gety(); + + return 999; + } + + + END { + print "END OF PROGRAM"; + return 10; + } + + END { + print "END OF PROGRAM 2"; + exit (100); + } + + END { + print "END OF PROGRAM 3"; + exit (900); + } diff --git a/ase/test/awk/simple-001.awk b/ase/test/awk/simple-001.awk new file mode 100644 index 00000000..87e95027 --- /dev/null +++ b/ase/test/awk/simple-001.awk @@ -0,0 +1,18 @@ + + function error() { exit (200); } + function getx() + { + if (x == 2) error(); + return x++; + } + + function gety() { return y++; } + + BEGIN { + x = 0; + y = 0; + print getx() + gety(); + print getx() + gety(); + print getx() + gety(); + print getx() + gety(); + } diff --git a/ase/test/awk/simple-002.awk b/ase/test/awk/simple-002.awk new file mode 100644 index 00000000..4d3ae5b5 --- /dev/null +++ b/ase/test/awk/simple-002.awk @@ -0,0 +1,24 @@ + + function error() { exit (200); } + function getx() + { + if (x == 2) error(); + return x++; + } + + function gety() { return y++; } + + BEGIN { + x = 0; + y = 0; + print getx() + gety(); + print getx() + gety(); + print getx() + gety(); + print getx() + gety(); + } + + + END { + print "END OF PROGRAM"; + } + diff --git a/ase/test/awk/simple-003.awk b/ase/test/awk/simple-003.awk new file mode 100644 index 00000000..26bdb0fe --- /dev/null +++ b/ase/test/awk/simple-003.awk @@ -0,0 +1,25 @@ + + function error() { exit (200); } + function getx() + { + if (x == 2) error(); + return x++; + } + + function gety() { return y++; } + + BEGIN { + x = 0; + y = 0; + print getx() + gety(); + print getx() + gety(); + print getx() + gety(); + print getx() + gety(); + } + + + END { + print "END OF PROGRAM"; + exit (20); + } + diff --git a/ase/test/awk/simple-004.awk b/ase/test/awk/simple-004.awk new file mode 100644 index 00000000..01785f00 --- /dev/null +++ b/ase/test/awk/simple-004.awk @@ -0,0 +1,28 @@ + + function error() { exit (200); } + function getx() + { + if (x == 2) error(); + return x++; + } + + function gety() { return y++; } + + BEGIN { + x = 0; + y = 0; + print getx() + gety(); + print getx() + gety(); + print getx() + gety(); + print getx() + gety(); + } + + + END { + print "END OF PROGRAM"; + exit (20); + } + + END { + print "END OF PROGRAM 2"; + } diff --git a/ase/test/awk/simple-005.awk b/ase/test/awk/simple-005.awk new file mode 100644 index 00000000..cfda77dd --- /dev/null +++ b/ase/test/awk/simple-005.awk @@ -0,0 +1,29 @@ + + function error() { exit (200); } + function getx() + { + if (x == 2) error(); + return x++; + } + + function gety() { return y++; } + + BEGIN { + x = 0; + y = 0; + print getx() + gety(); + print getx() + gety(); + print getx() + gety(); + print getx() + gety(); + } + + + END { + print "END OF PROGRAM"; + return 10; + } + + END { + print "END OF PROGRAM 2"; + return 20; + } diff --git a/ase/test/awk/simple-006.awk b/ase/test/awk/simple-006.awk new file mode 100644 index 00000000..432070b8 --- /dev/null +++ b/ase/test/awk/simple-006.awk @@ -0,0 +1,34 @@ + + function error() { exit (200); } + function getx() + { + if (x == 2) error(); + return x++; + } + + function gety() { return y++; } + + BEGIN { + x = 0; + y = 0; + print getx() + gety(); + print getx() + gety(); + print getx() + gety(); + print getx() + gety(); + } + + + END { + print "END OF PROGRAM"; + return 10; + } + + END { + print "END OF PROGRAM 2"; + exit (100); + } + + END { + print "END OF PROGRAM 3"; + exit (900); + }