enhanced qse_awk_rtx_strtonum() to handle a numeric string like 0999.112 as a floating point number

This commit is contained in:
hyung-hwan 2015-07-16 03:03:51 +00:00
parent 26440f1a96
commit 1963e62006

View File

@ -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->i_val = v;
val->nde = QSE_NULL; val->nde = QSE_NULL;
printf ("makeintval => %p\n", val);
#ifdef DEBUG_VAL #ifdef DEBUG_VAL
qse_errputstrf (QSE_T("makeintval => %jd [%p]\n"), (qse_intmax_t)v, val); qse_errputstrf (QSE_T("makeintval => %jd [%p]\n"), (qse_intmax_t)v, val);
#endif #endif
@ -1697,19 +1696,46 @@ int qse_awk_rtx_strtonum (
qse_awk_int_t* l, qse_awk_flt_t* r) qse_awk_int_t* l, qse_awk_flt_t* r)
{ {
const qse_char_t* endptr; const qse_char_t* endptr;
const qse_char_t* end;
end = ptr + len;
*l = qse_awk_strxtoint (rtx->awk, ptr, len, 0, &endptr); *l = qse_awk_strxtoint (rtx->awk, ptr, len, 0, &endptr);
if (endptr < ptr + len && if (endptr < end)
(*endptr == QSE_T('.') ||
*endptr == QSE_T('E') ||
*endptr == QSE_T('e')))
{ {
if (*endptr == QSE_T('.') || *endptr == QSE_T('E') || *endptr == QSE_T('e'))
{
handle_float:
*r = qse_awk_strxtoflt (rtx->awk, ptr, len, &endptr); *r = qse_awk_strxtoflt (rtx->awk, ptr, len, &endptr);
if (strict && endptr < ptr + len) return -1; if (strict && endptr < end) return -1;
return 1; /* flt */ 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 */ return 0; /* int */
} }