aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--ext/-test-/add_suffix/bug.c21
-rw-r--r--ext/-test-/add_suffix/depend1
-rw-r--r--ext/-test-/add_suffix/extconf.rb4
-rw-r--r--include/ruby/intern.h2
-rw-r--r--test/-ext-/test_add_suffix.rb47
-rw-r--r--util.c17
7 files changed, 91 insertions, 6 deletions
diff --git a/ChangeLog b/ChangeLog
index 5f7338ddc6..fb7732c00b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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
diff --git a/util.c b/util.c
index 48c212ec6a..a3fbd08c46 100644
--- a/util.c
+++ b/util.c
@@ -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