From 79beb0e53183ed1137ce7b737fbf94c737beb23b Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Wed, 11 Oct 2006 03:19:08 +0000 Subject: [PATCH] *** empty log message *** --- ase/awk/func.c | 15 +++++---- ase/awk/run.c | 73 +++++++++++++++++++++++++++++++++++--------- ase/test/awk/arg.awk | 4 +++ ase/test/awk/awk.c | 8 +++-- 4 files changed, 77 insertions(+), 23 deletions(-) diff --git a/ase/awk/func.c b/ase/awk/func.c index 186332f3..b03831bf 100644 --- a/ase/awk/func.c +++ b/ase/awk/func.c @@ -1,5 +1,5 @@ /* - * $Id: func.c,v 1.59 2006-10-10 14:08:55 bacon Exp $ + * $Id: func.c,v 1.60 2006-10-11 03:18:28 bacon Exp $ */ #include @@ -702,10 +702,18 @@ static int __bfn_split (xp_awk_run_t* run) num, 10, XP_NULL, key, xp_countof(key)); xp_assert (key_len != (xp_size_t)-1); + /* don't forget to update the reference count when you + * handle the assignment-like situation. anyway, it is + * incremented in advance as if the assignment was successful. + * it is decremented if the assignement fails. */ + xp_awk_refupval (t2); + if (xp_awk_map_putx ( ((xp_awk_val_map_t*)t1)->map, key, key_len, t2, XP_NULL) == -1) { + xp_awk_refdownval (run, t2); + if (str_free != XP_NULL) XP_AWK_FREE (run->awk, str_free); if (fs_free != XP_NULL) @@ -716,11 +724,6 @@ static int __bfn_split (xp_awk_run_t* run) return -1; } - /* don't forget to update the reference count - * when you handle the assignment-like situation - * with the internal data structures */ - xp_awk_refupval (t2); - num++; str_len = str_left - (p - str); } diff --git a/ase/awk/run.c b/ase/awk/run.c index be3279be..167261ba 100644 --- a/ase/awk/run.c +++ b/ase/awk/run.c @@ -1,5 +1,5 @@ /* - * $Id: run.c,v 1.230 2006-10-10 14:08:55 bacon Exp $ + * $Id: run.c,v 1.231 2006-10-11 03:18:29 bacon Exp $ */ #include @@ -60,7 +60,7 @@ static int __init_run ( static void __deinit_run (xp_awk_run_t* run); static int __build_runarg (xp_awk_run_t* run, xp_awk_runarg_t* runarg); -static int __run_main (xp_awk_run_t* run); +static int __run_main (xp_awk_run_t* run, xp_awk_runarg_t* runarg); static int __run_pattern_blocks (xp_awk_run_t* run); static int __run_pattern_block_chain ( xp_awk_run_t* run, xp_awk_chain_t* chain); @@ -233,7 +233,7 @@ int xp_awk_setglobal (xp_awk_run_t* run, xp_size_t idx, xp_awk_val_t* val) /* TODO: is this correct?? */ if (val->type == XP_AWK_VAL_MAP && - (idx >= XP_AWK_GLOBAL_ARGC && idx <= XP_AWK_GLOBAL_SUBSEP) && + (idx >= XP_AWK_GLOBAL_ARGC && idx <= XP_AWK_GLOBAL_SUBSEP) && idx != XP_AWK_GLOBAL_ARGV) { /* TODO: better error code */ @@ -467,13 +467,7 @@ int xp_awk_run (xp_awk_t* awk, runcbs->on_start (awk, run, runcbs->custom_data); } - if (runarg != XP_NULL && __build_runarg (run, runarg) == -1) - { -/*TODO: cleanup. error handling */ - return -1; - } - - n = __run_main (run); + n = __run_main (run, runarg); if (n == -1) { /* if no callback is specified, awk's error number @@ -760,6 +754,9 @@ static int __build_runarg (xp_awk_run_t* run, xp_awk_runarg_t* runarg) xp_size_t argc; xp_awk_val_t* v_argc; xp_awk_val_t* v_argv; + xp_awk_val_t* v_tmp; + xp_char_t key[xp_sizeof(xp_long_t)*8+2]; + xp_size_t key_len; v_argv = xp_awk_makemapval (run); if (v_argv == XP_NULL) @@ -771,10 +768,38 @@ static int __build_runarg (xp_awk_run_t* run, xp_awk_runarg_t* runarg) for (argc = 0, p = runarg; p->ptr != XP_NULL; argc++, p++) { - xp_printf (XP_T("ptr = %s, len = %d\n"), p->ptr, p->len); -/* TODO: create values */ + v_tmp = xp_awk_makestrval (run, p->ptr, p->len); + if (v_tmp == XP_NULL) + { + xp_awk_refdownval (run, v_argv); + run->errnum = XP_AWK_ENOMEM; + return -1; + } + + key_len = xp_awk_longtostr ( + argc, 10, XP_NULL, key, xp_countof(key)); + xp_assert (key_len != (xp_size_t)-1); + + /* increment reference count of v_tmp in advance as if + * it has successfully been assigned into the ARGV map */ + xp_awk_refupval (v_tmp); + + if (xp_awk_map_putx ( + ((xp_awk_val_map_t*)v_argv)->map, + key, key_len, v_tmp, XP_NULL) == -1) + { + /* if the assignment operation fails, decrements + * the reference of v_tmp to free it */ + xp_awk_refdownval (run, v_tmp); + + /* the other values previously assigned into the map + * will be freeed when v_argv is freed */ + xp_awk_refdownval (run, v_argv); + + run->errnum = XP_AWK_ENOMEM; + return -1; + } } -xp_printf (XP_T("argc = %d\n"), argc); v_argc = xp_awk_makeintval (run, (xp_long_t)argc); if (v_argc == XP_NULL) @@ -786,6 +811,8 @@ xp_printf (XP_T("argc = %d\n"), argc); xp_awk_refupval (v_argc); + xp_assert (STACK_GLOBAL(run,XP_AWK_GLOBAL_ARGC) == xp_awk_val_nil); + if (xp_awk_setglobal (run, XP_AWK_GLOBAL_ARGC, v_argc) == -1) { xp_awk_refdownval (run, v_argc); @@ -795,6 +822,13 @@ xp_printf (XP_T("argc = %d\n"), argc); if (xp_awk_setglobal (run, XP_AWK_GLOBAL_ARGV, v_argv) == -1) { + /* ARGC is assigned nil when ARGV assignment has failed. + * However, this requires preconditions, as follows: + * 1. __build_runarg should be called in a proper place + * as it is not a generic-purpose routine. + * 2. ARGC should be nil before __build_runarg is called + * If the restoration fails, nothing can salvage it. */ + xp_awk_setglobal (run, XP_AWK_GLOBAL_ARGC, xp_awk_val_nil); xp_awk_refdownval (run, v_argc); xp_awk_refdownval (run, v_argv); return -1; @@ -805,7 +839,7 @@ xp_printf (XP_T("argc = %d\n"), argc); return 0; } -static int __run_main (xp_awk_run_t* run) +static int __run_main (xp_awk_run_t* run, xp_awk_runarg_t* runarg) { xp_size_t nglobals, nargs, i; xp_size_t saved_stack_top; @@ -849,6 +883,17 @@ static int __run_main (xp_awk_run_t* run) run->stack_top = saved_stack_top; return -1; } + + if (runarg != XP_NULL && __build_runarg (run, runarg) == -1) + { + /* it can simply restore the top of the stack this way + * because the values pused onto the stack so far are + * all xp_awk_val_nils and xp_awk_val_zeros and + * __build_runarg doesn't push other values than them + * when it has failed */ + run->stack_top = saved_stack_top; + return -1; + } run->exit_level = EXIT_NONE; diff --git a/ase/test/awk/arg.awk b/ase/test/awk/arg.awk index 6713c771..2dee13ed 100644 --- a/ase/test/awk/arg.awk +++ b/ase/test/awk/arg.awk @@ -1,3 +1,7 @@ BEGIN { print "ARGC=", ARGC; + for (i in ARGV) + { + print "ARGV[" i "]", ARGV[i]; + } } diff --git a/ase/test/awk/awk.c b/ase/test/awk/awk.c index 119d5890..0b2ead65 100644 --- a/ase/test/awk/awk.c +++ b/ase/test/awk/awk.c @@ -1,5 +1,5 @@ /* - * $Id: awk.c,v 1.93 2006-10-10 14:09:23 bacon Exp $ + * $Id: awk.c,v 1.94 2006-10-11 03:19:08 bacon Exp $ */ #include @@ -741,8 +741,10 @@ static int __main (int argc, xp_char_t* argv[]) runarg[0].ptr = XP_T("argument 0"); runarg[0].len = xp_awk_strlen(runarg[0].ptr); - runarg[1].ptr = XP_NULL; - runarg[1].len = 0; + runarg[1].ptr = XP_T("argumetn 1"); + runarg[1].len = xp_awk_strlen(runarg[1].ptr); + runarg[2].ptr = XP_NULL; + runarg[2].len = 0; if (xp_awk_run (awk, &runios, &runcbs, runarg) == -1) {