enhanced more string comparison functions with case-insensitive operation

This commit is contained in:
hyung-hwan 2021-07-19 19:54:01 +00:00
parent 7d8f32c3cb
commit 05f99d1304
8 changed files with 154 additions and 67 deletions

View File

@ -220,7 +220,7 @@ int hawk_ucstr_to_uch_prop (const hawk_uch_t* name, hawk_uch_prop_t* id)
mid = left + (right - left) / 2;
kwp = &prop_tab[mid];
n = hawk_comp_ucstr_bcstr(name, kwp->name);
n = hawk_comp_ucstr_bcstr(name, kwp->name, 0);
if (n > 0)
{
/* if left, right, mid were of hawk_oow_t,
@ -252,7 +252,7 @@ int hawk_uchars_to_uch_prop (const hawk_uch_t* name, hawk_oow_t len, hawk_uch_pr
mid = left + (right - left) / 2;
kwp = &prop_tab[mid];
n = hawk_comp_uchars_bcstr(name, len, kwp->name);
n = hawk_comp_uchars_bcstr(name, len, kwp->name, 0);
if (n < 0)
{
/* if left, right, mid were of hawk_oow_t,
@ -318,7 +318,7 @@ int hawk_bchars_to_bch_prop (const hawk_bch_t* name, hawk_oow_t len, hawk_bch_pr
mid = left + (right - left) / 2;
kwp = &prop_tab[mid];
n = hawk_comp_bchars_bcstr(name, len, kwp->name);
n = hawk_comp_bchars_bcstr(name, len, kwp->name, 0);
if (n < 0)
{
/* if left, right, mid were of hawk_oow_t,

View File

@ -129,7 +129,7 @@ xci_t xgetcli (int argc, xch_t* const* argv, xcli_t* opt)
if (*str == ':') str++;
if (xcompcharscstr(opt->cur, end - opt->cur, str) != 0) continue;
if (xcompcharscstr(opt->cur, end - opt->cur, str, 0) != 0) continue;
/* match */
opt->cur = XEMSG;

View File

@ -452,31 +452,36 @@ HAWK_EXPORT int hawk_comp_bcstr_limited (
HAWK_EXPORT int hawk_comp_ucstr_bcstr (
const hawk_uch_t* str1,
const hawk_bch_t* str2
const hawk_bch_t* str2,
int ignorecase
);
HAWK_EXPORT int hawk_comp_uchars_ucstr (
const hawk_uch_t* str1,
hawk_oow_t len,
const hawk_uch_t* str2
const hawk_uch_t* str2,
int ignorecase
);
HAWK_EXPORT int hawk_comp_uchars_bcstr (
const hawk_uch_t* str1,
hawk_oow_t len,
const hawk_bch_t* str2
const hawk_bch_t* str2,
int ignorecase
);
HAWK_EXPORT int hawk_comp_bchars_bcstr (
const hawk_bch_t* str1,
hawk_oow_t len,
const hawk_bch_t* str2
const hawk_bch_t* str2,
int ignorecase
);
HAWK_EXPORT int hawk_comp_bchars_ucstr (
const hawk_bch_t* str1,
hawk_oow_t len,
const hawk_uch_t* str2
const hawk_uch_t* str2,
int ignorecase
);
HAWK_EXPORT void hawk_copy_uchars (

View File

@ -1324,7 +1324,7 @@ static int fnc_tcsetattr (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi) /* this is
pair = hawk_map_getfirstpair(((hawk_val_map_t*)a2)->map, &itr);
while (pair)
{
if (hawk_comp_oochars_bcstr(HAWK_MAP_KPTR(pair), HAWK_MAP_KLEN(pair), "cc") == 0)
if (hawk_comp_oochars_bcstr(HAWK_MAP_KPTR(pair), HAWK_MAP_KLEN(pair), "cc", 0) == 0)
{
hawk_bch_t* ptr;
hawk_oow_t len;
@ -1348,19 +1348,19 @@ static int fnc_tcsetattr (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi) /* this is
goto done;
}
if (hawk_comp_oochars_bcstr(HAWK_MAP_KPTR(pair), HAWK_MAP_KLEN(pair), "iflag") == 0)
if (hawk_comp_oochars_bcstr(HAWK_MAP_KPTR(pair), HAWK_MAP_KLEN(pair), "iflag", 0) == 0)
{
t.c_iflag = flag;
}
else if (hawk_comp_oochars_bcstr(HAWK_MAP_KPTR(pair), HAWK_MAP_KLEN(pair), "oflag") == 0)
else if (hawk_comp_oochars_bcstr(HAWK_MAP_KPTR(pair), HAWK_MAP_KLEN(pair), "oflag", 0) == 0)
{
t.c_oflag = flag;
}
else if (hawk_comp_oochars_bcstr(HAWK_MAP_KPTR(pair), HAWK_MAP_KLEN(pair), "cflag") == 0)
else if (hawk_comp_oochars_bcstr(HAWK_MAP_KPTR(pair), HAWK_MAP_KLEN(pair), "cflag", 0) == 0)
{
t.c_cflag = flag;
}
else if (hawk_comp_oochars_bcstr(HAWK_MAP_KPTR(pair), HAWK_MAP_KLEN(pair), "lflag") == 0)
else if (hawk_comp_oochars_bcstr(HAWK_MAP_KPTR(pair), HAWK_MAP_KLEN(pair), "lflag", 0) == 0)
{
t.c_lflag = flag;
}

View File

@ -970,7 +970,7 @@ static int parse_progunit (hawk_t* hawk)
name.len = HAWK_OOECS_LEN(hawk->tok.name);
name.ptr = HAWK_OOECS_PTR(hawk->tok.name);
if (hawk_comp_oochars_oocstr(name.ptr, name.len, HAWK_T("entry")) == 0)
if (hawk_comp_oochars_oocstr(name.ptr, name.len, HAWK_T("entry"), 0) == 0)
{
if (get_token(hawk) <= -1) return -1;
if (!MATCH(hawk, TOK_IDENT))
@ -997,7 +997,7 @@ static int parse_progunit (hawk_t* hawk)
hawk_copy_oochars_to_oocstr (hawk->parse.pragma.entry, HAWK_COUNTOF(hawk->parse.pragma.entry), HAWK_OOECS_PTR(hawk->tok.name), HAWK_OOECS_LEN(hawk->tok.name));
}
}
else if (hawk_comp_oochars_oocstr(name.ptr, name.len, HAWK_T("implicit")) == 0)
else if (hawk_comp_oochars_oocstr(name.ptr, name.len, HAWK_T("implicit"), 0) == 0)
{
/* @pragma implicit on
* @pragma implicit off */
@ -1011,11 +1011,11 @@ static int parse_progunit (hawk_t* hawk)
name.len = HAWK_OOECS_LEN(hawk->tok.name);
name.ptr = HAWK_OOECS_PTR(hawk->tok.name);
if (hawk_comp_oochars_oocstr(name.ptr, name.len, HAWK_T("on")) == 0)
if (hawk_comp_oochars_oocstr(name.ptr, name.len, HAWK_T("on"), 0) == 0)
{
hawk->parse.pragma.trait |= HAWK_IMPLICIT;
}
else if (hawk_comp_oochars_oocstr(name.ptr, name.len, HAWK_T("off")) == 0)
else if (hawk_comp_oochars_oocstr(name.ptr, name.len, HAWK_T("off"), 0) == 0)
{
hawk->parse.pragma.trait &= ~HAWK_IMPLICIT;
}
@ -1024,7 +1024,7 @@ static int parse_progunit (hawk_t* hawk)
goto error_ident_on_off_expected_for_implicit;
}
}
else if (hawk_comp_oochars_oocstr(name.ptr, name.len, HAWK_T("multilinestr")) == 0)
else if (hawk_comp_oochars_oocstr(name.ptr, name.len, HAWK_T("multilinestr"), 0) == 0)
{
if (get_token(hawk) <= -1) return -1;
if (!MATCH(hawk, TOK_IDENT))
@ -1036,11 +1036,11 @@ static int parse_progunit (hawk_t* hawk)
name.len = HAWK_OOECS_LEN(hawk->tok.name);
name.ptr = HAWK_OOECS_PTR(hawk->tok.name);
if (hawk_comp_oochars_oocstr(name.ptr, name.len, HAWK_T("on")) == 0)
if (hawk_comp_oochars_oocstr(name.ptr, name.len, HAWK_T("on"), 0) == 0)
{
hawk->parse.pragma.trait |= HAWK_MULTILINESTR;
}
else if (hawk_comp_oochars_oocstr(name.ptr, name.len, HAWK_T("off")) == 0)
else if (hawk_comp_oochars_oocstr(name.ptr, name.len, HAWK_T("off"), 0) == 0)
{
hawk->parse.pragma.trait &= ~HAWK_MULTILINESTR;
}
@ -1053,7 +1053,7 @@ static int parse_progunit (hawk_t* hawk)
* the pragmas up to this point affect the parser
* the following pragmas affect runtime
* --------------------------------------------------------------------- */
else if (hawk_comp_oochars_oocstr(name.ptr, name.len, HAWK_T("stack_limit")) == 0)
else if (hawk_comp_oochars_oocstr(name.ptr, name.len, HAWK_T("stack_limit"), 0) == 0)
{
hawk_int_t sl;
@ -1071,7 +1071,7 @@ static int parse_progunit (hawk_t* hawk)
/* take the specified value if it's greater than the existing value */
if (sl > hawk->parse.pragma.rtx_stack_limit) hawk->parse.pragma.rtx_stack_limit = sl;
}
else if (hawk_comp_oochars_oocstr(name.ptr, name.len, HAWK_T("striprecspc")) == 0)
else if (hawk_comp_oochars_oocstr(name.ptr, name.len, HAWK_T("striprecspc"), 0) == 0)
{
/* @pragma striprecspc on
* @pragma striprecspc off
@ -1091,11 +1091,11 @@ static int parse_progunit (hawk_t* hawk)
name.len = HAWK_OOECS_LEN(hawk->tok.name);
name.ptr = HAWK_OOECS_PTR(hawk->tok.name);
if (hawk_comp_oochars_oocstr(name.ptr, name.len, HAWK_T("on")) == 0)
if (hawk_comp_oochars_oocstr(name.ptr, name.len, HAWK_T("on"), 0) == 0)
{
is_on = 1;
}
else if (hawk_comp_oochars_oocstr(name.ptr, name.len, HAWK_T("off")) == 0)
else if (hawk_comp_oochars_oocstr(name.ptr, name.len, HAWK_T("off"), 0) == 0)
{
is_on = 0;
}
@ -1113,7 +1113,7 @@ static int parse_progunit (hawk_t* hawk)
hawk->parse.pragma.trait &= ~HAWK_STRIPRECSPC;
}
}
else if (hawk_comp_oochars_oocstr(name.ptr, name.len, HAWK_T("stripstrspc")) == 0)
else if (hawk_comp_oochars_oocstr(name.ptr, name.len, HAWK_T("stripstrspc"), 0) == 0)
{
/* @pragma stripstrspc on
* @pragma stripstrspc off
@ -1130,11 +1130,11 @@ static int parse_progunit (hawk_t* hawk)
name.len = HAWK_OOECS_LEN(hawk->tok.name);
name.ptr = HAWK_OOECS_PTR(hawk->tok.name);
if (hawk_comp_oochars_oocstr(name.ptr, name.len, HAWK_T("on")) == 0)
if (hawk_comp_oochars_oocstr(name.ptr, name.len, HAWK_T("on"), 0) == 0)
{
is_on = 1;
}
else if (hawk_comp_oochars_oocstr(name.ptr, name.len, HAWK_T("off")) == 0)
else if (hawk_comp_oochars_oocstr(name.ptr, name.len, HAWK_T("off"), 0) == 0)
{
is_on = 0;
}
@ -6860,13 +6860,13 @@ retry:
}
while (c == HAWK_T('_') || hawk_is_ooch_alpha(c) || hawk_is_ooch_digit(c));
if (hawk_comp_oochars_bcstr(HAWK_OOECS_PTR(tok->name), HAWK_OOECS_LEN(tok->name), "@SCRIPTNAME") == 0)
if (hawk_comp_oochars_bcstr(HAWK_OOECS_PTR(tok->name), HAWK_OOECS_LEN(tok->name), "@SCRIPTNAME", 0) == 0)
{
/* special parser-level word @SCRIPTNAME. substitute an actual value for it */
if (HAWK_UNLIKELY(hawk_ooecs_cpy(tok->name, (tok->loc.file? tok->loc.file: HAWK_T(""))) == (hawk_oow_t)-1)) return -1;
SET_TOKEN_TYPE (hawk, tok, TOK_STR);
}
else if (hawk_comp_oochars_bcstr(HAWK_OOECS_PTR(tok->name), HAWK_OOECS_LEN(tok->name), "@SCRIPTLINE") == 0)
else if (hawk_comp_oochars_bcstr(HAWK_OOECS_PTR(tok->name), HAWK_OOECS_LEN(tok->name), "@SCRIPTLINE", 0) == 0)
{
/* special parser-level word @SCRIPTLINE. subsitute an actual value for it */
if (HAWK_UNLIKELY(hawk_ooecs_fmt(tok->name, HAWK_T("%zu"), tok->loc.line) == (hawk_oow_t)-1)) return -1;
@ -7466,7 +7466,7 @@ static hawk_mod_t* query_module (hawk_t* hawk, const hawk_oocs_t segs[], int nse
/* TODO: binary search ... */
for (n = 0; n < HAWK_COUNTOF(static_modtab); n++)
{
if (hawk_comp_oochars_oocstr(segs[0].ptr, segs[0].len, static_modtab[n].modname) == 0)
if (hawk_comp_oochars_oocstr(segs[0].ptr, segs[0].len, static_modtab[n].modname, 0) == 0)
{
load = static_modtab[n].modload;
break;

View File

@ -247,8 +247,20 @@ int hawk_comp_bcstr_limited (const hawk_bch_t* str1, const hawk_bch_t* str2, haw
}
}
int hawk_comp_ucstr_bcstr (const hawk_uch_t* str1, const hawk_bch_t* str2)
int hawk_comp_ucstr_bcstr (const hawk_uch_t* str1, const hawk_bch_t* str2, int ignorecase)
{
if (ignorecase)
{
while (hawk_to_uch_lower(*str1) == hawk_to_bch_lower(*str2))
{
if (*str1 == '\0') return 0;
str1++; str2++;
}
return ((hawk_uchu_t)hawk_to_uch_lower(*str1) > (hawk_bchu_t)hawk_to_bch_lower(*str2))? 1: -1;
}
else
{
while (*str1 == *str2)
{
if (*str1 == '\0') return 0;
@ -256,14 +268,32 @@ int hawk_comp_ucstr_bcstr (const hawk_uch_t* str1, const hawk_bch_t* str2)
}
return ((hawk_uchu_t)*str1 > (hawk_bchu_t)*str2)? 1: -1;
}
}
int hawk_comp_uchars_ucstr (const hawk_uch_t* str1, hawk_oow_t len, const hawk_uch_t* str2)
int hawk_comp_uchars_ucstr (const hawk_uch_t* str1, hawk_oow_t len, const hawk_uch_t* str2, int ignorecase)
{
/* for "abc\0" of length 4 vs "abc", the fourth character
* of the first string is equal to the terminating null of
* the second string. the first string is still considered
* bigger */
if (ignorecase)
{
const hawk_uch_t* end = str1 + len;
hawk_uch_t c1;
hawk_uch_t c2;
while (str1 < end && *str2 != '\0')
{
c1 = hawk_to_uch_lower(*str1);
c2 = hawk_to_uch_lower(*str2);
if (c1 != c2) return ((hawk_uchu_t)c1 > (hawk_uchu_t)c2)? 1: -1;
str1++; str2++;
}
return (str1 < end)? 1: (*str2 == '\0'? 0: -1);
}
else
{
const hawk_uch_t* end = str1 + len;
while (str1 < end && *str2 != '\0')
{
@ -271,10 +301,27 @@ int hawk_comp_uchars_ucstr (const hawk_uch_t* str1, hawk_oow_t len, const hawk_u
str1++; str2++;
}
return (str1 < end)? 1: (*str2 == '\0'? 0: -1);
}
}
int hawk_comp_uchars_bcstr (const hawk_uch_t* str1, hawk_oow_t len, const hawk_bch_t* str2)
int hawk_comp_uchars_bcstr (const hawk_uch_t* str1, hawk_oow_t len, const hawk_bch_t* str2, int ignorecase)
{
if (ignorecase)
{
const hawk_uch_t* end = str1 + len;
hawk_uch_t c1;
hawk_bch_t c2;
while (str1 < end && *str2 != '\0')
{
c1 = hawk_to_uch_lower(*str1);
c2 = hawk_to_bch_lower(*str2);
if (c1 != c2) return ((hawk_uchu_t)c1 > (hawk_bchu_t)c2)? 1: -1;
str1++; str2++;
}
return (str1 < end)? 1: (*str2 == '\0'? 0: -1);
}
else
{
const hawk_uch_t* end = str1 + len;
while (str1 < end && *str2 != '\0')
{
@ -282,10 +329,27 @@ int hawk_comp_uchars_bcstr (const hawk_uch_t* str1, hawk_oow_t len, const hawk_b
str1++; str2++;
}
return (str1 < end)? 1: (*str2 == '\0'? 0: -1);
}
}
int hawk_comp_bchars_bcstr (const hawk_bch_t* str1, hawk_oow_t len, const hawk_bch_t* str2)
int hawk_comp_bchars_bcstr (const hawk_bch_t* str1, hawk_oow_t len, const hawk_bch_t* str2, int ignorecase)
{
if (ignorecase)
{
const hawk_bch_t* end = str1 + len;
hawk_bch_t c1;
hawk_bch_t c2;
while (str1 < end && *str2 != '\0')
{
c1 = hawk_to_bch_lower(*str1);
c2 = hawk_to_bch_lower(*str2);
if (c1 != c2) return ((hawk_bchu_t)c1 > (hawk_bchu_t)c2)? 1: -1;
str1++; str2++;
}
return (str1 < end)? 1: (*str2 == '\0'? 0: -1);
}
else
{
const hawk_bch_t* end = str1 + len;
while (str1 < end && *str2 != '\0')
{
@ -293,10 +357,27 @@ int hawk_comp_bchars_bcstr (const hawk_bch_t* str1, hawk_oow_t len, const hawk_b
str1++; str2++;
}
return (str1 < end)? 1: (*str2 == '\0'? 0: -1);
}
}
int hawk_comp_bchars_ucstr (const hawk_bch_t* str1, hawk_oow_t len, const hawk_uch_t* str2)
int hawk_comp_bchars_ucstr (const hawk_bch_t* str1, hawk_oow_t len, const hawk_uch_t* str2, int ignorecase)
{
if (ignorecase)
{
const hawk_bch_t* end = str1 + len;
hawk_bch_t c1;
hawk_uch_t c2;
while (str1 < end && *str2 != '\0')
{
c1 = hawk_to_bch_lower(*str1);
c2 = hawk_to_uch_lower(*str2);
if (c1 != c2) return ((hawk_bchu_t)c1 > (hawk_uchu_t)c2)? 1: -1;
str1++; str2++;
}
return (str1 < end)? 1: (*str2 == '\0'? 0: -1);
}
else
{
const hawk_bch_t* end = str1 + len;
while (str1 < end && *str2 != '\0')
{
@ -304,6 +385,7 @@ int hawk_comp_bchars_ucstr (const hawk_bch_t* str1, hawk_oow_t len, const hawk_u
str1++; str2++;
}
return (str1 < end)? 1: (*str2 == '\0'? 0: -1);
}
}
/* ------------------------------------------------------------------------ */
@ -3764,7 +3846,7 @@ hawk_cmgr_t* hawk_get_cmgr_by_ucstr (const hawk_uch_t* name)
for (i = 0; i < HAWK_COUNTOF(builtin_cmgr_tab); i++)
{
if (hawk_comp_ucstr_bcstr(name, builtin_cmgr_tab[i].name) == 0)
if (hawk_comp_ucstr_bcstr(name, builtin_cmgr_tab[i].name, 0) == 0)
{
return &builtin_cmgr[builtin_cmgr_tab[i].id];
}

View File

@ -19,16 +19,16 @@ int main ()
}
hawk_seterrbfmt (hawk, HAWK_NULL, HAWK_EINVAL, "%d %ld %s %hs", 10, 20L, "hawk", "hawk");
T_ASSERT1 (hawk_comp_oocstr_bcstr(hawk_geterrmsg(hawk), "10 20 hawk hawk") == 0, "hawk seterrbfmt #1");
T_ASSERT1 (hawk_comp_oocstr_bcstr(hawk_geterrmsg(hawk), "10 20 hawk hawk", 0) == 0, "hawk seterrbfmt #1");
hawk_logbfmt (hawk, HAWK_LOG_STDERR, "[%js]\n", hawk_geterrmsg(hawk));
hawk_seterrufmt (hawk, HAWK_NULL, HAWK_EINVAL, ufmt1, 9923, "hawk");
T_ASSERT1 (hawk_comp_oocstr_bcstr(hawk_geterrmsg(hawk), "09923 hawk ") == 0, "hawk seterrufmt #1");
T_ASSERT1 (hawk_comp_oocstr_bcstr(hawk_geterrmsg(hawk), "09923 hawk ", 0) == 0, "hawk seterrufmt #1");
hawk_logbfmt (hawk, HAWK_LOG_STDERR, "[%js]\n", hawk_geterrmsg(hawk));
#if 0
hawk_seterrufmt (hawk, HAWK_NULL, HAWK_EINVAL, ufmt2, 9923, "hawk", HAWK_SMPTR_TO_OOP(0x12345678));
T_ASSERT1 (hawk_comp_oocstr_bcstr(hawk_geterrmsg(hawk), "09923 hawk #\\p12345678") == 0, "hawk seterrufmt #1");
T_ASSERT1 (hawk_comp_oocstr_bcstr(hawk_geterrmsg(hawk), "09923 hawk #\\p12345678", 0) == 0, "hawk seterrufmt #1");
hawk_logbfmt (hawk, HAWK_LOG_STDERR, "[%js]\n", hawk_geterrmsg(hawk));
#endif

View File

@ -81,11 +81,11 @@ oops:
hawk_bch_t* subst (hawk_bch_t* buf, hawk_oow_t bsz, const hawk_bcs_t* ident, void* ctx)
{
if (hawk_comp_bchars_bcstr(ident->ptr, ident->len, "USER") == 0)
if (hawk_comp_bchars_bcstr(ident->ptr, ident->len, "USER", 0) == 0)
{
return buf + ((buf == HAWK_SUBST_NOBUF)? 3: hawk_copy_bcstr_to_bchars(buf, bsz, "sam"));
}
else if (hawk_comp_bchars_bcstr(ident->ptr, ident->len, "GROUP") == 0)
else if (hawk_comp_bchars_bcstr(ident->ptr, ident->len, "GROUP", 0) == 0)
{
return buf + ((buf == HAWK_SUBST_NOBUF)? 6: hawk_copy_bcstr_to_bchars(buf, bsz, "coders"));
}