diff --git a/ase/awk/parse.c b/ase/awk/parse.c index 7e826c56..0dfb1147 100644 --- a/ase/awk/parse.c +++ b/ase/awk/parse.c @@ -1,5 +1,5 @@ /* - * $Id: parse.c,v 1.145 2006-07-30 15:53:42 bacon Exp $ + * $Id: parse.c,v 1.146 2006-08-01 04:36:32 bacon Exp $ */ #include @@ -167,8 +167,11 @@ static xp_awk_nde_t* __parse_printf (xp_awk_t* awk); static int __get_token (xp_awk_t* awk); static int __get_number (xp_awk_t* awk); -static int __get_string (xp_awk_t* awk); -static int __get_regex (xp_awk_t* awk); +static int __get_charstr (xp_awk_t* awk); +static int __get_rexstr (xp_awk_t* awk); +static int __get_string ( + xp_awk_t* awk, xp_char_t end_char, + xp_char_t esc_char, xp_bool_t keep_esc_char); static int __get_char (xp_awk_t* awk); static int __unget_char (xp_awk_t* awk, xp_cint_t c); static int __skip_spaces (xp_awk_t* awk); @@ -1910,7 +1913,7 @@ static xp_awk_nde_t* __parse_primary (xp_awk_t* awk) /* the regular expression is tokenized here because * of the context-sensitivity of the slash symbol */ SET_TOKEN_TYPE (awk, TOKEN_REX); - if (__get_regex(awk) == -1) return XP_NULL; + if (__get_rexstr (awk) == -1) return XP_NULL; xp_assert (MATCH(awk,TOKEN_REX)); nde = (xp_awk_nde_rex_t*) @@ -3110,7 +3113,7 @@ static int __get_token (xp_awk_t* awk) { SET_TOKEN_TYPE (awk, TOKEN_STR); - if (__get_string(awk) == -1) return -1; + if (__get_charstr(awk) == -1) return -1; while (awk->opt.parse & XP_AWK_STRCONCAT) { @@ -3124,7 +3127,7 @@ static int __get_token (xp_awk_t* awk) c = awk->lex.curc; if (c != XP_T('\"')) break; - if (__get_string(awk) == -1) return -1; + if (__get_charstr(awk) == -1) return -1; } } @@ -3536,7 +3539,19 @@ static int __get_number (xp_awk_t* awk) return 0; } -static int __get_string (xp_awk_t* awk) +static int __get_charstr (xp_awk_t* awk) +{ + return __get_string (awk, XP_T('\"'), XP_T('\\'), xp_false); +} + +static int __get_rexstr (xp_awk_t* awk) +{ + return __get_string (awk, XP_T('/'), XP_T('\\'), xp_true); +} + +static int __get_string ( + xp_awk_t* awk, xp_char_t end_char, + xp_char_t esc_char, xp_bool_t keep_esc_char) { xp_cint_t c; int escaped = 0; @@ -3621,14 +3636,14 @@ static int __get_string (xp_awk_t* awk) } } - if (escaped == 0 && c == XP_T('\"')) + if (escaped == 0 && c == end_char) { /* terminating quote */ GET_CHAR_TO (awk, c); break; } - if (escaped == 0 && c == XP_T('\\')) + if (escaped == 0 && c == esc_char) { escaped = 1; continue; @@ -3673,6 +3688,10 @@ static int __get_string (xp_awk_t* awk) continue; } #endif + else if (keep_esc_char) + { + ADD_TOKEN_CHAR (awk, esc_char); + } escaped = 0; } @@ -3683,45 +3702,6 @@ static int __get_string (xp_awk_t* awk) return 0; } -static int __get_regex (xp_awk_t* awk) -{ - /* TODO: do proper regular expression parsing */ - /* TODO: think if the new line should be allowed to - * be included in to a regular expression */ - xp_cint_t c; - xp_bool_t escaped = xp_false; - - GET_CHAR_TO (awk, c); - while (1) - { - if (c == XP_CHAR_EOF) - { - awk->errnum = XP_AWK_EENDREX; - return -1; - } - - if (escaped == xp_false && c == XP_T('/')) - { - GET_CHAR_TO (awk, c); - break; - } - - if (escaped == xp_false && c == XP_T('\\')) - { - GET_CHAR_TO (awk, c); - escaped = xp_true; - continue; - } - - if (escaped == xp_true) escaped = xp_false; - - ADD_TOKEN_CHAR (awk, c); - GET_CHAR_TO (awk, c); - } - - return 0; -} - static int __get_char (xp_awk_t* awk) { xp_ssize_t n; diff --git a/ase/awk/run.c b/ase/awk/run.c index d3e3053b..2e55e789 100644 --- a/ase/awk/run.c +++ b/ase/awk/run.c @@ -1,5 +1,5 @@ /* - * $Id: run.c,v 1.146 2006-07-31 15:59:42 bacon Exp $ + * $Id: run.c,v 1.147 2006-08-01 04:36:32 bacon Exp $ */ #include @@ -39,13 +39,13 @@ enum #define PANIC(run,code) \ do { (run)->errnum = (code); return XP_NULL; } while (0) -#define PANIC2(awk,code,subcode) \ - do { (awk)->errnum = (code); (awk)->suberrnum = (subcode); return XP_NULL; } while (0) +#define PANIC2(run,code,subcode) \ + do { (run)->errnum = (code); (run)->suberrnum = (subcode); return XP_NULL; } while (0) #define PANIC_I(run,code) \ do { (run)->errnum = (code); return -1; } while (0) #define PANIC2_I(awk,code,subcode) \ - do { (awk)->errnum = (code); (awk)->suberrnum = (subcode); return -1; } while (0) + do { (run)->errnum = (code); (run)->suberrnum = (subcode); return -1; } while (0) static int __open_run (xp_awk_run_t* run, xp_awk_t* awk); static void __close_run (xp_awk_run_t* run); @@ -130,12 +130,10 @@ static xp_awk_val_t* __eval_binop_concat ( xp_awk_run_t* run, xp_awk_val_t* left, xp_awk_val_t* right); static xp_awk_val_t* __eval_binop_ma ( xp_awk_run_t* run, xp_awk_nde_t* left, xp_awk_nde_t* right); -static xp_awk_val_t* __eval_binop_ma0 ( - xp_awk_run_t* run, xp_awk_val_t* left, xp_awk_val_t* right); static xp_awk_val_t* __eval_binop_nm ( xp_awk_run_t* run, xp_awk_nde_t* left, xp_awk_nde_t* right); -static xp_awk_val_t* __eval_binop_nm0 ( - xp_awk_run_t* run, xp_awk_val_t* left, xp_awk_val_t* right); +static xp_awk_val_t* __eval_binop_match0 ( + xp_awk_run_t* run, xp_awk_val_t* left, xp_awk_val_t* right, int ret); static xp_awk_val_t* __eval_unary (xp_awk_run_t* run, xp_awk_nde_t* nde); static xp_awk_val_t* __eval_incpre (xp_awk_run_t* run, xp_awk_nde_t* nde); @@ -238,12 +236,17 @@ int xp_awk_run (xp_awk_t* awk) { /* TODO: find a way to set the errnum into awk object in a thread-safe way */ awk->errnum = run->errnum; + awk->suberrnum = run->suberrnum; xp_free (run); return -1; } n = __run_main (run); - if (n == -1) awk->errnum = run->errnum; + if (n == -1) + { + awk->errnum = run->errnum; + awk->suberrnum = run->suberrnum; + } __close_run (run); xp_free (run); @@ -272,6 +275,7 @@ static int __open_run (xp_awk_run_t* run, xp_awk_t* awk) run->opt = awk->opt.run; run->errnum = XP_AWK_ENOERR; + run->suberrnum = XP_AWK_ENOERR; /*run->tree = &awk->tree; */ /*run->nglobals = awk->tree.nglobals;*/ run->awk = awk; @@ -2829,7 +2833,7 @@ static xp_awk_val_t* __eval_binop_ma ( xp_awk_refupval (rv); - res = __eval_binop_ma0 (run, lv, rv); + res = __eval_binop_match0 (run, lv, rv, 1); xp_awk_refdownval (run, lv); xp_awk_refdownval (run, rv); @@ -2837,60 +2841,6 @@ static xp_awk_val_t* __eval_binop_ma ( return res; } -static xp_awk_val_t* __eval_binop_ma0 ( - xp_awk_run_t* run, xp_awk_val_t* left, xp_awk_val_t* right) -{ - xp_awk_val_t* res; - int n, errnum; - xp_char_t* str; - xp_size_t len; - - if (right->type == XP_AWK_VAL_REX) - { - if (left->type == XP_AWK_VAL_STR) - { - n = xp_awk_matchrex ( - ((xp_awk_val_rex_t*)right)->code, - ((xp_awk_val_str_t*)left)->buf, - ((xp_awk_val_str_t*)left)->len, - XP_NULL, XP_NULL, &errnum); - if (n == -1) PANIC2 (run, XP_AWK_EREXMATCH, errnum); - - res = xp_awk_makeintval (run, (n != 0)); - if (res == XP_NULL) PANIC (run, XP_AWK_ENOMEM); - } - else - { - str = xp_awk_valtostr (right, &errnum, XP_NULL, &len); - if (str == XP_NULL) PANIC (run, errnum); - - n = xp_awk_matchrex ( - ((xp_awk_val_rex_t*)right)->code, - str, len, XP_NULL, XP_NULL, &errnum); - if (n == -1) - { - xp_free (str); - PANIC2 (run, XP_AWK_EREXMATCH, errnum); - } - - res = xp_awk_makeintval (run, (n != 0)); - if (res == XP_NULL) - { - xp_free (str); - PANIC (run, XP_AWK_ENOMEM); - } - - xp_free (str); - } - - return res; - } - -/* TODO: implement the pattern matching operation properly */ - PANIC (run, XP_AWK_EOPERAND); - return XP_NULL; -} - static xp_awk_val_t* __eval_binop_nm ( xp_awk_run_t* run, xp_awk_nde_t* left, xp_awk_nde_t* right) { @@ -2912,7 +2862,7 @@ static xp_awk_val_t* __eval_binop_nm ( xp_awk_refupval (rv); - res = __eval_binop_nm0 (run, lv, rv); + res = __eval_binop_match0 (run, lv, rv, 0); xp_awk_refdownval (run, lv); xp_awk_refdownval (run, rv); @@ -2920,58 +2870,93 @@ static xp_awk_val_t* __eval_binop_nm ( return res; } -static xp_awk_val_t* __eval_binop_nm0 ( - xp_awk_run_t* run, xp_awk_val_t* left, xp_awk_val_t* right) +static xp_awk_val_t* __eval_binop_match0 ( + xp_awk_run_t* run, xp_awk_val_t* left, xp_awk_val_t* right, int ret) { xp_awk_val_t* res; int n, errnum; xp_char_t* str; xp_size_t len; + void* rex_code; if (right->type == XP_AWK_VAL_REX) { - if (left->type == XP_AWK_VAL_STR) + rex_code = ((xp_awk_val_rex_t*)right)->code; + } + else if (right->type == XP_AWK_VAL_STR) + { + rex_code = xp_awk_buildrex ( + ((xp_awk_val_str_t*)right)->buf, + ((xp_awk_val_str_t*)right)->len, &errnum); + if (rex_code == XP_NULL) + PANIC2 (run, XP_AWK_EREXBUILD, errnum); + } + else + { + str = xp_awk_valtostr (right, &errnum, XP_NULL, &len); + if (str == XP_NULL) PANIC (run, errnum); + + rex_code = xp_awk_buildrex (str, len, &errnum); + if (rex_code == XP_NULL) { - n = xp_awk_matchrex ( - ((xp_awk_val_rex_t*)right)->code, - ((xp_awk_val_str_t*)left)->buf, - ((xp_awk_val_str_t*)left)->len, - XP_NULL, XP_NULL, &errnum); - if (n == -1) PANIC2 (run, XP_AWK_EREXMATCH, errnum); - - res = xp_awk_makeintval (run, (n == 0)); - if (res == XP_NULL) PANIC (run, XP_AWK_ENOMEM); - } - else - { - str = xp_awk_valtostr (right, &errnum, XP_NULL, &len); - if (str == XP_NULL) PANIC (run, errnum); - - n = xp_awk_matchrex ( - ((xp_awk_val_rex_t*)right)->code, - str, len, XP_NULL, XP_NULL, &errnum); - if (n == -1) - { - xp_free (str); - PANIC2 (run, XP_AWK_EREXMATCH, errnum); - } - - res = xp_awk_makeintval (run, (n == 0)); - if (res == XP_NULL) - { - xp_free (str); - PANIC (run, XP_AWK_ENOMEM); - } - xp_free (str); + PANIC2 (run, XP_AWK_EREXBUILD, errnum); } - return res; + xp_free (str); } -/* TODO: implement the pattern matching operation properly */ - PANIC (run, XP_AWK_EOPERAND); - return XP_NULL; + if (left->type == XP_AWK_VAL_STR) + { + n = xp_awk_matchrex ( + rex_code, + ((xp_awk_val_str_t*)left)->buf, + ((xp_awk_val_str_t*)left)->len, + XP_NULL, XP_NULL, &errnum); + if (n == -1) + { + if (right->type != XP_AWK_VAL_REX) xp_free (rex_code); + PANIC2 (run, XP_AWK_EREXMATCH, errnum); + } + + res = xp_awk_makeintval (run, (n == ret)); + if (res == XP_NULL) + { + if (right->type != XP_AWK_VAL_REX) xp_free (rex_code); + PANIC (run, XP_AWK_ENOMEM); + } + } + else + { + str = xp_awk_valtostr (right, &errnum, XP_NULL, &len); + if (str == XP_NULL) + { + if (right->type != XP_AWK_VAL_REX) xp_free (rex_code); + PANIC (run, errnum); + } + + n = xp_awk_matchrex ( + rex_code, str, len, XP_NULL, XP_NULL, &errnum); + if (n == -1) + { + xp_free (str); + if (right->type != XP_AWK_VAL_REX) xp_free (rex_code); + PANIC2 (run, XP_AWK_EREXMATCH, errnum); + } + + res = xp_awk_makeintval (run, (n == ret)); + if (res == XP_NULL) + { + xp_free (str); + if (right->type != XP_AWK_VAL_REX) xp_free (rex_code); + PANIC (run, XP_AWK_ENOMEM); + } + + xp_free (str); + } + + if (right->type != XP_AWK_VAL_REX) xp_free (rex_code); + return res; } static xp_awk_val_t* __eval_unary (xp_awk_run_t* run, xp_awk_nde_t* nde) diff --git a/ase/test/awk/awk.c b/ase/test/awk/awk.c index 9c2b0f2b..62385453 100644 --- a/ase/test/awk/awk.c +++ b/ase/test/awk/awk.c @@ -1,5 +1,5 @@ /* - * $Id: awk.c,v 1.58 2006-07-31 15:59:43 bacon Exp $ + * $Id: awk.c,v 1.59 2006-08-01 04:36:33 bacon Exp $ */ #include @@ -602,13 +602,19 @@ static int __main (int argc, xp_char_t* argv[]) { #if defined(__STAND_ALONE) && !defined(_WIN32) && defined(XP_CHAR_IS_WCHAR) xp_printf ( - XP_T("error: cannot run program - [%d] %ls\n"), + XP_T("error: cannot run program - [%d] %ls"), xp_awk_geterrnum(awk), xp_awk_geterrstr(awk)); #else xp_printf ( - XP_T("error: cannot run program - [%d] %s\n"), + XP_T("error: cannot run program - [%d] %s"), xp_awk_geterrnum(awk), xp_awk_geterrstr(awk)); #endif + if (xp_awk_getsuberrnum(awk) != XP_AWK_ENOERR) + { + xp_printf (XP_T(" - %ls\n"), xp_awk_getsuberrstr(awk)); + } + xp_printf (XP_T("\n")); + xp_awk_close (awk); return -1; }