diff --git a/ChangeLog b/ChangeLog index 19a04fcad20ab0..25de42253fa2b1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,20 @@ +Mon Feb 3 13:18:05 2003 Yukihiro Matsumoto + + * re.c (rb_memsearch): algolithm body of String#index. + + * error.c (Init_Exception): "to_str" removed. + + * eval.c (eval): should not rely on Exception#to_str + + * eval.c (compile_error): ditto. + + * error.c (err_append): ditto. + +Sat Feb 1 23:56:29 2003 Yukihiro Matsumoto + + * hash.c (rb_hash_merge): Hash#merge, non destructive "update". + now there's also Hash#merge! which is an alias to "update". + Fri Jan 31 14:16:59 2003 Yukihiro Matsumoto * string.c (rb_str_index): search using Karp-Rabin algolithm. diff --git a/array.c b/array.c index 8151925b7e8567..7e039abf6a9d8d 100644 --- a/array.c +++ b/array.c @@ -1648,23 +1648,6 @@ rb_ary_cmp(ary1, ary2) return INT2FIX(-1); } -static VALUE -rb_ary_diff(ary1, ary2) - VALUE ary1, ary2; -{ - VALUE ary3; - long i; - - ary2 = to_ary(ary2); - ary3 = rb_ary_new(); - for (i=0; ilen; i++) { - if (rb_ary_includes(ary2, RARRAY(ary1)->ptr[i])) continue; - if (rb_ary_includes(ary3, RARRAY(ary1)->ptr[i])) continue; - rb_ary_push(ary3, RARRAY(ary1)->ptr[i]); - } - return ary3; -} - static VALUE ary_make_hash(ary1, ary2) VALUE ary1, ary2; @@ -1683,6 +1666,23 @@ ary_make_hash(ary1, ary2) return hash; } +static VALUE +rb_ary_diff(ary1, ary2) + VALUE ary1, ary2; +{ + VALUE ary3, hash; + long i; + + hash = ary_make_hash(to_ary(ary2), 0); + ary3 = rb_ary_new(); + + for (i=0; ilen; i++) { + if (st_lookup(RHASH(hash)->tbl, RARRAY(ary1)->ptr[i], 0)) continue; + rb_ary_push(ary3, RARRAY(ary1)->ptr[i]); + } + return ary3; +} + static VALUE rb_ary_and(ary1, ary2) VALUE ary1, ary2; diff --git a/error.c b/error.c index 468fbb6d1356bd..8b6b3249549d4b 100644 --- a/error.c +++ b/error.c @@ -544,7 +544,6 @@ Init_Exception() rb_define_method(rb_eException, "exception", exc_exception, -1); rb_define_method(rb_eException, "initialize", exc_initialize, -1); rb_define_method(rb_eException, "to_s", exc_to_s, 0); - rb_define_method(rb_eException, "to_str", exc_to_s, 0); rb_define_method(rb_eException, "message", exc_to_s, 0); rb_define_method(rb_eException, "inspect", exc_inspect, 0); rb_define_method(rb_eException, "backtrace", exc_backtrace, 0); @@ -1115,7 +1114,7 @@ err_append(s) ruby_errinfo = rb_exc_new2(rb_eSyntaxError, s); } else { - VALUE str = rb_str_to_str(ruby_errinfo); + VALUE str = rb_obj_as_string(ruby_errinfo); rb_str_cat2(str, "\n"); rb_str_cat2(str, s); diff --git a/eval.c b/eval.c index aedcefcf74f6d3..dc26c1c4a83b36 100644 --- a/eval.c +++ b/eval.c @@ -1351,7 +1351,7 @@ compile_error(at) } rb_str_buf_cat(str, "\n", 1); if (!NIL_P(ruby_errinfo)) { - rb_str_append(str, ruby_errinfo); + rb_str_append(str, rb_obj_as_string(ruby_errinfo)); } rb_exc_raise(rb_exc_new3(rb_eSyntaxError, str)); } @@ -5176,18 +5176,18 @@ eval(self, src, scope, file, line) ruby_set_current_source(); if (state) { if (state == TAG_RAISE) { - VALUE err; - VALUE errat; + VALUE err, errat, mesg; + mesg = rb_obj_as_string(ruby_errinfo); if (strcmp(file, "(eval)") == 0) { if (ruby_sourceline > 1) { errat = get_backtrace(ruby_errinfo); err = rb_str_dup(RARRAY(errat)->ptr[0]); rb_str_cat2(err, ": "); - rb_str_append(err, ruby_errinfo); + rb_str_append(err, mesg); } else { - err = rb_str_dup(ruby_errinfo); + err = mesg; } rb_exc_raise(rb_funcall(ruby_errinfo, rb_intern("exception"), 1, err)); } diff --git a/hash.c b/hash.c index 249bc645a59dee..d52ef7a40c1181 100644 --- a/hash.c +++ b/hash.c @@ -937,6 +937,13 @@ rb_hash_update(hash1, hash2) return hash1; } +static VALUE +rb_hash_merge(hash1, hash2) + VALUE hash1, hash2; +{ + return rb_hash_update(rb_obj_dup(hash1), hash2); +} + static int path_tainted = -1; static char **origenviron; @@ -1743,6 +1750,8 @@ Init_Hash() rb_define_method(rb_cHash,"invert", rb_hash_invert, 0); rb_define_method(rb_cHash,"update", rb_hash_update, 1); rb_define_method(rb_cHash,"replace", rb_hash_replace, 1); + rb_define_method(rb_cHash,"merge!", rb_hash_update, 1); + rb_define_method(rb_cHash,"merge", rb_hash_merge, 1); rb_define_method(rb_cHash,"include?", rb_hash_has_key, 1); rb_define_method(rb_cHash,"member?", rb_hash_has_key, 1); diff --git a/intern.h b/intern.h index 46980dfc43f678..1ed37a82ec5139 100644 --- a/intern.h +++ b/intern.h @@ -330,6 +330,7 @@ VALUE rb_length_by_each _((VALUE)); /* re.c */ int rb_memcmp _((char*,char*,long)); int rb_memcicmp _((char*,char*,long)); +int rb_memsearch _((char*,long,char*,long)); VALUE rb_reg_nth_defined _((int, VALUE)); VALUE rb_reg_nth_match _((int, VALUE)); VALUE rb_reg_last_match _((VALUE)); diff --git a/re.c b/re.c index 3ddfb30d77cf63..88281197283948 100644 --- a/re.c +++ b/re.c @@ -96,6 +96,59 @@ rb_memcmp(p1, p2, len) return rb_memcicmp(p1, p2, len); } +int +rb_memsearch(x0, m, y0, n) + char *x0, *y0; + long m, n; +{ + unsigned char *x = x0, *y = y0; + unsigned char *s, *e; + long d, i; + unsigned long hx, hy; + +#define KR_REHASH(a, b, h) ((((h) - (a)*d) << 1) + (b)) + + s = y; e = s + n - m + 1; + + /* Preprocessing */ + /* computes d = 2^(m-1) with + the left-shift operator */ + for (d = i = 1; i < m; ++i) + d = (d<<1); + + if (ruby_ignorecase) { + /* Prepare hash value */ + for (hy = hx = i = 0; i < m; ++i) { + hx = ((hx<<1) + casetable[x[i]]); + hy = ((hy<<1) + casetable[s[i]]); + } + /* Searching */ + while (s < e) { + if (hx == hy && rb_memcicmp(x, s, m) == 0) { + return s-y; + } + hy = KR_REHASH(casetable[*s], casetable[*(s+m)], hy); + s++; + } + } + else { + /* Prepare hash value */ + for (hy = hx = i = 0; i < m; ++i) { + hx = ((hx<<1) + x[i]); + hy = ((hy<<1) + s[i]); + } + /* Searching */ + while (s < e) { + if (hx == hy && memcmp(x, s, m) == 0) { + return s-y; + } + hy = KR_REHASH(*s, *(s+m), hy); + s++; + } + } + return -1; +} + #define REG_CASESTATE FL_USER0 #define KCODE_NONE 0 #define KCODE_EUC FL_USER1 @@ -469,7 +522,7 @@ rb_reg_kcode_m(re) case KCODE_UTF8: kcode = "utf8"; break; default: - rb_bug("unknow kcode - should not happen"); + rb_bug("unknown kcode - should not happen"); break; } return rb_str_new2(kcode); diff --git a/sample/test.rb b/sample/test.rb index c47ceedd430be4..4b0099058cf419 100644 --- a/sample/test.rb +++ b/sample/test.rb @@ -1228,7 +1228,7 @@ def dyna_var_check rescue x = $! end - test_ok(x && /Interrupt/ =~ x) + test_ok(x && /Interrupt/ =~ x.message) end test_check "eval" diff --git a/string.c b/string.c index c864f1fc1142d6..90449023c61701 100644 --- a/string.c +++ b/string.c @@ -838,48 +838,14 @@ rb_str_index(str, sub, offset) VALUE str, sub; long offset; { - char *s, *e, *p; - long len; - int d, hx, hy, i; - if (offset < 0) { offset += RSTRING(str)->len; if (offset < 0) return -1; } if (RSTRING(str)->len - offset < RSTRING(sub)->len) return -1; - s = RSTRING(str)->ptr+offset; - p = RSTRING(sub)->ptr; - len = RSTRING(sub)->len; - if (len == 0) return offset; - e = RSTRING(str)->ptr + RSTRING(str)->len - len + 1; - - /* seach using Karp-Rabin algolithm described in: - - EXACT STRING MATCHING ALGORITHMS - http://www-igm.univ-mlv.fr/~lecroq/string/index.html - */ - -#define KR_REHASH(a, b, h) ((((h) - (a)*d) << 1) + (b)) - - /* Preprocessing */ - /* computes d = 2^(m-1) with - the left-shift operator */ - for (d = i = 1; i < len; ++i) - d = (d<<1); - - for (hy = hx = i = 0; i < len; ++i) { - hx = ((hx<<1) + p[i]); - hy = ((hy<<1) + s[i]); - } - - /* Searching */ - while (s < e) { - if (hx == hy && rb_memcmp(p, s, len) == 0) - return (s-(RSTRING(str)->ptr)); - hy = KR_REHASH(*s, *(s+len), hy); - s++; - } - return -1; + if (RSTRING(sub)->len == 0) return offset; + return rb_memsearch(RSTRING(sub)->ptr, RSTRING(sub)->len, + RSTRING(str)->ptr+offset, RSTRING(str)->len-offset); } static VALUE