mruby-regexp: prefix exposed engine entry points with mrb_re_

The Pike VM and pattern compiler were exporting bare names like
`re_compile`, `re_exec`, `re_free`, `re_is_word_char`, `re_utf8_charlen`,
`re_utf8_decode`. `re_exec` in particular collides with the obsolete
BSD libc function of the same name (still present on FreeBSD/NetBSD
base), so embedding mruby alongside platform regex could surface a
link-time symbol clash.

Rename all six entry points to `mrb_re_*` to keep the gem's external
symbols inside mruby's namespace. Source file names and the public
header path are unchanged.

Refs #6858.

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
Yukihiro "Matz" Matsumoto
2026-05-25 06:09:11 +09:00
parent f6564c7db1
commit 19c857a773
6 changed files with 37 additions and 37 deletions
+7 -7
View File
@@ -76,7 +76,7 @@ typedef struct mrb_regexp_pattern {
uint8_t first_bytes[16]; /* bitmap of possible first bytes (128-bit, ASCII) */
mrb_bool has_first_bytes; /* true if first_bytes is usable for skipping */
mrb_bool is_literal; /* true if pattern is pure literal (no metacharacters) */
/* Cached VM state for pike_vm (avoids malloc per re_exec call) */
/* Cached VM state for pike_vm (avoids malloc per mrb_re_exec call) */
uint32_t *cached_visited; /* generation-based visited array */
void *cached_threads[2]; /* curr/next thread lists */
int cached_list_capa; /* capacity of cached thread lists */
@@ -113,21 +113,21 @@ typedef struct {
} re_thread_cache;
/* Compile a pattern string into bytecode */
mrb_regexp_pattern* re_compile(mrb_state *mrb, const char *pattern, mrb_int len, uint32_t flags);
mrb_regexp_pattern* mrb_re_compile(mrb_state *mrb, const char *pattern, mrb_int len, uint32_t flags);
/* Free a compiled pattern */
void re_free(mrb_state *mrb, mrb_regexp_pattern *pat);
void mrb_re_free(mrb_state *mrb, mrb_regexp_pattern *pat);
/* Execute a match.
Returns number of captures filled (0 = no match).
captures[2*n] = start, captures[2*n+1] = end for group n. */
int re_exec(mrb_state *mrb, const mrb_regexp_pattern *pat,
int mrb_re_exec(mrb_state *mrb, const mrb_regexp_pattern *pat,
const char *str, mrb_int len, mrb_int start,
int *captures, int captures_size);
/* UTF-8 helpers */
int re_utf8_charlen(const char *s, const char *end);
uint32_t re_utf8_decode(const char *s, int *len);
mrb_bool re_is_word_char(uint32_t c);
int mrb_re_utf8_charlen(const char *s, const char *end);
uint32_t mrb_re_utf8_decode(const char *s, int *len);
mrb_bool mrb_re_is_word_char(uint32_t c);
#endif /* MRB_RE_INTERNAL_H */
+3 -3
View File
@@ -183,7 +183,7 @@ class_add_shorthand(re_charclass *cc, int ch)
break;
case 'W':
for (int i = 0; i < 128; i++) {
if (!re_is_word_char(i)) class_set_bit(cc, (uint8_t)i);
if (!mrb_re_is_word_char(i)) class_set_bit(cc, (uint8_t)i);
}
cc->utf8_any = TRUE;
break;
@@ -857,7 +857,7 @@ compute_first_set(const re_inst *code, uint32_t code_len,
}
mrb_regexp_pattern*
re_compile(mrb_state *mrb, const char *pattern, mrb_int len, uint32_t flags)
mrb_re_compile(mrb_state *mrb, const char *pattern, mrb_int len, uint32_t flags)
{
re_compiler c;
memset(&c, 0, sizeof(c));
@@ -984,7 +984,7 @@ re_compile(mrb_state *mrb, const char *pattern, mrb_int len, uint32_t flags)
}
void
re_free(mrb_state *mrb, mrb_regexp_pattern *pat)
mrb_re_free(mrb_state *mrb, mrb_regexp_pattern *pat)
{
if (pat) {
mrb_free(mrb, pat->code);
+14 -14
View File
@@ -170,16 +170,16 @@ add_thread(pike_state *s, re_threadlist *list,
case RE_WBOUND:
{
mrb_bool before = (sp > s->str) && re_is_word_char((uint8_t)sp[-1]);
mrb_bool after = (sp < s->str_end) && re_is_word_char((uint8_t)*sp);
mrb_bool before = (sp > s->str) && mrb_re_is_word_char((uint8_t)sp[-1]);
mrb_bool after = (sp < s->str_end) && mrb_re_is_word_char((uint8_t)*sp);
if (before != after) { pc++; continue; }
}
return;
case RE_NWBOUND:
{
mrb_bool before = (sp > s->str) && re_is_word_char((uint8_t)sp[-1]);
mrb_bool after = (sp < s->str_end) && re_is_word_char((uint8_t)*sp);
mrb_bool before = (sp > s->str) && mrb_re_is_word_char((uint8_t)sp[-1]);
mrb_bool after = (sp < s->str_end) && mrb_re_is_word_char((uint8_t)*sp);
if (before == after) { pc++; continue; }
}
return;
@@ -301,7 +301,7 @@ pike_vm(mrb_state *mrb, const mrb_regexp_pattern *pat,
next.count = 0;
int ch = (uint8_t)*sp;
int advance = re_utf8_charlen(sp, str_end);
int advance = mrb_re_utf8_charlen(sp, str_end);
for (int i = 0; i < curr.count; i++) {
re_thread *th = &curr.threads[i];
@@ -404,22 +404,22 @@ bt_match(const mrb_regexp_pattern *pat, const char *str, const char *str_end,
case RE_ANY:
if (sp >= str_end || *sp == '\n') return FALSE;
sp += re_utf8_charlen(sp, str_end); pc++;
sp += mrb_re_utf8_charlen(sp, str_end); pc++;
break;
case RE_ANY_NL:
if (sp >= str_end) return FALSE;
sp += re_utf8_charlen(sp, str_end); pc++;
sp += mrb_re_utf8_charlen(sp, str_end); pc++;
break;
case RE_CLASS:
if (sp >= str_end || !class_match(&pat->classes[inst.a], (uint8_t)*sp)) return FALSE;
sp += re_utf8_charlen(sp, str_end); pc++;
sp += mrb_re_utf8_charlen(sp, str_end); pc++;
break;
case RE_NCLASS:
if (sp >= str_end || class_match(&pat->classes[inst.a], (uint8_t)*sp)) return FALSE;
sp += re_utf8_charlen(sp, str_end); pc++;
sp += mrb_re_utf8_charlen(sp, str_end); pc++;
break;
case RE_MATCH:
@@ -473,8 +473,8 @@ bt_match(const mrb_regexp_pattern *pat, const char *str, const char *str_end,
case RE_WBOUND:
{
mrb_bool before = (sp > str) && re_is_word_char((uint8_t)sp[-1]);
mrb_bool after = (sp < str_end) && re_is_word_char((uint8_t)*sp);
mrb_bool before = (sp > str) && mrb_re_is_word_char((uint8_t)sp[-1]);
mrb_bool after = (sp < str_end) && mrb_re_is_word_char((uint8_t)*sp);
if (before == after) return FALSE;
}
pc++;
@@ -482,8 +482,8 @@ bt_match(const mrb_regexp_pattern *pat, const char *str, const char *str_end,
case RE_NWBOUND:
{
mrb_bool before = (sp > str) && re_is_word_char((uint8_t)sp[-1]);
mrb_bool after = (sp < str_end) && re_is_word_char((uint8_t)*sp);
mrb_bool before = (sp > str) && mrb_re_is_word_char((uint8_t)sp[-1]);
mrb_bool after = (sp < str_end) && mrb_re_is_word_char((uint8_t)*sp);
if (before != after) return FALSE;
}
pc++;
@@ -611,7 +611,7 @@ literal_exec(const mrb_regexp_pattern *pat,
/* Public entry point */
int
re_exec(mrb_state *mrb, const mrb_regexp_pattern *pat,
mrb_re_exec(mrb_state *mrb, const mrb_regexp_pattern *pat,
const char *str, mrb_int len, mrb_int start,
int *captures, int captures_size)
{
+3 -3
View File
@@ -9,7 +9,7 @@
/* Return byte length of UTF-8 character at s.
Returns 1 for invalid sequences (treat as single byte). */
int
re_utf8_charlen(const char *s, const char *end)
mrb_re_utf8_charlen(const char *s, const char *end)
{
uint8_t c = (uint8_t)*s;
int len;
@@ -28,7 +28,7 @@ re_utf8_charlen(const char *s, const char *end)
/* Decode a UTF-8 character and return its codepoint.
*len is set to the byte length consumed. */
uint32_t
re_utf8_decode(const char *s, int *len)
mrb_re_utf8_decode(const char *s, int *len)
{
uint8_t c = (uint8_t)s[0];
uint32_t cp;
@@ -66,7 +66,7 @@ re_utf8_decode(const char *s, int *len)
/* Check if character is a "word" character (\w): [a-zA-Z0-9_] */
mrb_bool
re_is_word_char(uint32_t c)
mrb_re_is_word_char(uint32_t c)
{
if (c >= 'a' && c <= 'z') return TRUE;
if (c >= 'A' && c <= 'Z') return TRUE;
+9 -9
View File
@@ -19,7 +19,7 @@
/* Regexp data type */
static void regexp_free(mrb_state *mrb, void *ptr) {
re_free(mrb, (mrb_regexp_pattern*)ptr);
mrb_re_free(mrb, (mrb_regexp_pattern*)ptr);
}
static const struct mrb_data_type regexp_type = { "Regexp", regexp_free };
@@ -107,13 +107,13 @@ regexp_init(mrb_state *mrb, mrb_value self)
flags = parse_flags(mrb, flags_val);
}
/* Set @source and @flags before re_compile() so a Regexp that survives
/* Set @source and @flags before mrb_re_compile() so a Regexp that survives
a compile-time exception (e.g. picked up by ObjectSpace.each_object)
still has usable IVs for hash/eql?/inspect. */
mrb_iv_set(mrb, self, mrb_intern_lit(mrb, "@source"), pattern);
mrb_iv_set(mrb, self, mrb_intern_lit(mrb, "@flags"), mrb_int_value(mrb, (mrb_int)flags));
pat = re_compile(mrb, RSTRING_PTR(pattern), RSTRING_LEN(pattern), flags);
pat = mrb_re_compile(mrb, RSTRING_PTR(pattern), RSTRING_LEN(pattern), flags);
DATA_TYPE(self) = &regexp_type;
DATA_PTR(self) = pat;
@@ -206,7 +206,7 @@ exec_match(mrb_state *mrb, mrb_value self, mrb_value str, mrb_int pos)
int cap_size = pat->num_captures * 2;
int *captures = (int*)mrb_malloc(mrb, sizeof(int) * cap_size);
memset(captures, -1, sizeof(int) * cap_size);
int ncap = re_exec(mrb, pat, RSTRING_PTR(str), RSTRING_LEN(str), pos,
int ncap = mrb_re_exec(mrb, pat, RSTRING_PTR(str), RSTRING_LEN(str), pos,
captures, cap_size);
if (ncap == 0) {
@@ -244,7 +244,7 @@ regexp_match_p(mrb_state *mrb, mrb_value self)
mrb_regexp_pattern *pat = DATA_GET_PTR(mrb, self, &regexp_type, mrb_regexp_pattern);
if (!pat) mrb_raise(mrb, E_ARGUMENT_ERROR, "uninitialized Regexp");
int ncap = re_exec(mrb, pat, RSTRING_PTR(str), RSTRING_LEN(str), pos, NULL, 0);
int ncap = mrb_re_exec(mrb, pat, RSTRING_PTR(str), RSTRING_LEN(str), pos, NULL, 0);
return mrb_bool_value(ncap > 0);
}
@@ -281,7 +281,7 @@ regexp_case_match(mrb_state *mrb, mrb_value self)
pat = DATA_GET_PTR(mrb, self, &regexp_type, mrb_regexp_pattern);
if (!pat) return mrb_false_value();
int ncap = re_exec(mrb, pat, RSTRING_PTR(str), RSTRING_LEN(str), 0, NULL, 0);
int ncap = mrb_re_exec(mrb, pat, RSTRING_PTR(str), RSTRING_LEN(str), 0, NULL, 0);
return mrb_bool_value(ncap > 0);
}
@@ -726,7 +726,7 @@ regexp_gsub_str(mrb_state *mrb, mrb_value self)
while (pos <= slen) {
memset(captures, -1, sizeof(int) * cap_size);
int n = re_exec(mrb, pat, s, slen, pos, captures, cap_size);
int n = mrb_re_exec(mrb, pat, s, slen, pos, captures, cap_size);
if (n == 0) break;
/* save last match for $~ */
@@ -800,7 +800,7 @@ regexp_sub_str(mrb_state *mrb, mrb_value self)
int *captures = (int*)mrb_malloc(mrb, sizeof(int) * cap_size);
memset(captures, -1, sizeof(int) * cap_size);
int n = re_exec(mrb, pat, s, slen, 0, captures, cap_size);
int n = mrb_re_exec(mrb, pat, s, slen, 0, captures, cap_size);
if (n == 0) {
mrb_free(mrb, captures);
clear_match_globals(mrb);
@@ -858,7 +858,7 @@ regexp_scan(mrb_state *mrb, mrb_value self)
while (pos <= slen) {
memset(captures, -1, sizeof(int) * cap_size);
int n = re_exec(mrb, pat, s, slen, pos, captures, cap_size);
int n = mrb_re_exec(mrb, pat, s, slen, pos, captures, cap_size);
if (n == 0) break;
last_ncap = cap_size;
+1 -1
View File
@@ -381,7 +381,7 @@ assert("MatchData#named_captures") do
end
assert("Regexp - named captures survive /x preprocessing") do
# Regression: with /x, re_compile freed the stripped buffer that
# Regression: with /x, mrb_re_compile freed the stripped buffer that
# named_captures[i].name pointed into.
re = /(?<n>\d+) # comment
\s* (?<u>\w+) /x