diff options
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | ext/-test-/add_suffix/bug.c | 21 | ||||
-rw-r--r-- | ext/-test-/add_suffix/depend | 1 | ||||
-rw-r--r-- | ext/-test-/add_suffix/extconf.rb | 4 | ||||
-rw-r--r-- | include/ruby/intern.h | 2 | ||||
-rw-r--r-- | test/-ext-/test_add_suffix.rb | 47 | ||||
-rw-r--r-- | util.c | 17 |
7 files changed, 91 insertions, 6 deletions
@@ -1,3 +1,8 @@ +Fri Jul 30 07:59:53 2010 Nobuyoshi Nakada <nobu@ruby-lang.org> + + * util.c (ruby_add_suffix): fixed a bug returning uninitialized + value. + Fri Jul 30 07:48:04 2010 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp> * ext/tk/extconf.rb: use TK_XINCLUDES on tkConfig.sh when not empty, diff --git a/ext/-test-/add_suffix/bug.c b/ext/-test-/add_suffix/bug.c new file mode 100644 index 0000000000..882832ed34 --- /dev/null +++ b/ext/-test-/add_suffix/bug.c @@ -0,0 +1,21 @@ +#include "ruby.h" +#include "ruby/defines.h" +#ifndef HAVE_RUBY_ADD_SUFFIX +#define _WIN32 1 +#include "util.c" +#endif + +static VALUE +add_suffix(VALUE self, VALUE path, VALUE suffix) +{ + StringValueCStr(path); + ruby_add_suffix(path, StringValueCStr(suffix)); + return path; +} + +void +Init_bug(void) +{ + VALUE mBug = rb_define_module("Bug"); + rb_define_module_function(mBug, "add_suffix", add_suffix, 2); +} diff --git a/ext/-test-/add_suffix/depend b/ext/-test-/add_suffix/depend new file mode 100644 index 0000000000..943d0d9f21 --- /dev/null +++ b/ext/-test-/add_suffix/depend @@ -0,0 +1 @@ +bug.o: $(hdrdir)/ruby/util.h $(top_srcdir)/util.c diff --git a/ext/-test-/add_suffix/extconf.rb b/ext/-test-/add_suffix/extconf.rb new file mode 100644 index 0000000000..bffd1550f3 --- /dev/null +++ b/ext/-test-/add_suffix/extconf.rb @@ -0,0 +1,4 @@ +unless have_func("ruby_add_suffix", "ruby/util.h") + $INCFLAGS << " -I$(top_srcdir)" +end +create_makefile("-test-/add_suffix/bug") diff --git a/include/ruby/intern.h b/include/ruby/intern.h index 338c8bb1b7..c977a4bfd5 100644 --- a/include/ruby/intern.h +++ b/include/ruby/intern.h @@ -381,6 +381,8 @@ char *rb_path_end(const char *); VALUE rb_file_directory_p(VALUE,VALUE); VALUE rb_str_encode_ospath(VALUE); int rb_is_absolute_path(const char *); +const char *ruby_find_basename(const char *name, long *baselen, long *alllen); +const char *ruby_find_extname(const char *name, long *len); /* gc.c */ void ruby_set_stack_size(size_t); NORETURN(void rb_memerror(void)); diff --git a/test/-ext-/test_add_suffix.rb b/test/-ext-/test_add_suffix.rb new file mode 100644 index 0000000000..0520baef8c --- /dev/null +++ b/test/-ext-/test_add_suffix.rb @@ -0,0 +1,47 @@ +require 'test/unit' +require_relative '../ruby/envutil' +require "-test-/add_suffix/bug" + +class Test_AddSuffix < Test::Unit::TestCase + Dir = "/dev/null/".freeze + Style_1 = (Dir+"foo").freeze + + def test_style_0 + assert_equal("a.x.y", Bug.add_suffix("a.x", ".y")) + end + + def test_style_1 + assert_equal(Style_1+".y", Bug.add_suffix(Style_1+".c", ".y")) + suffix = ".bak".freeze + assert_equal(Style_1+suffix, Bug.add_suffix(Style_1.dup, suffix)) + assert_equal(Style_1+suffix, Bug.add_suffix(Style_1+".bar", suffix)) + assert_equal(Style_1+".$$$", Bug.add_suffix(Style_1+suffix, suffix)) + assert_equal(Style_1+suffix, Bug.add_suffix(Style_1+".$$$", suffix)) + assert_equal(Style_1+".~~~", Bug.add_suffix(Style_1+".$$$", ".$$$")) + assert_equal(Dir+"makefile"+suffix, Bug.add_suffix(Dir+"makefile", suffix)) + end + + def test_style_2 + suffix = "~" + assert_equal(Style_1+"~", Bug.add_suffix(Style_1.dup, suffix)) + assert_equal(Style_1+".c~", Bug.add_suffix(Style_1+".c", suffix)) + assert_equal(Style_1+".c~~", Bug.add_suffix(Style_1+".c~", suffix)) + assert_equal(Style_1+"~.c~~", Bug.add_suffix(Style_1+".c~~", suffix)) + assert_equal(Style_1+"~~.c~~", Bug.add_suffix(Style_1+"~.c~~", suffix)) + assert_equal(Style_1+"~~~~~.cc~", Bug.add_suffix(Style_1+"~~~~~.ccc", suffix)) + assert_equal(Style_1+"~~~~~.$$$", Bug.add_suffix(Style_1+"~~~~~.c~~", suffix)) + assert_equal(Dir+"foo~.pas", Bug.add_suffix(Dir+"foo.pas", suffix)) + assert_equal(Dir+"makefile.~", Bug.add_suffix(Dir+"makefile", suffix)) + assert_equal(Dir+"longname.fi~", Bug.add_suffix(Dir+"longname.fil", suffix)) + assert_equal(Dir+"longnam~.fi~", Bug.add_suffix(Dir+"longname.fi~", suffix)) + assert_equal(Dir+"longnam~.$$$", Bug.add_suffix(Dir+"longnam~.fi~", suffix)) + end + + def test_style_3 + base = "a"*1000 + suffix = "-"+"b"*1000 + assert_equal(base+".~~~", Bug.add_suffix(base, suffix)) + assert_equal(base+".~~~", Bug.add_suffix(base+".$$$", suffix)) + assert_equal(base+".$$$", Bug.add_suffix(base+".~~~", suffix)) + end +end @@ -234,8 +234,9 @@ ruby_strtoul(const char *str, char **endptr, int base) * suffix = ".bak" (style 1) * foo.bar => foo.bak * foo.bak => foo.$$$ (fallback) - * foo.$$$ => foo.~~~ (fallback) * makefile => makefile.bak + * suffix = ".$$$" (style 1) + * foo.$$$ => foo.~~~ (fallback) * * suffix = "~" (style 2) * foo.c => foo.c~ @@ -291,7 +292,10 @@ ruby_add_suffix(VALUE str, const char *suffix) if (*suffix == '.') { /* Style 1 */ if (ext) { - if (strEQ(ext, suffix)) goto fallback; + if (strEQ(ext, suffix)) { + extlen = sizeof(suffix1) - 1; /* suffix2 must be same length */ + suffix = strEQ(suffix, suffix1) ? suffix2 : suffix1; + } slen = ext - name; } rb_str_resize(str, slen); @@ -306,12 +310,13 @@ ruby_add_suffix(VALUE str, const char *suffix) p += slen; p[len] = '\0'; if (suffix[1] == '\0') { /* Style 2 */ + q = (char *)ruby_find_basename(buf, &baselen, 0); if (len <= 3) { + if (len == 0 && baselen >= 8 && p + 3 <= buf + sizeof(buf)) p[len++] = '.'; /* DOSISH */ p[len] = *suffix; p[++len] = '\0'; } - else if ((q = (char *)ruby_find_basename(buf, &baselen, 0)) && - baselen < 8) { + else if (q && baselen < 8) { q += baselen; *q++ = *suffix; if (ext) { @@ -332,9 +337,9 @@ ruby_add_suffix(VALUE str, const char *suffix) fallback: (void)memcpy(p, !ext || strEQ(ext, suffix1) ? suffix2 : suffix1, 5); } + rb_str_resize(str, strlen(buf)); + memcpy(RSTRING_PTR(str), buf, RSTRING_LEN(str)); } - rb_str_resize(str, strlen(buf)); - memcpy(RSTRING_PTR(str), buf, RSTRING_LEN(str)); } static int |