diff --git a/qse/lib/awk/fnc.c b/qse/lib/awk/fnc.c index 3408af29..9a0f3fda 100644 --- a/qse/lib/awk/fnc.c +++ b/qse/lib/awk/fnc.c @@ -22,7 +22,6 @@ static int fnc_close (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi); static int fnc_fflush (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi); -static int fnc_index (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi); static int fnc_sin (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi); static int fnc_cos (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi); @@ -57,7 +56,7 @@ static qse_awk_fnc_t sysfnctab[] = { {QSE_T("fflush"), 6}, 0, { {0, 1, QSE_NULL}, fnc_fflush, QSE_AWK_RIO }, QSE_NULL}, /* string functions */ - { {QSE_T("index"), 5}, 0, { {2, 3, QSE_NULL}, fnc_index, 0 }, QSE_NULL}, + { {QSE_T("index"), 5}, 0, { {2, 3, QSE_NULL}, qse_awk_fnc_index, 0 }, QSE_NULL}, { {QSE_T("substr"), 6}, 0, { {2, 3, QSE_NULL}, qse_awk_fnc_substr, 0 }, QSE_NULL}, { {QSE_T("length"), 6}, 1, { {0, 1, QSE_NULL}, qse_awk_fnc_length, 0 }, QSE_NULL}, { {QSE_T("split"), 5}, 0, { {2, 3, QSE_T("vrx")}, qse_awk_fnc_split, 0 }, QSE_NULL}, @@ -405,8 +404,90 @@ static int fnc_fflush (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi) return 0; } -static int fnc_index (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi) +static int index_or_rindex (qse_awk_rtx_t* rtx, int rindex) { + /* this is similar to the built-in index() function but doesn't + * care about IGNORECASE. */ + qse_size_t nargs; + qse_awk_val_t* a0, * a1; + qse_char_t* str0, * str1, * ptr; + qse_size_t len0, len1; + qse_awk_int_t idx, boundary = 1; + + nargs = qse_awk_rtx_getnargs (rtx); + a0 = qse_awk_rtx_getarg (rtx, 0); + a1 = qse_awk_rtx_getarg (rtx, 1); + + /* + index ("abc", "d", 3); + rindex ("abcdefabcdx", "cd", 8); + */ + + if (nargs >= 3) + { + qse_awk_val_t* a2; + int n; + + a2 = qse_awk_rtx_getarg (rtx, 2); + n = qse_awk_rtx_valtoint (rtx, a2, &boundary); + if (n <= -1) return -1; + } + + str0 = qse_awk_rtx_getvalstr (rtx, a0, &len0); + if (str0 == QSE_NULL) return -1; + + str1 = qse_awk_rtx_getvalstr (rtx, a1, &len1); + if (str1 == QSE_NULL) + { + if (a0->type != QSE_AWK_VAL_STR) + qse_awk_rtx_freevalstr (rtx, a0, str0); + 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_strxnrcasestr (&str0[0], boundary, str1, len1): + qse_strxnrstr (&str0[0], boundary, str1, len1); + } + else + { + /* 'boundary' acts as an start position */ + ptr = rtx->gbl.ignorecase? + qse_strxncasestr (&str0[boundary-1], len0-boundary+1, str1, len1): + qse_strxnstr (&str0[boundary-1], len0-boundary+1, str1, len1); + } + + idx = (ptr == QSE_NULL)? 0: ((qse_awk_int_t)(ptr-str0) + 1); + + qse_awk_rtx_freevalstr (rtx, a1, str1); + qse_awk_rtx_freevalstr (rtx, a0, str0); + + a0 = qse_awk_rtx_makeintval (rtx, idx); + if (a0 == QSE_NULL) return -1; + + qse_awk_rtx_setretval (rtx, a0); + return 0; +} + +int qse_awk_fnc_index (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi) +{ +/* qse_size_t nargs; qse_awk_val_t* a0, * a1, * v; qse_char_t* str0, * str1, * ptr; @@ -457,6 +538,13 @@ static int fnc_index (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi) qse_awk_rtx_setretval (rtx, v); return 0; +*/ + return index_or_rindex (rtx, 0); +} + +int qse_awk_fnc_rindex (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi) +{ + return index_or_rindex (rtx, 1); } int qse_awk_fnc_length (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi) diff --git a/qse/lib/awk/fnc.h b/qse/lib/awk/fnc.h index 86bb5017..91762078 100644 --- a/qse/lib/awk/fnc.h +++ b/qse/lib/awk/fnc.h @@ -42,6 +42,8 @@ extern "C" { qse_awk_fnc_t* qse_awk_findfnc (qse_awk_t* awk, const qse_cstr_t* name); +int qse_awk_fnc_index (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi); +int qse_awk_fnc_rindex (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi); int qse_awk_fnc_length (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi); int qse_awk_fnc_substr (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi); int qse_awk_fnc_split (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi); diff --git a/qse/lib/awk/mod-str.c b/qse/lib/awk/mod-str.c index 45b59b38..edf4d18f 100644 --- a/qse/lib/awk/mod-str.c +++ b/qse/lib/awk/mod-str.c @@ -80,91 +80,7 @@ static int fnc_ltrim (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi) static int fnc_rtrim (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi) { return trim (rtx, QSE_STRTRMX_RIGHT); -} - -static int index_or_rindex (qse_awk_rtx_t* rtx, int rindex) -{ - /* this is similar to the built-in index() function but doesn't - * care about IGNORECASE. */ - qse_size_t nargs; - qse_awk_val_t* a0, * a1; - qse_char_t* str0, * str1, * ptr; - qse_size_t len0, len1; - qse_awk_int_t idx, boundary = 1; - - nargs = qse_awk_rtx_getnargs (rtx); - a0 = qse_awk_rtx_getarg (rtx, 0); - a1 = qse_awk_rtx_getarg (rtx, 1); - - /* - str::index ("abc", "d", 3); - str::rindex ("abcdefabcdx", "cd", 8); - */ - - if (nargs >= 3) - { - qse_awk_val_t* a2; - int n; - - a2 = qse_awk_rtx_getarg (rtx, 2); - n = qse_awk_rtx_valtoint (rtx, a2, &boundary); - if (n <= -1) return -1; - } - - str0 = qse_awk_rtx_getvalstr (rtx, a0, &len0); - if (str0 == QSE_NULL) return -1; - - str1 = qse_awk_rtx_getvalstr (rtx, a1, &len1); - if (str1 == QSE_NULL) - { - if (a0->type != QSE_AWK_VAL_STR) - qse_awk_rtx_freevalstr (rtx, a0, str0); - return -1; - } - - if (nargs < 3) - { - boundary = rindex? len0: 1; - } - else - { - if (boundary == 0) boundary = 1; - else if (boundary < 0) boundary = len0 + boundary + 1; - } - - if (rindex) - { - /* 'boundary' acts as an end position */ - ptr = (boundary > len0 || boundary <= 0)? - QSE_NULL: qse_strxnrstr (&str0[0], boundary, str1, len1); - } - else - { - /* 'boundary' acts as a start position */ - ptr = (boundary > len0 || boundary <= 0)? - QSE_NULL: qse_strxnstr (&str0[boundary-1], len0-boundary+1, str1, len1); - } - - idx = (ptr == QSE_NULL)? 0: ((qse_awk_int_t)(ptr-str0) + 1); - - qse_awk_rtx_freevalstr (rtx, a1, str1); - qse_awk_rtx_freevalstr (rtx, a0, str0); - - a0 = qse_awk_rtx_makeintval (rtx, idx); - if (a0 == QSE_NULL) return -1; - - qse_awk_rtx_setretval (rtx, a0); - return 0; -} - -static int fnc_index (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi) -{ - return index_or_rindex (rtx, 0); -} -static int fnc_rindex (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi) -{ - return index_or_rindex (rtx, 1); -} +} static int is_class (qse_awk_rtx_t* rtx, qse_ctype_t ctype) { @@ -294,8 +210,6 @@ struct fnctab_t qse_awk_mod_sym_fnc_t info; }; -/* TODO: match. let str::match() change str::RLENGTH and str::RSTART */ -/* TODO: index. reuse fnc_index() in fnc.c */ #define A_MAX QSE_TYPE_MAX(int) @@ -303,7 +217,7 @@ static fnctab_t fnctab[] = { /* keep this table sorted for binary search in query(). */ { QSE_T("gsub"), { { 2, 3, QSE_T("xvr")}, qse_awk_fnc_gsub, 0 } }, - { QSE_T("index"), { { 2, 3, QSE_NULL }, fnc_index, 0 } }, + { QSE_T("index"), { { 2, 3, QSE_NULL }, qse_awk_fnc_index, 0 } }, { QSE_T("isalnum"), { { 1, 1, QSE_NULL }, fnc_isalnum, 0 } }, { QSE_T("isalpha"), { { 1, 1, QSE_NULL }, fnc_isalpha, 0 } }, { QSE_T("isblank"), { { 1, 1, QSE_NULL }, fnc_isblank, 0 } }, @@ -321,7 +235,7 @@ static fnctab_t fnctab[] = { QSE_T("match"), { { 2, 3, QSE_T("vxv") }, qse_awk_fnc_match, 0 } }, { QSE_T("normspace"), { { 1, 1, QSE_NULL }, fnc_normspace, 0 } }, { QSE_T("printf"), { { 1, A_MAX, QSE_NULL }, qse_awk_fnc_sprintf, 0 } }, - { QSE_T("rindex"), { { 2, 3, QSE_NULL }, fnc_rindex, 0 } }, + { QSE_T("rindex"), { { 2, 3, QSE_NULL }, qse_awk_fnc_rindex, 0 } }, { QSE_T("rtrim"), { { 1, 1, QSE_NULL }, fnc_rtrim, 0 } }, { QSE_T("split"), { { 2, 3, QSE_T("vrx") }, qse_awk_fnc_split, 0 } }, { QSE_T("sub"), { { 2, 3, QSE_T("xvr") }, qse_awk_fnc_sub, 0 } },