From c45908e41f47c88674b73a754ecd0535449b667a Mon Sep 17 00:00:00 2001 From: matz Date: Tue, 27 Aug 2002 08:31:08 +0000 Subject: * file.c (rb_find_file): $LOAD_PATH must not be empty. * file.c (rb_find_file_ext): ditto. * range.c (range_eq): class check should be based on range.class, instead of Range to work with Range.dup. * range.c (range_eql): ditto. * class.c (rb_mod_dup): need to preserve metaclass and flags. * object.c (rb_cstr_to_dbl): had a buffer overrun. * marshal.c (w_class): integrate singleton check into a funciton to follow DRY principle. * marshal.c (w_uclass): should check singleton method. * object.c (rb_obj_dup): dmark and dfree functions must be match for T_DATA type. * object.c (rb_obj_dup): class of the duped object must be match to the class of the original. * re.c (rb_reg_quote): do not escape \t, \f, \r, \n, for they are not regular expression metacharacters. * time.c (time_s_alloc): use time_free instead of free (null check, also serves for type mark). * time.c (time_s_at): check dfree function too. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@2748 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 44 +++++++++++++++++++++++++++++++++++++++ array.c | 51 ++++++++++++++------------------------------- class.c | 5 +---- configure.in | 3 +-- eval.c | 2 +- file.c | 37 ++++++++++++++++++++------------- hash.c | 44 +++++++++++++++------------------------ io.c | 10 +++++---- lib/thread.rb | 3 +++ marshal.c | 66 +++++++++++++++++++++++++++++++--------------------------- numeric.c | 8 +++---- object.c | 49 +++++++++++++++++++++++++++++-------------- range.c | 4 ++-- re.c | 47 ++++++++++++++++++++++------------------- string.c | 52 ++++++---------------------------------------- struct.c | 11 +++++----- time.c | 67 ++++++++++++++++++++++++++++++----------------------------- version.h | 8 +++---- 18 files changed, 262 insertions(+), 249 deletions(-) diff --git a/ChangeLog b/ChangeLog index e683cd54d2..a8dcf5a1af 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,24 @@ +Tue Aug 27 15:03:35 2002 Yukihiro Matsumoto + + * file.c (rb_find_file): $LOAD_PATH must not be empty. + + * file.c (rb_find_file_ext): ditto. + +Tue Aug 27 02:35:21 2002 Yukihiro Matsumoto + + * range.c (range_eq): class check should be based on range.class, + instead of Range to work with Range.dup. + + * range.c (range_eql): ditto. + +Mon Aug 26 18:17:56 2002 Yukihiro Matsumoto + + * class.c (rb_mod_dup): need to preserve metaclass and flags. + +Mon Aug 26 10:44:18 2002 Tanaka Akira + + * object.c (rb_cstr_to_dbl): had a buffer overrun. + Sun Aug 25 20:10:32 2002 Wakou Aoyama * lib/cgi.rb (CGI#form): fix ruby-bugs-ja:PR#280, add default action. @@ -10,6 +31,19 @@ Sat Aug 24 15:32:16 2002 Nobuyoshi Nakada * eval.c (module_setup): unused variable. [ruby-core:00358] +Sat Aug 24 14:59:02 2002 Yukihiro Matsumoto + + * marshal.c (w_class): integrate singleton check into a funciton + to follow DRY principle. + + * marshal.c (w_uclass): should check singleton method. + + * object.c (rb_obj_dup): dmark and dfree functions must be match + for T_DATA type. + + * object.c (rb_obj_dup): class of the duped object must be match + to the class of the original. + Sat Aug 24 13:57:28 2002 Tanaka Akira * lib/time.rb (Time.rfc2822, Time#rfc2822): preserve localtimeness. @@ -22,6 +56,16 @@ Fri Aug 23 23:59:57 2002 Nobuyoshi Nakada * eval.c (umethod_call): removed. +Fri Aug 23 23:39:17 2002 Yukihiro Matsumoto + + * re.c (rb_reg_quote): do not escape \t, \f, \r, \n, for they are + not regular expression metacharacters. + + * time.c (time_s_alloc): use time_free instead of free (null check, + also serves for type mark). + + * time.c (time_s_at): check dfree function too. + Fri Aug 23 17:06:48 2002 WATANABE Hirofumi * configure.in: RUBY_SO_NAME is msvcrt-rubyXX on mswin32/mingw32. diff --git a/array.c b/array.c index 0f016eb1a4..f88e1b1cc2 100644 --- a/array.c +++ b/array.c @@ -796,41 +796,23 @@ rb_ary_empty_p(ary) } static VALUE -ary_copy(ary, clone) - VALUE ary; - int clone; -{ - VALUE copy; - - ary_make_shared(ary); - copy = rb_obj_alloc(rb_cArray); - if (clone) CLONESETUP(copy, ary); - else DUPSETUP(copy, ary); - RARRAY(copy)->ptr = RARRAY(ary)->ptr; - RARRAY(copy)->len = RARRAY(ary)->len; - RARRAY(copy)->aux.shared = RARRAY(ary)->aux.shared; +rb_ary_become(copy, orig) + VALUE copy, orig; +{ + orig = to_ary(orig); + ary_make_shared(orig); + if (RARRAY(copy)->ptr) free(RARRAY(copy)->ptr); + RARRAY(copy)->ptr = RARRAY(orig)->ptr; + RARRAY(copy)->len = RARRAY(orig)->len; + RARRAY(copy)->aux.shared = RARRAY(orig)->aux.shared; FL_SET(copy, ELTS_SHARED); return copy; } -static VALUE -rb_ary_clone(ary) - VALUE ary; -{ - return ary_copy(ary, Qtrue); -} - VALUE rb_ary_dup(ary) VALUE ary; -{ - return ary_copy(ary, Qfalse); -} - -static VALUE -ary_dup(ary) - VALUE ary; { VALUE dup = rb_ary_new2(RARRAY(ary)->len); @@ -1059,7 +1041,7 @@ static VALUE rb_ary_reverse_m(ary) VALUE ary; { - return rb_ary_reverse(ary_dup(ary)); + return rb_ary_reverse(rb_ary_dup(ary)); } int @@ -1137,7 +1119,7 @@ VALUE rb_ary_sort(ary) VALUE ary; { - ary = ary_dup(ary); + ary = rb_ary_dup(ary); rb_ary_sort_bang(ary); return ary; } @@ -1319,7 +1301,7 @@ static VALUE rb_ary_reject(ary) VALUE ary; { - ary = ary_dup(ary); + ary = rb_ary_dup(ary); rb_ary_reject_bang(ary); return ary; } @@ -1715,7 +1697,7 @@ static VALUE rb_ary_uniq(ary) VALUE ary; { - ary = ary_dup(ary); + ary = rb_ary_dup(ary); rb_ary_uniq_bang(ary); return ary; } @@ -1747,7 +1729,7 @@ static VALUE rb_ary_compact(ary) VALUE ary; { - ary = ary_dup(ary); + ary = rb_ary_dup(ary); rb_ary_compact_bang(ary); return ary; } @@ -1826,7 +1808,7 @@ static VALUE rb_ary_flatten(ary) VALUE ary; { - ary = ary_dup(ary); + ary = rb_ary_dup(ary); rb_ary_flatten_bang(ary); return ary; } @@ -1874,8 +1856,7 @@ Init_Array() rb_define_method(rb_cArray, "rindex", rb_ary_rindex, 1); rb_define_method(rb_cArray, "indexes", rb_ary_indexes, -1); rb_define_method(rb_cArray, "indices", rb_ary_indexes, -1); - rb_define_method(rb_cArray, "clone", rb_ary_clone, 0); - rb_define_method(rb_cArray, "dup", rb_ary_dup, 0); + rb_define_method(rb_cArray, "become", rb_ary_become, 1); rb_define_method(rb_cArray, "join", rb_ary_join_m, -1); rb_define_method(rb_cArray, "reverse", rb_ary_reverse_m, 0); rb_define_method(rb_cArray, "reverse!", rb_ary_reverse_bang, 0); diff --git a/class.c b/class.c index 6fb7b51519..a35d85f0ed 100644 --- a/class.c +++ b/class.c @@ -89,10 +89,7 @@ rb_mod_dup(mod) { VALUE dup = rb_mod_clone(mod); - DUPSETUP(dup, mod); - if (FL_TEST(mod, FL_SINGLETON)) { - FL_SET(dup, FL_SINGLETON); - } + RBASIC(dup)->flags = RBASIC(mod)->flags & (T_MASK|FL_TAINT|FL_SINGLETON); return dup; } diff --git a/configure.in b/configure.in index f96249ad92..fcd77fba3e 100644 --- a/configure.in +++ b/configure.in @@ -97,8 +97,7 @@ AC_PROG_GCC_TRADITIONAL AC_PROG_YACC AC_CHECK_TOOL(RANLIB, ranlib, :) -AC_CHECK_TOOL(AR, ar) -AC_CHECK_PROGS(AR, ar aal, ar) +AC_CHECK_TOOL(AR, ar aal, ar) case "$target_os" in cygwin*|mingw*) diff --git a/eval.c b/eval.c index fdde01f3d5..f7b865ab7a 100644 --- a/eval.c +++ b/eval.c @@ -8865,7 +8865,7 @@ rb_thread_cleanup() curr = curr_thread; while (curr->status == THREAD_KILLED) { - curr = curr_thread->prev; + curr = curr->prev; } FOREACH_THREAD_FROM(curr, th) { diff --git a/file.c b/file.c index 781cd9ac82..00b2fb070c 100644 --- a/file.c +++ b/file.c @@ -2015,22 +2015,22 @@ rb_stat_init(obj, fname) } static VALUE -rb_stat_clone(obj) - VALUE obj; +rb_stat_become(obj, orig) + VALUE obj, orig; { struct stat *nst; - VALUE clone; - - clone = rb_obj_alloc(RBASIC(obj)->klass); - CLONESETUP(clone,obj); - if (DATA_PTR(obj)) { + /* need better argument type check */ + if (!rb_obj_is_kind_of(orig, rb_obj_class(obj))) { + rb_raise(rb_eTypeError, "wrong argument type"); + } + if (DATA_PTR(orig)) { nst = ALLOC(struct stat); - *nst = *(struct stat*)DATA_PTR(obj); - DATA_PTR(clone) = nst; + *nst = *(struct stat*)DATA_PTR(orig); + DATA_PTR(obj) = nst; } - return clone; + return obj; } static VALUE @@ -2457,6 +2457,7 @@ rb_find_file_ext(filep, ext) VALUE str = RARRAY(rb_load_path)->ptr[i]; SafeStringValue(str); + if (RSTRING(str)->len == 0) return 0; path = RSTRING(str)->ptr; for (j=0; ext[j]; j++) { fname = rb_str_dup(*filep); @@ -2520,15 +2521,23 @@ rb_find_file(path) } } tmp = rb_ary_join(tmp, rb_str_new2(PATH_SEP)); - lpath = StringValuePtr(tmp); - if (rb_safe_level() >= 2 && !rb_path_check(lpath)) { - rb_raise(rb_eSecurityError, "loading from unsafe path %s", lpath); + if (RSTRING(tmp)->len == 0) { + lpath = 0; + } + else { + lpath = RSTRING(tmp)->ptr; + if (rb_safe_level() >= 2 && !rb_path_check(lpath)) { + rb_raise(rb_eSecurityError, "loading from unsafe path %s", lpath); + } } } else { lpath = 0; } + if (!lpath) { + return 0; /* no path, no load */ + } f = dln_find_file(f, lpath); if (file_load_ok(f)) { return rb_str_new2(f); @@ -2646,7 +2655,7 @@ Init_File() rb_cStat = rb_define_class_under(rb_cFile, "Stat", rb_cObject); rb_define_singleton_method(rb_cStat, "allocate", rb_stat_s_alloc, 0); rb_define_method(rb_cStat, "initialize", rb_stat_init, 1); - rb_define_method(rb_cStat, "clone", rb_stat_clone, 0); + rb_define_method(rb_cStat, "become", rb_stat_become, 1); rb_include_module(rb_cStat, rb_mComparable); diff --git a/hash.c b/hash.c index 46b7cecead..e7fa574e12 100644 --- a/hash.c +++ b/hash.c @@ -248,37 +248,28 @@ rb_hash_s_create(argc, argv, klass) } static VALUE -rb_hash_clone(hash) +to_hash(hash) VALUE hash; { - VALUE clone = rb_obj_clone(hash); - - RHASH(clone)->ifnone = RHASH(hash)->ifnone; - RHASH(clone)->tbl = (st_table*)st_copy(RHASH(hash)->tbl); - - return clone; + return rb_convert_type(hash, T_HASH, "Hash", "to_hash"); } static VALUE -rb_hash_dup(hash) - VALUE hash; +rb_hash_become(copy, orig) + VALUE copy, orig; { - VALUE dup = rb_obj_dup(hash); - - if (FL_TEST(hash, HASH_PROC_DEFAULT)) { - FL_SET(dup, HASH_PROC_DEFAULT); + orig = to_hash(orig); + if (RHASH(copy)->tbl) st_free_table(RHASH(copy)->tbl); + RHASH(copy)->tbl = (st_table*)st_copy(RHASH(orig)->tbl); + RHASH(copy)->ifnone = RHASH(orig)->ifnone; + if (FL_TEST(orig, HASH_PROC_DEFAULT)) { + FL_SET(copy, HASH_PROC_DEFAULT); } - if (FL_TEST(hash, HASH_DELETED)) { - FL_SET(dup, HASH_DELETED); + if (FL_TEST(orig, HASH_DELETED)) { + FL_SET(copy, HASH_DELETED); } - return dup; -} -static VALUE -to_hash(hash) - VALUE hash; -{ - return rb_convert_type(hash, T_HASH, "Hash", "to_hash"); + return copy; } static int @@ -983,7 +974,7 @@ env_delete(obj, name) char *nam, *val; rb_secure(4); - StringValue(name); + SafeStringValue(name); nam = RSTRING(name)->ptr; if (strlen(nam) != RSTRING(name)->len) { rb_raise(rb_eArgError, "bad environment variable name"); @@ -994,9 +985,9 @@ env_delete(obj, name) ruby_setenv(nam, 0); #ifdef __BORLANDC__ - if (strcmpi(nam, "PATH") == 0 && !OBJ_TAINTED(name)) { + if (strcmpi(nam, "PATH") == 0) { #else - if (strcmp(nam, "PATH") == 0 && !OBJ_TAINTED(name)) { + if (strcmp(nam, "PATH") == 0) { #endif path_tainted = 0; } @@ -1616,8 +1607,7 @@ Init_Hash() rb_define_singleton_method(rb_cHash, "[]", rb_hash_s_create, -1); rb_define_method(rb_cHash,"initialize", rb_hash_initialize, -1); - rb_define_method(rb_cHash,"clone", rb_hash_clone, 0); - rb_define_method(rb_cHash,"dup", rb_hash_dup, 0); + rb_define_method(rb_cHash,"become", rb_hash_become, 1); rb_define_method(rb_cHash,"rehash", rb_hash_rehash, 0); rb_define_method(rb_cHash,"to_hash", rb_hash_to_hash, 0); diff --git a/io.c b/io.c index 5fcd46bd11..3d9a4380b0 100644 --- a/io.c +++ b/io.c @@ -643,14 +643,16 @@ read_all(fptr, siz) VALUE str; long bytes = 0; long n; + long pos = 0; if (feof(fptr->f)) return Qnil; READ_CHECK(fptr->f); if (!siz) siz = BUFSIZ; str = rb_tainted_str_new(0, siz); + pos = ftell(fptr->f); for (;;) { n = rb_io_fread(RSTRING(str)->ptr+bytes, siz-bytes, fptr->f); - if (n == 0 && bytes == 0) { + if (pos > 0 && n == 0 && bytes == 0) { if (feof(fptr->f)) return Qnil; rb_sys_fail(fptr->path); } @@ -2249,14 +2251,14 @@ rb_io_reopen(argc, argv, file) } static VALUE -rb_io_clone(io) +rb_io_become(clone, io) VALUE io; { OpenFile *fptr, *orig; int fd; char *mode; - VALUE clone = rb_obj_clone(io); + io = rb_io_get_io(io); GetOpenFile(io, orig); MakeOpenFile(clone, fptr); @@ -3777,7 +3779,7 @@ Init_IO() rb_define_hooked_variable("$.", &lineno, 0, lineno_setter); rb_define_virtual_variable("$_", rb_lastline_get, rb_lastline_set); - rb_define_method(rb_cIO, "clone", rb_io_clone, 0); + rb_define_method(rb_cIO, "become", rb_io_become, 1); rb_define_method(rb_cIO, "reopen", rb_io_reopen, -1); rb_define_method(rb_cIO, "print", rb_io_print, -1); diff --git a/lib/thread.rb b/lib/thread.rb index 7666bccecf..1a08aa7761 100644 --- a/lib/thread.rb +++ b/lib/thread.rb @@ -249,6 +249,7 @@ class SizedQueuem_tbl->num_entries > 0 || + RCLASS(klass)->iv_tbl->num_entries > 1) { + rb_raise(rb_eTypeError, "singleton can't be dumped"); + } + } + path = rb_class2name(klass); + w_unique(path, arg); +} + +static void +w_uclass(obj, base_klass, arg) + VALUE obj, base_klass; + struct dump_arg *arg; +{ + VALUE klass = CLASS_OF(obj); + char *path; + + while (FL_TEST(klass, FL_SINGLETON) || BUILTIN_TYPE(klass) == T_ICLASS) { + if (RCLASS(klass)->m_tbl->num_entries > 0 || + RCLASS(klass)->iv_tbl->num_entries > 1) { + rb_raise(rb_eTypeError, "singleton can't be dumped"); + } + klass = RCLASS(klass)->super; + } + + if (klass != base_klass) { w_byte(TYPE_UCLASS, arg); w_unique(rb_class2name(CLASS_OF(obj)), arg); } @@ -472,41 +501,16 @@ w_object(obj, arg, limit) case T_OBJECT: w_byte(TYPE_OBJECT, arg); - { - VALUE klass = CLASS_OF(obj); - char *path; - - while (FL_TEST(klass, FL_SINGLETON) || BUILTIN_TYPE(klass) == T_ICLASS) { - if (RCLASS(klass)->m_tbl->num_entries > 0 || - RCLASS(klass)->iv_tbl->num_entries > 1) { - rb_raise(rb_eTypeError, "singleton can't be dumped"); - } - klass = RCLASS(klass)->super; - } - path = rb_class2name(klass); - w_unique(path, arg); - w_ivar(ROBJECT(obj)->iv_tbl, &c_arg); - } + w_class(obj, arg); + w_ivar(ROBJECT(obj)->iv_tbl, &c_arg); break; case T_DATA: w_byte(TYPE_DATA, arg); - { - VALUE klass = CLASS_OF(obj); - char *path; - - if (FL_TEST(klass, FL_SINGLETON)) { - if (RCLASS(klass)->m_tbl->num_entries > 0 || - RCLASS(klass)->iv_tbl->num_entries > 1) { - rb_raise(rb_eTypeError, "singleton can't be dumped"); - } - } - path = rb_class2name(klass); - w_unique(path, arg); - } { VALUE v; + w_class(obj, arg); if (!rb_respond_to(obj, s_dump_data)) { rb_raise(rb_eTypeError, "class %s needs to have instance method `_dump_data'", diff --git a/numeric.c b/numeric.c index 3c9a20e500..1bc23a76fa 100644 --- a/numeric.c +++ b/numeric.c @@ -88,11 +88,11 @@ rb_num_coerce_bin(x, y) } static VALUE -num_clone(x) - VALUE x; +num_become(x, y) + VALUE x, y; { /* Numerics are immutable values, which should not be copied */ - rb_raise(rb_eTypeError, "can't clone %s", rb_class2name(CLASS_OF(x))); + rb_raise(rb_eTypeError, "can't copy %s", rb_class2name(CLASS_OF(x))); return Qnil; /* not reached */ } @@ -1630,7 +1630,7 @@ Init_Numeric() rb_include_module(rb_cNumeric, rb_mComparable); rb_define_method(rb_cNumeric, "coerce", num_coerce, 1); - rb_define_method(rb_cNumeric, "clone", num_clone, 0); + rb_define_method(rb_cNumeric, "become", num_become, 1); rb_define_method(rb_cNumeric, "+@", num_uplus, 0); rb_define_method(rb_cNumeric, "-@", num_uminus, 0); diff --git a/object.c b/object.c index c223c5861d..cbc37944f3 100644 --- a/object.c +++ b/object.c @@ -33,7 +33,7 @@ VALUE rb_cSymbol; static ID eq, eql; static ID inspect; -static ID clone; +static ID become; static ID alloc; VALUE @@ -95,15 +95,18 @@ rb_obj_clone(obj) VALUE obj; { VALUE clone; + int frozen; if (rb_special_const_p(obj)) { rb_raise(rb_eTypeError, "can't clone %s", rb_class2name(CLASS_OF(obj))); } clone = rb_obj_alloc(rb_class_real(RBASIC(obj)->klass)); - CLONESETUP(clone,obj); - if (TYPE(clone) == T_OBJECT && ROBJECT(obj)->iv_tbl) { - ROBJECT(clone)->iv_tbl = st_copy(ROBJECT(obj)->iv_tbl); - } + CLONESETUP(clone, obj); + frozen = OBJ_FROZEN(obj); + FL_UNSET(clone, FL_FREEZE); /* temporarily remove frozen flag */ + rb_funcall(clone, become, 1, obj); + if (frozen) OBJ_FREEZE(clone); /* restore frozen status */ + OBJ_INFECT(clone, obj); return clone; } @@ -117,18 +120,31 @@ rb_obj_dup(obj) if (rb_special_const_p(obj)) { rb_raise(rb_eTypeError, "can't dup %s", rb_class2name(CLASS_OF(obj))); } - dup = rb_funcall(obj, clone, 0, 0); - if (TYPE(dup) != TYPE(obj)) { - rb_raise(rb_eTypeError, "dupulicated object must be same type"); + dup = rb_obj_alloc(rb_class_real(RBASIC(obj)->klass)); + DUPSETUP(dup, obj); + rb_funcall(dup, become, 1, obj); + OBJ_INFECT(dup, obj); + + return dup; +} + +VALUE +rb_obj_become(obj, orig) + VALUE obj, orig; +{ + long type; + + if ((type = TYPE(obj)) != TYPE(orig) || + rb_obj_class(obj) != rb_obj_class(orig)) { + rb_raise(rb_eTypeError, "become should take same class object"); } - if (!SPECIAL_CONST_P(dup)) { - OBJSETUP(dup, rb_obj_class(obj), BUILTIN_TYPE(obj)); - OBJ_INFECT(dup, obj); - if (FL_TEST(obj, FL_EXIVAR)) { - FL_SET(dup, FL_EXIVAR); + if (type == T_OBJECT) { + if (ROBJECT(obj)->iv_tbl) st_free_table(ROBJECT(obj)->iv_tbl); + if (ROBJECT(orig)->iv_tbl) { + ROBJECT(obj)->iv_tbl = st_copy(ROBJECT(orig)->iv_tbl); } } - return dup; + return obj; } static VALUE @@ -1009,7 +1025,7 @@ rb_cstr_to_dbl(p, badcheck) return d; } if (*end) { - char *buf = ALLOCA_N(char, strlen(p)); + char *buf = ALLOCA_N(char, strlen(p)+1); char *n = buf; while (p < end) *n++ = *p++; @@ -1267,6 +1283,7 @@ Init_Object() rb_define_method(rb_mKernel, "clone", rb_obj_clone, 0); rb_define_method(rb_mKernel, "dup", rb_obj_dup, 0); + rb_define_method(rb_mKernel, "become", rb_obj_become, 1); rb_define_method(rb_mKernel, "taint", rb_obj_taint, 0); rb_define_method(rb_mKernel, "tainted?", rb_obj_tainted, 0); @@ -1402,5 +1419,5 @@ Init_Object() eq = rb_intern("=="); eql = rb_intern("eql?"); inspect = rb_intern("inspect"); - clone = rb_intern("clone"); + become = rb_intern("become"); } diff --git a/range.c b/range.c index 5fb39a3cac..b7d921f404 100644 --- a/range.c +++ b/range.c @@ -95,7 +95,7 @@ range_eq(range, obj) VALUE range, obj; { if (range == obj) return Qtrue; - if (!rb_obj_is_kind_of(obj, rb_cRange)) return Qfalse; + if (!rb_obj_is_kind_of(obj, rb_obj_class(range))) return Qfalse; if (!rb_equal(rb_ivar_get(range, id_beg), rb_ivar_get(obj, id_beg))) return Qfalse; @@ -153,7 +153,7 @@ range_eql(range, obj) VALUE range, obj; { if (range == obj) return Qtrue; - if (!rb_obj_is_kind_of(obj, rb_cRange)) return Qfalse; + if (!rb_obj_is_kind_of(obj, rb_obj_class(obj))) return Qfalse; if (!rb_eql(rb_ivar_get(range, id_beg), rb_ivar_get(obj, id_beg))) return Qfalse; diff --git a/re.c b/re.c index a8e4cc3b0b..87c06d675d 100644 --- a/re.c +++ b/re.c @@ -544,6 +544,23 @@ match_clone(match) return (VALUE)clone; } +static VALUE +match_dup(match) + VALUE match; +{ + NEWOBJ(dup, struct RMatch); + DUPSETUP(dup, match); + + dup->str = RMATCH(match)->str; + dup->regs = 0; + + dup->regs = ALLOC(struct re_registers); + dup->regs->allocated = 0; + re_copy_registers(dup->regs, RMATCH(match)->regs); + + return (VALUE)dup; +} + static VALUE match_size(match) VALUE match; @@ -1195,7 +1212,6 @@ rb_reg_quote(str) continue; } switch (c) { - case '\t': case '\f': case '\r': case '\n': case '[': case ']': case '{': case '}': case '(': case ')': case '|': case '-': case '*': case '.': case '\\': @@ -1224,22 +1240,6 @@ rb_reg_quote(str) continue; } switch (c) { - case '\t': - c = 't'; - *t++ = '\\'; - break; - case '\f': - c = 'f'; - *t++ = '\\'; - break; - case '\r': - c = 'r'; - *t++ = '\\'; - break; - case '\n': - c = 'n'; - *t++ = '\\'; - break; case '[': case ']': case '{': case '}': case '(': case ')': case '|': case '-': case '*': case '.': case '\\': @@ -1329,11 +1329,13 @@ rb_reg_options(re) } static VALUE -rb_reg_clone(re) +rb_reg_become(clone, re) VALUE re; { - VALUE clone = rb_obj_clone(re); - + /* need better argument type check */ + if (!rb_obj_is_kind_of(re, rb_obj_class(clone))) { + rb_raise(rb_eTypeError, "wrong argument type"); + } RREGEXP(clone)->ptr = 0; RREGEXP(clone)->len = 0; RREGEXP(clone)->str = 0; @@ -1578,7 +1580,7 @@ Init_Regexp() rb_define_singleton_method(rb_cRegexp, "last_match", rb_reg_s_last_match, -1); rb_define_method(rb_cRegexp, "initialize", rb_reg_initialize_m, -1); - rb_define_method(rb_cRegexp, "clone", rb_reg_clone, 0); + rb_define_method(rb_cRegexp, "become", rb_reg_become, 1); rb_define_method(rb_cRegexp, "==", rb_reg_equal, 1); rb_define_method(rb_cRegexp, "=~", rb_reg_match, 1); rb_define_method(rb_cRegexp, "===", rb_reg_match, 1); @@ -1602,7 +1604,10 @@ Init_Regexp() rb_undef_method(CLASS_OF(rb_cMatch), "allocate"); rb_undef_method(CLASS_OF(rb_cMatch), "new"); + /* to be replaced by allocation framework */ rb_define_method(rb_cMatch, "clone", match_clone, 0); + rb_define_method(rb_cMatch, "dup", match_dup, 0); + rb_define_method(rb_cMatch, "size", match_size, 0); rb_define_method(rb_cMatch, "length", match_size, 0); rb_define_method(rb_cMatch, "offset", match_offset, 1); diff --git a/string.c b/string.c index 7488940275..a4f597f2a4 100644 --- a/string.c +++ b/string.c @@ -292,56 +292,17 @@ rb_obj_as_string(obj) return str; } -static VALUE -str_copy(str, clone) - VALUE str; - int clone; -{ - VALUE str2; - int flags; - - StringValue(str); - - if (FL_TEST(str, ELTS_SHARED)) { - str2 = rb_str_new3(RSTRING(str)->aux.shared); - } - else if (FL_TEST(str, STR_ASSOC)) { - str2 = str_new(RSTRING(str)->ptr, RSTRING(str)->len); - RSTRING(str2)->aux.shared = RSTRING(str)->aux.shared; - } - else if (OBJ_FROZEN(str)) { - str2 = rb_str_new3(str); - } - else { - str2 = rb_str_new3(rb_str_new4(str)); - } - flags = FL_TEST(str2, ELTS_SHARED|STR_ASSOC); - if (clone) { - CLONESETUP(str2, str); - } - else { - DUPSETUP(str2, str); - } - if (flags) FL_SET(str2, flags); - return str2; -} +static VALUE rb_str_replace _((VALUE, VALUE)); VALUE rb_str_dup(str) VALUE str; { - return str_copy(str, Qfalse); -} - -static VALUE -rb_str_clone(str) - VALUE str; -{ - return str_copy(str, Qtrue); + VALUE dup = rb_str_s_alloc(rb_cString); + rb_str_replace(dup, str); + return dup; } -static VALUE rb_str_replace _((VALUE, VALUE)); - static VALUE rb_str_init(argc, argv, str) int argc; @@ -1425,7 +1386,7 @@ get_pat(pat) } val = rb_reg_quote(pat); #if RUBY_VERSION_CODE < 180 - if (val != pat) { + if (val != pat && rb_str_cmp(val, pat) != 0) { rb_warn("string pattern instead of regexp; metacharacters no longer effective"); } #endif @@ -3154,8 +3115,7 @@ Init_String() rb_include_module(rb_cString, rb_mEnumerable); rb_define_singleton_method(rb_cString, "allocate", rb_str_s_alloc, 0); rb_define_method(rb_cString, "initialize", rb_str_init, -1); - rb_define_method(rb_cString, "clone", rb_str_clone, 0); - rb_define_method(rb_cString, "dup", rb_str_dup, 0); + rb_define_method(rb_cString, "become", rb_str_replace, 1); rb_define_method(rb_cString, "<=>", rb_str_cmp_m, 1); rb_define_method(rb_cString, "==", rb_str_equal, 1); rb_define_method(rb_cString, "===", rb_str_equal, 1); diff --git a/struct.c b/struct.c index a15555c2ab..1a378c865f 100644 --- a/struct.c +++ b/struct.c @@ -421,11 +421,12 @@ rb_struct_to_a(s) } static VALUE -rb_struct_clone(s) - VALUE s; +rb_struct_become(clone, s) + VALUE clone, s; { - VALUE clone = rb_obj_clone(s); - + if (!rb_obj_is_kind_of(s, rb_obj_class(clone))) { + rb_raise(rb_eTypeError, "wrong argument type"); + } RSTRUCT(clone)->ptr = ALLOC_N(VALUE, RSTRUCT(s)->len); RSTRUCT(clone)->len = RSTRUCT(s)->len; MEMCPY(RSTRUCT(clone)->ptr, RSTRUCT(s)->ptr, VALUE, RSTRUCT(clone)->len); @@ -589,7 +590,7 @@ Init_Struct() rb_define_singleton_method(rb_cStruct, "new", rb_struct_s_def, -1); rb_define_method(rb_cStruct, "initialize", rb_struct_initialize, -2); - rb_define_method(rb_cStruct, "clone", rb_struct_clone, 0); + rb_define_method(rb_cStruct, "become", rb_struct_become, 1); rb_define_method(rb_cStruct, "==", rb_struct_equal, 1); diff --git a/time.c b/time.c index 3b80965161..40e565ce9e 100644 --- a/time.c +++ b/time.c @@ -43,6 +43,13 @@ struct time_object { #define GetTimeval(obj, tobj) \ Data_Get_Struct(obj, struct time_object, tobj) +static void +time_free(tobj) + struct time_object *tobj; +{ + if (tobj) free(tobj); +} + static VALUE time_s_alloc(klass) VALUE klass; @@ -50,7 +57,7 @@ time_s_alloc(klass) VALUE obj; struct time_object *tobj; - obj = Data_Make_Struct(klass, struct time_object, 0, free, tobj); + obj = Data_Make_Struct(klass, struct time_object, 0, time_free, tobj); tobj->tm_got=0; if (gettimeofday(&tobj->tv, 0) < 0) { rb_sys_fail("gettimeofday"); @@ -100,7 +107,7 @@ time_new_internal(klass, sec, usec) rb_raise(rb_eArgError, "time must be positive"); #endif - obj = Data_Make_Struct(klass, struct time_object, 0, free, tobj); + obj = Data_Make_Struct(klass, struct time_object, 0, time_free, tobj); tobj->tm_got = 0; tobj->tv.tv_sec = sec; tobj->tv.tv_usec = usec; @@ -179,7 +186,7 @@ rb_time_timeval(time) struct time_object *tobj; struct timeval t; - if (rb_obj_is_kind_of(time, rb_cTime)) { + if (TYPE(time) == T_DATA && RDATA(time)->dfree == time_free) { GetTimeval(time, tobj); t = tobj->tv; return t; @@ -204,7 +211,7 @@ time_s_at(argc, argv, klass) tv = rb_time_timeval(time); } t = time_new_internal(klass, tv.tv_sec, tv.tv_usec); - if (TYPE(time) == T_DATA) { + if (TYPE(time) == T_DATA && RDATA(time)->dfree == time_free) { struct time_object *tobj, *tobj2; GetTimeval(time, tobj); @@ -717,7 +724,7 @@ time_cmp(time1, time2) RFLOAT(time2)->value); } - if (rb_obj_is_kind_of(time2, rb_cTime)) { + if (TYPE(time2) == T_DATA && RDATA(time2)->dfree == time_free) { GetTimeval(time2, tobj2); if (tobj1->tv.tv_sec == tobj2->tv.tv_sec) { if (tobj1->tv.tv_usec == tobj2->tv.tv_usec) return INT2FIX(0); @@ -754,7 +761,7 @@ time_eql(time1, time2) struct time_object *tobj1, *tobj2; GetTimeval(time1, tobj1); - if (rb_obj_is_kind_of(time2, rb_cTime)) { + if (TYPE(time2) == T_DATA && RDATA(time2)->dfree == time_free) { GetTimeval(time2, tobj2); if (tobj1->tv.tv_sec == tobj2->tv.tv_sec) { if (tobj1->tv.tv_usec == tobj2->tv.tv_usec) return Qtrue; @@ -787,18 +794,28 @@ time_hash(time) } static VALUE -time_clone(time) - VALUE time; +time_become(copy, time) + VALUE copy, time; { - VALUE clone; - struct time_object *tobj, *tclone; + struct time_object *tobj, *tcopy; + if (TYPE(time) != T_DATA || RDATA(time)->dfree != time_free) { + rb_raise(rb_eTypeError, "wrong argument type"); + } GetTimeval(time, tobj); - clone = Data_Make_Struct(0, struct time_object, 0, free, tclone); - CLONESETUP(clone, time); - MEMCPY(tclone, tobj, struct time_object, 1); + GetTimeval(copy, tcopy); + MEMCPY(tcopy, tobj, struct time_object, 1); + + return copy; +} - return clone; +static VALUE +time_dup(time) + VALUE time; +{ + VALUE dup = time_s_alloc(rb_cTime); + time_become(dup, time); + return dup; } static void @@ -862,21 +879,6 @@ time_gmtime(time) return time; } -static VALUE -time_dup(time) - VALUE time; -{ - VALUE clone; - struct time_object *tobj, *tclone; - - GetTimeval(time, tobj); - clone = Data_Make_Struct(0, struct time_object, 0, free, tclone); - DUPSETUP(clone, time); - MEMCPY(tclone, tobj, struct time_object, 1); - - return clone; -} - static VALUE time_getlocaltime(time) VALUE time; @@ -948,7 +950,7 @@ time_plus(time1, time2) GetTimeval(time1, tobj); - if (rb_obj_is_kind_of(time2, rb_cTime)) { + if (TYPE(time2) == T_DATA && RDATA(time2)->dfree == time_free) { rb_raise(rb_eTypeError, "time + time?"); } v = NUM2DBL(time2); @@ -988,7 +990,7 @@ time_minus(time1, time2) double f, d, v; GetTimeval(time1, tobj); - if (rb_obj_is_kind_of(time2, rb_cTime)) { + if (TYPE(time2) == T_DATA && RDATA(time2)->dfree == time_free) { struct time_object *tobj2; GetTimeval(time2, tobj2); @@ -1429,8 +1431,7 @@ Init_Time() rb_define_method(rb_cTime, "<=>", time_cmp, 1); rb_define_method(rb_cTime, "eql?", time_eql, 1); rb_define_method(rb_cTime, "hash", time_hash, 0); - rb_define_method(rb_cTime, "clone", time_clone, 0); - rb_define_method(rb_cTime, "dup", time_dup, 0); + rb_define_method(rb_cTime, "become", time_become, 1); rb_define_method(rb_cTime, "localtime", time_localtime, 0); rb_define_method(rb_cTime, "gmtime", time_gmtime, 0); diff --git a/version.h b/version.h index 6ba60b6814..5f448bc1e2 100644 --- a/version.h +++ b/version.h @@ -1,4 +1,4 @@ -#define RUBY_VERSION "1.7.2" -#define RUBY_RELEASE_DATE "2002-08-24" -#define RUBY_VERSION_CODE 172 -#define RUBY_RELEASE_CODE 20020824 +#define RUBY_VERSION "1.7.3" +#define RUBY_RELEASE_DATE "2002-08-27" +#define RUBY_VERSION_CODE 173 +#define RUBY_RELEASE_CODE 20020827 -- cgit v1.2.3