This commit is contained in:
hyung-hwan 2007-12-07 23:58:44 +00:00
parent 742f92043b
commit 99685d17a1
12 changed files with 319 additions and 35 deletions

View File

@ -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_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_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_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_afn (ase_awk_run_t* run, ase_awk_nde_t* nde);
static ase_awk_val_t* eval_call ( static ase_awk_val_t* eval_call (
ase_awk_run_t* run, ase_awk_nde_t* nde, 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 ( static int get_reference (
ase_awk_run_t* run, ase_awk_nde_t* nde, ase_awk_val_t*** ref); 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); n = run_main (run, main, runarg);
if (n == -1) 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. awk->errnum = run->errnum;
* this feature is used by eval_expression to awk->errlin = run->errlin;
* abort the evaluation when exit() is executed
* during function evaluation */ ase_strxcpy (
n = 0; awk->errmsg, ASE_COUNTOF(awk->errmsg),
run->errlin = 0; run->errmsg);
run->errmsg[0] = ASE_T('\0');
} }
else else
{ {
/* if no callback is specified, awk's error number ase_awk_seterrnum (awk, ASE_AWK_ERUNTIME);
* 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);
}
} }
} }
@ -1188,6 +1180,21 @@ static int set_globals_to_default (ase_awk_run_t* run)
return 0; 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 ( static int run_main (
ase_awk_run_t* run, const ase_char_t* main, ase_awk_run_t* run, const ase_char_t* main,
ase_awk_runarg_t* runarg) ase_awk_runarg_t* runarg)
@ -1246,6 +1253,7 @@ static int run_main (
if (n == 0 && main != ASE_NULL) if (n == 0 && main != ASE_NULL)
{ {
/* run the given function */ /* run the given function */
struct capture_retval_data_t crdata;
ase_awk_nde_call_t nde; ase_awk_nde_call_t nde;
nde.type = ASE_AWK_NDE_AFN; nde.type = ASE_AWK_NDE_AFN;
@ -1259,6 +1267,7 @@ static int run_main (
if (runarg != ASE_NULL) if (runarg != ASE_NULL)
{ {
if (!(run->awk->option & ASE_AWK_ARGSTOMAIN)) if (!(run->awk->option & ASE_AWK_ARGSTOMAIN))
{ {
/* if the option is not set, the arguments /* if the option is not set, the arguments
@ -1322,8 +1331,31 @@ static int run_main (
ASE_ASSERT (nrunargs == nde.nargs); ASE_ASSERT (nrunargs == nde.nargs);
} }
v = eval_afn (run, (ase_awk_nde_t*)&nde); crdata.run = run;
if (v == ASE_NULL) n = -1; 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 else
{ {
ase_awk_refupval (run, v); ase_awk_refupval (run, v);
@ -1411,6 +1443,17 @@ static int run_main (
if (run_block (run, blk) == -1) n = -1; 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 && if (n == 0 &&
(run->awk->tree.chain != ASE_NULL || (run->awk->tree.chain != ASE_NULL ||
run->awk->tree.end != 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 (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 /* the first END block is executed if the program is not
* explicitly aborted with ase_awk_stop */ * explicitly aborted with ase_awk_stop */
for (nde = run->awk->tree.end; 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 */ /* restore stack */
nargs = (ase_size_t)STACK_NARGS(run); nargs = (ase_size_t)STACK_NARGS(run);
ASE_ASSERT (nargs == 0); 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) if (run->exit_level >= EXIT_GLOBAL)
{ {
/* returns ASE_NULL as if an error occurred but /* 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 * detect this condition and treat it as a
* non-error condition.*/ * non-error condition.*/
run->errnum = ASE_AWK_ENOERR; 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 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_nde_call_t* call = (ase_awk_nde_call_t*)nde;
ase_awk_afn_t* afn; 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 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 /* run->stack_base has not been set for this
* stack frame. so the STACK_ARG macro cannot be used as in * 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 ( static ase_awk_val_t* eval_call (
ase_awk_run_t* run, ase_awk_nde_t* nde, 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_awk_nde_call_t* call = (ase_awk_nde_call_t*)nde;
ase_size_t saved_stack_top; ase_size_t saved_stack_top;
@ -5539,6 +5612,14 @@ static ase_awk_val_t* eval_call (
v = STACK_RETVAL(run); v = STACK_RETVAL(run);
if (n == -1) 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 /* if the earlier operations failed and this function
* has to return a error, the return value is just * has to return a error, the return value is just
* destroyed and replaced by nil */ * destroyed and replaced by nil */

6
ase/configure vendored
View File

@ -25712,9 +25712,9 @@ _ACEOF
fi fi
# Check whether --enable-mode or --disable-mode was given. # Check whether --enable-debug or --disable-debug was given.
if test "${enable_mode+set}" = set; then if test "${enable_debug+set}" = set; then
enableval="$enable_mode" enableval="$enable_debug"
enable_debug_is=$enableval enable_debug_is=$enableval
else else
enable_debug_is=no enable_debug_is=no

View File

@ -99,7 +99,7 @@ else
AC_DEFINE([ASE_CHAR_IS_MCHAR],[],[char is mchar]) AC_DEFINE([ASE_CHAR_IS_MCHAR],[],[char is mchar])
fi 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)])], [build the library in the debug mode (default. no)])],
enable_debug_is=$enableval,enable_debug_is=no) enable_debug_is=$enableval,enable_debug_is=no)
if test "$enable_debug_is" = "yes" if test "$enable_debug_is" = "yes"

View File

@ -21,6 +21,10 @@
#include <crtdbg.h> #include <crtdbg.h>
#endif #endif
#if defined(__linux) && defined(_DEBUG)
#include <mcheck.h>
#endif
class TestAwk: public ASE::StdAwk class TestAwk: public ASE::StdAwk
{ {
public: public:

View File

@ -0,0 +1,5 @@
function main() {
x = 0;
y = 0;
return 999;
}

36
ase/test/awk/main-002.awk Normal file
View File

@ -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);
}

View File

@ -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();
}

View File

@ -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";
}

View File

@ -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);
}

View File

@ -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";
}

View File

@ -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;
}

View File

@ -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);
}