summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNobuyoshi Nakada <nobu@ruby-lang.org>2026-05-02 18:25:46 +0900
committerNobuyoshi Nakada <nobu.nakada@gmail.com>2026-05-13 17:37:48 +0900
commite3cccd28ea7954d29a15e0fd2495febdaa5bc306 (patch)
treeb628729a0adc48bca2c373348daa8fcfc197f594
parent820554c8d219089cae4fa71af4586e139c593ae7 (diff)
pathname: Move chop_basename to pathname.c
-rw-r--r--pathname.c21
-rw-r--r--pathname_builtin.rb11
2 files changed, 21 insertions, 11 deletions
diff --git a/pathname.c b/pathname.c
index aec9fb3d00..2a006b4899 100644
--- a/pathname.c
+++ b/pathname.c
@@ -213,6 +213,26 @@ path_sub_ext(VALUE self, VALUE repl)
return rb_class_new_instance(1, &path, rb_obj_class(self));
}
+/* :nodoc: */
+/* chop_basename(path) -> [pre-basename, basename] or nil */
+static VALUE
+chop_basename(VALUE self, VALUE path)
+{
+ long baselen, alllen = RSTRING_LEN(check_strpath(path));
+ if (alllen <= 0) return Qnil;
+ rb_encoding *enc = rb_enc_get(path);
+ const char *name = RSTRING_PTR(path);
+ const char *base = ruby_enc_find_basename(name, &baselen, &alllen, enc);
+ if (baselen < 1) return Qnil;
+ if (baselen == 1 && isdirsep(*base)) return Qnil;
+ RUBY_ASSERT(base >= name);
+ RUBY_ASSERT(base <= RSTRING_END(path));
+ VALUE dir = rb_str_subseq(path, 0, base - name);
+ VALUE basename = rb_enc_str_new(base, alllen, enc);
+ RB_GC_GUARD(path);
+ return rb_assoc_new(dir, basename);
+}
+
#include "pathname_builtin.rbinc"
static void init_ids(void);
@@ -239,6 +259,7 @@ InitVM_pathname(void)
rb_define_method(rb_cPathname, "absolute?", path_absolute_p, 0);
rb_define_private_method(rb_cPathname, "has_separator?", has_separator_p, 1);
+ rb_define_private_method(rb_cPathname, "chop_basename", chop_basename, 1);
rb_provide("pathname.so");
}
diff --git a/pathname_builtin.rb b/pathname_builtin.rb
index 26f7f4025f..0885aa3085 100644
--- a/pathname_builtin.rb
+++ b/pathname_builtin.rb
@@ -338,17 +338,6 @@ class Pathname
self
end
- # chop_basename(path) -> [pre-basename, basename] or nil
- def chop_basename(path) # :nodoc:
- base = File.basename(path)
- if /\A#{SEPARATOR_PAT}?\z/o.match?(base)
- return nil
- else
- return path[0, path.rindex(base)], base
- end
- end
- private :chop_basename
-
# split_names(path) -> prefix, [name, ...]
def split_names(path) # :nodoc:
names = []