From 488b8e58bc90b29655bd9f85611abcebc58bb11f Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Wed, 6 May 2026 20:08:02 +0900 Subject: pathname: Move root? to pathname.c --- file.c | 5 +++++ internal/file.h | 1 + pathname.c | 19 +++++++++++++++++++ pathname_builtin.rb | 11 ----------- 4 files changed, 25 insertions(+), 11 deletions(-) diff --git a/file.c b/file.c index db29642ac2..b045e8e899 100644 --- a/file.c +++ b/file.c @@ -3767,6 +3767,11 @@ skipprefixroot(const char *path, const char *end, rb_encoding *enc) #endif } +char * +rb_enc_path_skip_prefix_root(const char *path, const char *end, rb_encoding *enc) +{ + return skipprefixroot(path, end, enc); +} static char * enc_path_last_separator(const char *path, const char *end, bool mb_enc, rb_encoding *enc) diff --git a/internal/file.h b/internal/file.h index 29e9cdf4b9..1aa4c67043 100644 --- a/internal/file.h +++ b/internal/file.h @@ -25,6 +25,7 @@ VALUE rb_get_path_check_to_string(VALUE); VALUE rb_get_path_check_convert(VALUE); VALUE rb_get_path_check_no_convert(VALUE); int ruby_is_fd_loadable(int fd); +char *rb_enc_path_skip_prefix_root(const char *path, const char *end, rb_encoding *enc); RUBY_SYMBOL_EXPORT_BEGIN /* file.c (export) */ diff --git a/pathname.c b/pathname.c index 87382dd804..e8959bb976 100644 --- a/pathname.c +++ b/pathname.c @@ -111,6 +111,24 @@ path_sub(int argc, VALUE *argv, VALUE self) return rb_class_new_instance(1, &str, rb_obj_class(self)); } +/* + * Predicate method for root directories. Returns +true+ if the + * pathname consists of consecutive slashes. + * + * It doesn't access the filesystem. So it may return +false+ for some + * pathnames which points to roots such as /usr/... + */ +static VALUE +path_root_p(VALUE self) +{ + VALUE path = get_strpath(self); + if (RSTRING_LEN(path) == 0) return Qfalse; + const char *ptr = RSTRING_PTR(path), *end = RSTRING_END(path); + rb_encoding *enc = rb_enc_get(path); + const char *base = rb_enc_path_skip_prefix_root(ptr, end, enc); + return RBOOL(base == end); +} + /* * call-seq: * absolute? -> true or false @@ -159,6 +177,7 @@ InitVM_pathname(void) rb_cPathname = rb_define_class("Pathname", rb_cObject); rb_define_method(rb_cPathname, "<=>", path_cmp, 1); rb_define_method(rb_cPathname, "sub", path_sub, -1); + rb_define_method(rb_cPathname, "root?", path_root_p, 0); rb_define_method(rb_cPathname, "absolute?", path_absolute_p, 0); rb_provide("pathname.so"); diff --git a/pathname_builtin.rb b/pathname_builtin.rb index b9cba0260f..cab20678db 100644 --- a/pathname_builtin.rb +++ b/pathname_builtin.rb @@ -621,17 +621,6 @@ class Pathname end end - # - # Predicate method for root directories. Returns +true+ if the - # pathname consists of consecutive slashes. - # - # It doesn't access the filesystem. So it may return +false+ for some - # pathnames which points to roots such as /usr/... - # - def root? - chop_basename(@path) == nil && SEPARATOR_PAT.match?(@path) - end - # The opposite of Pathname#absolute? # # It returns +false+ if the pathname begins with a slash. -- cgit v1.2.3