string.c: add mrb_strcasecmp_p for case-insensitive comparison

Move casecmp_p from mruby-string-ext and mruby-encoding to core as
mrb_strcasecmp_p (predicate function returning mrb_bool). Add
MRB_STR_CASECMP_P macro to internal.h for comparing mrb_value strings
with literal strings.

This eliminates code duplication and avoids static function name
collision for future amalgamation support.

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
Yukihiro "Matz" Matsumoto
2025-12-23 10:41:21 +09:00
parent ce570c28bb
commit 768a1f7752
4 changed files with 23 additions and 42 deletions
+3
View File
@@ -163,6 +163,9 @@ mrb_value mrb_str_inspect(mrb_state *mrb, mrb_value str);
mrb_bool mrb_str_beg_len(mrb_int str_len, mrb_int *begp, mrb_int *lenp);
mrb_value mrb_str_byte_subseq(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len);
mrb_value mrb_str_aref(mrb_state *mrb, mrb_value str, mrb_value idx, mrb_value len);
mrb_bool mrb_strcasecmp_p(const char *s1, mrb_int len1, const char *s2, mrb_int len2);
#define MRB_STR_CASECMP_P(str, lit) \
mrb_strcasecmp_p(RSTRING_PTR(str), RSTRING_LEN(str), lit, sizeof(lit"")-1)
uint32_t mrb_byte_hash(const uint8_t*, mrb_int);
uint32_t mrb_byte_hash_step(const uint8_t*, mrb_int, uint32_t);
+3 -21
View File
@@ -8,24 +8,6 @@
#define ENC_BINARY "BINARY"
#define ENC_UTF8 "UTF-8"
#define ENC_COMP_P(enc, enc_lit) \
casecmp_p(RSTRING_PTR(enc), RSTRING_LEN(enc), enc_lit, sizeof(enc_lit"")-1)
static mrb_bool
casecmp_p(const char *s1, mrb_int len1, const char *s2, mrb_int len2)
{
if (len1 != len2) return FALSE;
const char *e1 = s1 + len1;
const char *e2 = s2 + len2;
while (s1 < e1 && s2 < e2) {
if (*s1 != *s2 && TOUPPER(*s1) != TOUPPER(*s2)) return FALSE;
s1++;
s2++;
}
return TRUE;
}
/*
* call-seq:
* string.valid_encoding? -> true or false
@@ -104,11 +86,11 @@ str_force_encoding(mrb_state *mrb, mrb_value self)
mrb_get_args(mrb, "S", &enc);
struct RString *s = mrb_str_ptr(self);
if (ENC_COMP_P(enc, ENC_ASCII_8BIT) ||
ENC_COMP_P(enc, ENC_BINARY)) {
if (MRB_STR_CASECMP_P(enc, ENC_ASCII_8BIT) ||
MRB_STR_CASECMP_P(enc, ENC_BINARY)) {
s->flags |= MRB_STR_BINARY;
}
else if (ENC_COMP_P(enc, ENC_UTF8)) {
else if (MRB_STR_CASECMP_P(enc, ENC_UTF8)) {
s->flags &= ~MRB_STR_BINARY;
}
else {
+3 -21
View File
@@ -11,24 +11,6 @@
#define ENC_BINARY "BINARY"
#define ENC_UTF8 "UTF-8"
#define ENC_COMP_P(enc, enc_lit) \
casecmp_p(RSTRING_PTR(enc), RSTRING_LEN(enc), enc_lit, sizeof(enc_lit"")-1)
static mrb_bool
casecmp_p(const char *s1, mrb_int len1, const char *s2, mrb_int len2)
{
if (len1 != len2) return FALSE;
const char *e1 = s1 + len1;
const char *e2 = s2 + len2;
while (s1 < e1 && s2 < e2) {
if (*s1 != *s2 && TOUPPER(*s1) != TOUPPER(*s2)) return FALSE;
s1++;
s2++;
}
return TRUE;
}
static mrb_value
int_chr_binary(mrb_state *mrb, mrb_value num)
{
@@ -873,12 +855,12 @@ int_chr(mrb_state *mrb, mrb_value num)
mrb_get_args(mrb, "|S?", &enc, &enc_given);
if (!enc_given ||
ENC_COMP_P(enc, ENC_ASCII_8BIT) ||
ENC_COMP_P(enc, ENC_BINARY)) {
MRB_STR_CASECMP_P(enc, ENC_ASCII_8BIT) ||
MRB_STR_CASECMP_P(enc, ENC_BINARY)) {
return int_chr_binary(mrb, num);
}
#ifdef MRB_UTF8_STRING
else if (ENC_COMP_P(enc, ENC_UTF8)) {
else if (MRB_STR_CASECMP_P(enc, ENC_UTF8)) {
return int_chr_utf8(mrb, num);
}
#endif
+14
View File
@@ -50,6 +50,20 @@ str_check_length(mrb_state *mrb, mrb_int len)
#endif
}
mrb_bool
mrb_strcasecmp_p(const char *s1, mrb_int len1, const char *s2, mrb_int len2)
{
if (len1 != len2) return FALSE;
const char *e1 = s1 + len1;
while (s1 < e1) {
if (*s1 != *s2 && TOUPPER(*s1) != TOUPPER(*s2)) return FALSE;
s1++;
s2++;
}
return TRUE;
}
static struct RString*
str_init_normal_capa(mrb_state *mrb, struct RString *s,
const char *p, mrb_int len, mrb_int capa)