From 835615cc97d9dc5fc3694683221fb397e89d7c7a Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Sun, 10 Sep 2006 15:50:34 +0000 Subject: [PATCH] *** empty log message *** --- ase/awk/awk.h | 7 +- ase/awk/extio.c | 3 +- ase/awk/misc.c | 30 ++++- ase/awk/rex.c | 78 ++++++++---- ase/awk/rex.h | 9 +- ase/awk/run.c | 293 ++++++++++++++++++++++++++++++++++++------- ase/awk/str.c | 22 +++- ase/awk/str.h | 3 +- ase/test/awk/t40.awk | 9 ++ ase/test/awk/t41.awk | 4 + ase/test/awk/t42.awk | 13 ++ 11 files changed, 392 insertions(+), 79 deletions(-) create mode 100644 ase/test/awk/t40.awk create mode 100644 ase/test/awk/t41.awk create mode 100644 ase/test/awk/t42.awk diff --git a/ase/awk/awk.h b/ase/awk/awk.h index 439bd374..9529a315 100644 --- a/ase/awk/awk.h +++ b/ase/awk/awk.h @@ -1,5 +1,5 @@ /* - * $Id: awk.h,v 1.113 2006-09-09 04:52:39 bacon Exp $ + * $Id: awk.h,v 1.114 2006-09-10 15:50:34 bacon Exp $ */ #ifndef _XP_AWK_AWK_H_ @@ -375,6 +375,11 @@ int xp_awk_strxncmp ( const xp_char_t* s1, xp_size_t len1, const xp_char_t* s2, xp_size_t len2); +int xp_awk_strxncasecmp ( + xp_awk_t* awk, + const xp_char_t* s1, xp_size_t len1, + const xp_char_t* s2, xp_size_t len2); + xp_char_t* xp_awk_strxnstr ( const xp_char_t* str, xp_size_t strsz, const xp_char_t* sub, xp_size_t subsz); diff --git a/ase/awk/extio.c b/ase/awk/extio.c index 6e02c13d..9810fcf4 100644 --- a/ase/awk/extio.c +++ b/ase/awk/extio.c @@ -1,5 +1,5 @@ /* - * $Id: extio.c,v 1.46 2006-09-05 04:10:23 bacon Exp $ + * $Id: extio.c,v 1.47 2006-09-10 15:50:34 bacon Exp $ */ #include @@ -292,6 +292,7 @@ int xp_awk_readextio ( /* TODO: safematchrex */ n = xp_awk_matchrex ( run->awk, run->rex.rs, + ((run->rex.ignorecase)? XP_AWK_REX_IGNORECASE: 0), XP_AWK_STR_BUF(buf), XP_AWK_STR_LEN(buf), &match_ptr, &match_len, &run->errnum); if (n == -1) diff --git a/ase/awk/misc.c b/ase/awk/misc.c index b2001895..657d8660 100644 --- a/ase/awk/misc.c +++ b/ase/awk/misc.c @@ -1,5 +1,5 @@ /* - * $Id: misc.c,v 1.18 2006-09-09 04:52:40 bacon Exp $ + * $Id: misc.c,v 1.19 2006-09-10 15:50:34 bacon Exp $ */ #include @@ -449,6 +449,28 @@ int xp_awk_strxncmp ( return (*s1 > *s2)? 1: -1; } +int xp_awk_strxncasecmp ( + xp_awk_t* awk, + const xp_char_t* s1, xp_size_t len1, + const xp_char_t* s2, xp_size_t len2) +{ + xp_char_t c1, c2; + const xp_char_t* end1 = s1 + len1; + const xp_char_t* end2 = s2 + len2; + + c1 = XP_AWK_TOUPPER (awk, *s1); + c2 = XP_AWK_TOUPPER (awk, *s2); + while (s1 < end1 && s2 < end2 && c1 == c2) + { + s1++, s2++; + c1 = XP_AWK_TOUPPER (awk, *s1); + c2 = XP_AWK_TOUPPER (awk, *s2); + } + if (s1 == end1 && s2 == end2) return 0; + if (c1 == c2) return (s1 < end1)? 1: -1; + return (c1 > c2)? 1: -1; +} + xp_char_t* xp_awk_strxnstr ( const xp_char_t* str, xp_size_t strsz, const xp_char_t* sub, xp_size_t subsz) @@ -704,12 +726,12 @@ xp_char_t* xp_awk_strxntokbyrex ( const xp_char_t* str_ptr = s; xp_size_t str_len = len; -xp_printf (XP_T("ignorecase = %d\n"), run->rex.ignorecase); while (len > 0) { n = xp_awk_matchrex ( - run->awk, rex, ptr, left, - &match_ptr, &match_len, errnum); + run->awk, rex, + ((run->rex.ignorecase)? XP_AWK_REX_IGNORECASE: 0), + ptr, left, &match_ptr, &match_len, errnum); if (n == -1) return XP_NULL; if (n == 0) { diff --git a/ase/awk/rex.c b/ase/awk/rex.c index 89dc25f5..f2b7ec26 100644 --- a/ase/awk/rex.c +++ b/ase/awk/rex.c @@ -1,5 +1,5 @@ /* - * $Id: rex.c,v 1.28 2006-09-05 15:18:16 bacon Exp $ + * $Id: rex.c,v 1.29 2006-09-10 15:50:34 bacon Exp $ */ #include @@ -122,6 +122,7 @@ struct __matcher_t int cur; } depth; + int ignorecase; int errnum; }; @@ -193,7 +194,6 @@ static const xp_byte_t* __match_occurrences ( static xp_bool_t __test_charset ( __matcher_t* matcher, const xp_byte_t* p, xp_size_t csc, xp_char_t c); -#ifndef XP_AWK_NTDDK static xp_bool_t __cc_isalnum (xp_awk_t* awk, xp_char_t c); static xp_bool_t __cc_isalpha (xp_awk_t* awk, xp_char_t c); static xp_bool_t __cc_isblank (xp_awk_t* awk, xp_char_t c); @@ -206,13 +206,11 @@ static xp_bool_t __cc_ispunct (xp_awk_t* awk, xp_char_t c); static xp_bool_t __cc_isspace (xp_awk_t* awk, xp_char_t c); static xp_bool_t __cc_isupper (xp_awk_t* awk, xp_char_t c); static xp_bool_t __cc_isxdigit (xp_awk_t* awk, xp_char_t c); -#endif static const xp_byte_t* __print_pattern (const xp_byte_t* p); static const xp_byte_t* __print_branch (const xp_byte_t* p); static const xp_byte_t* __print_atom (const xp_byte_t* p); -#ifndef XP_AWK_NTDDK struct __char_class_t { const xp_char_t* name; @@ -246,7 +244,6 @@ static struct __char_class_t __char_class[] = { XP_NULL, 0, XP_NULL } }; -#endif void* xp_awk_buildrex ( xp_awk_t* awk, const xp_char_t* ptn, xp_size_t len, int* errnum) @@ -301,7 +298,7 @@ void* xp_awk_buildrex ( } int xp_awk_matchrex ( - xp_awk_t* awk, void* code, + xp_awk_t* awk, void* code, int option, const xp_char_t* str, xp_size_t len, const xp_char_t** match_ptr, xp_size_t* match_len, int* errnum) { @@ -320,6 +317,8 @@ int xp_awk_matchrex ( matcher.depth.max = awk->max_depth; */ matcher.depth.max = 0; matcher.depth.cur = 0; +// TODO: set it to a good value + matcher.ignorecase = (option & XP_AWK_REX_IGNORECASE)? 1: 0; mat.matched = xp_false; /* TODO: should it allow an offset here??? */ @@ -1208,19 +1207,36 @@ static const xp_byte_t* __match_ord_char ( ubound = cp->ubound; cc = *(xp_char_t*)p; p += xp_sizeof(cc); + if (matcher->ignorecase) cc = XP_AWK_TOUPPER(matcher->awk, cc); /* merge the same consecutive codes * for example, a{1,10}a{0,10} is shortened to a{1,20} */ - while (p < mat->branch_end && - cp->cmd == ((const struct __code_t*)p)->cmd) + if (matcher->ignorecase) { - if (*(xp_char_t*)(p+xp_sizeof(*cp)) != cc) break; + while (p < mat->branch_end && + cp->cmd == ((const struct __code_t*)p)->cmd) + { + if (XP_AWK_TOUPPER (matcher->awk, *(xp_char_t*)(p+xp_sizeof(*cp))) != cc) break; - lbound += ((const struct __code_t*)p)->lbound; - ubound += ((const struct __code_t*)p)->ubound; + lbound += ((const struct __code_t*)p)->lbound; + ubound += ((const struct __code_t*)p)->ubound; - p += xp_sizeof(*cp) + xp_sizeof(cc); + p += xp_sizeof(*cp) + xp_sizeof(cc); + } + } + else + { + while (p < mat->branch_end && + cp->cmd == ((const struct __code_t*)p)->cmd) + { + if (*(xp_char_t*)(p+xp_sizeof(*cp)) != cc) break; + + lbound += ((const struct __code_t*)p)->lbound; + ubound += ((const struct __code_t*)p)->ubound; + + p += xp_sizeof(*cp) + xp_sizeof(cc); + } } //xp_printf (XP_T("lbound = %u, ubound = %u\n"), @@ -1230,11 +1246,23 @@ static const xp_byte_t* __match_ord_char ( mat->match_len = 0; /* find the longest match */ - while (si < ubound) + if (matcher->ignorecase) { - if (&mat->match_ptr[si] >= matcher->match.str.end) break; - if (cc != mat->match_ptr[si]) break; - si++; + while (si < ubound) + { + if (&mat->match_ptr[si] >= matcher->match.str.end) break; + if (cc != XP_AWK_TOUPPER (matcher->awk, mat->match_ptr[si])) break; + si++; + } + } + else + { + while (si < ubound) + { + if (&mat->match_ptr[si] >= matcher->match.str.end) break; + if (cc != mat->match_ptr[si]) break; + si++; + } } //xp_printf (XP_T("max si = %d, lbound = %u, ubound = %u\n"), si, lbound, ubound); @@ -1253,6 +1281,7 @@ static const xp_byte_t* __match_charset ( const struct __code_t* cp; xp_size_t si = 0, lbound, ubound, csc, csl; xp_bool_t n; + xp_char_t c; cp = (const struct __code_t*)p; p += xp_sizeof(*cp); xp_assert (cp->cmd == CMD_CHARSET); @@ -1270,7 +1299,10 @@ static const xp_byte_t* __match_charset ( { if (&mat->match_ptr[si] >= matcher->match.str.end) break; - n = __test_charset (matcher, p, csc, mat->match_ptr[si]); + c = mat->match_ptr[si]; + if (matcher->ignorecase) c = XP_AWK_TOUPPER(matcher->awk, c); + + n = __test_charset (matcher, p, csc, c); if (cp->negate) n = !n; if (!n) break; @@ -1518,6 +1550,8 @@ xp_bool_t __test_charset ( if (c0 == CHARSET_ONE) { c1 = *(xp_char_t*)p; + if (matcher->ignorecase) + c1 = XP_AWK_TOUPPER(matcher->awk, c1); if (c == c1) return xp_true; } else if (c0 == CHARSET_RANGE) @@ -1526,16 +1560,19 @@ xp_bool_t __test_charset ( p += xp_sizeof(c1); c2 = *(xp_char_t*)p; + if (matcher->ignorecase) + { + c1 = XP_AWK_TOUPPER(matcher->awk, c1); + c2 = XP_AWK_TOUPPER(matcher->awk, c2); + } if (c >= c1 && c <= c2) return xp_true; } -#ifndef XP_AWK_NTDDK else if (c0 == CHARSET_CLASS) { c1 = *(xp_char_t*)p; if (__char_class[c1].func ( matcher->awk, c)) return xp_true; } -#endif else { xp_assert (!"should never happen - invalid charset code"); @@ -1548,8 +1585,6 @@ xp_bool_t __test_charset ( return xp_false; } -#ifndef XP_AWK_NTDDK - static xp_bool_t __cc_isalnum (xp_awk_t* awk, xp_char_t c) { return XP_AWK_ISALNUM (awk, c); @@ -1746,4 +1781,3 @@ static const xp_byte_t* __print_atom (const xp_byte_t* p) return p; } -#endif diff --git a/ase/awk/rex.h b/ase/awk/rex.h index 6125570b..cc7f2b4e 100644 --- a/ase/awk/rex.h +++ b/ase/awk/rex.h @@ -1,5 +1,5 @@ /* - * $Id: rex.h,v 1.15 2006-09-01 03:44:16 bacon Exp $ + * $Id: rex.h,v 1.16 2006-09-10 15:50:34 bacon Exp $ **/ #ifndef _XP_AWK_REX_H_ @@ -42,6 +42,11 @@ #define XP_AWK_REX_LEN(code) \ (*(xp_size_t*)((xp_byte_t*)(code)+xp_sizeof(xp_size_t))) +enum xp_awk_rex_option_t +{ + XP_AWK_REX_IGNORECASE = (1 << 0) +}; + #ifdef __cplusplus extern "C" { #endif @@ -51,7 +56,7 @@ void* xp_awk_buildrex ( xp_size_t len, int* errnum); int xp_awk_matchrex ( - xp_awk_t* awk, void* code, + xp_awk_t* awk, void* code, int option, const xp_char_t* str, xp_size_t len, const xp_char_t** match_ptr, xp_size_t* match_len, int* errnum); diff --git a/ase/awk/run.c b/ase/awk/run.c index 687df273..5b4c6949 100644 --- a/ase/awk/run.c +++ b/ase/awk/run.c @@ -1,5 +1,5 @@ /* - * $Id: run.c,v 1.198 2006-09-08 15:26:49 bacon Exp $ + * $Id: run.c,v 1.199 2006-09-10 15:50:34 bacon Exp $ */ #include @@ -181,6 +181,7 @@ static int __split_record (xp_awk_run_t* run); static int __clear_record (xp_awk_run_t* run, xp_bool_t noline); static int __recomp_record_fields ( xp_awk_run_t* run, xp_size_t lv, xp_char_t* str, xp_size_t len); +static int __shorten_record (xp_awk_run_t* run, xp_size_t nflds); static xp_char_t* __idxnde_to_str ( xp_awk_run_t* run, xp_awk_nde_t* nde, xp_size_t* len); @@ -348,8 +349,22 @@ int xp_awk_setglobal (void* run, xp_size_t idx, xp_awk_val_t* val) ((xp_awk_run_t*)run)->rex.ignorecase = 1; } } + else if (idx == XP_AWK_GLOBAL_NF) + { + int n; + xp_long_t lv; + xp_real_t rv; -/* TODO: if idx == XP_AWK_GLOBAL_NF recompute $0, etc */ + /* TODO: need to recompute $0, etc */ + n = xp_awk_valtonum (run, val, &lv, &rv); + if (n == -1) return -1; + if (n == 1) lv = (xp_long_t)rv; + + if (lv < r->inrec.nflds) + { + if (__shorten_record (r, (xp_size_t)lv) == -1) return -1; + } + } xp_awk_refdownval (run, old); STACK_GLOBAL((xp_awk_run_t*)run,idx) = val; @@ -1932,6 +1947,7 @@ static xp_awk_val_t* __eval_expression (xp_awk_run_t* run, xp_awk_nde_t* nde) n = xp_awk_matchrex ( ((xp_awk_run_t*)run)->awk, ((xp_awk_val_rex_t*)v)->code, + ((((xp_awk_run_t*)run)->rex.ignorecase)? XP_AWK_REX_IGNORECASE: 0), ((xp_awk_val_str_t*)run->inrec.d0)->buf, ((xp_awk_val_str_t*)run->inrec.d0)->len, XP_NULL, XP_NULL, &errnum); @@ -2762,11 +2778,23 @@ static xp_awk_val_t* __eval_binop_eq ( else if (left->type == XP_AWK_VAL_STR && right->type == XP_AWK_VAL_STR) { - r = xp_awk_strxncmp ( - ((xp_awk_val_str_t*)left)->buf, - ((xp_awk_val_str_t*)left)->len, - ((xp_awk_val_str_t*)right)->buf, - ((xp_awk_val_str_t*)right)->len) == 0; + if (run->rex.ignorecase) + { + r = xp_awk_strxncasecmp ( + run->awk, + ((xp_awk_val_str_t*)left)->buf, + ((xp_awk_val_str_t*)left)->len, + ((xp_awk_val_str_t*)right)->buf, + ((xp_awk_val_str_t*)right)->len) == 0; + } + else + { + r = xp_awk_strxncmp ( + ((xp_awk_val_str_t*)left)->buf, + ((xp_awk_val_str_t*)left)->len, + ((xp_awk_val_str_t*)right)->buf, + ((xp_awk_val_str_t*)right)->len) == 0; + } } else { @@ -2817,11 +2845,23 @@ static xp_awk_val_t* __eval_binop_ne ( else if (left->type == XP_AWK_VAL_STR && right->type == XP_AWK_VAL_STR) { - r = xp_awk_strxncmp ( - ((xp_awk_val_str_t*)left)->buf, - ((xp_awk_val_str_t*)left)->len, - ((xp_awk_val_str_t*)right)->buf, - ((xp_awk_val_str_t*)right)->len) != 0; + if (run->rex.ignorecase) + { + r = xp_awk_strxncasecmp ( + run->awk, + ((xp_awk_val_str_t*)left)->buf, + ((xp_awk_val_str_t*)left)->len, + ((xp_awk_val_str_t*)right)->buf, + ((xp_awk_val_str_t*)right)->len) != 0; + } + else + { + r = xp_awk_strxncmp ( + ((xp_awk_val_str_t*)left)->buf, + ((xp_awk_val_str_t*)left)->len, + ((xp_awk_val_str_t*)right)->buf, + ((xp_awk_val_str_t*)right)->len) != 0; + } } else { @@ -2866,11 +2906,23 @@ static xp_awk_val_t* __eval_binop_gt ( else if (left->type == XP_AWK_VAL_STR && right->type == XP_AWK_VAL_STR) { - r = xp_awk_strxncmp ( - ((xp_awk_val_str_t*)left)->buf, - ((xp_awk_val_str_t*)left)->len, - ((xp_awk_val_str_t*)right)->buf, - ((xp_awk_val_str_t*)right)->len) > 0; + if (run->rex.ignorecase) + { + r = xp_awk_strxncasecmp ( + run->awk, + ((xp_awk_val_str_t*)left)->buf, + ((xp_awk_val_str_t*)left)->len, + ((xp_awk_val_str_t*)right)->buf, + ((xp_awk_val_str_t*)right)->len) > 0; + } + else + { + r = xp_awk_strxncmp ( + ((xp_awk_val_str_t*)left)->buf, + ((xp_awk_val_str_t*)left)->len, + ((xp_awk_val_str_t*)right)->buf, + ((xp_awk_val_str_t*)right)->len) > 0; + } } else { @@ -2915,11 +2967,23 @@ static xp_awk_val_t* __eval_binop_ge ( else if (left->type == XP_AWK_VAL_STR && right->type == XP_AWK_VAL_STR) { - r = xp_awk_strxncmp ( - ((xp_awk_val_str_t*)left)->buf, - ((xp_awk_val_str_t*)left)->len, - ((xp_awk_val_str_t*)right)->buf, - ((xp_awk_val_str_t*)right)->len) >= 0; + if (run->rex.ignorecase) + { + r = xp_awk_strxncasecmp ( + run->awk, + ((xp_awk_val_str_t*)left)->buf, + ((xp_awk_val_str_t*)left)->len, + ((xp_awk_val_str_t*)right)->buf, + ((xp_awk_val_str_t*)right)->len) >= 0; + } + else + { + r = xp_awk_strxncmp ( + ((xp_awk_val_str_t*)left)->buf, + ((xp_awk_val_str_t*)left)->len, + ((xp_awk_val_str_t*)right)->buf, + ((xp_awk_val_str_t*)right)->len) >= 0; + } } else { @@ -2964,11 +3028,23 @@ static xp_awk_val_t* __eval_binop_lt ( else if (left->type == XP_AWK_VAL_STR && right->type == XP_AWK_VAL_STR) { - r = xp_awk_strxncmp ( - ((xp_awk_val_str_t*)left)->buf, - ((xp_awk_val_str_t*)left)->len, - ((xp_awk_val_str_t*)right)->buf, - ((xp_awk_val_str_t*)right)->len) < 0; + if (run->rex.ignorecase) + { + r = xp_awk_strxncasecmp ( + run->awk, + ((xp_awk_val_str_t*)left)->buf, + ((xp_awk_val_str_t*)left)->len, + ((xp_awk_val_str_t*)right)->buf, + ((xp_awk_val_str_t*)right)->len) < 0; + } + else + { + r = xp_awk_strxncmp ( + ((xp_awk_val_str_t*)left)->buf, + ((xp_awk_val_str_t*)left)->len, + ((xp_awk_val_str_t*)right)->buf, + ((xp_awk_val_str_t*)right)->len) < 0; + } } else { @@ -3013,11 +3089,23 @@ static xp_awk_val_t* __eval_binop_le ( else if (left->type == XP_AWK_VAL_STR && right->type == XP_AWK_VAL_STR) { - r = xp_awk_strxncmp ( - ((xp_awk_val_str_t*)left)->buf, - ((xp_awk_val_str_t*)left)->len, - ((xp_awk_val_str_t*)right)->buf, - ((xp_awk_val_str_t*)right)->len) <= 0; + if (run->rex.ignorecase) + { + r = xp_awk_strxncasecmp ( + run->awk, + ((xp_awk_val_str_t*)left)->buf, + ((xp_awk_val_str_t*)left)->len, + ((xp_awk_val_str_t*)right)->buf, + ((xp_awk_val_str_t*)right)->len) <= 0; + } + else + { + r = xp_awk_strxncmp ( + ((xp_awk_val_str_t*)left)->buf, + ((xp_awk_val_str_t*)left)->len, + ((xp_awk_val_str_t*)right)->buf, + ((xp_awk_val_str_t*)right)->len) <= 0; + } } else { @@ -3398,6 +3486,7 @@ static xp_awk_val_t* __eval_binop_match0 ( { n = xp_awk_matchrex ( run->awk, rex_code, + ((run->rex.ignorecase)? XP_AWK_REX_IGNORECASE: 0), ((xp_awk_val_str_t*)left)->buf, ((xp_awk_val_str_t*)left)->len, XP_NULL, XP_NULL, &errnum); @@ -3428,6 +3517,7 @@ static xp_awk_val_t* __eval_binop_match0 ( n = xp_awk_matchrex ( run->awk, rex_code, + ((run->rex.ignorecase)? XP_AWK_REX_IGNORECASE: 0), str, len, XP_NULL, XP_NULL, &errnum); if (n == -1) { @@ -4930,7 +5020,7 @@ static int __recomp_record_fields ( xp_awk_run_t* run, xp_size_t lv, xp_char_t* str, xp_size_t len) { xp_awk_val_t* v; - xp_char_t* ofsp = XP_NULL, * ofs; + xp_char_t* ofs_free = XP_NULL, * ofs; xp_size_t ofs_len; xp_size_t max, i, nflds; @@ -4981,21 +5071,27 @@ static int __recomp_record_fields ( if (max > 1) { v = STACK_GLOBAL(run, XP_AWK_GLOBAL_OFS); - if (v != xp_awk_val_nil) - { - ofsp = xp_awk_valtostr ( - run, v, xp_true, XP_NULL, &ofs_len); - if (ofsp == XP_NULL) return -1; + xp_awk_refupval (v); - ofs = ofsp; - } - else + if (v == xp_awk_val_nil) { /* OFS not set */ ofs = XP_T(" "); ofs_len = 1; } + else if (v->type == XP_AWK_VAL_STR) + { + ofs = ((xp_awk_val_str_t*)v)->buf; + ofs_len = ((xp_awk_val_str_t*)v)->len; + } + else + { + ofs = xp_awk_valtostr ( + run, v, xp_true, XP_NULL, &ofs_len); + if (ofs == XP_NULL) return -1; + ofs_free = ofs; + } } for (i = 0; i < max; i++) @@ -5006,7 +5102,9 @@ static int __recomp_record_fields ( &run->inrec.line, ofs, ofs_len) == (xp_size_t)-1) { - if (ofsp != XP_NULL) XP_AWK_FREE (run->awk, ofsp); + if (ofs_free != XP_NULL) + XP_AWK_FREE (run->awk, ofs_free); + if (max > 1) xp_awk_refdownval (run, v); run->errnum = XP_AWK_ENOMEM; return -1; } @@ -5024,7 +5122,9 @@ static int __recomp_record_fields ( if (xp_awk_str_ncat ( &run->inrec.line, str, len) == (xp_size_t)-1) { - if (ofsp != XP_NULL) XP_AWK_FREE (run->awk, ofsp); + if (ofs_free != XP_NULL) + XP_AWK_FREE (run->awk, ofs_free); + if (max > 1) xp_awk_refdownval (run, v); run->errnum = XP_AWK_ENOMEM; return -1; } @@ -5032,7 +5132,9 @@ static int __recomp_record_fields ( tmp = xp_awk_makestrval (run, str,len); if (tmp == XP_NULL) { - if (ofsp != XP_NULL) XP_AWK_FREE (run->awk, ofsp); + if (ofs_free != XP_NULL) + XP_AWK_FREE (run->awk, ofs_free); + if (max > 1) xp_awk_refdownval (run, v); run->errnum = XP_AWK_ENOMEM; return -1; } @@ -5053,7 +5155,9 @@ static int __recomp_record_fields ( if (xp_awk_str_cat ( &run->inrec.line, XP_T("")) == (xp_size_t)-1) { - if (ofsp != XP_NULL) XP_AWK_FREE (run->awk, ofsp); + if (ofs_free != XP_NULL) + XP_AWK_FREE (run->awk, ofs_free); + if (max > 1) xp_awk_refdownval (run, v); run->errnum = XP_AWK_ENOMEM; return -1; } @@ -5080,14 +5184,17 @@ static int __recomp_record_fields ( if (xp_awk_str_ncat (&run->inrec.line, tmp->buf, tmp->len) == (xp_size_t)-1) { - if (ofsp != XP_NULL) XP_AWK_FREE (run->awk, ofsp); + if (ofs_free != XP_NULL) + XP_AWK_FREE (run->awk, ofs_free); + if (max > 1) xp_awk_refdownval (run, v); run->errnum = XP_AWK_ENOMEM; return -1; } } } - if (ofsp != XP_NULL) XP_AWK_FREE (run->awk, ofsp); + if (ofs_free != XP_NULL) XP_AWK_FREE (run->awk, ofs_free); + if (max > 1) xp_awk_refdownval (run, v); v = STACK_GLOBAL(run, XP_AWK_GLOBAL_NF); xp_assert (v->type == XP_AWK_VAL_INT); @@ -5107,6 +5214,98 @@ static int __recomp_record_fields ( return 0; } +static int __shorten_record (xp_awk_run_t* run, xp_size_t nflds) +{ + xp_awk_val_t* v; + xp_char_t* ofs_free = XP_NULL, * ofs; + xp_size_t ofs_len, i; + xp_awk_str_t tmp; + + xp_assert (nflds <= run->inrec.nflds); + + if (nflds > 1) + { + v = STACK_GLOBAL(run, XP_AWK_GLOBAL_OFS); + xp_awk_refupval (v); + + if (v == xp_awk_val_nil) + { + /* OFS not set */ + ofs = XP_T(" "); + ofs_len = 1; + } + else if (v->type == XP_AWK_VAL_STR) + { + ofs = ((xp_awk_val_str_t*)v)->buf; + ofs_len = ((xp_awk_val_str_t*)v)->len; + } + else + { + ofs = xp_awk_valtostr ( + run, v, xp_true, XP_NULL, &ofs_len); + if (ofs == XP_NULL) return -1; + + ofs_free = ofs; + } + } + + if (xp_awk_str_open (&tmp, + XP_AWK_STR_LEN(&run->inrec.line), run->awk) == XP_NULL) + { + run->errnum = XP_AWK_ENOMEM; + return -1; + } + + for (i = 0; i < nflds; i++) + { + if (i > 0 && xp_awk_str_ncat (&tmp, ofs, ofs_len) == (xp_size_t)-1) + { + if (ofs_free != XP_NULL) + XP_AWK_FREE (run->awk, ofs_free); + if (nflds > 1) xp_awk_refdownval (run, v); + run->errnum = XP_AWK_ENOMEM; + return -1; + } + + if (xp_awk_str_ncat (&tmp, + run->inrec.flds[i].ptr, + run->inrec.flds[i].len) == (xp_size_t)-1) + { + if (ofs_free != XP_NULL) + XP_AWK_FREE (run->awk, ofs_free); + if (nflds > 1) xp_awk_refdownval (run, v); + run->errnum = XP_AWK_ENOMEM; + return -1; + } + } + + if (ofs_free != XP_NULL) XP_AWK_FREE (run->awk, ofs_free); + if (nflds > 1) xp_awk_refdownval (run, v); + + v = (xp_awk_val_t*) xp_awk_makestrval ( + run, XP_AWK_STR_BUF(&tmp), XP_AWK_STR_LEN(&tmp)); + if (v == XP_NULL) + { + run->errnum = XP_AWK_ENOMEM; + return -1; + } + + xp_awk_refdownval (run, run->inrec.d0); + run->inrec.d0 = v; + xp_awk_refupval (run->inrec.d0); + + xp_awk_str_swap (&tmp, &run->inrec.line); + xp_awk_str_close (&tmp); + + for (i = nflds; i < run->inrec.nflds; i++) + { + xp_awk_refdownval (run, run->inrec.flds[i].val); + } + + run->inrec.nflds = nflds; + return 0; +} + static xp_char_t* __idxnde_to_str ( xp_awk_run_t* run, xp_awk_nde_t* nde, xp_size_t* len) { diff --git a/ase/awk/str.c b/ase/awk/str.c index a33ae7fd..d47c7e74 100644 --- a/ase/awk/str.c +++ b/ase/awk/str.c @@ -1,5 +1,5 @@ /* - * $Id: str.c,v 1.3 2006-09-01 07:18:40 bacon Exp $ + * $Id: str.c,v 1.4 2006-09-10 15:50:34 bacon Exp $ */ #include @@ -47,6 +47,26 @@ void xp_awk_str_forfeit (xp_awk_str_t* str) if (str->__dynamic) XP_AWK_FREE (str->awk, str); } +void xp_awk_str_swap (xp_awk_str_t* str, xp_awk_str_t* str1) +{ + xp_awk_str_t tmp; + + tmp.buf = str->buf; + tmp.size = str->size; + tmp.capa = str->capa; + tmp.awk = str->awk; + + str->buf = str1->buf; + str->size = str1->size; + str->capa = str1->capa; + str->awk = str1->awk; + + str1->buf = tmp.buf; + str1->size = tmp.size; + str1->capa = tmp.capa; + str1->awk = tmp.awk; +} + xp_size_t xp_awk_str_cpy (xp_awk_str_t* str, const xp_char_t* s) { /* TODO: improve it */ diff --git a/ase/awk/str.h b/ase/awk/str.h index 4b5e75f3..1d26a90b 100644 --- a/ase/awk/str.h +++ b/ase/awk/str.h @@ -1,5 +1,5 @@ /* - * $Id: str.h,v 1.1 2006-08-31 16:00:20 bacon Exp $ + * $Id: str.h,v 1.2 2006-09-10 15:50:34 bacon Exp $ */ #ifndef _XP_AWK_STR_H_ @@ -36,6 +36,7 @@ xp_awk_str_t* xp_awk_str_open ( void xp_awk_str_close (xp_awk_str_t* str); void xp_awk_str_forfeit (xp_awk_str_t* str); +void xp_awk_str_swap (xp_awk_str_t* str, xp_awk_str_t* str2); xp_size_t xp_awk_str_cpy (xp_awk_str_t* str, const xp_char_t* s); diff --git a/ase/test/awk/t40.awk b/ase/test/awk/t40.awk new file mode 100644 index 00000000..0896fc4f --- /dev/null +++ b/ase/test/awk/t40.awk @@ -0,0 +1,9 @@ +BEGIN { + FS="[a-c]+"; + IGNORECASE=0.1; +} +{ + print "NF=" NF; + for (i = 0; i < NF; i++) print i " [" $(i+1) "]"; +} + diff --git a/ase/test/awk/t41.awk b/ase/test/awk/t41.awk new file mode 100644 index 00000000..6a82e3d1 --- /dev/null +++ b/ase/test/awk/t41.awk @@ -0,0 +1,4 @@ +BEGIN { IGNORECASE=1; } +$0 == "abc" { + print "[" $0 "]"; +} diff --git a/ase/test/awk/t42.awk b/ase/test/awk/t42.awk new file mode 100644 index 00000000..259c7bd2 --- /dev/null +++ b/ase/test/awk/t42.awk @@ -0,0 +1,13 @@ + +BEGIN { + FS=":"; + OFS="::"; +} + +{ + $2=1.23; + NF=4; + print "NF=" NF; + print "[" $10 "]"; + print "$0=[" $0 "]"; +}