changed the second parameter of qse_awk_rtx_strtonum() to accept the base value on top of the 'strict' conversion bit.
enhanced awk's str::tonum() to accept the optional base parameter
This commit is contained in:
parent
eb79fa721f
commit
5743a341cc
@ -2777,13 +2777,17 @@ QSE_EXPORT int qse_awk_rtx_valtoflt (
|
|||||||
* memory pointed to by \a l; A string containng '.', 'E', or 'e' is
|
* memory pointed to by \a l; A string containng '.', 'E', or 'e' is
|
||||||
* converted to a floating-pointer number and it is stored into memory
|
* converted to a floating-pointer number and it is stored into memory
|
||||||
* pointed to by \a r. If \a strict is 0, the function takes up to the last
|
* pointed to by \a r. If \a strict is 0, the function takes up to the last
|
||||||
* valid character and never fails. If \a strict is non-zero, an invalid
|
* valid character and never fails. If \a strict is 1, an invalid
|
||||||
* character causes the function to return an error.
|
* character causes the function to return an error.
|
||||||
*
|
*
|
||||||
* \return 0 if converted to an integer,
|
* \return 0 if converted to an integer,
|
||||||
* 1 if converted to a floating-point number
|
* 1 if converted to a floating-point number
|
||||||
* -1 on error.
|
* -1 on error.
|
||||||
*/
|
*/
|
||||||
|
#define QSE_AWK_RTX_STRTONUM_MAKE_OPTION(strict,base) (((strict) & 1) | ((base) << 8))
|
||||||
|
#define QSE_AWK_RTX_STRTONUM_GET_OPTION_STRICT(option) ((option) & 1)
|
||||||
|
#define QSE_AWK_RTX_STRTONUN_GET_OPTION_BASE(option) ((option) >> 8)
|
||||||
|
|
||||||
QSE_EXPORT int qse_awk_rtx_strtonum (
|
QSE_EXPORT int qse_awk_rtx_strtonum (
|
||||||
qse_awk_rtx_t* rtx, /**< runtime context */
|
qse_awk_rtx_t* rtx, /**< runtime context */
|
||||||
int strict, /**< determines to perform strict check */
|
int strict, /**< determines to perform strict check */
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
#include <qse/cmn/chr.h>
|
#include <qse/cmn/chr.h>
|
||||||
#include "../cmn/mem-prv.h"
|
#include "../cmn/mem-prv.h"
|
||||||
#include "fnc.h"
|
#include "fnc.h"
|
||||||
|
#include "val.h"
|
||||||
|
|
||||||
static int fnc_normspace (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
|
static int fnc_normspace (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
|
||||||
{
|
{
|
||||||
@ -215,6 +216,7 @@ static int fnc_value (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
|
|||||||
static int fnc_tonum (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
|
static int fnc_tonum (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
|
||||||
{
|
{
|
||||||
/* str::tonum (value) */
|
/* str::tonum (value) */
|
||||||
|
/* str::tonum (string, base) */
|
||||||
|
|
||||||
qse_awk_val_t* retv;
|
qse_awk_val_t* retv;
|
||||||
qse_awk_val_t* a0;
|
qse_awk_val_t* a0;
|
||||||
@ -224,7 +226,27 @@ static int fnc_tonum (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
|
|||||||
|
|
||||||
a0 = qse_awk_rtx_getarg(rtx, 0);
|
a0 = qse_awk_rtx_getarg(rtx, 0);
|
||||||
|
|
||||||
|
if (QSE_AWK_RTX_GETVALTYPE(rtx, a0) == QSE_AWK_VAL_STR && qse_awk_rtx_getnargs(rtx) >= 2)
|
||||||
|
{
|
||||||
|
/* if the value is known to be a string, it supports the optional
|
||||||
|
* base parameter */
|
||||||
|
qse_awk_val_t* a1 = qse_awk_rtx_getarg(rtx, 1);
|
||||||
|
qse_awk_int_t base;
|
||||||
|
|
||||||
|
if (qse_awk_rtx_valtoint(rtx, a1, &base) <= -1) return -1;
|
||||||
|
rx = qse_awk_rtx_strtonum (
|
||||||
|
rtx,
|
||||||
|
QSE_AWK_RTX_STRTONUM_MAKE_OPTION(0, base),
|
||||||
|
((qse_awk_val_str_t*)a0)->val.ptr,
|
||||||
|
((qse_awk_val_str_t*)a0)->val.len,
|
||||||
|
&lv, &rv
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
rx = qse_awk_rtx_valtonum(rtx, a0, &lv, &rv);
|
rx = qse_awk_rtx_valtonum(rtx, a0, &lv, &rv);
|
||||||
|
}
|
||||||
|
|
||||||
if (rx == 0)
|
if (rx == 0)
|
||||||
{
|
{
|
||||||
retv = qse_awk_rtx_makeintval(rtx, lv);
|
retv = qse_awk_rtx_makeintval(rtx, lv);
|
||||||
@ -281,7 +303,7 @@ static fnctab_t fnctab[] =
|
|||||||
{ QSE_T("sub"), { { 2, 3, QSE_T("xvr") }, qse_awk_fnc_sub, 0 } },
|
{ QSE_T("sub"), { { 2, 3, QSE_T("xvr") }, qse_awk_fnc_sub, 0 } },
|
||||||
{ QSE_T("substr"), { { 2, 3, QSE_NULL }, qse_awk_fnc_substr, 0 } },
|
{ QSE_T("substr"), { { 2, 3, QSE_NULL }, qse_awk_fnc_substr, 0 } },
|
||||||
{ QSE_T("tolower"), { { 1, 1, QSE_NULL }, qse_awk_fnc_tolower, 0 } },
|
{ QSE_T("tolower"), { { 1, 1, QSE_NULL }, qse_awk_fnc_tolower, 0 } },
|
||||||
{ QSE_T("tonum"), { { 1, 1, QSE_NULL }, fnc_tonum, 0 } },
|
{ QSE_T("tonum"), { { 1, 2, QSE_NULL }, fnc_tonum, 0 } },
|
||||||
{ QSE_T("toupper"), { { 1, 1, QSE_NULL }, qse_awk_fnc_toupper, 0 } },
|
{ QSE_T("toupper"), { { 1, 1, QSE_NULL }, qse_awk_fnc_toupper, 0 } },
|
||||||
{ QSE_T("trim"), { { 1, 1, QSE_NULL }, fnc_trim, 0 } },
|
{ QSE_T("trim"), { { 1, 1, QSE_NULL }, fnc_trim, 0 } },
|
||||||
{ QSE_T("value"), { { 1, 1, QSE_NULL }, fnc_value, 0 } }
|
{ QSE_T("value"), { { 1, 1, QSE_NULL }, fnc_value, 0 } }
|
||||||
|
@ -4204,7 +4204,8 @@ static QSE_INLINE int __cmp_int_str (
|
|||||||
qse_awk_flt_t rr;
|
qse_awk_flt_t rr;
|
||||||
|
|
||||||
n = qse_awk_rtx_strtonum (
|
n = qse_awk_rtx_strtonum (
|
||||||
rtx, 1,
|
rtx,
|
||||||
|
QSE_AWK_RTX_STRTONUM_MAKE_OPTION(1, 0),
|
||||||
((qse_awk_val_str_t*)right)->val.ptr,
|
((qse_awk_val_str_t*)right)->val.ptr,
|
||||||
((qse_awk_val_str_t*)right)->val.len,
|
((qse_awk_val_str_t*)right)->val.len,
|
||||||
&ll, &rr
|
&ll, &rr
|
||||||
|
@ -2185,9 +2185,9 @@ static int fnc_setioattr (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
|
|||||||
qse_awk_flt_t r;
|
qse_awk_flt_t r;
|
||||||
int x;
|
int x;
|
||||||
|
|
||||||
/* no error is returned by qse_awk_rtx_strnum() if the second
|
/* no error is returned by qse_awk_rtx_strnum() if the strict option
|
||||||
* parameter is 0. so i don't check for an error */
|
* of the second parameter is 0. so i don't check for an error */
|
||||||
x = qse_awk_rtx_strtonum (rtx, 0, ptr[2], len[2], &l, &r);
|
x = qse_awk_rtx_strtonum(rtx, QSE_AWK_RTX_STRTONUM_MAKE_OPTION(0, 0), ptr[2], len[2], &l, &r);
|
||||||
if (x == 0) r = (qse_awk_flt_t)l;
|
if (x == 0) r = (qse_awk_flt_t)l;
|
||||||
|
|
||||||
ioattr = find_or_make_ioattr (rtx, &rxtn->cmgrtab, ptr[0], len[0]);
|
ioattr = find_or_make_ioattr (rtx, &rxtn->cmgrtab, ptr[0], len[0]);
|
||||||
|
@ -443,7 +443,7 @@ qse_awk_val_t* qse_awk_rtx_makenstrvalwithxstr (qse_awk_rtx_t* rtx, const qse_cs
|
|||||||
qse_awk_int_t l;
|
qse_awk_int_t l;
|
||||||
qse_awk_flt_t r;
|
qse_awk_flt_t r;
|
||||||
|
|
||||||
x = qse_awk_rtx_strtonum (rtx, 1, str->ptr, str->len, &l, &r);
|
x = qse_awk_rtx_strtonum(rtx, QSE_AWK_RTX_STRTONUM_MAKE_OPTION(1, 0), str->ptr, str->len, &l, &r);
|
||||||
v = qse_awk_rtx_makestrvalwithxstr(rtx, str);
|
v = qse_awk_rtx_makestrvalwithxstr(rtx, str);
|
||||||
|
|
||||||
if (v == QSE_NULL) return QSE_NULL;
|
if (v == QSE_NULL) return QSE_NULL;
|
||||||
@ -1555,7 +1555,8 @@ static int val_ref_to_num (
|
|||||||
if (idx == 0)
|
if (idx == 0)
|
||||||
{
|
{
|
||||||
return qse_awk_rtx_strtonum (
|
return qse_awk_rtx_strtonum (
|
||||||
rtx, 0,
|
rtx,
|
||||||
|
QSE_AWK_RTX_STRTONUM_MAKE_OPTION(0, 0),
|
||||||
QSE_STR_PTR(&rtx->inrec.line),
|
QSE_STR_PTR(&rtx->inrec.line),
|
||||||
QSE_STR_LEN(&rtx->inrec.line),
|
QSE_STR_LEN(&rtx->inrec.line),
|
||||||
l, r
|
l, r
|
||||||
@ -1564,7 +1565,8 @@ static int val_ref_to_num (
|
|||||||
else if (idx <= rtx->inrec.nflds)
|
else if (idx <= rtx->inrec.nflds)
|
||||||
{
|
{
|
||||||
return qse_awk_rtx_strtonum (
|
return qse_awk_rtx_strtonum (
|
||||||
rtx, 0,
|
rtx,
|
||||||
|
QSE_AWK_RTX_STRTONUM_MAKE_OPTION(0, 0),
|
||||||
rtx->inrec.flds[idx-1].ptr,
|
rtx->inrec.flds[idx-1].ptr,
|
||||||
rtx->inrec.flds[idx-1].len,
|
rtx->inrec.flds[idx-1].len,
|
||||||
l, r
|
l, r
|
||||||
@ -1573,7 +1575,7 @@ static int val_ref_to_num (
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
return qse_awk_rtx_strtonum (
|
return qse_awk_rtx_strtonum (
|
||||||
rtx, 0, QSE_T(""), 0, l, r
|
rtx, QSE_AWK_RTX_STRTONUM_MAKE_OPTION(0, 0), QSE_T(""), 0, l, r
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1628,7 +1630,8 @@ int qse_awk_rtx_valtonum (
|
|||||||
case QSE_AWK_VAL_STR:
|
case QSE_AWK_VAL_STR:
|
||||||
{
|
{
|
||||||
return qse_awk_rtx_strtonum (
|
return qse_awk_rtx_strtonum (
|
||||||
rtx, 0,
|
rtx,
|
||||||
|
QSE_AWK_RTX_STRTONUM_MAKE_OPTION(0, 0),
|
||||||
((qse_awk_val_str_t*)v)->val.ptr,
|
((qse_awk_val_str_t*)v)->val.ptr,
|
||||||
((qse_awk_val_str_t*)v)->val.len,
|
((qse_awk_val_str_t*)v)->val.len,
|
||||||
l, r
|
l, r
|
||||||
@ -1691,15 +1694,18 @@ int qse_awk_rtx_valtoflt (
|
|||||||
}
|
}
|
||||||
|
|
||||||
int qse_awk_rtx_strtonum (
|
int qse_awk_rtx_strtonum (
|
||||||
qse_awk_rtx_t* rtx, int strict,
|
qse_awk_rtx_t* rtx, int option,
|
||||||
const qse_char_t* ptr, qse_size_t len,
|
const qse_char_t* ptr, qse_size_t len,
|
||||||
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;
|
const qse_char_t* end;
|
||||||
|
|
||||||
|
int strict = QSE_AWK_RTX_STRTONUM_GET_OPTION_STRICT(option);
|
||||||
|
int base = QSE_AWK_RTX_STRTONUN_GET_OPTION_BASE(option);
|
||||||
|
|
||||||
end = ptr + len;
|
end = ptr + len;
|
||||||
*l = qse_awk_strxtoint (rtx->awk, ptr, len, 0, &endptr);
|
*l = qse_awk_strxtoint(rtx->awk, ptr, len, base, &endptr);
|
||||||
if (endptr < end)
|
if (endptr < end)
|
||||||
{
|
{
|
||||||
if (*endptr == QSE_T('.') || *endptr == QSE_T('E') || *endptr == QSE_T('e'))
|
if (*endptr == QSE_T('.') || *endptr == QSE_T('E') || *endptr == QSE_T('e'))
|
||||||
|
Loading…
Reference in New Issue
Block a user