From 1963e6200610a2f44eb331c7653ce5ab6418a3b5 Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Thu, 16 Jul 2015 03:03:51 +0000 Subject: [PATCH] enhanced qse_awk_rtx_strtonum() to handle a numeric string like 0999.112 as a floating point number --- qse/lib/awk/val.c | 44 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 35 insertions(+), 9 deletions(-) diff --git a/qse/lib/awk/val.c b/qse/lib/awk/val.c index 02b6937b..1e6452d9 100644 --- a/qse/lib/awk/val.c +++ b/qse/lib/awk/val.c @@ -160,7 +160,6 @@ qse_awk_val_t* qse_awk_rtx_makeintval (qse_awk_rtx_t* rtx, qse_awk_int_t v) val->i_val = v; val->nde = QSE_NULL; -printf ("makeintval => %p\n", val); #ifdef DEBUG_VAL qse_errputstrf (QSE_T("makeintval => %jd [%p]\n"), (qse_intmax_t)v, val); #endif @@ -1697,19 +1696,46 @@ int qse_awk_rtx_strtonum ( qse_awk_int_t* l, qse_awk_flt_t* r) { const qse_char_t* endptr; + const qse_char_t* end; + end = ptr + len; *l = qse_awk_strxtoint (rtx->awk, ptr, len, 0, &endptr); - if (endptr < ptr + len && - (*endptr == QSE_T('.') || - *endptr == QSE_T('E') || - *endptr == QSE_T('e'))) + if (endptr < end) { - *r = qse_awk_strxtoflt (rtx->awk, ptr, len, &endptr); - if (strict && endptr < ptr + len) return -1; - return 1; /* flt */ + if (*endptr == QSE_T('.') || *endptr == QSE_T('E') || *endptr == QSE_T('e')) + { + handle_float: + *r = qse_awk_strxtoflt (rtx->awk, ptr, len, &endptr); + if (strict && endptr < end) return -1; + return 1; /* flt */ + } + else if (QSE_AWK_ISDIGIT(awk, *endptr)) + { + const qse_char_t* p = endptr; + do { p++; } while (p < end && QSE_AWK_ISDIGIT(awk, *p)); + if (p < end && (*p == QSE_T('.') || *p == QSE_T('E') || *p == QSE_T('e'))) + { + /* it's probably an floating-point number. + * + * 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 qse_awk_strxtoint() as + * the numeric string beginning with 0 is treated + * as an octal number. + * + * getting side-tracked, + * BEGIN { b=99; printf "%f\n", (0 b 1.000); } + * the above code cause this function to get 0991, not 0991.000 + * because of the default CONVFMT '%.6g' which doesn't produce '.000'. + * so such a number is not treated as a floating-point number. + */ + goto handle_float; + } + } } - if (strict && endptr < ptr + len) return -1; + if (strict && endptr < end) return -1; return 0; /* int */ }