diff --git a/ase/awk/awk.c b/ase/awk/awk.c index 6c3a0850..c2eb655f 100644 --- a/ase/awk/awk.c +++ b/ase/awk/awk.c @@ -1,5 +1,5 @@ /* - * $Id: awk.c,v 1.58 2006-07-13 15:43:39 bacon Exp $ + * $Id: awk.c,v 1.59 2006-07-25 16:41:40 bacon Exp $ */ #include @@ -61,6 +61,17 @@ xp_awk_t* xp_awk_open (void) return XP_NULL; } + if (xp_awk_rex_open (&awk->rex) == XP_NULL) + { + xp_str_close (&awk->token.name); + xp_awk_map_close (&awk->tree.afns); + xp_awk_tab_close (&awk->parse.globals); + xp_awk_tab_close (&awk->parse.locals); + xp_awk_tab_close (&awk->parse.params); + xp_free (awk); + return XP_NULL; + } + awk->opt.parse = 0; awk->opt.run = 0; awk->errnum = XP_AWK_ENOERR; @@ -105,6 +116,7 @@ int xp_awk_close (xp_awk_t* awk) xp_awk_tab_close (&awk->parse.globals); xp_awk_tab_close (&awk->parse.locals); xp_awk_tab_close (&awk->parse.params); + xp_awk_rex_close (&awk->rex); xp_str_close (&awk->token.name); xp_free (awk); diff --git a/ase/awk/awk.h b/ase/awk/awk.h index 62d58800..e7fde3d7 100644 --- a/ase/awk/awk.h +++ b/ase/awk/awk.h @@ -1,5 +1,5 @@ /* - * $Id: awk.h,v 1.79 2006-07-19 11:45:23 bacon Exp $ + * $Id: awk.h,v 1.80 2006-07-25 16:41:40 bacon Exp $ */ #ifndef _XP_AWK_AWK_H_ @@ -127,6 +127,7 @@ enum XP_AWK_ETOOFEWARGS, /* too few arguments */ XP_AWK_ETOOMANYARGS, /* too many arguments */ XP_AWK_EGETLINE, /* getline expected */ + XP_AWK_EREXCMPL, /* cannot compile the regular expressio n*/ /* run time error */ XP_AWK_EDIVBYZERO, /* divide by zero */ diff --git a/ase/awk/awk_i.h b/ase/awk/awk_i.h index 83554242..4075770d 100644 --- a/ase/awk/awk_i.h +++ b/ase/awk/awk_i.h @@ -1,5 +1,5 @@ /* - * $Id: awk_i.h,v 1.31 2006-07-17 04:17:40 bacon Exp $ + * $Id: awk_i.h,v 1.32 2006-07-25 16:41:40 bacon Exp $ */ #ifndef _XP_AWK_AWKI_H_ @@ -17,6 +17,7 @@ typedef struct xp_awk_tree_t xp_awk_tree_t; #include #endif +#include #include #include #include @@ -24,7 +25,6 @@ typedef struct xp_awk_tree_t xp_awk_tree_t; #include #include #include -#include #ifdef _WIN32 #pragma warning (disable: 4996) @@ -103,6 +103,9 @@ struct xp_awk_t xp_size_t nlocals_max; } parse; + /* regular expression compiler */ + xp_awk_rex_t rex; + /* source buffer management */ struct { @@ -189,6 +192,9 @@ struct xp_awk_run_t /* extio chain */ xp_awk_extio_t* extio; + /* regular expression matcher */ + xp_awk_rex_t rex_matcher; + int opt; int errnum; diff --git a/ase/awk/err.c b/ase/awk/err.c index f2adc301..f6c7c353 100644 --- a/ase/awk/err.c +++ b/ase/awk/err.c @@ -1,5 +1,5 @@ /* - * $Id: err.c,v 1.26 2006-07-05 16:20:23 bacon Exp $ + * $Id: err.c,v 1.27 2006-07-25 16:41:40 bacon Exp $ */ #include @@ -59,6 +59,7 @@ const xp_char_t* xp_awk_geterrstr (xp_awk_t* awk) XP_T("too few arguments"), XP_T("too many arguments"), XP_T("getline expected"), + XP_T("cannot compile the regular expression"), XP_T("divide by zero"), XP_T("invalid operand"), @@ -75,7 +76,8 @@ const xp_char_t* xp_awk_geterrstr (xp_awk_t* awk) XP_T("internal error that should never have happened") }; - if (awk->errnum >= 0 && awk->errnum < xp_countof(__errstr)) { + if (awk->errnum >= 0 && awk->errnum < xp_countof(__errstr)) + { return __errstr[awk->errnum]; } diff --git a/ase/awk/parse.c b/ase/awk/parse.c index c5f7e53e..cb79f9fe 100644 --- a/ase/awk/parse.c +++ b/ase/awk/parse.c @@ -1,5 +1,5 @@ /* - * $Id: parse.c,v 1.138 2006-07-17 04:17:40 bacon Exp $ + * $Id: parse.c,v 1.139 2006-07-25 16:41:40 bacon Exp $ */ #include @@ -1901,31 +1901,41 @@ static xp_awk_nde_t* __parse_primary (xp_awk_t* awk) } else if (MATCH(awk,TOKEN_DIV)) { - xp_awk_nde_str_t* nde; + xp_awk_nde_rex_t* nde; - /* the regular expression is tokenized because of - * context-sensitivity of the slash symbol */ + /* 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; xp_assert (MATCH(awk,TOKEN_REX)); - nde = (xp_awk_nde_str_t*) + nde = (xp_awk_nde_rex_t*) xp_malloc (xp_sizeof(xp_awk_nde_rex_t)); if (nde == XP_NULL) PANIC (awk, XP_AWK_ENOMEM); nde->type = XP_AWK_NDE_REX; nde->next = XP_NULL; - nde->len = XP_STR_LEN(&awk->token.name); - nde->buf = xp_strxdup(XP_STR_BUF(&awk->token.name), nde->len); - if (nde->buf == XP_NULL) + + if (xp_awk_rex_compile (&awk->rex, + XP_STR_BUF(&awk->token.name), + XP_STR_LEN(&awk->token.name)) == -1) + { + xp_free (nde); + PANIC (awk, XP_AWK_EREXCMPL); + } + + nde->len = awk->rex.code.size; + nde->buf = xp_malloc (nde->len); + if (nde->buf == XP_NULL) { xp_free (nde); PANIC (awk, XP_AWK_ENOMEM); } + xp_memcpy (nde->buf, awk->rex.code.buf, nde->len); + if (__get_token(awk) == -1) { - xp_free (nde->buf); xp_free (nde); return XP_NULL; } @@ -3690,14 +3700,7 @@ static int __get_regex (xp_awk_t* awk) continue; } - if (escaped == xp_true) - { - if (c == XP_T('n')) c = XP_T('\n'); - else if (c == XP_T('r')) c = XP_T('\r'); - else if (c == XP_T('t')) c = XP_T('\t'); - /* TODO: more escape characters */ - escaped = xp_false; - } + if (escaped == xp_true) escaped = xp_false; ADD_TOKEN_CHAR (awk, c); GET_CHAR_TO (awk, c); diff --git a/ase/awk/rex.c b/ase/awk/rex.c index a6b1eb02..d3892f91 100644 --- a/ase/awk/rex.c +++ b/ase/awk/rex.c @@ -1,5 +1,5 @@ /* - * $Id: rex.c,v 1.12 2006-07-24 16:23:19 bacon Exp $ + * $Id: rex.c,v 1.13 2006-07-25 16:41:40 bacon Exp $ */ #include @@ -208,6 +208,37 @@ void xp_awk_rex_close (xp_awk_rex_t* rex) if (rex->__dynamic) xp_free (rex); } +int xp_awk_rex_geterrnum (xp_awk_rex_t* rex) +{ + return rex->errnum; +} + +const xp_char_t* xp_awk_rex_geterrstr (xp_awk_rex_t* rex) +{ + static const xp_char_t* __errstr[] = + { + XP_T("no error"), + XP_T("out of memory"), + XP_T("no pattern compiled"), + XP_T("a right parenthesis is expected"), + XP_T("a right bracket is expected"), + XP_T("a right brace is expected"), + XP_T("a colon is expected"), + XP_T("invalid character range"), + XP_T("invalid character class"), + XP_T("invalid boundary range"), + XP_T("unexpected end of the pattern"), + XP_T("garbage after the pattern") + }; + + if (rex->errnum >= 0 && rex->errnum < xp_countof(__errstr)) + { + return __errstr[rex->errnum]; + } + + return XP_T("unknown error"); +} + int xp_awk_rex_compile (xp_awk_rex_t* rex, const xp_char_t* ptn, xp_size_t len) { rex->ptn.ptr = ptn; @@ -799,22 +830,25 @@ int xp_awk_rex_match (xp_awk_rex_t* rex, rex->match.str.ptr = str; rex->match.str.end = str + len; +/* TODO: shoud it allow an offset here??? */ mat.match_ptr = str + offset; while (mat.match_ptr < rex->match.str.end) { - __match_pattern (rex, rex->code.buf, &mat); + if (__match_pattern ( + rex, rex->code.buf, &mat) == XP_NULL) return -1; + if (mat.matched) { - *match_ptr = mat.match_ptr; - *match_len = mat.match_len; + if (match_ptr != XP_NULL) *match_ptr = mat.match_ptr; + if (match_len != XP_NULL) *match_len = mat.match_len; break; } mat.match_ptr++; } - return (mat.matched)? 0: -1; + return (mat.matched)? 1: 0; } static const xp_byte_t* __match_pattern ( @@ -837,6 +871,8 @@ static const xp_byte_t* __match_pattern ( mat2.match_ptr = mat->match_ptr; p = __match_branch (rex, p, &mat2); + if (p == XP_NULL) return XP_NULL; + if (mat2.matched) { mat->matched = xp_true; @@ -851,40 +887,51 @@ static const xp_byte_t* __match_pattern ( static const xp_byte_t* __match_branch ( xp_awk_rex_t* rex, const xp_byte_t* base, struct __match_t* mat) { - const xp_byte_t* p; - xp_size_t na, bl; - - p = base; - - na = *(xp_size_t*)p; p += xp_sizeof(na); - bl = *(xp_size_t*)p; p += xp_sizeof(bl); -//xp_printf (XP_T("NA = %u, BL = %u\n"), (unsigned)na, (unsigned)bl); - - /* remember the current branch to work on */ + /* + * branch body (base+sizeof(NA)+sizeof(BL)---+ + * BL=base+sizeof(NA) ---------+ | + * base=NA ------+ | | + * | | | + * |NA(xp_size_t)|BL(xp_size_t)|ATOMS.........| + */ mat->branch = base; - mat->branch_end = base + bl; + mat->branch_end = base + *((xp_size_t*)(base+xp_sizeof(xp_size_t))); - return __match_branch_body (rex, p, mat); + return __match_branch_body ( + rex, base+xp_sizeof(xp_size_t)*2, mat); } static const xp_byte_t* __match_branch_body ( xp_awk_rex_t* rex, const xp_byte_t* base, struct __match_t* mat) { const xp_byte_t* p; - struct __match_t mat2; +// struct __match_t mat2; + xp_size_t match_len = 0; mat->matched = xp_false; mat->match_len = 0; +/* TODO: is mat2 necessary here ? */ +/* mat2.match_ptr = mat->match_ptr; mat2.branch = mat->branch; mat2.branch_end = mat->branch_end; +*/ p = base; while (p < mat->branch_end) { + p = __match_atom (rex, p, mat); + if (p == XP_NULL) return XP_NULL; + + if (!mat->matched) break; + + mat->match_ptr = &mat->match_ptr[mat->match_len]; + match_len += mat->match_len; +#if 0 p = __match_atom (rex, p, &mat2); + if (p == XP_NULL) return XP_NULL; if (!mat2.matched) { @@ -896,8 +943,10 @@ static const xp_byte_t* __match_branch_body ( mat->match_len += mat2.match_len; mat2.match_ptr = &mat2.match_ptr[mat2.match_len]; +#endif } + if (mat->matched) mat->match_len = match_len; return mat->branch_end; } @@ -1093,26 +1142,17 @@ static const xp_byte_t* __match_charset ( static const xp_byte_t* __match_group ( xp_awk_rex_t* rex, const xp_byte_t* base, struct __match_t* mat) { - const xp_byte_t* p = base, * sub; + const xp_byte_t* p = base; const struct __code_t* cp; struct __match_t mat2; - xp_size_t si = 0, nb, el; - -xp_size_t grp_len[100]; + xp_size_t si = 0, grp_len_static[16], * grp_len; cp = (const struct __code_t*)p; p += xp_sizeof(*cp); xp_assert (cp->cmd == CMD_GROUP); - /* peep at the header of a subpattern */ - sub = p; - nb = *(xp_size_t*)p; p += xp_sizeof(nb); - el = *(xp_size_t*)p; p += xp_sizeof(el); - mat->matched = xp_false; mat->match_len = 0; - mat2.match_ptr = mat->match_ptr; - /* * A grouped pattern, unlike other atoms, can match one or more * characters. When it is requested with a variable occurrences, @@ -1137,16 +1177,37 @@ xp_size_t grp_len[100]; * abcabcabcxyz */ -// TODO: make this dynamic...... -grp_len[si] = 0; + if (cp->ubound < xp_countof(grp_len_static)) + { + grp_len = grp_len_static; + } + else + { + grp_len = (xp_size_t*) xp_malloc ( + xp_sizeof(xp_size_t) * cp->ubound); + if (grp_len == XP_NULL) + { + rex->errnum = XP_AWK_REX_ENOMEM; + return XP_NULL; + } + } + + grp_len[si] = 0; + + mat2.match_ptr = mat->match_ptr; while (si < cp->ubound) { if (mat2.match_ptr >= rex->match.str.end) break; - __match_pattern (rex, sub, &mat2); + if (__match_pattern (rex, p, &mat2) == XP_NULL) + { + if (grp_len != grp_len_static) xp_free (grp_len); + return XP_NULL; + } if (!mat2.matched) break; -grp_len[si+1] = grp_len[si] + mat2.match_len; + grp_len[si+1] = grp_len[si] + mat2.match_len; + mat2.match_ptr += mat2.match_len; mat2.match_len = 0; mat2.matched = xp_false; @@ -1154,8 +1215,10 @@ grp_len[si+1] = grp_len[si] + mat2.match_len; si++; } - p = sub + el; + /* increment p by the length of the subpattern */ + p += *(xp_size_t*)(p+xp_sizeof(xp_size_t)); + /* check the boundary */ if (si >= cp->lbound && si <= cp->ubound) { if (cp->lbound == cp->ubound || p >= mat->branch_end) @@ -1177,6 +1240,12 @@ grp_len[si+1] = grp_len[si] + mat2.match_len; //xp_printf (XP_T("GROUP si = %d [%s]\n"), si, mat->match_ptr); tmp = __match_branch_body (rex, p, &mat2); + if (tmp == XP_NULL) + { + if (grp_len != grp_len_static) + xp_free (grp_len); + return XP_NULL; + } if (mat2.matched) { @@ -1194,6 +1263,7 @@ grp_len[si+1] = grp_len[si] + mat2.match_len; } + if (grp_len != grp_len_static) xp_free (grp_len); return p; } diff --git a/ase/awk/run.c b/ase/awk/run.c index 2e24977a..5004126b 100644 --- a/ase/awk/run.c +++ b/ase/awk/run.c @@ -1,5 +1,5 @@ /* - * $Id: run.c,v 1.135 2006-07-17 04:17:40 bacon Exp $ + * $Id: run.c,v 1.136 2006-07-25 16:41:40 bacon Exp $ */ #include @@ -49,6 +49,7 @@ static void __close_run (xp_awk_run_t* run); static int __run_main (xp_awk_run_t* run); 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); +static int __handle_pattern (xp_awk_run_t* run, xp_awk_val_t* val); static int __run_block (xp_awk_run_t* run, xp_awk_nde_blk_t* nde); static int __run_statement (xp_awk_run_t* run, xp_awk_nde_t* nde); static int __run_if (xp_awk_run_t* run, xp_awk_nde_if_t* nde); @@ -290,6 +291,14 @@ static int __open_run ( return -1; } + if (xp_awk_rex_open (&run->rex_matcher) == XP_NULL) + { + xp_awk_map_close (&run->named); + xp_str_close (&run->inrec.line); + run->errnum = XP_AWK_ENOMEM; + return -1; + } + run->extio = XP_NULL; return 0; } @@ -300,6 +309,18 @@ static void __close_run (xp_awk_run_t* run) /* TODO: what if this operation fails? */ xp_awk_clearextio (run); + /* destroy input record. __clear_record should be called + * before the run stack has been destroyed because it may try + * to change the value to XP_AWK_GLOBAL_NF. */ + __clear_record (run, xp_false); + if (run->inrec.flds != XP_NULL) + { + xp_free (run->inrec.flds); + run->inrec.flds = XP_NULL; + run->inrec.maxflds = 0; + } + xp_str_close (&run->inrec.line); + /* destroy run stack */ if (run->stack != XP_NULL) { @@ -312,19 +333,12 @@ static void __close_run (xp_awk_run_t* run) run->stack_limit = 0; } + /* destroy the regular expression matcher */ + xp_awk_rex_close (&run->rex_matcher); + /* destroy named variables */ xp_awk_map_close (&run->named); - /* destroy input record */ - __clear_record (run, xp_false); - if (run->inrec.flds != XP_NULL) - { - xp_free (run->inrec.flds); - run->inrec.flds = XP_NULL; - run->inrec.maxflds = 0; - } - xp_str_close (&run->inrec.line); - /* destroy values in free list */ while (run->icache_count > 0) { @@ -593,7 +607,14 @@ static int __run_pattern_block_chain (xp_awk_run_t* run, xp_awk_chain_t* chain) if (ptn->next == XP_NULL) { - if (xp_awk_valtobool(v1)) + int n = __handle_pattern (run, v1); + if (n == -1) + { + xp_awk_refdownval (run, v1); + return -1; + } + + if (n == 1) { xp_awk_nde_blk_t* blk; blk = (xp_awk_nde_blk_t*)chain->action; @@ -622,6 +643,34 @@ static int __run_pattern_block_chain (xp_awk_run_t* run, xp_awk_chain_t* chain) return 0; } +static int __handle_pattern (xp_awk_run_t* run, xp_awk_val_t* val) +{ + int n; + + if (val->type == XP_AWK_VAL_REX) + { + xp_assert (run->inrec.d0->type == XP_AWK_VAL_STR); + +/* TODO: do it properly match value...*/ + //xp_awk_rex_setpattern (v->buf, v->len); + + n = xp_awk_rex_match (&run->rex_matcher, + ((xp_awk_val_str_t*)run->inrec.d0)->buf, + ((xp_awk_val_str_t*)run->inrec.d0)->len, + XP_NULL, XP_NULL); + + if (n == -1) + { +// TODO: convert rex_matcher->errnum to run->errnum. + PANIC_I (run, XP_AWK_ENOMEM); + }; + } + else n = xp_awk_valtobool(val)? 1: 0; + + return n; +} + + static int __run_block (xp_awk_run_t* run, xp_awk_nde_blk_t* nde) { xp_awk_nde_t* p; @@ -1771,11 +1820,29 @@ static xp_awk_val_t* __do_assignment_pos ( } xp_free (str); - /* TODO: consider if "val" of a non-string type should be - * converted into a string value */ - xp_awk_refdownval (run, run->inrec.d0); - run->inrec.d0 = val; - xp_awk_refupval (val); + if (val->type == XP_AWK_VAL_STR) + { + xp_awk_refdownval (run, run->inrec.d0); + run->inrec.d0 = val; + xp_awk_refupval (val); + } + else + { + v = xp_awk_makestrval ( + XP_STR_BUF(&run->inrec.line), + XP_STR_LEN(&run->inrec.line)); + if (v == XP_NULL) + { + __clear_record (run, xp_false); + PANIC (run, XP_AWK_ENOMEM); + } + + xp_awk_refdownval (run, run->inrec.d0); + run->inrec.d0 = v; + xp_awk_refupval (v); + + val = v; + } if (__split_record (run) == -1) { @@ -3341,19 +3408,25 @@ static xp_awk_val_t* __eval_real (xp_awk_run_t* run, xp_awk_nde_t* nde) static xp_awk_val_t* __eval_str (xp_awk_run_t* run, xp_awk_nde_t* nde) { xp_awk_val_t* val; + val = xp_awk_makestrval ( ((xp_awk_nde_str_t*)nde)->buf, ((xp_awk_nde_str_t*)nde)->len); if (val == XP_NULL) PANIC (run, XP_AWK_ENOMEM); + return val; } static xp_awk_val_t* __eval_rex (xp_awk_run_t* run, xp_awk_nde_t* nde) { -/* TODO */ -xp_printf (XP_T("eval_rex not implemented yet...\n")); - PANIC (run, XP_AWK_EINTERNAL); - return XP_NULL; + xp_awk_val_t* val; + + val = xp_awk_makerexval ( + ((xp_awk_nde_rex_t*)nde)->buf, + ((xp_awk_nde_rex_t*)nde)->len); + if (val == XP_NULL) PANIC (run, XP_AWK_ENOMEM); + + return val; } static xp_awk_val_t* __eval_named (xp_awk_run_t* run, xp_awk_nde_t* nde) diff --git a/ase/awk/tree.c b/ase/awk/tree.c index 0dcbaa9c..24849c13 100644 --- a/ase/awk/tree.c +++ b/ase/awk/tree.c @@ -1,5 +1,5 @@ /* - * $Id: tree.c,v 1.65 2006-07-14 05:21:30 bacon Exp $ + * $Id: tree.c,v 1.66 2006-07-25 16:41:40 bacon Exp $ */ #include @@ -227,8 +227,8 @@ static int __print_expression (xp_awk_nde_t* nde) case XP_AWK_NDE_REX: { - /* TODO: buf, len */ - xp_printf (XP_T("/%s/"), ((xp_awk_nde_rex_t*)nde)->buf); + /* TODO: print it properly */ + xp_printf (XP_T("/**REX**/")); break; } diff --git a/ase/awk/tree.h b/ase/awk/tree.h index 432882df..2d17de84 100644 --- a/ase/awk/tree.h +++ b/ase/awk/tree.h @@ -1,5 +1,5 @@ /* - * $Id: tree.h,v 1.60 2006-07-14 05:21:30 bacon Exp $ + * $Id: tree.h,v 1.61 2006-07-25 16:41:40 bacon Exp $ */ #ifndef _XP_AWK_TREE_H_ @@ -205,8 +205,7 @@ struct xp_awk_nde_str_t struct xp_awk_nde_rex_t { XP_AWK_NDE_HDR; - /* TODO: implement the regular expression value node */ - xp_char_t* buf; + xp_byte_t* buf; xp_size_t len; }; diff --git a/ase/awk/val.c b/ase/awk/val.c index 10eee78c..40c14e19 100644 --- a/ase/awk/val.c +++ b/ase/awk/val.c @@ -1,5 +1,5 @@ /* - * $Id: val.c,v 1.44 2006-07-17 14:27:09 bacon Exp $ + * $Id: val.c,v 1.45 2006-07-25 16:41:40 bacon Exp $ */ #include @@ -135,25 +135,24 @@ xp_awk_val_t* xp_awk_makestrval2 ( return (xp_awk_val_t*)val; } -xp_awk_val_t* xp_awk_makerexval (const xp_char_t* str, xp_size_t len) +xp_awk_val_t* xp_awk_makerexval (const xp_byte_t* buf, xp_size_t len) { xp_awk_val_rex_t* val; -/* TDOO: implement the regular expression value */ val = (xp_awk_val_rex_t*) xp_malloc (xp_sizeof(xp_awk_val_rex_t)); if (val == XP_NULL) return XP_NULL; - val->type = XP_AWK_VAL_STR; + val->type = XP_AWK_VAL_REX; val->ref = 0; val->len = len; - val->buf = xp_strxdup (str, len); + val->buf = xp_malloc (len); if (val->buf == XP_NULL) { xp_free (val); return XP_NULL; } -/*xp_printf (XP_T("makerexval => %p\n"), val);*/ + xp_memcpy (val->buf, buf, len); return (xp_awk_val_t*)val; } @@ -235,7 +234,6 @@ xp_printf (XP_T("\n"));*/ return; case XP_AWK_VAL_REX: - /* TODO: implement the regular expression value properly */ xp_free (((xp_awk_val_rex_t*)val)->buf); xp_free (val); return; @@ -306,6 +304,8 @@ xp_bool_t xp_awk_valtobool (xp_awk_val_t* val) return ((xp_awk_val_real_t*)val)->val != 0.0; case XP_AWK_VAL_STR: return ((xp_awk_val_str_t*)val)->len > 0; + case XP_AWK_VAL_REX: /* TODO: is this correct? */ + return ((xp_awk_val_rex_t*)val)->len > 0; case XP_AWK_VAL_MAP: return xp_false; /* TODO: is this correct? */ } diff --git a/ase/awk/val.h b/ase/awk/val.h index 6f6bea12..ee35f248 100644 --- a/ase/awk/val.h +++ b/ase/awk/val.h @@ -1,5 +1,5 @@ /* - * $Id: val.h,v 1.31 2006-07-17 04:17:40 bacon Exp $ + * $Id: val.h,v 1.32 2006-07-25 16:41:40 bacon Exp $ */ #ifndef _XP_AWK_VAL_H_ @@ -104,7 +104,7 @@ xp_awk_val_t* xp_awk_makestrval (const xp_char_t* str, xp_size_t len); xp_awk_val_t* xp_awk_makestrval2 ( const xp_char_t* str1, xp_size_t len1, const xp_char_t* str2, xp_size_t len2); -xp_awk_val_t* xp_awk_makerexval (const xp_char_t* str, xp_size_t len); +xp_awk_val_t* xp_awk_makerexval (const xp_byte_t* buf, xp_size_t len); xp_awk_val_t* xp_awk_makemapval (xp_awk_run_t* run); xp_bool_t xp_awk_isbuiltinval (xp_awk_val_t* val); diff --git a/ase/test/awk/rex.c b/ase/test/awk/rex.c index 00cea768..f6d3c7bf 100644 --- a/ase/test/awk/rex.c +++ b/ase/test/awk/rex.c @@ -25,12 +25,12 @@ int xp_main (int argc, const xp_char_t* argv[]) //ptn = XP_T("^he.llo(jo(in|kk)s|com)+h*e{1,40}abc|[^abc][de-f]|^he.llo(jo(in|kk)s|com)+h*e{1,40}abc|[^abc][de-f]"); //ptn = XP_T("^he.llo(jo(in|kk)s|com)+h*e{1,40}abc|[^abc][de-f]"); //ptn = XP_T("^he.llo(jo(in|kk)s|com)|[^x[:space:][:alpha:]j][^abc][de-f]|^he.llo(jo(in|kk)s|com)|[^x[:space:][:alpha:]j][^abc][de-f]"); - //ptn = XP_T("^.{0,2}.z[^[:space:]]+(abc|zzz){1,2}khg"); + ptn = XP_T("^.{0,2}.z[^[:space:]]+(abc|zzz){1,2}khg"); // - ptn = XP_T("a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}"); //a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}"); + //ptn = XP_T("a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}"); //a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}a{1,10}"); if (xp_awk_rex_compile (rex, ptn, xp_strlen(ptn)) == -1) { - xp_printf (XP_T("cannot compile pattern...\n")); + xp_printf (XP_T("cannot compile pattern - %s\n"), xp_awk_rex_geterrstr(rex)); xp_awk_rex_close (rex); return -1; } @@ -38,20 +38,25 @@ int xp_main (int argc, const xp_char_t* argv[]) xp_awk_rex_print (rex); { + int n; const xp_char_t* str = XP_T("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); const xp_char_t* match_ptr; xp_size_t match_len; //if (xp_awk_rex_match (rex, XP_T("azhabc"), 6, &match_ptr, &match_len) == 0) - //if (xp_awk_rex_match (rex, XP_T("azhzzzabckhgi"), 13, &match_ptr, &match_len) == 0) - if (xp_awk_rex_match (rex, str, xp_strlen(str), &match_ptr, &match_len) == 0) + n = xp_awk_rex_match (rex, XP_T("azhzzzabckhgi"), 13, &match_ptr, &match_len); + //if (xp_awk_rex_match (rex, str, xp_strlen(str), &match_ptr, &match_len) == 0) + if (n == 1) { xp_printf (XP_T("match = %s, match length = %u\n"), match_ptr, match_len); } - else + else if (n == 0) { xp_printf (XP_T("go to hell\n")); } - + else /* if (n == -1) */ + { + xp_printf (XP_T("ERROR: %s\n"), xp_awk_rex_geterrstr(rex)); + } } xp_awk_rex_close (rex); return 0; diff --git a/ase/test/awk/t16.awk b/ase/test/awk/t16.awk index 534131b7..ef2ca32e 100644 --- a/ase/test/awk/t16.awk +++ b/ase/test/awk/t16.awk @@ -1 +1 @@ -{ $0=" "; print NF; print "a" $0 "b"; x = $1; } +/hello/ { $0=" "; print NF; print "a" $0 "b"; x = $1; }