diff options
| author | Nobuyoshi Nakada <nobu@ruby-lang.org> | 2026-05-02 17:02:48 +0900 |
|---|---|---|
| committer | Nobuyoshi Nakada <nobu.nakada@gmail.com> | 2026-05-13 17:37:48 +0900 |
| commit | 820554c8d219089cae4fa71af4586e139c593ae7 (patch) | |
| tree | 8797ae595bab17e0d9d7ad1b4dbfa59fe5299a53 | |
| parent | 7c5c967fca7c873414b1eed56d662dc4118123dd (diff) | |
pathname: Move sub_ext to pathname.c
Including platform depending code.
| -rw-r--r-- | pathname.c | 28 | ||||
| -rw-r--r-- | pathname_builtin.rb | 20 |
2 files changed, 28 insertions, 20 deletions
diff --git a/pathname.c b/pathname.c index 72930ff473..aec9fb3d00 100644 --- a/pathname.c +++ b/pathname.c @@ -186,6 +186,33 @@ has_separator_p(VALUE self, VALUE path) return Qfalse; } +/* + * Return a pathname with +repl+ added as a suffix to the basename. + * + * If self has no extension part, +repl+ is appended. + * + * Pathname.new('/usr/bin/shutdown').sub_ext('.rb') + * #=> #<Pathname:/usr/bin/shutdown.rb> + */ +static VALUE +path_sub_ext(VALUE self, VALUE repl) +{ + VALUE path = get_strpath(self); + long len = RSTRING_LEN(path); + const char *ptr = RSTRING_PTR(path); + const char *ext = ruby_enc_find_extname(ptr, &len, rb_enc_get(path)); + if (len > 0) { + RUBY_ASSERT(ext, "should point the last dot"); + path = rb_str_subseq(path, 0, ext - ptr); + } + else { + /* no dot or dotted file */ + path = rb_str_dup(path); + } + path = rb_str_append(path, repl); + return rb_class_new_instance(1, &path, rb_obj_class(self)); +} + #include "pathname_builtin.rbinc" static void init_ids(void); @@ -207,6 +234,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, "sub_ext", path_sub_ext, 1); rb_define_method(rb_cPathname, "root?", path_root_p, 0); rb_define_method(rb_cPathname, "absolute?", path_absolute_p, 0); diff --git a/pathname_builtin.rb b/pathname_builtin.rb index 5bab73ea49..26f7f4025f 100644 --- a/pathname_builtin.rb +++ b/pathname_builtin.rb @@ -298,26 +298,6 @@ class Pathname "#<#{self.class}:#{@path}>" end - # Return a pathname with +repl+ added as a suffix to the basename. - # - # If self has no extension part, +repl+ is appended. - # - # Pathname.new('/usr/bin/shutdown').sub_ext('.rb') - # #=> #<Pathname:/usr/bin/shutdown.rb> - def sub_ext(repl) - ext = File.extname(@path) - - # File.extname("foo.bar:stream") returns ".bar" on NTFS and not ".bar:stream" - # (see ruby_enc_find_extname()). - # The behavior of Pathname#sub_ext is to replace everything - # from the start of the extname until the end of the path with repl. - unless @path.end_with?(ext) - ext = @path[@path.rindex(ext)..] - end - - self.class.new(@path.chomp(ext) + repl) - end - if File::ALT_SEPARATOR # Separator list string. separator_list = Regexp.quote "#{File::ALT_SEPARATOR}#{File::SEPARATOR}" |
