enhanced str::index()/str::rindex() to handle byte strings

This commit is contained in:
hyung-hwan 2019-04-25 17:34:04 +00:00
parent 7811171dff
commit 1f980cbfb8
2 changed files with 94 additions and 46 deletions

View File

@ -419,8 +419,6 @@ static int index_or_rindex (qse_awk_rtx_t* rtx, int rindex)
* care about IGNORECASE. */ * care about IGNORECASE. */
qse_size_t nargs; qse_size_t nargs;
qse_awk_val_t* a0, * a1; qse_awk_val_t* a0, * a1;
qse_char_t* str0, * str1, * ptr;
qse_size_t len0, len1;
qse_awk_int_t idx, boundary = 1; qse_awk_int_t idx, boundary = 1;
nargs = qse_awk_rtx_getnargs(rtx); nargs = qse_awk_rtx_getnargs(rtx);
@ -442,11 +440,60 @@ static int index_or_rindex (qse_awk_rtx_t* rtx, int rindex)
if (n <= -1) return -1; if (n <= -1) return -1;
} }
if (QSE_AWK_RTX_GETVALTYPE(rtx, a0) == QSE_AWK_VAL_MBS)
{
qse_mchar_t* str0, * str1, * ptr;
qse_size_t len0, len1;
str0 = ((qse_awk_val_mbs_t*)a0)->val.ptr;
len0 = ((qse_awk_val_mbs_t*)a0)->val.len;
str1 = qse_awk_rtx_getvalmbs(rtx, a1, &len1);
if (!str1) return -1;
if (nargs < 3)
{
boundary = rindex? len0: 1;
}
else
{
if (boundary == 0) boundary = 1;
else if (boundary < 0) boundary = len0 + boundary + 1;
}
if (boundary > len0 || boundary <= 0)
{
ptr = QSE_NULL;
}
else if (rindex)
{
/* 'boundary' acts as an end position */
ptr = rtx->gbl.ignorecase?
qse_mbsxnrcasestr(&str0[0], boundary, str1, len1):
qse_mbsxnrstr(&str0[0], boundary, str1, len1);
}
else
{
/* 'boundary' acts as an start position */
ptr = rtx->gbl.ignorecase?
qse_mbsxncasestr(&str0[boundary-1], len0 -boundary + 1, str1, len1):
qse_mbsxnstr(&str0[boundary-1], len0 - boundary + 1, str1, len1);
}
idx = (ptr == QSE_NULL)? 0: ((qse_awk_int_t)(ptr - str0) + 1);
qse_awk_rtx_freevalmbs (rtx, a1, str1);
}
else
{
qse_char_t* str0, * str1, * ptr;
qse_size_t len0, len1;
str0 = qse_awk_rtx_getvalstr(rtx, a0, &len0); str0 = qse_awk_rtx_getvalstr(rtx, a0, &len0);
if (str0 == QSE_NULL) return -1; if (!str0) return -1;
str1 = qse_awk_rtx_getvalstr(rtx, a1, &len1); str1 = qse_awk_rtx_getvalstr(rtx, a1, &len1);
if (str1 == QSE_NULL) if (!str1)
{ {
qse_awk_rtx_freevalstr (rtx, a0, str0); qse_awk_rtx_freevalstr (rtx, a0, str0);
return -1; return -1;
@ -485,6 +532,7 @@ static int index_or_rindex (qse_awk_rtx_t* rtx, int rindex)
qse_awk_rtx_freevalstr (rtx, a1, str1); qse_awk_rtx_freevalstr (rtx, a1, str1);
qse_awk_rtx_freevalstr (rtx, a0, str0); qse_awk_rtx_freevalstr (rtx, a0, str0);
}
a0 = qse_awk_rtx_makeintval(rtx, idx); a0 = qse_awk_rtx_makeintval(rtx, idx);
if (a0 == QSE_NULL) return -1; if (a0 == QSE_NULL) return -1;

View File

@ -331,7 +331,7 @@ static int fnc_tonum (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
&lv, &rv &lv, &rv
); );
} }
if (QSE_AWK_RTX_GETVALTYPE(rtx, a0) == QSE_AWK_VAL_STR && qse_awk_rtx_getnargs(rtx) >= 2) else 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 /* if the value is known to be a string, it supports the optional
* base parameter */ * base parameter */