diff --git a/string.c b/string.c index 6988e08..8b508bf 100644 --- a/string.c +++ b/string.c @@ -3192,6 +3192,24 @@ rb_str_casecmp(VALUE str1, VALUE str2) return INT2FIX(-1); } +/* + * call-seq: + * str.casecmp?(other_str) -> true or false + * + * Case-insensitive string comparison. + * + * "abcdef".casecmp?("abcde") #=> false + * "aBcDeF".casecmp?("abcdef") #=> true + * "abcdef".casecmp?("abcdefg") #=> false + * "abcdef".casecmp?("ABCDEF") #=> true + */ + +static VALUE +rb_str_casecmp_p(VALUE str1, VALUE str2) +{ + return rb_str_casecmp(str1, str2) == INT2FIX(0) ? Qtrue : Qfalse; +} + #define rb_str_index(str, sub, offset) rb_strseq_index(str, sub, offset, 0) static long @@ -9604,6 +9622,22 @@ sym_casecmp(VALUE sym, VALUE other) } /* + * call-seq: + * sym.casecmp?(other) -> true, false, or nil + * + * Case-insensitive symbol comparison. + */ + +static VALUE +sym_casecmp_p(VALUE sym, VALUE other) +{ + if (!SYMBOL_P(other)) { + return Qnil; + } + return sym_casecmp(sym, other) == INT2FIX(0) ? Qtrue : Qfalse; +} + +/* * call-seq: * sym =~ obj -> integer or nil * @@ -9802,6 +9836,7 @@ Init_String(void) rb_define_method(rb_cString, "eql?", rb_str_eql, 1); rb_define_method(rb_cString, "hash", rb_str_hash_m, 0); rb_define_method(rb_cString, "casecmp", rb_str_casecmp, 1); + rb_define_method(rb_cString, "casecmp?", rb_str_casecmp_p, 1); rb_define_method(rb_cString, "+", rb_str_plus, 1); rb_define_method(rb_cString, "*", rb_str_times, 1); rb_define_method(rb_cString, "%", rb_str_format_m, 1); @@ -9951,6 +9986,7 @@ Init_String(void) rb_define_method(rb_cSymbol, "<=>", sym_cmp, 1); rb_define_method(rb_cSymbol, "casecmp", sym_casecmp, 1); + rb_define_method(rb_cSymbol, "casecmp?", sym_casecmp_p, 1); rb_define_method(rb_cSymbol, "=~", sym_match, 1); rb_define_method(rb_cSymbol, "[]", sym_aref, -1); diff --git a/test/ruby/enc/test_utf16.rb b/test/ruby/enc/test_utf16.rb index 99b48c2..865c465 100644 --- a/test/ruby/enc/test_utf16.rb +++ b/test/ruby/enc/test_utf16.rb @@ -138,6 +138,12 @@ def test_casecmp assert_not_equal(0, s1.casecmp(s2), "#{encdump s1}.casecmp(#{encdump s2})") end + def test_casecmp? + s1 = "aa".force_encoding("utf-16be") + s2 = "AA" + assert_not_equal(true, s1.casecmp?(s2), "#{encdump s1}.casecmp?(#{encdump s2})") + end + def test_end_with s1 = "ab".force_encoding("utf-16be") s2 = "b".force_encoding("utf-16be") @@ -382,4 +388,11 @@ def test_casecmp2 a = ary.sort {|x,y| x.casecmp(y) } assert_equal(e, a) end + + def test_casecmp2? + assert_equal(true, "\0A".force_encoding("UTF-16BE").casecmp?("\0a".force_encoding("UTF-16BE"))) + assert_not_equal(true, "\0A".force_encoding("UTF-16LE").casecmp?("\0a".force_encoding("UTF-16LE"))) + assert_not_equal(true, "A\0".force_encoding("UTF-16BE").casecmp?("a\0".force_encoding("UTF-16BE"))) + assert_equal(true, "A\0".force_encoding("UTF-16LE").casecmp?("a\0".force_encoding("UTF-16LE"))) + end end diff --git a/test/ruby/test_m17n.rb b/test/ruby/test_m17n.rb index 950d205..033fdb0 100644 --- a/test/ruby/test_m17n.rb +++ b/test/ruby/test_m17n.rb @@ -1155,6 +1155,12 @@ def test_casecmp assert_not_equal(0, s1.casecmp(s2)) end + def test_casecmp? + s1 = s("\x81\x41") + s2 = s("\x81\x61") + assert_not_equal(true, s1.casecmp?(s2)) + end + def test_reverse bug11387 = '[ruby-dev:49189] [Bug #11387]' s1 = u("abcdefghij\xf0") diff --git a/test/ruby/test_m17n_comb.rb b/test/ruby/test_m17n_comb.rb index 99c162a..1f2f8b1 100644 --- a/test/ruby/test_m17n_comb.rb +++ b/test/ruby/test_m17n_comb.rb @@ -593,6 +593,14 @@ def test_str_casecmp } end + def test_str_casecmp? + combination(STRINGS, STRINGS) {|s1, s2| + next unless s1.valid_encoding? && s2.valid_encoding? && Encoding.compatible?(s1, s2) + r = s1.casecmp?(s2) + assert_equal(s1.casecmp(s2) == 0, r) + } + end + def test_str_center combination(STRINGS, [0,1,2,3,10]) {|s1, width| t = s1.center(width) diff --git a/test/ruby/test_string.rb b/test/ruby/test_string.rb index b1d795e..bde5c21 100644 --- a/test/ruby/test_string.rb +++ b/test/ruby/test_string.rb @@ -2210,6 +2210,10 @@ def test_casecmp assert_equal(1, "\u3042B".casecmp("\u3042a")) end + def test_casecmp? + assert_equal(false, "\u3042B".casecmp?("\u3042a")) + end + def test_upcase2 assert_equal("\u3042AB", "\u3042aB".upcase) end diff --git a/test/ruby/test_symbol.rb b/test/ruby/test_symbol.rb index d8c91c1..999d240 100644 --- a/test/ruby/test_symbol.rb +++ b/test/ruby/test_symbol.rb @@ -276,6 +276,13 @@ def test_casecmp assert_nil(:foo.casecmp("foo")) end + def test_casecmp? + assert_equal(true, :FoO.casecmp?(:fOO)) + assert_equal(false, :FoO.casecmp?(:BaR)) + assert_equal(false, :baR.casecmp?(:FoO)) + assert_nil(:foo.casecmp?("foo")) + end + def test_length assert_equal(3, :FoO.length) assert_equal(3, :FoO.size)