From fc18cd2db65cdfe39e36e63003d4346c5af40826 Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Wed, 29 May 2013 08:46:23 +0000 Subject: [PATCH] enhanced split(),ENVIRON,ARGV in awk to build a numeric string if a string can be converted to a number --- qse/cmd/awk/awk.c | 4 ++-- qse/include/qse/awk/Awk.hpp | 20 +++++++++------- qse/include/qse/awk/awk.h | 12 ++++++++++ qse/lib/awk/Awk.cpp | 48 ++++++++++++++++++++++++------------- qse/lib/awk/StdAwk.cpp | 5 ++-- qse/lib/awk/fnc.c | 6 +++-- qse/lib/awk/run.c | 2 +- qse/lib/awk/std.c | 10 ++++++-- qse/lib/awk/val.c | 8 +++++++ 9 files changed, 81 insertions(+), 34 deletions(-) diff --git a/qse/cmd/awk/awk.c b/qse/cmd/awk/awk.c index 7847c0be..db34415c 100644 --- a/qse/cmd/awk/awk.c +++ b/qse/cmd/awk/awk.c @@ -292,7 +292,7 @@ static qse_htb_walk_t set_global ( static int apply_fs_and_gvm (qse_awk_rtx_t* rtx, struct arg_t* arg) { - if (arg->fs != QSE_NULL) + if (arg->fs) { qse_awk_val_t* fs; @@ -306,7 +306,7 @@ static int apply_fs_and_gvm (qse_awk_rtx_t* rtx, struct arg_t* arg) qse_awk_rtx_refdownval (rtx, fs); } - if (arg->gvm != QSE_NULL) + if (arg->gvm) { /* set the value of user-defined global variables * to a runtime context */ diff --git a/qse/include/qse/awk/Awk.hpp b/qse/include/qse/awk/Awk.hpp index ca32305d..5b2bb3cf 100644 --- a/qse/include/qse/awk/Awk.hpp +++ b/qse/include/qse/awk/Awk.hpp @@ -718,10 +718,10 @@ public: int setInt (Run* r, long_t v); int setFlt (flt_t v); int setFlt (Run* r, flt_t v); - int setStr (const char_t* str, size_t len); - int setStr (Run* r, const char_t* str, size_t len); - int setStr (const char_t* str); - int setStr (Run* r, const char_t* str); + int setStr (const char_t* str, size_t len, bool numeric = false); + int setStr (Run* r, const char_t* str, size_t len, bool numeric = false); + int setStr (const char_t* str, bool numeric = false); + int setStr (Run* r, const char_t* str, bool numeric = false); int setIndexedVal ( const Index& idx, @@ -758,25 +758,29 @@ public: int setIndexedStr ( const Index& idx, const char_t* str, - size_t len + size_t len, + bool numeric = false ); int setIndexedStr ( Run* r, const Index& idx, const char_t* str, - size_t len + size_t len, + bool numeric = false ); int setIndexedStr ( const Index& idx, - const char_t* str + const char_t* str, + bool numeric = false ); int setIndexedStr ( Run* r, const Index& idx, - const char_t* str + const char_t* str, + bool numeric = false ); /// diff --git a/qse/include/qse/awk/awk.h b/qse/include/qse/awk/awk.h index 0472c2fa..68b92394 100644 --- a/qse/include/qse/awk/awk.h +++ b/qse/include/qse/awk/awk.h @@ -2358,6 +2358,18 @@ QSE_EXPORT qse_awk_val_t* qse_awk_rtx_makestrval2 ( qse_size_t len2 ); + +/** + * The qse_awk_rtx_makenstrvalwithstr() function creates a numeric string + * value from a null-terminated string. A numeric string is a string value + * whose one of the header fields \b nstr is 1. + * \return value on success, #QSE_NULL on failure + */ +QSE_EXPORT qse_awk_val_t* qse_awk_rtx_makenstrvalwithstr ( + qse_awk_rtx_t* rtx, + const qse_char_t* str +); + /** * The qse_awk_rtx_makenstrvalwithcstr() function creates a numeric string * value. A numeric string is a string value whose one of the header fields diff --git a/qse/lib/awk/Awk.cpp b/qse/lib/awk/Awk.cpp index b9dd096b..6832a010 100644 --- a/qse/lib/awk/Awk.cpp +++ b/qse/lib/awk/Awk.cpp @@ -573,7 +573,7 @@ int Awk::Value::setFlt (Run* r, flt_t v) return n; } -int Awk::Value::setStr (const char_t* str, size_t len) +int Awk::Value::setStr (const char_t* str, size_t len, bool numeric) { if (this->run == QSE_NULL) { @@ -581,13 +581,19 @@ int Awk::Value::setStr (const char_t* str, size_t len) * set an error number for the same reason */ return -1; } - return setStr (this->run, str, len); + return setStr (this->run, str, len, numeric); } -int Awk::Value::setStr (Run* r, const char_t* str, size_t len) +int Awk::Value::setStr (Run* r, const char_t* str, size_t len, bool numeric) { val_t* tmp; - tmp = qse_awk_rtx_makestrval (r->rtx, str, len); + + cstr_t cstr; + cstr.ptr = str; + cstr.len = len; + + tmp = numeric? qse_awk_rtx_makenstrvalwithcstr (r->rtx, &cstr): + qse_awk_rtx_makestrvalwithcstr (r->rtx, &cstr); if (tmp == QSE_NULL) { r->awk->retrieveError (r); @@ -599,16 +605,17 @@ int Awk::Value::setStr (Run* r, const char_t* str, size_t len) return n; } -int Awk::Value::setStr (const char_t* str) +int Awk::Value::setStr (const char_t* str, bool numeric) { if (this->run == QSE_NULL) return -1; - return setStr (this->run, str); + return setStr (this->run, str, numeric); } -int Awk::Value::setStr (Run* r, const char_t* str) +int Awk::Value::setStr (Run* r, const char_t* str, bool numeric) { val_t* tmp; - tmp = qse_awk_rtx_makestrvalwithstr (r->rtx, str); + tmp = numeric? qse_awk_rtx_makenstrvalwithstr (r->rtx, str): + qse_awk_rtx_makestrvalwithstr (r->rtx, str); if (tmp == QSE_NULL) { r->awk->retrieveError (r); @@ -733,17 +740,23 @@ int Awk::Value::setIndexedFlt (Run* r, const Index& idx, flt_t v) return n; } -int Awk::Value::setIndexedStr (const Index& idx, const char_t* str, size_t len) +int Awk::Value::setIndexedStr (const Index& idx, const char_t* str, size_t len, bool numeric) { if (run == QSE_NULL) return -1; - return setIndexedStr (run, idx, str, len); + return setIndexedStr (run, idx, str, len, numeric); } int Awk::Value::setIndexedStr ( - Run* r, const Index& idx, const char_t* str, size_t len) + Run* r, const Index& idx, const char_t* str, size_t len, bool numeric) { val_t* tmp; - tmp = qse_awk_rtx_makestrval (r->rtx, str, len); + + cstr_t cstr; + cstr.ptr = str; + cstr.len = len; + + tmp = numeric? qse_awk_rtx_makenstrvalwithcstr (r->rtx, &cstr): + qse_awk_rtx_makestrvalwithcstr (r->rtx, &cstr); if (tmp == QSE_NULL) { r->awk->retrieveError (r); @@ -757,16 +770,17 @@ int Awk::Value::setIndexedStr ( return n; } -int Awk::Value::setIndexedStr (const Index& idx, const char_t* str) +int Awk::Value::setIndexedStr (const Index& idx, const char_t* str, bool numeric) { if (run == QSE_NULL) return -1; - return setIndexedStr (run, idx, str); + return setIndexedStr (run, idx, str, numeric); } -int Awk::Value::setIndexedStr (Run* r, const Index& idx, const char_t* str) +int Awk::Value::setIndexedStr (Run* r, const Index& idx, const char_t* str, bool numeric) { val_t* tmp; - tmp = qse_awk_rtx_makestrvalwithstr (r->rtx, str); + tmp = numeric? qse_awk_rtx_makenstrvalwithstr (r->rtx, str): + qse_awk_rtx_makestrvalwithstr (r->rtx, str); if (tmp == QSE_NULL) { r->awk->retrieveError (r); @@ -1412,7 +1426,7 @@ int Awk::dispatch_function (Run* run, const fnc_info_t* fi) } else { - xx = args[i].setStr (run, QSE_T(""), 0); + xx = args[i].setStr (run, QSE_T(""), (size_t)0); } break; } diff --git a/qse/lib/awk/StdAwk.cpp b/qse/lib/awk/StdAwk.cpp index d0194382..ce756d3f 100644 --- a/qse/lib/awk/StdAwk.cpp +++ b/qse/lib/awk/StdAwk.cpp @@ -225,7 +225,7 @@ int StdAwk::build_argcv (Run* run) if (argv.setIndexedStr ( Value::IntIndex(i), this->runarg.ptr[i].ptr, - this->runarg.ptr[i].len) <= -1) return -1; + this->runarg.ptr[i].len, true) <= -1) return -1; } run->setGlobal (this->gbl_argc, (long_t)this->runarg.len); @@ -297,7 +297,8 @@ int StdAwk::__build_environ (Run* run, void* envptr) *eq = QSE_WT('='); #endif - v_env.setIndexedStr (Value::Index (kptr, klen), vptr); + // numeric string + v_env.setIndexedStr (Value::Index (kptr, klen), vptr, true); #if ((defined(QSE_ENV_CHAR_IS_MCHAR) && defined(QSE_CHAR_IS_MCHAR)) || \ (defined(QSE_ENV_CHAR_IS_WCHAR) && defined(QSE_CHAR_IS_WCHAR))) diff --git a/qse/lib/awk/fnc.c b/qse/lib/awk/fnc.c index ffb60fed..3db10646 100644 --- a/qse/lib/awk/fnc.c +++ b/qse/lib/awk/fnc.c @@ -766,8 +766,10 @@ static int fnc_split (qse_awk_rtx_t* run, const qse_awk_fnc_info_t* fi) QSE_ASSERT ((tok.ptr != QSE_NULL && tok.len > 0) || tok.len == 0); - /* create the field string */ - t2 = qse_awk_rtx_makestrvalwithcstr (run, &tok); + /* create the field string - however, the split function must + * create a numeric string if the string is a number */ + /*t2 = qse_awk_rtx_makestrvalwithcstr (run, &tok);*/ + t2 = qse_awk_rtx_makenstrvalwithcstr (run, &tok); if (t2 == QSE_NULL) goto oops; /* put it into the map */ diff --git a/qse/lib/awk/run.c b/qse/lib/awk/run.c index 2399b5ea..af3d610b 100644 --- a/qse/lib/awk/run.c +++ b/qse/lib/awk/run.c @@ -4371,7 +4371,7 @@ static int __cmp_str_str ( if (ls->nstr == 0 || rs->nstr == 0) { - /* nother are definitely a string */ + /* both are definitely strings */ return (rtx->gbl.ignorecase)? qse_strxncasecmp (ls->val.ptr, ls->val.len, rs->val.ptr, rs->val.len): qse_strxncmp (ls->val.ptr, ls->val.len, rs->val.ptr, rs->val.len); diff --git a/qse/lib/awk/std.c b/qse/lib/awk/std.c index b0b549bc..94a837ff 100644 --- a/qse/lib/awk/std.c +++ b/qse/lib/awk/std.c @@ -1814,7 +1814,10 @@ static int build_argcv ( { for (argc = 1, p = icf; *p; p++, argc++) { - v_tmp = qse_awk_rtx_makestrvalwithstr (rtx, *p); + /* the argument must compose a numeric string if it can be. + * so call qse_awk_rtx_makenstrvalwithstr() instead of + * qse_awk_rtx_makestrvalwithstr(). */ + v_tmp = qse_awk_rtx_makenstrvalwithstr (rtx, *p); if (v_tmp == QSE_NULL) { qse_awk_rtx_refdownval (rtx, v_argv); @@ -1941,7 +1944,10 @@ static int __build_environ ( *eq = QSE_WT('='); #endif - v_tmp = qse_awk_rtx_makestrvalwithstr (rtx, vptr); + /* the string in ENVIRON should be a numeric string if + * it can be converted to a number. call makenstrval() + * instead of makestrval() */ + v_tmp = qse_awk_rtx_makenstrvalwithstr (rtx, vptr); if (v_tmp == QSE_NULL) { #if ((defined(QSE_ENV_CHAR_IS_MCHAR) && defined(QSE_CHAR_IS_MCHAR)) || \ diff --git a/qse/lib/awk/val.c b/qse/lib/awk/val.c index 407ecd54..a7c2bf99 100644 --- a/qse/lib/awk/val.c +++ b/qse/lib/awk/val.c @@ -406,6 +406,14 @@ init: return (qse_awk_val_t*)val; } +qse_awk_val_t* qse_awk_rtx_makenstrvalwithstr (qse_awk_rtx_t* rtx, const qse_char_t* str) +{ + qse_cstr_t cstr; + cstr.ptr = str; + cstr.len = qse_strlen(str); + return qse_awk_rtx_makenstrvalwithcstr (rtx, &cstr); +} + qse_awk_val_t* qse_awk_rtx_makenstrvalwithcstr (qse_awk_rtx_t* rtx, const qse_cstr_t* str) { int x;