From 7c5c967fca7c873414b1eed56d662dc4118123dd Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Wed, 6 May 2026 18:12:01 +0900 Subject: pathname: Define has_separator? instead of SEPARATOR_PAT --- depend | 2 ++ pathname.c | 32 ++++++++++++++++++++++++++++++++ pathname_builtin.rb | 8 ++++---- 3 files changed, 38 insertions(+), 4 deletions(-) diff --git a/depend b/depend index 33249a03be..7faf59f5a4 100644 --- a/depend +++ b/depend @@ -11146,6 +11146,7 @@ pathname.$(OBJEXT): $(top_srcdir)/internal/compilers.h pathname.$(OBJEXT): $(top_srcdir)/internal/file.h pathname.$(OBJEXT): $(top_srcdir)/internal/serial.h pathname.$(OBJEXT): $(top_srcdir)/internal/static_assert.h +pathname.$(OBJEXT): $(top_srcdir)/internal/string.h pathname.$(OBJEXT): $(top_srcdir)/internal/vm.h pathname.$(OBJEXT): $(top_srcdir)/internal/warnings.h pathname.$(OBJEXT): {$(VPATH)}assert.h @@ -11162,6 +11163,7 @@ pathname.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h pathname.$(OBJEXT): {$(VPATH)}builtin.h pathname.$(OBJEXT): {$(VPATH)}config.h pathname.$(OBJEXT): {$(VPATH)}defines.h +pathname.$(OBJEXT): {$(VPATH)}encindex.h pathname.$(OBJEXT): {$(VPATH)}encoding.h pathname.$(OBJEXT): {$(VPATH)}intern.h pathname.$(OBJEXT): {$(VPATH)}internal.h diff --git a/pathname.c b/pathname.c index e8959bb976..72930ff473 100644 --- a/pathname.c +++ b/pathname.c @@ -1,6 +1,7 @@ #include "ruby.h" #include "internal.h" #include "internal/file.h" +#include "internal/string.h" #include "internal/vm.h" #if defined __CYGWIN__ || defined DOSISH @@ -17,6 +18,14 @@ static VALUE rb_cPathname; static ID id_at_path; static ID id_sub; +static VALUE +check_strpath(VALUE path) +{ + Check_Type(path, T_STRING); + rb_get_path_check_no_convert(path); + return path; +} + static VALUE get_strpath(VALUE obj) { @@ -156,6 +165,27 @@ path_absolute_p(VALUE self) return RBOOL(isdirsep(ptr[0])); } +/* :nodoc: */ +static VALUE +has_separator_p(VALUE self, VALUE path) +{ + const char *ptr = RSTRING_PTR(check_strpath(path)); + const char *end = RSTRING_END(path); + if (alt_separator) { + rb_encoding *enc = rb_enc_get(path); + bool mb = !rb_str_enc_fastpath(path); + while (ptr < end) { + if (isdirsep(*ptr)) return Qtrue; + ptr += (mb ? rb_enc_mbclen(ptr, end, enc) : 1); + } + } + else { + /* assume '/' will never be trailing bytes */ + if (memchr(ptr, '/', end - ptr)) return Qtrue; + } + return Qfalse; +} + #include "pathname_builtin.rbinc" static void init_ids(void); @@ -180,6 +210,8 @@ InitVM_pathname(void) rb_define_method(rb_cPathname, "root?", path_root_p, 0); rb_define_method(rb_cPathname, "absolute?", path_absolute_p, 0); + rb_define_private_method(rb_cPathname, "has_separator?", has_separator_p, 1); + rb_provide("pathname.so"); } diff --git a/pathname_builtin.rb b/pathname_builtin.rb index a38e28de8a..5bab73ea49 100644 --- a/pathname_builtin.rb +++ b/pathname_builtin.rb @@ -383,7 +383,7 @@ class Pathname def prepend_prefix(prefix, relpath) # :nodoc: if relpath.empty? File.dirname(prefix) - elsif SEPARATOR_PAT.match?(prefix) + elsif has_separator?(prefix) prefix = File.dirname(prefix) prefix = File.join(prefix, "") if File.basename(prefix + 'a') != 'a' prefix + relpath @@ -524,7 +524,7 @@ class Pathname end end pre.tr!(File::ALT_SEPARATOR, File::SEPARATOR) if File::ALT_SEPARATOR - if SEPARATOR_PAT.match?(File.basename(pre)) + if has_separator?(File.basename(pre)) names.shift while names[0] == '..' end self.class.new(prepend_prefix(pre, File.join(*names))) @@ -573,7 +573,7 @@ class Pathname names.unshift base if base != '.' end pre.tr!(File::ALT_SEPARATOR, File::SEPARATOR) if File::ALT_SEPARATOR - if SEPARATOR_PAT.match?(File.basename(pre)) + if has_separator?(File.basename(pre)) names.shift while names[0] == '..' end if names.empty? @@ -800,7 +800,7 @@ class Pathname basename_list2.shift end r1 = chop_basename(prefix1) - if !r1 && (r1 = SEPARATOR_PAT.match?(File.basename(prefix1))) + if !r1 && (r1 = has_separator?(File.basename(prefix1))) while !basename_list2.empty? && basename_list2.first == '..' index_list2.shift basename_list2.shift -- cgit v1.2.3