From f0d588414ec13f8bfa8441932c433956956b9a42 Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Sun, 8 Mar 2020 15:04:47 +0000 Subject: [PATCH] added %u to printf changed %c with an empty string to '\0' in printf fixed the execution behavior of double patterned action block(e.g. /a/,/b/) fixed a bug in NF=value assignment handling fixed a bug when assigning NF with a large number than the current number of records fixed a bug in converting multidimensional array index to a string --- hawk/bin/main.c | 4 +- hawk/lib/Hawk.cpp | 16 +- hawk/lib/HawkStd.cpp | 2 +- hawk/lib/fnc.c | 9 +- hawk/lib/gem-nwif2.c | 6 +- hawk/lib/hawk-prv.h | 4 +- hawk/lib/hawk-utl.h | 26 ++-- hawk/lib/hawk.h | 30 +++- hawk/lib/mod-str.c | 4 +- hawk/lib/parse.c | 6 +- hawk/lib/pio.c | 8 +- hawk/lib/rec.c | 263 +++++++++++++++++++++++---------- hawk/lib/run.c | 341 +++++++++++++++++-------------------------- hawk/lib/std.c | 52 +++---- hawk/lib/utl-str.c | 92 +++++++++--- hawk/lib/val.c | 28 ++-- 16 files changed, 502 insertions(+), 389 deletions(-) diff --git a/hawk/bin/main.c b/hawk/bin/main.c index eed7c2af..6457e48b 100644 --- a/hawk/bin/main.c +++ b/hawk/bin/main.c @@ -400,8 +400,8 @@ static int apply_fs_and_gvs_to_rtx (hawk_rtx_t* rtx, arg_t* arg) { hawk_val_t* v; - v = (arg->gvm.ptr[i].uc)? hawk_rtx_makenstrvalwithuchars(rtx, arg->gvm.ptr[i].value.ptr, arg->gvm.ptr[i].value.len): - hawk_rtx_makenstrvalwithbchars(rtx, arg->gvm.ptr[i].value.ptr, arg->gvm.ptr[i].value.len); + v = (arg->gvm.ptr[i].uc)? hawk_rtx_makenumorstrvalwithuchars(rtx, arg->gvm.ptr[i].value.ptr, arg->gvm.ptr[i].value.len): + hawk_rtx_makenumorstrvalwithbchars(rtx, arg->gvm.ptr[i].value.ptr, arg->gvm.ptr[i].value.len); if (HAWK_UNLIKELY(!v)) return -1; hawk_rtx_refupval (rtx, v); diff --git a/hawk/lib/Hawk.cpp b/hawk/lib/Hawk.cpp index f17ec197..76ea8d2e 100644 --- a/hawk/lib/Hawk.cpp +++ b/hawk/lib/Hawk.cpp @@ -709,7 +709,7 @@ int Hawk::Value::setStr (Run* r, const hawk_uch_t* str, hawk_oow_t len, bool num { hawk_val_t* tmp; - tmp = numeric? hawk_rtx_makenstrvalwithuchars(r->rtx, str, len): + tmp = numeric? hawk_rtx_makenumorstrvalwithuchars(r->rtx, str, len): hawk_rtx_makestrvalwithuchars(r->rtx, str, len); if (tmp == HAWK_NULL) { @@ -732,7 +732,7 @@ int Hawk::Value::setStr (Run* r, const hawk_uch_t* str, bool numeric) { hawk_val_t* tmp; - tmp = numeric? hawk_rtx_makenstrvalwithucstr(r->rtx, str): + tmp = numeric? hawk_rtx_makenumorstrvalwithuchars(r->rtx, str, hawk_count_ucstr(str)): hawk_rtx_makestrvalwithucstr(r->rtx, str); if (tmp == HAWK_NULL) { @@ -762,7 +762,7 @@ int Hawk::Value::setStr (Run* r, const hawk_bch_t* str, hawk_oow_t len, bool num { hawk_val_t* tmp; - tmp = numeric? hawk_rtx_makenstrvalwithbchars(r->rtx, str, len): + tmp = numeric? hawk_rtx_makenumorstrvalwithbchars(r->rtx, str, len): hawk_rtx_makestrvalwithbchars(r->rtx, str, len); if (tmp == HAWK_NULL) { @@ -785,7 +785,7 @@ int Hawk::Value::setStr (Run* r, const hawk_bch_t* str, bool numeric) { hawk_val_t* tmp; - tmp = numeric? hawk_rtx_makenstrvalwithbcstr(r->rtx, str): + tmp = numeric? hawk_rtx_makenumorstrvalwithbchars(r->rtx, str, hawk_count_bcstr(str)): hawk_rtx_makestrvalwithbcstr(r->rtx, str); if (tmp == HAWK_NULL) { @@ -974,7 +974,7 @@ int Hawk::Value::setIndexedStr (Run* r, const Index& idx, const hawk_uch_t* str, { hawk_val_t* tmp; - tmp = numeric? hawk_rtx_makenstrvalwithuchars(r->rtx, str, len): + tmp = numeric? hawk_rtx_makenumorstrvalwithuchars(r->rtx, str, len): hawk_rtx_makestrvalwithuchars(r->rtx, str, len); if (tmp == HAWK_NULL) { @@ -998,7 +998,7 @@ int Hawk::Value::setIndexedStr (const Index& idx, const hawk_uch_t* str, bool nu int Hawk::Value::setIndexedStr (Run* r, const Index& idx, const hawk_uch_t* str, bool numeric) { hawk_val_t* tmp; - tmp = numeric? hawk_rtx_makenstrvalwithucstr(r->rtx, str): + tmp = numeric? hawk_rtx_makenumorstrvalwithuchars(r->rtx, str, hawk_count_ucstr(str)): hawk_rtx_makestrvalwithucstr(r->rtx, str); if (tmp == HAWK_NULL) { @@ -1023,7 +1023,7 @@ int Hawk::Value::setIndexedStr (Run* r, const Index& idx, const hawk_bch_t* str, { hawk_val_t* tmp; - tmp = numeric? hawk_rtx_makenstrvalwithbchars(r->rtx, str, len): + tmp = numeric? hawk_rtx_makenumorstrvalwithbchars(r->rtx, str, len): hawk_rtx_makestrvalwithbchars(r->rtx, str, len); if (tmp == HAWK_NULL) { @@ -1047,7 +1047,7 @@ int Hawk::Value::setIndexedStr (const Index& idx, const hawk_bch_t* str, bool nu int Hawk::Value::setIndexedStr (Run* r, const Index& idx, const hawk_bch_t* str, bool numeric) { hawk_val_t* tmp; - tmp = numeric? hawk_rtx_makenstrvalwithbcstr(r->rtx, str): + tmp = numeric? hawk_rtx_makenumorstrvalwithbchars(r->rtx, str, hawk_count_bcstr(str)): hawk_rtx_makestrvalwithbcstr(r->rtx, str); if (tmp == HAWK_NULL) { diff --git a/hawk/lib/HawkStd.cpp b/hawk/lib/HawkStd.cpp index 1d8f93d6..3a07ada9 100644 --- a/hawk/lib/HawkStd.cpp +++ b/hawk/lib/HawkStd.cpp @@ -334,7 +334,7 @@ int HawkStd::build_environ (Run* run, env_char_t* envarr[]) } } - return run->setGlobal (this->gbl_environ, v_env); + return run->setGlobal(this->gbl_environ, v_env); } int HawkStd::make_additional_globals (Run* run) diff --git a/hawk/lib/fnc.c b/hawk/lib/fnc.c index 025171c0..49643c73 100644 --- a/hawk/lib/fnc.c +++ b/hawk/lib/fnc.c @@ -938,10 +938,11 @@ int hawk_fnc_split (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi) HAWK_ASSERT ((tok.ptr != HAWK_NULL && tok.len > 0) || tok.len == 0); /* create the field string - however, the split function must - * create a numeric string if the string is a number */ + * create a numeric value if the string is a number */ /*t2 = hawk_rtx_makestrvalwithoocs (rtx, &tok);*/ - t2 = hawk_rtx_makenstrvalwithoocs (rtx, &tok); - if (t2 == HAWK_NULL) goto oops; + /*t2 = hawk_rtx_makenstrvalwithoocs(rtx, &tok); */ + t2 = hawk_rtx_makenumorstrvalwithoochars(rtx, tok.ptr, tok.len); + if (HAWK_UNLIKELY(!t2)) goto oops; /* put it into the map */ key_len = hawk_int_to_oocstr(++nflds, 10, HAWK_NULL, key_buf, HAWK_COUNTOF(key_buf)); @@ -1233,7 +1234,7 @@ static int __substitute (hawk_rtx_t* rtx, hawk_int_t max_count) if (a2 == HAWK_NULL) { int n; - n = hawk_rtx_setrec(rtx, 0, HAWK_OOECS_OOCS(&new)); + n = hawk_rtx_setrec(rtx, 0, HAWK_OOECS_OOCS(&new), 0); if (n <= -1) goto oops; } else diff --git a/hawk/lib/gem-nwif2.c b/hawk/lib/gem-nwif2.c index 1a0fea5a..bf294cc2 100644 --- a/hawk/lib/gem-nwif2.c +++ b/hawk/lib/gem-nwif2.c @@ -387,7 +387,7 @@ static void read_proc_net_if_inet6 (hawk_gem_t* gem, hawk_ifcfg_t* cfg, struct i if (count >= 6) { - index = hawk_bchars_to_int(tok[1].ptr, tok[1].len, 16, HAWK_NULL, 1); + index = hawk_bchars_to_int(tok[1].ptr, tok[1].len, HAWK_OOCHARS_TO_INT_MAKE_OPTION(1, 1, 16), HAWK_NULL, HAWK_NULL); if (index == cfg->index) { int ti; @@ -397,11 +397,11 @@ static void read_proc_net_if_inet6 (hawk_gem_t* gem, hawk_ifcfg_t* cfg, struct i if (hawk_bchars_to_bin(tok[0].ptr, tok[0].len, (hawk_uint8_t*)&skad->in6.sin6_addr, HAWK_SIZEOF(skad->in6.sin6_addr)) <= -1) break; /* tok[3] is the scope type, not the actual scope. * i leave this code for reference only. - skad->in6.sin6_scope_id = hawk_bchars_to_int(tok[3].ptr, tok[3].len, 16, HAWK_NULL, 1); */ + skad->in6.sin6_scope_id = hawk_bchars_to_int(tok[3].ptr, tok[3].len, HAWK_OOCHARS_TO_INT_MAKE_OPTION(1, 1, 16), HAWK_NULL, HAWK_NULL); */ skad->in6.sin6_family = HAWK_AF_INET6; skad = (hawk_skad_alt_t*)&cfg->mask; - ti = hawk_bchars_to_int(tok[2].ptr, tok[0].len, 16, HAWK_NULL, 1); + ti = hawk_bchars_to_int(tok[2].ptr, tok[0].len, HAWK_OOCHARS_TO_INT_MAKE_OPTION(1, 1, 16), HAWK_NULL, HAWK_NULL); prefix_to_in6 (ti, &skad->in6.sin6_addr); skad->in6.sin6_family = HAWK_AF_INET6; goto done; diff --git a/hawk/lib/hawk-prv.h b/hawk/lib/hawk-prv.h index bcad2d3d..42f65af6 100644 --- a/hawk/lib/hawk-prv.h +++ b/hawk/lib/hawk-prv.h @@ -401,8 +401,8 @@ struct hawk_rtx_t struct { const hawk_ooch_t* ptr; - hawk_oow_t len; - hawk_val_t* val; /* $1 .. $NF */ + hawk_oow_t len; + hawk_val_t* val; /* $1 .. $NF */ }* flds; } inrec; diff --git a/hawk/lib/hawk-utl.h b/hawk/lib/hawk-utl.h index bdba69e6..8e21fb3a 100644 --- a/hawk/lib/hawk-utl.h +++ b/hawk/lib/hawk-utl.h @@ -815,15 +815,20 @@ HAWK_EXPORT hawk_oow_t hawk_int_to_oocstr ( hawk_oow_t size ); +#define HAWK_OOCHARS_TO_INT_MAKE_OPTION(ltrim,rtrim,base) (((!!(ltrim)) << 2) | ((!!(rtrim)) << 4) | ((base) << 8)) +#define HAWK_OOCHARS_TO_INT_GET_OPTION_LTRIM(option) ((option) & 4) +#define HAWK_OOCHARS_TO_INT_GET_OPTION_RTRIM(option) ((option) & 8) +#define HAWK_OOCHARS_TO_INT_GET_OPTION_BASE(option) ((option) >> 8) + /** * The hawk_uchars_to_int() function converts a wide character string to an integer. */ HAWK_EXPORT hawk_int_t hawk_uchars_to_int ( - const hawk_uch_t* str, - hawk_oow_t len, - int base, - const hawk_uch_t** endptr, - int stripspc + const hawk_uch_t* str, + hawk_oow_t len, + int option, + const hawk_uch_t** endptr, + int* is_sober ); /** @@ -832,9 +837,9 @@ HAWK_EXPORT hawk_int_t hawk_uchars_to_int ( HAWK_EXPORT hawk_int_t hawk_bchars_to_int ( const hawk_bch_t* str, hawk_oow_t len, - int base, + int option, const hawk_bch_t** endptr, - int stripspc + int* is_sober ); /** @@ -873,9 +878,10 @@ HAWK_EXPORT hawk_flt_t hawk_bchars_to_flt ( * 1 if converted to a floating-point number * -1 on error. */ -#define HAWK_OOCHARS_TO_NUM_MAKE_OPTION(strict,stripspc,base) (((!!(strict)) << 0) | ((!!(stripspc)) << 1) | ((base) << 8)) -#define HAWK_OOCHARS_TO_NUM_GET_OPTION_STRICT(option) ((option) & 1) -#define HAWK_OOCHARS_TO_NUM_GET_OPTION_STRIPSPC(option) ((option) & 2) +#define HAWK_OOCHARS_TO_NUM_MAKE_OPTION(nopartial,reqsober,stripspc,base) (((!!(nopartial)) << 0) | ((!!(reqsober)) << 1) | ((!!(stripspc)) << 2) | ((base) << 8)) +#define HAWK_OOCHARS_TO_NUM_GET_OPTION_NOPARTIAL(option) ((option) & 1) +#define HAWK_OOCHARS_TO_NUM_GET_OPTION_REQSOBER(option) ((option) & 2) +#define HAWK_OOCHARS_TO_NUM_GET_OPTION_STRIPSPC(option) ((option) & 4) #define HAWK_OOCHARS_TO_NUM_GET_OPTION_BASE(option) ((option) >> 8) HAWK_EXPORT int hawk_bchars_to_num ( diff --git a/hawk/lib/hawk.h b/hawk/lib/hawk.h index b4f16c9b..1f09d656 100644 --- a/hawk/lib/hawk.h +++ b/hawk/lib/hawk.h @@ -2582,9 +2582,19 @@ HAWK_EXPORT int hawk_rtx_clrrec ( * input fields ($1 to $N). */ HAWK_EXPORT int hawk_rtx_setrec ( - hawk_rtx_t* rtx, /**< runtime context */ - hawk_oow_t idx, /**< 0 for $0, N for $N */ - const hawk_oocs_t* str /**< string */ + hawk_rtx_t* rtx, /**< runtime context */ + hawk_oow_t idx, /**< 0 for $0, N for $N */ + const hawk_oocs_t* str, /**< string */ + int prefer_number /* if true, a numeric string makes an int or flt value */ +); + +/** + * The hawk_rtx_truncrec() function lowered the number of fields in a record. + * The caller must ensure that \a nflds is less than the current number of fields + */ +HAWK_EXPORT int hawk_rtx_truncrec ( + hawk_rtx_t* rtx, + hawk_oow_t nflds ); /** @@ -2798,6 +2808,20 @@ hawk_val_t* hawk_rtx_makembsvalwithucs ( const hawk_ucs_t* ucs ); +/* -------------------------------------------------------------------------- */ + +HAWK_EXPORT hawk_val_t* hawk_rtx_makenumormbsvalwithuchars ( + hawk_rtx_t* rtx, + const hawk_uch_t* ptr, + hawk_oow_t len +); + +HAWK_EXPORT hawk_val_t* hawk_rtx_makenumormbsvalwithbchars ( + hawk_rtx_t* rtx, + const hawk_bch_t* ptr, + hawk_oow_t len +); + /* -------------------------------------------------------------------------- */ diff --git a/hawk/lib/mod-str.c b/hawk/lib/mod-str.c index c3825f9d..fa0cc24d 100644 --- a/hawk/lib/mod-str.c +++ b/hawk/lib/mod-str.c @@ -487,7 +487,7 @@ static int fnc_tonum (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi) if (hawk_rtx_valtoint(rtx, a1, &base) <= -1) return -1; rx = hawk_bchars_to_num( - HAWK_OOCHARS_TO_NUM_MAKE_OPTION(0, (hawk->opt.trait & HAWK_STRIPSTRSPC), base), + HAWK_OOCHARS_TO_NUM_MAKE_OPTION(0, 0, (hawk->opt.trait & HAWK_STRIPSTRSPC), base), ((hawk_val_mbs_t*)a0)->val.ptr, ((hawk_val_mbs_t*)a0)->val.len, &lv, &rv @@ -502,7 +502,7 @@ static int fnc_tonum (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi) if (hawk_rtx_valtoint(rtx, a1, &base) <= -1) return -1; rx = hawk_oochars_to_num( - HAWK_OOCHARS_TO_NUM_MAKE_OPTION(0, (hawk->opt.trait & HAWK_STRIPSTRSPC), base), + HAWK_OOCHARS_TO_NUM_MAKE_OPTION(0, 0, (hawk->opt.trait & HAWK_STRIPSTRSPC), base), ((hawk_val_str_t*)a0)->val.ptr, ((hawk_val_str_t*)a0)->val.len, &lv, &rv diff --git a/hawk/lib/parse.c b/hawk/lib/parse.c index af5bffda..b043ea23 100644 --- a/hawk/lib/parse.c +++ b/hawk/lib/parse.c @@ -1049,7 +1049,9 @@ static int parse_progunit (hawk_t* awk) return -1; } - sl = hawk_oochars_to_int(HAWK_OOECS_PTR(awk->tok.name), HAWK_OOECS_LEN(awk->tok.name), 0, HAWK_NULL, (awk->opt.trait & HAWK_STRIPSTRSPC)); + sl = hawk_oochars_to_int(HAWK_OOECS_PTR(awk->tok.name), HAWK_OOECS_LEN(awk->tok.name), + HAWK_OOCHARS_TO_INT_MAKE_OPTION((awk->opt.trait & HAWK_STRIPSTRSPC), (awk->opt.trait & HAWK_STRIPSTRSPC), 0), + HAWK_NULL, HAWK_NULL); if (sl < HAWK_MIN_RTX_STACK_LIMIT) sl = HAWK_MIN_RTX_STACK_LIMIT; else if (sl > HAWK_MAX_RTX_STACK_LIMIT) sl = HAWK_MAX_RTX_STACK_LIMIT; /* take the specified value if it's greater than the existing value */ @@ -4619,7 +4621,7 @@ static hawk_nde_t* parse_primary_int (hawk_t* hawk, const hawk_loc_t* xloc) /* create the node for the literal */ nde = (hawk_nde_int_t*)new_int_node ( hawk, - hawk_oochars_to_int (HAWK_OOECS_PTR(hawk->tok.name), HAWK_OOECS_LEN(hawk->tok.name), 0, HAWK_NULL, (hawk->opt.trait & HAWK_STRIPSTRSPC)), + hawk_oochars_to_int (HAWK_OOECS_PTR(hawk->tok.name), HAWK_OOECS_LEN(hawk->tok.name), HAWK_OOCHARS_TO_INT_MAKE_OPTION((hawk->opt.trait & HAWK_STRIPSTRSPC), (hawk->opt.trait & HAWK_STRIPSTRSPC), 0), HAWK_NULL, HAWK_NULL), xloc ); if (nde == HAWK_NULL) return HAWK_NULL; diff --git a/hawk/lib/pio.c b/hawk/lib/pio.c index 7fa33062..e2983691 100644 --- a/hawk/lib/pio.c +++ b/hawk/lib/pio.c @@ -89,8 +89,8 @@ static int get_highest_fd (hawk_pio_t* pio) if (de->d_name[0] == HAWK_BT('.')) continue; - l = hawk_bchars_to_int(de->d_name, hawk_count_bcstr(de->d_name), 10, &endptr, 0); - if (*endptr == HAWK_BT('\0')) + l = hawk_bchars_to_int(de->d_name, hawk_count_bcstr(de->d_name), HAWK_OOCHARS_TO_INT_MAKE_OPTION(0, 0, 10), &endptr, HAWK_NULL); + if (*endptr == '\0') { fd = (int)l; if ((hawk_intptr_t)fd == l && fd != HAWK_DIRFD(d)) @@ -161,8 +161,8 @@ static int close_open_fds_using_proc (hawk_pio_t* pio, int* excepts, hawk_oow_t if (de->d_name[0] == HAWK_BT('.')) continue; - l = hawk_bchars_to_int(de->d_name, hawk_count_bcstr(de->d_name), 10, &endptr, 0); - if (*endptr == HAWK_BT('\0')) + l = hawk_bchars_to_int(de->d_name, hawk_count_bcstr(de->d_name), HAWK_OOCHARS_TO_INT_MAKE_OPTION(0, 0, 10), &endptr, HAWK_NULL); + if (*endptr == '\0') { int fd = (int)l; if ((hawk_intptr_t)fd == l && fd != HAWK_DIRFD(d) && fd > 2) diff --git a/hawk/lib/rec.c b/hawk/lib/rec.c index 0d588692..a38a70b0 100644 --- a/hawk/lib/rec.c +++ b/hawk/lib/rec.c @@ -26,10 +26,10 @@ #include "hawk-prv.h" -static int split_record (hawk_rtx_t* run); -static int recomp_record_fields (hawk_rtx_t* run, hawk_oow_t lv, const hawk_oocs_t* str); +static int split_record (hawk_rtx_t* run, int prefer_number); +static int recomp_record_fields (hawk_rtx_t* run, hawk_oow_t lv, const hawk_oocs_t* str, int prefer_number); -int hawk_rtx_setrec (hawk_rtx_t* rtx, hawk_oow_t idx, const hawk_oocs_t* str) +int hawk_rtx_setrec (hawk_rtx_t* rtx, hawk_oow_t idx, const hawk_oocs_t* str, int prefer_number) { hawk_val_t* v; @@ -43,58 +43,66 @@ int hawk_rtx_setrec (hawk_rtx_t* rtx, hawk_oow_t idx, const hawk_oocs_t* str) else { if (hawk_rtx_clrrec(rtx, 0) <= -1) return -1; - - if (hawk_ooecs_ncpy(&rtx->inrec.line, str->ptr, str->len) == (hawk_oow_t)-1) - { - hawk_rtx_clrrec (rtx, 0); - return -1; - } + if (hawk_ooecs_ncpy(&rtx->inrec.line, str->ptr, str->len) == (hawk_oow_t)-1) goto oops; } - v = hawk_rtx_makenstrvalwithoocs(rtx, str); - if (HAWK_UNLIKELY(!v)) - { - hawk_rtx_clrrec (rtx, 0); - return -1; - } + if (split_record(rtx, prefer_number) <= -1) goto oops; - HAWK_ASSERT (HAWK_RTX_GETVALTYPE (rtx, rtx->inrec.d0) == HAWK_VAL_NIL); - /* d0 should be cleared before the next line is reached - * as it doesn't call hawk_rtx_refdownval on rtx->inrec.d0 */ - rtx->inrec.d0 = v; - hawk_rtx_refupval (rtx, v); - - if (split_record(rtx) <= -1) - { - hawk_rtx_clrrec (rtx, 0); - return -1; - } + v = prefer_number? hawk_rtx_makenumorstrvalwithoochars(rtx, HAWK_OOECS_PTR(&rtx->inrec.line), HAWK_OOECS_LEN(&rtx->inrec.line)): + hawk_rtx_makenstrvalwithoochars(rtx, HAWK_OOECS_PTR(&rtx->inrec.line), HAWK_OOECS_LEN(&rtx->inrec.line)); + if (HAWK_UNLIKELY(!v)) goto oops; } else { - if (recomp_record_fields(rtx, idx, str) <= -1) - { - hawk_rtx_clrrec (rtx, 0); - return -1; - } + if (recomp_record_fields(rtx, idx, str, prefer_number) <= -1) goto oops; /* recompose $0 */ - v = hawk_rtx_makestrvalwithoocs(rtx, HAWK_OOECS_OOCS(&rtx->inrec.line)); - if (HAWK_UNLIKELY(!v)) - { - hawk_rtx_clrrec (rtx, 0); - return -1; - } - - hawk_rtx_refdownval (rtx, rtx->inrec.d0); - rtx->inrec.d0 = v; - hawk_rtx_refupval (rtx, v); + v = hawk_rtx_makestrvalwithoochars(rtx, HAWK_OOECS_PTR(&rtx->inrec.line), HAWK_OOECS_LEN(&rtx->inrec.line)); + if (HAWK_UNLIKELY(!v)) goto oops; } + if (HAWK_RTX_GETVALTYPE(rtx, rtx->inrec.d0) != HAWK_VAL_NIL) hawk_rtx_refdownval (rtx, rtx->inrec.d0); + rtx->inrec.d0 = v; + hawk_rtx_refupval (rtx, v); + return 0; + +oops: + hawk_rtx_clrrec (rtx, 0); + return -1; } -static int split_record (hawk_rtx_t* rtx) +#if 0 +static int merge_fields (hawk_rtx_t* rtx) +{ + hawk_oow_t i; + + hawk_ooecs_clear (&rtx->inrec.line); + + for (i = 0; i < rtx->inrec.nflds; i++) + { + hawk_ooch_t* vp; + hawk_oow_t vl; + + if (HAWK_LIKELY(i > 0)) + { + if (hawk_ooecs_ncat(&rtx->inrec.line, rtx->gbl.ofs.ptr, rtx->gbl.ofs.len) == (hawk_oow_t)-1) return -1; + } + + vp = hawk_rtx_getvaloocstr(rtx, rtx->inrec.flds[i].val, &vl); + if (HAWK_UNLIKELY(!vp)) return -1; + + vl = hawk_ooecs_ncat(&rtx->inrec.line, vp, vl); + hawk_rtx_freevaloocstr (rtx, rtx->inrec.flds[i].val, vp); + + if (HAWK_UNLIKELY(vl == (hawk_oow_t)-1)) return -1; + } + + return 1; +} +#endif + +static int split_record (hawk_rtx_t* rtx, int prefer_number) { hawk_oocs_t tok; hawk_ooch_t* p, * px; @@ -197,7 +205,7 @@ static int split_record (hawk_rtx_t* rtx) if (nflds > rtx->inrec.maxflds) { void* tmp = hawk_rtx_allocmem(rtx, HAWK_SIZEOF(*rtx->inrec.flds) * nflds); - if (!tmp) + if (HAWK_UNLIKELY(!tmp)) { if (fs_free) hawk_rtx_freemem (rtx, fs_free); return -1; @@ -296,9 +304,11 @@ static int split_record (hawk_rtx_t* rtx) rtx->inrec.flds[rtx->inrec.nflds].ptr = tok.ptr; rtx->inrec.flds[rtx->inrec.nflds].len = tok.len; - rtx->inrec.flds[rtx->inrec.nflds].val = hawk_rtx_makenstrvalwithoocs (rtx, &tok); - - if (rtx->inrec.flds[rtx->inrec.nflds].val == HAWK_NULL) + /*rtx->inrec.flds[rtx->inrec.nflds].val = hawk_rtx_makenstrvalwithoocs(rtx, &tok);*/ + rtx->inrec.flds[rtx->inrec.nflds].val = + prefer_number? hawk_rtx_makenumorstrvalwithoochars(rtx, tok.ptr, tok.len): + hawk_rtx_makestrvalwithoochars(rtx, tok.ptr, tok.len); + if (HAWK_UNLIKELY(!rtx->inrec.flds[rtx->inrec.nflds].val)) { if (fs_free) hawk_rtx_freemem (rtx, fs_free); return -1; @@ -317,7 +327,7 @@ static int split_record (hawk_rtx_t* rtx) if (v == HAWK_NULL) return -1; hawk_rtx_refupval (rtx, v); - if (hawk_rtx_setgbl(rtx, HAWK_GBL_NF, v) == -1) + if (hawk_rtx_setgbl(rtx, HAWK_GBL_NF, v) <= -1) { hawk_rtx_refdownval (rtx, v); return -1; @@ -326,30 +336,29 @@ static int split_record (hawk_rtx_t* rtx) return 0; } -int hawk_rtx_clrrec (hawk_rtx_t* run, int skip_inrec_line) +int hawk_rtx_clrrec (hawk_rtx_t* rtx, int skip_inrec_line) { hawk_oow_t i; int n = 0; - if (run->inrec.d0 != hawk_val_nil) + if (HAWK_RTX_GETVALTYPE(rtx, rtx->inrec.d0) != HAWK_VAL_NIL) { - hawk_rtx_refdownval (run, run->inrec.d0); - run->inrec.d0 = hawk_val_nil; + hawk_rtx_refdownval (rtx, rtx->inrec.d0); + rtx->inrec.d0 = hawk_val_nil; } - if (run->inrec.nflds > 0) + if (rtx->inrec.nflds > 0) { - HAWK_ASSERT (run->inrec.flds != HAWK_NULL); + HAWK_ASSERT (rtx->inrec.flds != HAWK_NULL); - for (i = 0; i < run->inrec.nflds; i++) + for (i = 0; i < rtx->inrec.nflds; i++) { - HAWK_ASSERT (run->inrec.flds[i].val != HAWK_NULL); - hawk_rtx_refdownval (run, run->inrec.flds[i].val); + HAWK_ASSERT (rtx->inrec.flds[i].val != HAWK_NULL); + hawk_rtx_refdownval (rtx, rtx->inrec.flds[i].val); } - run->inrec.nflds = 0; + rtx->inrec.nflds = 0; - if (hawk_rtx_setgbl ( - run, HAWK_GBL_NF, HAWK_VAL_ZERO) == -1) + if (hawk_rtx_setgbl(rtx, HAWK_GBL_NF, HAWK_VAL_ZERO) <= -1) { /* first of all, this should never happen. * if it happened, it would return an error @@ -358,19 +367,26 @@ int hawk_rtx_clrrec (hawk_rtx_t* run, int skip_inrec_line) } } - HAWK_ASSERT (run->inrec.nflds == 0); - if (!skip_inrec_line) hawk_ooecs_clear (&run->inrec.line); + HAWK_ASSERT (rtx->inrec.nflds == 0); + if (!skip_inrec_line) hawk_ooecs_clear (&rtx->inrec.line); return n; } -static int recomp_record_fields (hawk_rtx_t* rtx, hawk_oow_t lv, const hawk_oocs_t* str) +static int recomp_record_fields (hawk_rtx_t* rtx, hawk_oow_t lv, const hawk_oocs_t* str, int prefer_number) { hawk_val_t* v; hawk_oow_t max, i, nflds; /* recomposes the record and the fields when $N has been assigned - * a new value and recomputes NF accordingly */ + * a new value and recomputes NF accordingly. + * + * BEGIN { OFS=":" } { $2 = "Q"; print $0; } + * If input is abc def xxx, $0 becomes abc:Q:xxx. + * + * We should store the value in rtx->inrec.line so that the caller + * can use it to make a value for $0. + */ HAWK_ASSERT (lv > 0); max = (lv > rtx->inrec.nflds)? lv: rtx->inrec.nflds; @@ -385,7 +401,7 @@ static int recomp_record_fields (hawk_rtx_t* rtx, hawk_oow_t lv, const hawk_oocs * the field spaces are resized */ tmp = hawk_rtx_reallocmem(rtx, rtx->inrec.flds, HAWK_SIZEOF(*rtx->inrec.flds) * max); - if (!tmp) return -1; + if (HAWK_UNLIKELY(!tmp)) return -1; rtx->inrec.flds = tmp; rtx->inrec.maxflds = max; @@ -411,11 +427,11 @@ static int recomp_record_fields (hawk_rtx_t* rtx, hawk_oow_t lv, const hawk_oocs if (hawk_ooecs_ncat(&rtx->inrec.line, str->ptr, str->len) == (hawk_oow_t)-1) return -1; - tmp = hawk_rtx_makestrvalwithoocs (rtx, str); - if (tmp == HAWK_NULL) return -1; + tmp = prefer_number? hawk_rtx_makenumorstrvalwithoochars(rtx, str->ptr, str->len): + hawk_rtx_makestrvalwithoochars(rtx, str->ptr, str->len); + if (HAWK_UNLIKELY(!tmp)) return -1; - if (i < nflds) - hawk_rtx_refdownval (rtx, rtx->inrec.flds[i].val); + if (i < nflds) hawk_rtx_refdownval (rtx, rtx->inrec.flds[i].val); else rtx->inrec.nflds++; rtx->inrec.flds[i].val = tmp; @@ -438,27 +454,29 @@ static int recomp_record_fields (hawk_rtx_t* rtx, hawk_oow_t lv, const hawk_oocs } else { - hawk_val_str_t* tmp; + hawk_ooch_t* vp; + hawk_oow_t vl; - tmp = (hawk_val_str_t*)rtx->inrec.flds[i].val; + vp = hawk_rtx_getvaloocstr(rtx, rtx->inrec.flds[i].val, &vl); + if (HAWK_UNLIKELY(!vp)) return -1; - rtx->inrec.flds[i].ptr = HAWK_OOECS_PTR(&rtx->inrec.line) + HAWK_OOECS_LEN(&rtx->inrec.line); - rtx->inrec.flds[i].len = tmp->val.len; + vl = hawk_ooecs_ncat(&rtx->inrec.line, vp, vl); + hawk_rtx_freevaloocstr (rtx, rtx->inrec.flds[i].val, vp); - if (hawk_ooecs_ncat(&rtx->inrec.line, tmp->val.ptr, tmp->val.len) == (hawk_oow_t)-1) return -1; + if (HAWK_UNLIKELY(vl == (hawk_oow_t)-1)) return -1; } } - v = hawk_rtx_getgbl (rtx, HAWK_GBL_NF); - HAWK_ASSERT (HAWK_RTX_GETVALTYPE (rtx, v) == HAWK_VAL_INT); + v = hawk_rtx_getgbl(rtx, HAWK_GBL_NF); + HAWK_ASSERT (HAWK_RTX_GETVALTYPE(rtx, v) == HAWK_VAL_INT); - if (HAWK_RTX_GETINTFROMVAL (rtx, v)!= max) + if (HAWK_RTX_GETINTFROMVAL(rtx, v) != max) { v = hawk_rtx_makeintval (rtx, (hawk_int_t)max); if (v == HAWK_NULL) return -1; hawk_rtx_refupval (rtx, v); - if (hawk_rtx_setgbl (rtx, HAWK_GBL_NF, v) == -1) + if (hawk_rtx_setgbl(rtx, HAWK_GBL_NF, v) <= -1) { hawk_rtx_refdownval (rtx, v); return -1; @@ -469,3 +487,94 @@ static int recomp_record_fields (hawk_rtx_t* rtx, hawk_oow_t lv, const hawk_oocs return 0; } +int hawk_rtx_truncrec (hawk_rtx_t* rtx, hawk_oow_t nflds) +{ + hawk_val_t* v; + hawk_ooch_t* ofs_free = HAWK_NULL, * ofs_ptr; + hawk_oow_t ofs_len, i; + hawk_ooecs_t tmp; + hawk_val_type_t vtype; + + HAWK_ASSERT (nflds <= rtx->inrec.nflds); + + if (nflds > 1) + { + v = RTX_STACK_GBL(rtx, HAWK_GBL_OFS); + hawk_rtx_refupval (rtx, v); + vtype = HAWK_RTX_GETVALTYPE(rtx, v); + + if (vtype == HAWK_VAL_NIL) + { + /* OFS not set */ + ofs_ptr = HAWK_T(" "); + ofs_len = 1; + } + else if (vtype == HAWK_VAL_STR) + { + ofs_ptr = ((hawk_val_str_t*)v)->val.ptr; + ofs_len = ((hawk_val_str_t*)v)->val.len; + } + else + { + hawk_rtx_valtostr_out_t out; + + out.type = HAWK_RTX_VALTOSTR_CPLDUP; + if (hawk_rtx_valtostr(rtx, v, &out) <= -1) return -1; + + ofs_ptr = out.u.cpldup.ptr; + ofs_len = out.u.cpldup.len; + ofs_free = ofs_ptr; + } + } + + if (hawk_ooecs_init(&tmp, hawk_rtx_getgem(rtx), HAWK_OOECS_LEN(&rtx->inrec.line)) <= -1) + { + if (ofs_free) hawk_rtx_freemem (rtx, ofs_free); + if (nflds > 1) hawk_rtx_refdownval (rtx, v); + return -1; + } + + for (i = 0; i < nflds; i++) + { + if (i > 0 && hawk_ooecs_ncat(&tmp,ofs_ptr,ofs_len) == (hawk_oow_t)-1) + { + hawk_ooecs_fini (&tmp); + if (ofs_free) hawk_rtx_freemem (rtx, ofs_free); + if (nflds > 1) hawk_rtx_refdownval (rtx, v); + return -1; + } + + if (hawk_ooecs_ncat(&tmp, rtx->inrec.flds[i].ptr, rtx->inrec.flds[i].len) == (hawk_oow_t)-1) + { + hawk_ooecs_fini (&tmp); + if (ofs_free) hawk_rtx_freemem (rtx, ofs_free); + if (nflds > 1) hawk_rtx_refdownval (rtx, v); + return -1; + } + } + + if (ofs_free) hawk_rtx_freemem (rtx, ofs_free); + if (nflds > 1) hawk_rtx_refdownval (rtx, v); + + v = (hawk_val_t*)hawk_rtx_makestrvalwithoocs(rtx, HAWK_OOECS_OOCS(&tmp)); + if (!v) + { + hawk_ooecs_fini (&tmp); + return -1; + } + + if (HAWK_RTX_GETVALTYPE(rtx, rtx->inrec.d0) != HAWK_VAL_NIL) hawk_rtx_refdownval (rtx, rtx->inrec.d0); + rtx->inrec.d0 = v; + hawk_rtx_refupval (rtx, rtx->inrec.d0); + + hawk_ooecs_swap (&tmp, &rtx->inrec.line); + hawk_ooecs_fini (&tmp); + + for (i = nflds; i < rtx->inrec.nflds; i++) + { + hawk_rtx_refdownval (rtx, rtx->inrec.flds[i].val); + } + + rtx->inrec.nflds = nflds; + return 0; +} diff --git a/hawk/lib/run.c b/hawk/lib/run.c index 69d41224..2465b209 100644 --- a/hawk/lib/run.c +++ b/hawk/lib/run.c @@ -213,7 +213,6 @@ static int __raw_push (hawk_rtx_t* rtx, void* val); } while (0) static int read_record (hawk_rtx_t* rtx); -static int shorten_record (hawk_rtx_t* rtx, hawk_oow_t nflds); static hawk_ooch_t* idxnde_to_str (hawk_rtx_t* rtx, hawk_nde_t* nde, hawk_ooch_t* buf, hawk_oow_t* len); @@ -341,7 +340,7 @@ static int set_global (hawk_rtx_t* rtx, int idx, hawk_nde_var_t* var, hawk_val_t } } - if (old == val) + if (old == val && idx != HAWK_GBL_NF) /* read the comment in the case block for HAWK_GBL_NF below */ { /* if the old value is the same as the new value, don't take any actions. * note that several inspections have been performed before this check, @@ -384,8 +383,8 @@ static int set_global (hawk_rtx_t* rtx, int idx, hawk_nde_var_t* var, hawk_val_t int n; hawk_int_t lv; - n = hawk_rtx_valtoint (rtx, val, &lv); - if (n <= -1) return -1; + n = hawk_rtx_valtoint(rtx, val, &lv); + if (HAWK_UNLIKELY(n <= -1)) return -1; rtx->gbl.fnr = lv; break; @@ -462,15 +461,42 @@ static int set_global (hawk_rtx_t* rtx, int idx, hawk_nde_var_t* var, hawk_val_t n = hawk_rtx_valtoint(rtx, val, &lv); if (n <= -1) return -1; - if (lv < (hawk_int_t)rtx->inrec.nflds) + if (lv < 0) { - if (shorten_record(rtx, (hawk_oow_t)lv) == -1) + hawk_rtx_seterrfmt (rtx, HAWK_NULL, HAWK_EINVAL, HAWK_T("negative value into NF")); + return -1; + } + + if (lv < (hawk_int_t)rtx->inrec.nflds || (assign && lv == (hawk_int_t)rtx->inrec.nflds)) + { + /* when NF is assigned a value, it should rebuild $X values. + * even when there is no change in the value like NF = NF, + * it has to rebuil $X values with the current OFS value. + * { OFS=":"; NF=NF; print $0; } + * the NF=value assignment is indicated by a non-zero value in the 'assign' variable. + * 'assign' is 0 if this function is called from a different context such as + * explicit call to hawk_rtx_setgbl(). + */ + + if (hawk_rtx_truncrec(rtx, (hawk_oow_t)lv) <= -1) { /* adjust the error line */ /*if (var) ADJERR_LOC (rtx, &var->loc);*/ return -1; } } + else if (lv > (hawk_int_t)rtx->inrec.nflds) + { + hawk_oocs_t cs; + cs.ptr = HAWK_T(""); + cs.len = 0; + if (hawk_rtx_setrec(rtx, lv, &cs, 0) <= -1) return -1; + } + + /* for all other globals, it returns before this switch/case block is reached + * if the same value is assigned. but NF change requires extra action to take + * as coded before this switch/case block. */ + if (old == val) return 0; break; } @@ -663,7 +689,7 @@ int hawk_rtx_setgbltostrbyname (hawk_rtx_t* rtx, const hawk_ooch_t* name, const } else { - n = set_global(rtx, id, HAWK_NULL, v, 1); + n = set_global(rtx, id, HAWK_NULL, v, 0); } hawk_rtx_refdownval (rtx, v); @@ -1265,7 +1291,7 @@ static int prepare_globals (hawk_rtx_t* rtx) hawk_rtx_seterrnum (rtx, HAWK_NULL, HAWK_ENOMEM); goto oops; } - } + } /* override NF to zero */ if (hawk_rtx_setgbl(rtx, HAWK_GBL_NF, HAWK_VAL_ZERO) <= -1) goto oops; @@ -1454,7 +1480,7 @@ static hawk_val_t* run_bpae_loop (hawk_rtx_t* rtx) rtx->active_block = blk; rtx->exit_level = EXIT_NONE; - if (run_block (rtx, blk) == -1) ret = -1; + if (run_block(rtx, blk) <= -1) ret = -1; } if (ret <= -1 && hawk_rtx_geterrnum(rtx) == HAWK_ENOERR) @@ -1866,7 +1892,7 @@ static int run_pblocks (hawk_rtx_t* rtx) rtx->exit_level = EXIT_NONE; n = read_record(rtx); - if (n == -1) + if (n <= -1) { ADJUST_ERROR (rtx); return -1; /* error */ @@ -1875,7 +1901,7 @@ static int run_pblocks (hawk_rtx_t* rtx) if (rtx->awk->tree.chain) { - if (run_pblock_chain(rtx, rtx->awk->tree.chain) == -1) return -1; + if (run_pblock_chain(rtx, rtx->awk->tree.chain) <= -1) return -1; } } @@ -1953,41 +1979,24 @@ static int run_pblock (hawk_rtx_t* rtx, hawk_chain_t* cha, hawk_oow_t bno) hawk_val_t* v1; v1 = eval_expression(rtx, ptn); - if (!v1) return -1; + if (HAWK_UNLIKELY(!v1)) return -1; hawk_rtx_refupval (rtx, v1); - - if (hawk_rtx_valtobool(rtx, v1)) - { - rtx->active_block = blk; - if (run_block(rtx, blk) <= -1) - { - hawk_rtx_refdownval (rtx, v1); - return -1; - } - - rtx->pattern_range_state[bno] = 1; - } - + rtx->pattern_range_state[bno] = hawk_rtx_valtobool(rtx, v1); hawk_rtx_refdownval (rtx, v1); } - else if (rtx->pattern_range_state[bno] == 1) + + if (rtx->pattern_range_state[bno] == 1) { hawk_val_t* v2; v2 = eval_expression(rtx, ptn->next); if (!v2) return -1; hawk_rtx_refupval (rtx, v2); + rtx->pattern_range_state[bno] = !hawk_rtx_valtobool(rtx, v2); + hawk_rtx_refdownval (rtx, v2); rtx->active_block = blk; - if (run_block(rtx, blk) <= -1) - { - hawk_rtx_refdownval(rtx, v2); - return -1; - } - - if (hawk_rtx_valtobool(rtx, v2)) rtx->pattern_range_state[bno] = 0; - - hawk_rtx_refdownval (rtx, v2); + if (run_block(rtx, blk) <= -1) return -1; } } } @@ -3294,6 +3303,7 @@ static hawk_val_t* eval_expression (hawk_rtx_t* rtx, hawk_nde_t* nde) if (HAWK_RTX_GETVALTYPE (rtx, v) == HAWK_VAL_REX) { hawk_oocs_t vs; + int free_vs = 0; /* special case where a regular expression is used in * without any match operators: @@ -3312,28 +3322,36 @@ static hawk_val_t* eval_expression (hawk_rtx_t* rtx, hawk_nde_t* nde) } else { - /* the internal value representing $0 should always be of the string type once it has been set/updated. it is nil initially. */ + #if 0 + /* the internal value representing $0 should always be of the string type + * once it has been set/updated. it is nil initially. */ HAWK_ASSERT (HAWK_RTX_GETVALTYPE(rtx, rtx->inrec.d0) == HAWK_VAL_STR); vs.ptr = ((hawk_val_str_t*)rtx->inrec.d0)->val.ptr; vs.len = ((hawk_val_str_t*)rtx->inrec.d0)->val.len; + #else + vs.ptr = hawk_rtx_getvaloocstr(rtx, rtx->inrec.d0, &vs.len); + if (!vs.ptr) + { + ADJERR_LOC (rtx, &nde->loc); + hawk_rtx_refdownval (rtx, v); + return HAWK_NULL; + } + + free_vs = 1; + #endif } n = hawk_rtx_matchval(rtx, v, &vs, &vs, HAWK_NULL, HAWK_NULL); + hawk_rtx_refdownval (rtx, v); + if (free_vs) hawk_rtx_freevaloocstr (rtx, rtx->inrec.d0, vs.ptr); if (n <= -1) { ADJERR_LOC (rtx, &nde->loc); - hawk_rtx_refdownval (rtx, v); return HAWK_NULL; } - hawk_rtx_refdownval (rtx, v); v = hawk_rtx_makeintval(rtx, (n != 0)); - if (v == HAWK_NULL) - { - /* adjust error line */ - ADJERR_LOC (rtx, &nde->loc); - return HAWK_NULL; - } + HAWK_ASSERT (v != HAWK_NULL); /* this will never fail as the value is 0 or 1 */ } return v; @@ -3766,7 +3784,7 @@ retry: hawk_rtx_refupval (rtx, tmp); x = hawk_rtx_setgbl(rtx, (int)var->id.idxa, tmp); hawk_rtx_refdownval (rtx, tmp); - if (x <= -1) + if (HAWK_UNLIKELY(x <= -1)) { ADJERR_LOC (rtx, &var->loc); return HAWK_NULL; @@ -3820,6 +3838,7 @@ retry: str = idxnde_to_str(rtx, var->idx, idxbuf, &len); if (str == HAWK_NULL) return HAWK_NULL; + #if defined(DEBUG_RUN) hawk_logfmt (hawk_rtx_gethawk(rtx), HAWK_T("**** index str=>%s, map->ref=%d, map->type=%d\n"), str, (int)map->ref, (int)map->type); #endif @@ -3882,7 +3901,7 @@ static hawk_val_t* do_assignment_pos (hawk_rtx_t* rtx, hawk_nde_pos_t* pos, hawk str = out.u.cpldup; } - n = hawk_rtx_setrec(rtx, (hawk_oow_t)lv, &str); + n = hawk_rtx_setrec(rtx, (hawk_oow_t)lv, &str, 0); if (vtype == HAWK_VAL_STR) { @@ -4071,8 +4090,8 @@ static hawk_val_t* eval_binop_land (hawk_rtx_t* run, hawk_nde_t* left, hawk_nde_ hawk_val_t* lv, * rv, * res; HAWK_ASSERT (left->next == HAWK_NULL); - lv = eval_expression (run, left); - if (lv == HAWK_NULL) return HAWK_NULL; + lv = eval_expression(run, left); + if (HAWK_UNLIKELY(!lv)) return HAWK_NULL; hawk_rtx_refupval (run, lv); if (!hawk_rtx_valtobool(run, lv)) @@ -4082,8 +4101,8 @@ static hawk_val_t* eval_binop_land (hawk_rtx_t* run, hawk_nde_t* left, hawk_nde_ else { HAWK_ASSERT (right->next == HAWK_NULL); - rv = eval_expression (run, right); - if (rv == HAWK_NULL) + rv = eval_expression(run, right); + if (HAWK_UNLIKELY(!rv)) { hawk_rtx_refdownval (run, lv); return HAWK_NULL; @@ -4121,14 +4140,14 @@ static hawk_val_t* eval_binop_in (hawk_rtx_t* rtx, hawk_nde_t* left, hawk_nde_t* /* evaluate the left-hand side of the operator */ len = HAWK_COUNTOF(idxbuf); str = (left->type == HAWK_NDE_GRP)? - idxnde_to_str (rtx, ((hawk_nde_grp_t*)left)->body, idxbuf, &len): - idxnde_to_str (rtx, left, idxbuf, &len); - if (str == HAWK_NULL) return HAWK_NULL; + idxnde_to_str(rtx, ((hawk_nde_grp_t*)left)->body, idxbuf, &len): + idxnde_to_str(rtx, left, idxbuf, &len); + if (HAWK_UNLIKELY(!str)) return HAWK_NULL; /* evaluate the right-hand side of the operator */ HAWK_ASSERT (right->next == HAWK_NULL); - rv = eval_expression (rtx, right); - if (rv == HAWK_NULL) + rv = eval_expression(rtx, right); + if (HAWK_UNLIKELY(!rv)) { if (str != idxbuf) hawk_rtx_freemem (rtx, str); return HAWK_NULL; @@ -4164,49 +4183,46 @@ static hawk_val_t* eval_binop_in (hawk_rtx_t* rtx, hawk_nde_t* left, hawk_nde_t* return HAWK_NULL; } -static hawk_val_t* eval_binop_bor ( - hawk_rtx_t* rtx, hawk_val_t* left, hawk_val_t* right) +static hawk_val_t* eval_binop_bor (hawk_rtx_t* rtx, hawk_val_t* left, hawk_val_t* right) { hawk_int_t l1, l2; - if (hawk_rtx_valtoint (rtx, left, &l1) <= -1 || - hawk_rtx_valtoint (rtx, right, &l2) <= -1) + if (hawk_rtx_valtoint(rtx, left, &l1) <= -1 || + hawk_rtx_valtoint(rtx, right, &l2) <= -1) { hawk_rtx_seterrnum (rtx, HAWK_NULL, HAWK_EOPERAND); return HAWK_NULL; } - return hawk_rtx_makeintval (rtx, l1 | l2); + return hawk_rtx_makeintval(rtx, l1 | l2); } -static hawk_val_t* eval_binop_bxor ( - hawk_rtx_t* rtx, hawk_val_t* left, hawk_val_t* right) +static hawk_val_t* eval_binop_bxor (hawk_rtx_t* rtx, hawk_val_t* left, hawk_val_t* right) { hawk_int_t l1, l2; - if (hawk_rtx_valtoint (rtx, left, &l1) <= -1 || - hawk_rtx_valtoint (rtx, right, &l2) <= -1) + if (hawk_rtx_valtoint(rtx, left, &l1) <= -1 || + hawk_rtx_valtoint(rtx, right, &l2) <= -1) { hawk_rtx_seterrnum (rtx, HAWK_NULL, HAWK_EOPERAND); return HAWK_NULL; } - return hawk_rtx_makeintval (rtx, l1 ^ l2); + return hawk_rtx_makeintval(rtx, l1 ^ l2); } -static hawk_val_t* eval_binop_band ( - hawk_rtx_t* rtx, hawk_val_t* left, hawk_val_t* right) +static hawk_val_t* eval_binop_band (hawk_rtx_t* rtx, hawk_val_t* left, hawk_val_t* right) { hawk_int_t l1, l2; - if (hawk_rtx_valtoint (rtx, left, &l1) <= -1 || - hawk_rtx_valtoint (rtx, right, &l2) <= -1) + if (hawk_rtx_valtoint(rtx, left, &l1) <= -1 || + hawk_rtx_valtoint(rtx, right, &l2) <= -1) { hawk_rtx_seterrnum (rtx, HAWK_NULL, HAWK_EOPERAND); return HAWK_NULL; } - return hawk_rtx_makeintval (rtx, l1 & l2); + return hawk_rtx_makeintval(rtx, l1 & l2); } /* -------------------------------------------------------------------- */ @@ -4345,7 +4361,7 @@ static HAWK_INLINE int __cmp_int_str (hawk_rtx_t* rtx, hawk_val_t* left, hawk_va hawk_flt_t rr; n = hawk_oochars_to_num( - HAWK_OOCHARS_TO_NUM_MAKE_OPTION(1, (hawk->opt.trait & HAWK_STRIPSTRSPC), 0), + HAWK_OOCHARS_TO_NUM_MAKE_OPTION(1, 0, (hawk->opt.trait & HAWK_STRIPSTRSPC), 0), ((hawk_val_str_t*)right)->val.ptr, ((hawk_val_str_t*)right)->val.len, &ll, &rr @@ -4385,7 +4401,7 @@ static HAWK_INLINE int __cmp_int_mbs (hawk_rtx_t* rtx, hawk_val_t* left, hawk_va hawk_flt_t rr; n = hawk_bchars_to_num ( - HAWK_OOCHARS_TO_NUM_MAKE_OPTION(1, (hawk->opt.trait & HAWK_STRIPSTRSPC), 0), + HAWK_OOCHARS_TO_NUM_MAKE_OPTION(1, 0, (hawk->opt.trait & HAWK_STRIPSTRSPC), 0), ((hawk_val_mbs_t*)right)->val.ptr, ((hawk_val_mbs_t*)right)->val.len, &ll, &rr @@ -4503,7 +4519,7 @@ static HAWK_INLINE int __cmp_flt_mbs (hawk_rtx_t* rtx, hawk_val_t* left, hawk_va } str0 = hawk_rtx_valtobcstrdup(rtx, left, &len0); - if (!str0) return CMP_ERROR; + if (HAWK_UNLIKELY(!str0)) return CMP_ERROR; n = hawk_comp_bchars(str0, len0, ((hawk_val_mbs_t*)right)->val.ptr, ((hawk_val_mbs_t*)right)->val.len, rtx->gbl.ignorecase); hawk_rtx_freemem (rtx, str0); @@ -4551,7 +4567,7 @@ static HAWK_INLINE int __cmp_str_str (hawk_rtx_t* rtx, hawk_val_t* left, hawk_va { hawk_t* hawk = hawk_rtx_gethawk(rtx); hawk_val_str_t* ls, * rs; - + int stripspc; ls = (hawk_val_str_t*)left; rs = (hawk_val_str_t*)right; @@ -4562,17 +4578,19 @@ static HAWK_INLINE int __cmp_str_str (hawk_rtx_t* rtx, hawk_val_t* left, hawk_va return hawk_comp_oochars(ls->val.ptr, ls->val.len, rs->val.ptr, rs->val.len, rtx->gbl.ignorecase); } + stripspc = (hawk->opt.trait & HAWK_STRIPSTRSPC); + if (ls->nstr == 1) { hawk_int_t ll; - ll = hawk_oochars_to_int(ls->val.ptr, ls->val.len, 0, HAWK_NULL, (hawk->opt.trait & HAWK_STRIPSTRSPC)); + ll = hawk_oochars_to_int(ls->val.ptr, ls->val.len, HAWK_OOCHARS_TO_INT_MAKE_OPTION(stripspc, stripspc, 0), HAWK_NULL, HAWK_NULL); if (rs->nstr == 1) { hawk_int_t rr; - rr = hawk_oochars_to_int(rs->val.ptr, rs->val.len, 0, HAWK_NULL, (hawk->opt.trait & HAWK_STRIPSTRSPC)); + rr = hawk_oochars_to_int(rs->val.ptr, rs->val.len, HAWK_OOCHARS_TO_INT_MAKE_OPTION(stripspc, stripspc, 0), HAWK_NULL, HAWK_NULL); return (ll > rr)? 1: (ll < rr)? -1: 0; @@ -4583,7 +4601,7 @@ static HAWK_INLINE int __cmp_str_str (hawk_rtx_t* rtx, hawk_val_t* left, hawk_va HAWK_ASSERT (rs->nstr == 2); - rr = hawk_oochars_to_flt(rs->val.ptr, rs->val.len, HAWK_NULL, (hawk->opt.trait & HAWK_STRIPSTRSPC)); + rr = hawk_oochars_to_flt(rs->val.ptr, rs->val.len, HAWK_NULL, stripspc); return (ll > rr)? 1: (ll < rr)? -1: 0; @@ -4595,13 +4613,13 @@ static HAWK_INLINE int __cmp_str_str (hawk_rtx_t* rtx, hawk_val_t* left, hawk_va HAWK_ASSERT (ls->nstr == 2); - ll = hawk_oochars_to_flt(ls->val.ptr, ls->val.len, HAWK_NULL, (hawk->opt.trait & HAWK_STRIPSTRSPC)); + ll = hawk_oochars_to_flt(ls->val.ptr, ls->val.len, HAWK_NULL, stripspc); if (rs->nstr == 1) { hawk_int_t rr; - rr = hawk_oochars_to_int(rs->val.ptr, rs->val.len, 0, HAWK_NULL, (hawk->opt.trait & HAWK_STRIPSTRSPC)); + rr = hawk_oochars_to_int(rs->val.ptr, rs->val.len, HAWK_OOCHARS_TO_INT_MAKE_OPTION(stripspc, stripspc, 0), HAWK_NULL, HAWK_NULL); return (ll > rr)? 1: (ll < rr)? -1: 0; @@ -4612,7 +4630,7 @@ static HAWK_INLINE int __cmp_str_str (hawk_rtx_t* rtx, hawk_val_t* left, hawk_va HAWK_ASSERT (rs->nstr == 2); - rr = hawk_oochars_to_flt(rs->val.ptr, rs->val.len, HAWK_NULL, (hawk->opt.trait & HAWK_STRIPSTRSPC)); + rr = hawk_oochars_to_flt(rs->val.ptr, rs->val.len, HAWK_NULL, stripspc); return (ll > rr)? 1: (ll < rr)? -1: 0; @@ -6789,7 +6807,7 @@ read_console_again: if (p->var == HAWK_NULL) { /* set $0 with the input value */ - x = hawk_rtx_setrec(rtx, 0, HAWK_OOECS_OOCS(buf)); + x = hawk_rtx_setrec(rtx, 0, HAWK_OOECS_OOCS(buf), 1); if (x <= -1) return HAWK_NULL; } else @@ -6797,8 +6815,8 @@ read_console_again: hawk_val_t* v; /* treat external input numerically if it can compose a number. */ - v = hawk_rtx_makestrvalwithoocs(rtx, HAWK_OOECS_OOCS(buf)); - /*v = hawk_rtx_makenumorstrvalwithoochars(rtx, HAWK_OOECS_PTR(buf), HAWK_OOECS_LEN(buf));*/ + /*v = hawk_rtx_makestrvalwithoocs(rtx, HAWK_OOECS_OOCS(buf));*/ + v = hawk_rtx_makenumorstrvalwithoochars(rtx, HAWK_OOECS_PTR(buf), HAWK_OOECS_LEN(buf)); if (HAWK_UNLIKELY(!v)) { ADJERR_LOC (rtx, &nde->loc); @@ -6907,8 +6925,8 @@ read_console_again: hawk_val_t* v; /* treat external input numerically if it can compose a number. */ - v = hawk_rtx_makembsvalwithbcs(rtx, HAWK_BECS_BCS(buf)); - /*v = hawk_rtx_makenumormbsvalwithbchars(rtx, HAWK_BECS_PTR(buf), HAWK_BECS_LEN(buf));*/ + /*v = hawk_rtx_makembsvalwithbcs(rtx, HAWK_BECS_BCS(buf));*/ + v = hawk_rtx_makenumormbsvalwithbchars(rtx, HAWK_BECS_PTR(buf), HAWK_BECS_LEN(buf)); if (v == HAWK_NULL) { ADJERR_LOC (rtx, &nde->loc); @@ -6986,7 +7004,7 @@ static int read_record (hawk_rtx_t* rtx) hawk_ooecs_t* buf; read_again: - if (hawk_rtx_clrrec (rtx, 0) == -1) return -1; + if (hawk_rtx_clrrec(rtx, 0) <= -1) return -1; buf = &rtx->inrec.line; n = hawk_rtx_readio(rtx, HAWK_IN_CONSOLE, HAWK_T(""), buf); @@ -7014,104 +7032,12 @@ read_again: } } - if (hawk_rtx_setrec(rtx, 0, HAWK_OOECS_OOCS(buf)) <= -1 || + if (hawk_rtx_setrec(rtx, 0, HAWK_OOECS_OOCS(buf), 1) <= -1 || update_fnr(rtx, rtx->gbl.fnr + 1, rtx->gbl.nr + 1) <= -1) return -1; return 1; } -static int shorten_record (hawk_rtx_t* rtx, hawk_oow_t nflds) -{ - hawk_val_t* v; - hawk_ooch_t* ofs_free = HAWK_NULL, * ofs_ptr; - hawk_oow_t ofs_len, i; - hawk_ooecs_t tmp; - hawk_val_type_t vtype; - - HAWK_ASSERT (nflds <= rtx->inrec.nflds); - - if (nflds > 1) - { - v = RTX_STACK_GBL(rtx, HAWK_GBL_OFS); - hawk_rtx_refupval (rtx, v); - vtype = HAWK_RTX_GETVALTYPE(rtx, v); - - if (vtype == HAWK_VAL_NIL) - { - /* OFS not set */ - ofs_ptr = HAWK_T(" "); - ofs_len = 1; - } - else if (vtype == HAWK_VAL_STR) - { - ofs_ptr = ((hawk_val_str_t*)v)->val.ptr; - ofs_len = ((hawk_val_str_t*)v)->val.len; - } - else - { - hawk_rtx_valtostr_out_t out; - - out.type = HAWK_RTX_VALTOSTR_CPLDUP; - if (hawk_rtx_valtostr (rtx, v, &out) <= -1) return -1; - - ofs_ptr = out.u.cpldup.ptr; - ofs_len = out.u.cpldup.len; - ofs_free = ofs_ptr; - } - } - - if (hawk_ooecs_init(&tmp, hawk_rtx_getgem(rtx), HAWK_OOECS_LEN(&rtx->inrec.line)) <= -1) - { - if (ofs_free) hawk_rtx_freemem (rtx, ofs_free); - if (nflds > 1) hawk_rtx_refdownval (rtx, v); - return -1; - } - - for (i = 0; i < nflds; i++) - { - if (i > 0 && hawk_ooecs_ncat(&tmp,ofs_ptr,ofs_len) == (hawk_oow_t)-1) - { - hawk_ooecs_fini (&tmp); - if (ofs_free) hawk_rtx_freemem (rtx, ofs_free); - if (nflds > 1) hawk_rtx_refdownval (rtx, v); - return -1; - } - - if (hawk_ooecs_ncat(&tmp, rtx->inrec.flds[i].ptr, rtx->inrec.flds[i].len) == (hawk_oow_t)-1) - { - hawk_ooecs_fini (&tmp); - if (ofs_free) hawk_rtx_freemem (rtx, ofs_free); - if (nflds > 1) hawk_rtx_refdownval (rtx, v); - return -1; - } - } - - if (ofs_free) hawk_rtx_freemem (rtx, ofs_free); - if (nflds > 1) hawk_rtx_refdownval (rtx, v); - - v = (hawk_val_t*)hawk_rtx_makestrvalwithoocs(rtx, HAWK_OOECS_OOCS(&tmp)); - if (!v) - { - hawk_ooecs_fini (&tmp); - return -1; - } - - hawk_rtx_refdownval (rtx, rtx->inrec.d0); - rtx->inrec.d0 = v; - hawk_rtx_refupval (rtx, rtx->inrec.d0); - - hawk_ooecs_swap (&tmp, &rtx->inrec.line); - hawk_ooecs_fini (&tmp); - - for (i = nflds; i < rtx->inrec.nflds; i++) - { - hawk_rtx_refdownval (rtx, rtx->inrec.flds[i].val); - } - - rtx->inrec.nflds = nflds; - return 0; -} - static hawk_ooch_t* idxnde_to_str (hawk_rtx_t* rtx, hawk_nde_t* nde, hawk_ooch_t* buf, hawk_oow_t* len) { hawk_ooch_t* str; @@ -7124,8 +7050,8 @@ static hawk_ooch_t* idxnde_to_str (hawk_rtx_t* rtx, hawk_nde_t* nde, hawk_ooch_t hawk_rtx_valtostr_out_t out; /* single node index */ - idx = eval_expression (rtx, nde); - if (!idx) return HAWK_NULL; + idx = eval_expression(rtx, nde); + if (HAWK_UNLIKELY(!idx)) return HAWK_NULL; hawk_rtx_refupval (rtx, idx); @@ -7170,6 +7096,7 @@ static hawk_ooch_t* idxnde_to_str (hawk_rtx_t* rtx, hawk_nde_t* nde, hawk_ooch_t hawk_ooecs_t idxstr; hawk_oocs_t tmp; hawk_rtx_valtostr_out_t out; + hawk_nde_t* xnde; out.type = HAWK_RTX_VALTOSTR_STRPCAT; out.u.strpcat = &idxstr; @@ -7180,10 +7107,11 @@ static hawk_ooch_t* idxnde_to_str (hawk_rtx_t* rtx, hawk_nde_t* nde, hawk_ooch_t return HAWK_NULL; } + xnde = nde; while (nde) { idx = eval_expression(rtx, nde); - if (!idx) + if (HAWK_UNLIKELY(!idx)) { hawk_ooecs_fini (&idxstr); return HAWK_NULL; @@ -7191,7 +7119,7 @@ static hawk_ooch_t* idxnde_to_str (hawk_rtx_t* rtx, hawk_nde_t* nde, hawk_ooch_t hawk_rtx_refupval (rtx, idx); - if (HAWK_OOECS_LEN(&idxstr) > 0 && hawk_ooecs_ncat(&idxstr, rtx->gbl.subsep.ptr, rtx->gbl.subsep.len) == (hawk_oow_t)-1) + if (xnde != nde && hawk_ooecs_ncat(&idxstr, rtx->gbl.subsep.ptr, rtx->gbl.subsep.len) == (hawk_oow_t)-1) { hawk_rtx_refdownval (rtx, idx); hawk_ooecs_fini (&idxstr); @@ -7447,10 +7375,10 @@ wp_mod_main: if (i >= fmt_len) break; - if (fmt[i] == HAWK_T('d') || fmt[i] == HAWK_T('i') || - fmt[i] == HAWK_T('x') || fmt[i] == HAWK_T('X') || - fmt[i] == HAWK_T('b') || fmt[i] == HAWK_T('B') || - fmt[i] == HAWK_T('o')) + if (fmt[i] == 'd' || fmt[i] == 'i' || + fmt[i] == 'x' || fmt[i] == 'X' || + fmt[i] == 'b' || fmt[i] == 'B' || + fmt[i] == 'o' || fmt[i] == 'u') { hawk_val_t* v; hawk_int_t l; @@ -7550,8 +7478,8 @@ wp_mod_main: switch (fmt[i]) { - case HAWK_T('B'): - case HAWK_T('b'): + case 'B': + case 'b': fmt_flags |= 2; fmt_uint = 1; if (l && (flags & FLAG_HASH)) @@ -7561,9 +7489,9 @@ wp_mod_main: } break; - case HAWK_T('X'): + case 'X': fmt_flags |= HAWK_FMT_INTMAX_UPPERCASE; - case HAWK_T('x'): + case 'x': fmt_flags |= 16; fmt_uint = 1; if (l && (flags & FLAG_HASH)) @@ -7573,7 +7501,7 @@ wp_mod_main: } break; - case HAWK_T('o'): + case 'o': fmt_flags |= 8; fmt_uint = 1; if (flags & FLAG_HASH) @@ -7585,7 +7513,9 @@ wp_mod_main: fmt_flags |= HAWK_FMT_INTMAX_ZEROLEAD; } break; - + + case 'u': + fmt_uint = 1; default: fmt_flags |= 10; if (flags & FLAG_PLUS) @@ -7737,13 +7667,13 @@ wp_mod_main: } else { - v = eval_expression (rtx, args); - if (v == HAWK_NULL) return HAWK_NULL; + v = eval_expression(rtx, args); + if (!HAWK_UNLIKELY(v)) return HAWK_NULL; } } hawk_rtx_refupval (rtx, v); - vtype = HAWK_RTX_GETVALTYPE (rtx, v); + vtype = HAWK_RTX_GETVALTYPE(rtx, v); switch (vtype) { case HAWK_VAL_NIL: @@ -7762,23 +7692,14 @@ wp_mod_main: break; case HAWK_VAL_STR: - ch_len = ((hawk_val_str_t*)v)->val.len; - if (ch_len > 0) - { - ch = ((hawk_val_str_t*)v)->val.ptr[0]; - ch_len = 1; - } - else ch = HAWK_T('\0'); + /* printf("%c", "") => produces '\0' character */ + ch = (((hawk_val_str_t*)v)->val.len > 0)? ((hawk_val_str_t*)v)->val.ptr[0]: '\0'; + ch_len = 1; break; case HAWK_VAL_MBS: - ch_len = ((hawk_val_mbs_t*)v)->val.len; - if (ch_len > 0) - { - ch = ((hawk_val_mbs_t*)v)->val.ptr[0]; - ch_len = 1; - } - else ch = HAWK_T('\0'); + ch = (((hawk_val_mbs_t*)v)->val.len > 0)? ((hawk_val_mbs_t*)v)->val.ptr[0]: '\0'; + ch_len = 1; break; default: diff --git a/hawk/lib/std.c b/hawk/lib/std.c index af2837b2..25cb016d 100644 --- a/hawk/lib/std.c +++ b/hawk/lib/std.c @@ -2465,11 +2465,10 @@ static int build_argcv (hawk_rtx_t* rtx, int argc_id, int argv_id, const hawk_oo { for (argc = 1, p = icf; *p; p++, argc++) { - /* the argument must compose a numeric string if it can be. - * so call hawk_rtx_makenstrvalwithoocstr() instead of - * hawk_rtx_makestrvalwithoocstr(). */ - v_tmp = hawk_rtx_makenstrvalwithoocstr (rtx, *p); - if (v_tmp == HAWK_NULL) + /* the argument must compose a numeric value if possible */ + /*v_tmp = hawk_rtx_makenstrvalwithoocstr(rtx, *p); */ + v_tmp = hawk_rtx_makenumorstrvalwithoochars(rtx, *p, hawk_count_oocstr(*p)); + if (HAWK_UNLIKELY(!v_tmp)) { hawk_rtx_refdownval (rtx, v_argv); return -1; @@ -2538,31 +2537,32 @@ static int build_environ (hawk_rtx_t* rtx, int gbl_id, env_char_t* envarr[]) { env_char_t* eq; hawk_ooch_t* kptr, * vptr; - hawk_oow_t klen, count; + hawk_oow_t klen, vlen, count; for (count = 0; envarr[count]; count++) { #if ((defined(ENV_CHAR_IS_BCH) && defined(HAWK_OOCH_IS_BCH)) || \ (defined(ENV_CHAR_IS_UCH) && defined(HAWK_OOCH_IS_UCH))) - eq = hawk_find_oochar_in_oocstr(envarr[count], HAWK_T('=')); - if (eq == HAWK_NULL || eq == envarr[count]) continue; + eq = hawk_find_oochar_in_oocstr(envarr[count], '='); + if (HAWK_UNLIKELY(!eq || eq == envarr[count])) continue; kptr = envarr[count]; klen = eq - envarr[count]; vptr = eq + 1; + vlen = hawk_count_oocstr(vptr); #elif defined(ENV_CHAR_IS_BCH) - eq = hawk_find_bchar_in_bcstr(envarr[count], HAWK_BT('=')); - if (eq == HAWK_NULL || eq == envarr[count]) continue; + eq = hawk_find_bchar_in_bcstr(envarr[count], '='); + if (HAWK_UNLIKELY(!eq || eq == envarr[count])) continue; - *eq = HAWK_BT('\0'); + *eq = '\0'; /* dupbtoucstr() may fail for invalid encoding. as the environment * variaables are not under control, call mbstowcsalldup() instead * to go on despite encoding failure */ kptr = hawk_rtx_dupbtoucstr(rtx, envarr[count], &klen, 1); - vptr = hawk_rtx_dupbtoucstr(rtx, eq + 1, HAWK_NULL, 1); - if (kptr == HAWK_NULL || vptr == HAWK_NULL) + vptr = hawk_rtx_dupbtoucstr(rtx, eq + 1, &vlen, 1); + if (HAWK_UNLIKELY(!kptr || !vptr)) { if (kptr) hawk_rtx_freemem (rtx, kptr); if (vptr) hawk_rtx_freemem (rtx, vptr); @@ -2570,16 +2570,16 @@ static int build_environ (hawk_rtx_t* rtx, int gbl_id, env_char_t* envarr[]) return -1; } - *eq = HAWK_BT('='); + *eq = '='; #else - eq = hawk_find_uchar_in_ucstr(envarr[count], HAWK_UT('=')); - if (eq == HAWK_NULL || eq == envarr[count]) continue; + eq = hawk_find_uchar_in_ucstr(envarr[count], '='); + if (HAWK_UNLIKELY(!eq || eq == envarr[count])) continue; - *eq = HAWK_UT('\0'); + *eq = '\0'; kptr = hawk_rtx_duputobcstr(rtx, envarr[count], &klen); - vptr = hawk_rtx_duputobcstr(rtx, eq + 1, HAWK_NULL); - if (kptr == HAWK_NULL || vptr == HAWK_NULL) + vptr = hawk_rtx_duputobcstr(rtx, eq + 1, &vlen); + if (HAWK_UNLIKELY(!kptr || !vptr)) { if (kptr) hawk_rtx_freemem (rtx, kptr); if (vptr) hawk_rtx_freeme (rtx, vptr): @@ -2587,14 +2587,14 @@ static int build_environ (hawk_rtx_t* rtx, int gbl_id, env_char_t* envarr[]) return -1; } - *eq = HAWK_UT('='); + *eq = '='; #endif - /* the string in ENVIRON should be a numeric string if - * it can be converted to a number. call makenstrval() - * instead of makestrval() */ - v_tmp = hawk_rtx_makenstrvalwithoocstr(rtx, vptr); - if (v_tmp == HAWK_NULL) + /* the string in ENVIRON should be a numeric value if + * it can be converted to a number. + /*v_tmp = hawk_rtx_makenstrvalwithoocstr(rtx, vptr);*/ + v_tmp = hawk_rtx_makenumorstrvalwithoochars(rtx, vptr, vlen); + if (HAWK_UNLIKELY(!v_tmp)) { #if ((defined(ENV_CHAR_IS_BCH) && defined(HAWK_OOCH_IS_BCH)) || \ (defined(ENV_CHAR_IS_UCH) && defined(HAWK_OOCH_IS_UCH))) @@ -2990,7 +2990,7 @@ static int fnc_setioattr (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi) /* no error is returned by hawk_rtx_strnum() if the strict option * of the second parameter is 0. so i don't check for an error */ - x = hawk_oochars_to_num(HAWK_OOCHARS_TO_NUM_MAKE_OPTION(0, (hawk->opt.trait & HAWK_STRIPSTRSPC), 0), ptr[2], len[2], &l, &r); + x = hawk_oochars_to_num(HAWK_OOCHARS_TO_NUM_MAKE_OPTION(0, 0, (hawk->opt.trait & HAWK_STRIPSTRSPC), 0), ptr[2], len[2], &l, &r); if (x == 0) r = (hawk_flt_t)l; ioattr = find_or_make_ioattr(rtx, &rxtn->cmgrtab, ptr[0], len[0]); diff --git a/hawk/lib/utl-str.c b/hawk/lib/utl-str.c index ed116e5a..931ff4dd 100644 --- a/hawk/lib/utl-str.c +++ b/hawk/lib/utl-str.c @@ -1914,18 +1914,19 @@ hawk_oow_t hawk_int_to_oocstr (hawk_int_t value, int radix, const hawk_ooch_t* p /* ------------------------------------------------------------------------ */ -hawk_int_t hawk_uchars_to_int (const hawk_uch_t* str, hawk_oow_t len, int base, const hawk_uch_t** endptr, int stripspc) +hawk_int_t hawk_uchars_to_int (const hawk_uch_t* str, hawk_oow_t len, int option, const hawk_uch_t** endptr, int* is_sober) { hawk_int_t n = 0; - const hawk_uch_t* p; + const hawk_uch_t* p, * pp; const hawk_uch_t* end; hawk_oow_t rem; int digit, negative = 0; + int base = HAWK_OOCHARS_TO_INT_GET_OPTION_BASE(option); p = str; end = str + len; - - if (stripspc) + + if (HAWK_OOCHARS_TO_INT_GET_OPTION_LTRIM(option)) { /* strip off leading spaces */ while (p < end && hawk_is_uch_space(*p)) p++; @@ -1976,10 +1977,11 @@ hawk_int_t hawk_uchars_to_int (const hawk_uch_t* str, hawk_oow_t len, int base, } /* process the digits */ + pp = p; while (p < end) { - if (*p >= '0' && *p <= '9') - digit = *p - '0'; + if (*p >= '0' && *p <= '9') { + digit = *p - '0'; } else if (*p >= 'A' && *p <= 'Z') digit = *p - 'A' + 10; else if (*p >= 'a' && *p <= 'z') @@ -1992,22 +1994,33 @@ hawk_int_t hawk_uchars_to_int (const hawk_uch_t* str, hawk_oow_t len, int base, p++; } + /* base 8: at least a zero digit has been seen. + * other case: p > pp to be able to have at least 1 meaningful digit. */ + if (is_sober) *is_sober = (base == 8 || p > pp); + + if (HAWK_OOCHARS_TO_INT_GET_OPTION_RTRIM(option)) + { + /* consume trailing spaces */ + while (p < end && hawk_is_uch_space(*p)) p++; + } + if (endptr) *endptr = p; return (negative)? -n: n; } -hawk_int_t hawk_bchars_to_int (const hawk_bch_t* str, hawk_oow_t len, int base, const hawk_bch_t** endptr, int stripspc) +hawk_int_t hawk_bchars_to_int (const hawk_bch_t* str, hawk_oow_t len, int option, const hawk_bch_t** endptr, int* is_sober) { hawk_int_t n = 0; - const hawk_bch_t* p; + const hawk_bch_t* p, * pp; const hawk_bch_t* end; hawk_oow_t rem; int digit, negative = 0; + int base = HAWK_OOCHARS_TO_INT_GET_OPTION_BASE(option); p = str; end = str + len; - if (stripspc) + if (HAWK_OOCHARS_TO_INT_GET_OPTION_LTRIM(option)) { /* strip off leading spaces */ while (p < end && hawk_is_bch_space(*p)) p++; @@ -2058,6 +2071,7 @@ hawk_int_t hawk_bchars_to_int (const hawk_bch_t* str, hawk_oow_t len, int base, } /* process the digits */ + pp = p; while (p < end) { if (*p >= '0' && *p <= '9') @@ -2074,6 +2088,16 @@ hawk_int_t hawk_bchars_to_int (const hawk_bch_t* str, hawk_oow_t len, int base, p++; } + /* base 8: at least a zero digit has been seen. + * other case: p > pp to be able to have at least 1 meaningful digit. */ + if (is_sober) *is_sober = (base == 8 || p > pp); + + if (HAWK_OOCHARS_TO_INT_GET_OPTION_RTRIM(option)) + { + /* consume trailing spaces */ + while (p < end && hawk_is_bch_space(*p)) p++; + } + if (endptr) *endptr = p; return (negative)? -n: n; } @@ -2306,7 +2330,12 @@ no_exp: else fraction *= dbl_exp; done: - if (endptr != HAWK_NULL) *endptr = p; + if (stripspc) + { + /* consume trailing spaces */ + while (p < end && hawk_is_uch_space(*p)) p++; + } + if (endptr) *endptr = p; return (negative)? -fraction: fraction; } @@ -2510,7 +2539,12 @@ no_exp: else fraction *= dbl_exp; done: - if (endptr != HAWK_NULL) *endptr = p; + if (stripspc) + { + /* consume trailing spaces */ + while (p < end && hawk_is_bch_space(*p)) p++; + } + if (endptr) *endptr = p; return (negative)? -fraction: fraction; } @@ -2519,19 +2553,21 @@ int hawk_uchars_to_num (int option, const hawk_uch_t* ptr, hawk_oow_t len, hawk_ const hawk_uch_t* endptr; const hawk_uch_t* end; - int strict = HAWK_OOCHARS_TO_NUM_GET_OPTION_STRICT(option); + int nopartial = HAWK_OOCHARS_TO_NUM_GET_OPTION_NOPARTIAL(option); + int reqsober = HAWK_OOCHARS_TO_NUM_GET_OPTION_REQSOBER(option); int stripspc = HAWK_OOCHARS_TO_NUM_GET_OPTION_STRIPSPC(option); int base = HAWK_OOCHARS_TO_NUM_GET_OPTION_BASE(option); + int is_sober; end = ptr + len; - *l = hawk_uchars_to_int(ptr, len, base, &endptr, stripspc); + *l = hawk_uchars_to_int(ptr, len, HAWK_OOCHARS_TO_INT_MAKE_OPTION(stripspc,0,base), &endptr, &is_sober); if (endptr < end) { if (*endptr == '.' || *endptr == 'E' || *endptr == 'e') { handle_float: *r = hawk_uchars_to_flt(ptr, len, &endptr, stripspc); - if (strict && endptr < end) return -1; + if (nopartial && endptr < end) return -1; return 1; /* flt */ } else if (hawk_is_uch_digit(*endptr)) @@ -2545,7 +2581,7 @@ int hawk_uchars_to_num (int option, const hawk_uch_t* ptr, hawk_oow_t len, hawk_ * BEGIN { b=99; printf "%f\n", (0 b 1.112); } * * for the above code, this function gets '0991.112'. - * and endptr points to '9' after hawk_strxtoint() as + * and endptr points to '9' after hawk_uchars_to_int() as * the numeric string beginning with 0 is treated * as an octal number. * @@ -2558,9 +2594,15 @@ int hawk_uchars_to_num (int option, const hawk_uch_t* ptr, hawk_oow_t len, hawk_ goto handle_float; } } + + if (stripspc) + { + while (endptr < end && hawk_is_uch_space(*endptr)) endptr++; + } } - if (strict && endptr < end) return -1; + if (reqsober && !is_sober) return -1; + if (nopartial && endptr < end) return -1; return 0; /* int */ } @@ -2569,19 +2611,21 @@ int hawk_bchars_to_num (int option, const hawk_bch_t* ptr, hawk_oow_t len, hawk_ const hawk_bch_t* endptr; const hawk_bch_t* end; - int strict = HAWK_OOCHARS_TO_NUM_GET_OPTION_STRICT(option); + int nopartial = HAWK_OOCHARS_TO_NUM_GET_OPTION_NOPARTIAL(option); + int reqsober = HAWK_OOCHARS_TO_NUM_GET_OPTION_REQSOBER(option); int stripspc = HAWK_OOCHARS_TO_NUM_GET_OPTION_STRIPSPC(option); int base = HAWK_OOCHARS_TO_NUM_GET_OPTION_BASE(option); + int is_sober; end = ptr + len; - *l = hawk_bchars_to_int(ptr, len, base, &endptr, stripspc); + *l = hawk_bchars_to_int(ptr, len, HAWK_OOCHARS_TO_INT_MAKE_OPTION(stripspc,0,base), &endptr, &is_sober); if (endptr < end) { if (*endptr == '.' || *endptr == 'E' || *endptr == 'e') { handle_float: *r = hawk_bchars_to_flt(ptr, len, &endptr, stripspc); - if (strict && endptr < end) return -1; + if (nopartial && endptr < end) return -1; return 1; /* flt */ } else if (hawk_is_uch_digit(*endptr)) @@ -2595,7 +2639,7 @@ int hawk_bchars_to_num (int option, const hawk_bch_t* ptr, hawk_oow_t len, hawk_ * BEGIN { b=99; printf "%f\n", (0 b 1.112); } * * for the above code, this function gets '0991.112'. - * and endptr points to '9' after hawk_strxtoint() as + * and endptr points to '9' after hawk_bchars_to_int() as * the numeric string beginning with 0 is treated * as an octal number. * @@ -2608,9 +2652,15 @@ int hawk_bchars_to_num (int option, const hawk_bch_t* ptr, hawk_oow_t len, hawk_ goto handle_float; } } + + if (stripspc) + { + while (endptr < end && hawk_is_bch_space(*endptr)) endptr++; + } } - if (strict && endptr < end) return -1; + if (reqsober && !is_sober) return -1; + if (nopartial && endptr < end) return -1; return 0; /* int */ } diff --git a/hawk/lib/val.c b/hawk/lib/val.c index ed5b444c..82e4606d 100644 --- a/hawk/lib/val.c +++ b/hawk/lib/val.c @@ -307,7 +307,7 @@ hawk_val_t* hawk_rtx_makenumorstrvalwithuchars (hawk_rtx_t* rtx, const hawk_uch_ hawk_int_t l; hawk_flt_t r; - x = hawk_uchars_to_num(HAWK_OOCHARS_TO_NUM_MAKE_OPTION(1, (hawk->opt.trait & HAWK_STRIPSTRSPC), 0), ptr, len, &l, &r); + x = hawk_uchars_to_num(HAWK_OOCHARS_TO_NUM_MAKE_OPTION(1, 1, (hawk->opt.trait & HAWK_STRIPSTRSPC), 0), ptr, len, &l, &r); if (x == 0) return hawk_rtx_makeintval(rtx, l); else if (x >= 1) return hawk_rtx_makefltval(rtx, r); @@ -321,7 +321,7 @@ hawk_val_t* hawk_rtx_makenumorstrvalwithbchars (hawk_rtx_t* rtx, const hawk_bch_ hawk_int_t l; hawk_flt_t r; - x = hawk_bchars_to_num(HAWK_OOCHARS_TO_NUM_MAKE_OPTION(1, (hawk->opt.trait & HAWK_STRIPSTRSPC), 0), ptr, len, &l, &r); + x = hawk_bchars_to_num(HAWK_OOCHARS_TO_NUM_MAKE_OPTION(1, 1, (hawk->opt.trait & HAWK_STRIPSTRSPC), 0), ptr, len, &l, &r); if (x == 0) return hawk_rtx_makeintval(rtx, l); else if (x >= 1) return hawk_rtx_makefltval(rtx, r); @@ -339,7 +339,7 @@ hawk_val_t* hawk_rtx_makenstrvalwithuchars (hawk_rtx_t* rtx, const hawk_uch_t* p hawk_int_t l; hawk_flt_t r; - x = hawk_uchars_to_num(HAWK_OOCHARS_TO_NUM_MAKE_OPTION(1, (hawk->opt.trait & HAWK_STRIPSTRSPC), 0), ptr, len, &l, &r); + x = hawk_uchars_to_num(HAWK_OOCHARS_TO_NUM_MAKE_OPTION(1, 0, (hawk->opt.trait & HAWK_STRIPSTRSPC), 0), ptr, len, &l, &r); v = hawk_rtx_makestrvalwithuchars(rtx, ptr, len); if (!v) return HAWK_NULL; @@ -363,7 +363,7 @@ hawk_val_t* hawk_rtx_makenstrvalwithbchars (hawk_rtx_t* rtx, const hawk_bch_t* p hawk_int_t l; hawk_flt_t r; - x = hawk_bchars_to_num(HAWK_OOCHARS_TO_NUM_MAKE_OPTION(1, (hawk->opt.trait & HAWK_STRIPSTRSPC), 0), ptr, len, &l, &r); + x = hawk_bchars_to_num(HAWK_OOCHARS_TO_NUM_MAKE_OPTION(1, 0, (hawk->opt.trait & HAWK_STRIPSTRSPC), 0), ptr, len, &l, &r); v = hawk_rtx_makestrvalwithbchars(rtx, ptr, len); if (!v) return HAWK_NULL; @@ -465,7 +465,7 @@ hawk_val_t* hawk_rtx_makenumormbsvalwithuchars (hawk_rtx_t* rtx, const hawk_uch_ hawk_int_t l; hawk_flt_t r; - x = hawk_uchars_to_num(HAWK_OOCHARS_TO_NUM_MAKE_OPTION(1, (hawk->opt.trait & HAWK_STRIPSTRSPC), 0), ptr, len, &l, &r); + x = hawk_uchars_to_num(HAWK_OOCHARS_TO_NUM_MAKE_OPTION(1, 1, (hawk->opt.trait & HAWK_STRIPSTRSPC), 0), ptr, len, &l, &r); if (x == 0) return hawk_rtx_makeintval(rtx, l); else if (x >= 1) return hawk_rtx_makefltval(rtx, r); @@ -479,7 +479,7 @@ hawk_val_t* hawk_rtx_makenumormbsvalwithbchars (hawk_rtx_t* rtx, const hawk_bch_ hawk_int_t l; hawk_flt_t r; - x = hawk_bchars_to_num(HAWK_OOCHARS_TO_NUM_MAKE_OPTION(1, (hawk->opt.trait & HAWK_STRIPSTRSPC), 0), ptr, len, &l, &r); + x = hawk_bchars_to_num(HAWK_OOCHARS_TO_NUM_MAKE_OPTION(1, 1, (hawk->opt.trait & HAWK_STRIPSTRSPC), 0), ptr, len, &l, &r); if (x == 0) return hawk_rtx_makeintval(rtx, l); else if (x >= 1) return hawk_rtx_makefltval(rtx, r); @@ -1651,7 +1651,7 @@ static int val_ref_to_num (hawk_rtx_t* rtx, const hawk_val_ref_t* ref, hawk_int_ if (idx == 0) { return hawk_oochars_to_num( - HAWK_OOCHARS_TO_NUM_MAKE_OPTION(0, (hawk->opt.trait & HAWK_STRIPSTRSPC), 0), + HAWK_OOCHARS_TO_NUM_MAKE_OPTION(0, 0, (hawk->opt.trait & HAWK_STRIPSTRSPC), 0), HAWK_OOECS_PTR(&rtx->inrec.line), HAWK_OOECS_LEN(&rtx->inrec.line), l, r @@ -1660,7 +1660,7 @@ static int val_ref_to_num (hawk_rtx_t* rtx, const hawk_val_ref_t* ref, hawk_int_ else if (idx <= rtx->inrec.nflds) { return hawk_oochars_to_num( - HAWK_OOCHARS_TO_NUM_MAKE_OPTION(0, (hawk->opt.trait & HAWK_STRIPSTRSPC), 0), + HAWK_OOCHARS_TO_NUM_MAKE_OPTION(0, 0, (hawk->opt.trait & HAWK_STRIPSTRSPC), 0), rtx->inrec.flds[idx-1].ptr, rtx->inrec.flds[idx-1].len, l, r @@ -1668,7 +1668,7 @@ static int val_ref_to_num (hawk_rtx_t* rtx, const hawk_val_ref_t* ref, hawk_int_ } else { - return hawk_oochars_to_num(HAWK_OOCHARS_TO_NUM_MAKE_OPTION(0, (hawk->opt.trait & HAWK_STRIPSTRSPC), 0), HAWK_T(""), 0, l, r); + return hawk_oochars_to_num(HAWK_OOCHARS_TO_NUM_MAKE_OPTION(0, 0, (hawk->opt.trait & HAWK_STRIPSTRSPC), 0), HAWK_T(""), 0, l, r); } } @@ -1715,7 +1715,7 @@ int hawk_rtx_valtonum (hawk_rtx_t* rtx, const hawk_val_t* v, hawk_int_t* l, hawk case HAWK_VAL_STR: return hawk_oochars_to_num( - HAWK_OOCHARS_TO_NUM_MAKE_OPTION(0, (hawk->opt.trait & HAWK_STRIPSTRSPC), 0), + HAWK_OOCHARS_TO_NUM_MAKE_OPTION(0, 0, (hawk->opt.trait & HAWK_STRIPSTRSPC), 0), ((hawk_val_str_t*)v)->val.ptr, ((hawk_val_str_t*)v)->val.len, l, r @@ -1723,7 +1723,7 @@ int hawk_rtx_valtonum (hawk_rtx_t* rtx, const hawk_val_t* v, hawk_int_t* l, hawk case HAWK_VAL_MBS: return hawk_bchars_to_num( - HAWK_OOCHARS_TO_NUM_MAKE_OPTION(0, (hawk->opt.trait & HAWK_STRIPSTRSPC), 0), + HAWK_OOCHARS_TO_NUM_MAKE_OPTION(0, 0, (hawk->opt.trait & HAWK_STRIPSTRSPC), 0), ((hawk_val_mbs_t*)v)->val.ptr, ((hawk_val_mbs_t*)v)->val.len, l, r @@ -1942,7 +1942,7 @@ int hawk_rtx_setrefval (hawk_rtx_t* rtx, hawk_val_ref_t* ref, hawk_val_t* val) * for no duplication. jumping to the default case * and callinghawk_rtx_valtooocstrdup() would also work, anyway. */ hawk_rtx_refupval (rtx, val); - x = hawk_rtx_setrec(rtx, (hawk_oow_t)ref->adr, &((hawk_val_str_t*)val)->val); + x = hawk_rtx_setrec(rtx, (hawk_oow_t)ref->adr, &((hawk_val_str_t*)val)->val, 0); hawk_rtx_refdownval (rtx, val); return x; } @@ -1953,7 +1953,7 @@ int hawk_rtx_setrefval (hawk_rtx_t* rtx, hawk_val_ref_t* ref, hawk_val_t* val) /* same as str in the mchar mode */ int x; hawk_rtx_refupval (rtx, val); - x = hawk_rtx_setrec(rtx, (hawk_oow_t)ref->adr, &((hawk_val_mbs_t*)val)->val); + x = hawk_rtx_setrec(rtx, (hawk_oow_t)ref->adr, &((hawk_val_mbs_t*)val)->val, 0); hawk_rtx_refdownval (rtx, val); return x; } @@ -1967,7 +1967,7 @@ int hawk_rtx_setrefval (hawk_rtx_t* rtx, hawk_val_ref_t* ref, hawk_val_t* val) str.ptr = hawk_rtx_valtooocstrdup(rtx, val, &str.len); hawk_rtx_refupval (rtx, val); - x = hawk_rtx_setrec(rtx, (hawk_oow_t)ref->adr, &str); + x = hawk_rtx_setrec(rtx, (hawk_oow_t)ref->adr, &str, 0); hawk_rtx_refdownval (rtx, val); hawk_rtx_freemem (rtx, str.ptr); return x;