diff options
| author | Nobuyoshi Nakada <nobu@ruby-lang.org> | 2026-05-06 18:12:01 +0900 |
|---|---|---|
| committer | Nobuyoshi Nakada <nobu.nakada@gmail.com> | 2026-05-13 17:37:48 +0900 |
| commit | 7c5c967fca7c873414b1eed56d662dc4118123dd (patch) | |
| tree | e6dc94810c4c84276d059e06065203e04db2f88c | |
| parent | d8e6bf63edf8941d968ed7657c418133c47ae344 (diff) | |
pathname: Define has_separator? instead of SEPARATOR_PAT
| -rw-r--r-- | depend | 2 | ||||
| -rw-r--r-- | pathname.c | 32 | ||||
| -rw-r--r-- | pathname_builtin.rb | 8 |
3 files changed, 38 insertions, 4 deletions
@@ -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 @@ -18,6 +19,14 @@ 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) { VALUE strpath; @@ -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 |
