diff --git a/ChangeLog b/ChangeLog index 969a49f97c..7b08560928 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +Sun Aug 1 14:59:04 2010 Tanaka Akira + + * ext/pathname/pathname.c (path_sub_ext): Pathname#sub_ext translated + from pathname.rb. + Sun Aug 1 10:23:48 2010 Yusuke Endoh * lib/irb/init.rb (IRB.parse_opts): set VERBOSE to true when debug diff --git a/ext/pathname/lib/pathname.rb b/ext/pathname/lib/pathname.rb index b0639a4079..c30be4c948 100644 --- a/ext/pathname/lib/pathname.rb +++ b/ext/pathname/lib/pathname.rb @@ -39,15 +39,6 @@ class Pathname SEPARATOR_PAT = /#{Regexp.quote File::SEPARATOR}/ end - # Return a pathname which the extension of the basename is substituted by - # repl. - # - # If self has no extension part, repl is appended. - def sub_ext(repl) - ext = File.extname(@path) - self.class.new(@path.chomp(ext) + repl) - end - # chop_basename(path) -> [pre-basename, basename] or nil def chop_basename(path) base = File.basename(path) diff --git a/ext/pathname/pathname.c b/ext/pathname/pathname.c index 37fc87b500..ecfe11cfc8 100644 --- a/ext/pathname/pathname.c +++ b/ext/pathname/pathname.c @@ -167,6 +167,37 @@ path_sub(int argc, VALUE *argv, VALUE self) return rb_class_new_instance(1, &str, rb_obj_class(self)); } +/* + * Return a pathname which the extension of the basename is substituted by + * repl. + * + * If self has no extension part, repl is appended. + */ +static VALUE +path_sub_ext(VALUE self, VALUE repl) +{ + VALUE str = get_strpath(self); + VALUE str2; + long extlen; + const char *ext; + const char *p; + + StringValue(repl); + p = RSTRING_PTR(str); + ext = ruby_find_extname(p, &extlen); + if (ext == NULL) { + ext = p + RSTRING_LEN(str); + } + else if (extlen <= 1) { + ext += extlen; + } + str2 = rb_str_dup(str); + rb_str_set_len(str2, ext-p); + rb_str_append(str2, repl); + OBJ_INFECT(str2, str); + return rb_class_new_instance(1, &str2, rb_obj_class(self)); +} + /* * == Pathname * @@ -364,4 +395,5 @@ Init_pathname() rb_define_method(rb_cPathname, "to_path", path_to_s, 0); rb_define_method(rb_cPathname, "inspect", path_inspect, 0); rb_define_method(rb_cPathname, "sub", path_sub, -1); + rb_define_method(rb_cPathname, "sub_ext", path_sub_ext, 1); }