summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2002-08-27 08:31:08 +0000
committermatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2002-08-27 08:31:08 +0000
commitc45908e41f47c88674b73a754ecd0535449b667a (patch)
treea27bb0f2ca80fa80b9582ddcb8312eee673b0bd5
parentcd3d4a01f248fad1a73ff0b66b7a8d1653f64c19 (diff)
* 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
-rw-r--r--ChangeLog44
-rw-r--r--array.c51
-rw-r--r--class.c5
-rw-r--r--configure.in3
-rw-r--r--eval.c2
-rw-r--r--file.c37
-rw-r--r--hash.c44
-rw-r--r--io.c10
-rw-r--r--lib/thread.rb3
-rw-r--r--marshal.c66
-rw-r--r--numeric.c8
-rw-r--r--object.c49
-rw-r--r--range.c4
-rw-r--r--re.c47
-rw-r--r--string.c52
-rw-r--r--struct.c11
-rw-r--r--time.c67
-rw-r--r--version.h8
18 files changed, 262 insertions, 249 deletions
diff --git a/ChangeLog b/ChangeLog
index e683cd5..a8dcf5a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,24 @@
+Tue Aug 27 15:03:35 2002 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * 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 <matz@ruby-lang.org>
+
+ * 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 <matz@ruby-lang.org>
+
+ * class.c (rb_mod_dup): need to preserve metaclass and flags.
+
+Mon Aug 26 10:44:18 2002 Tanaka Akira <akr@m17n.org>
+
+ * object.c (rb_cstr_to_dbl): had a buffer overrun.
+
Sun Aug 25 20:10:32 2002 Wakou Aoyama <wakou@ruby-lang.org>
* 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 <nobu.nokada@softhome.net>
* eval.c (module_setup): unused variable. [ruby-core:00358]
+Sat Aug 24 14:59:02 2002 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * 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 <akr@m17n.org>
* lib/time.rb (Time.rfc2822, Time#rfc2822): preserve localtimeness.
@@ -22,6 +56,16 @@ Fri Aug 23 23:59:57 2002 Nobuyoshi Nakada <nobu.nokada@softhome.net>
* eval.c (umethod_call): removed.
+Fri Aug 23 23:39:17 2002 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * 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 <eban@ruby-lang.org>
* configure.in: RUBY_SO_NAME is msvcrt-rubyXX on mswin32/mingw32.
diff --git a/array.c b/array.c
index 0f016eb..f88e1b1 100644
--- a/array.c
+++ b/array.c
@@ -796,42 +796,24 @@ 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);
DUPSETUP(dup, ary);
@@ -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 6fb7b51..a35d85f 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 f96249a..fcd77fb 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 fdde01f..f7b865a 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 781cd9a..00b2fb0 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 46b7cec..e7fa574 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 5fcd46b..3d9a438 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 7666bcc..1a08aa7 100644
--- a/lib/thread.rb
+++ b/lib/thread.rb
@@ -249,6 +249,7 @@ class SizedQueue<Queue
super
end
alias << push
+ alias enq push
def pop(*args)
retval = super
@@ -269,6 +270,8 @@ class SizedQueue<Queue
end
retval
end
+ alias shift pop
+ alias deq pop
def num_waiting
@waiting.size + @queue_wait.size
diff --git a/marshal.c b/marshal.c
index faddee8..96ab7fc 100644
--- a/marshal.c
+++ b/marshal.c
@@ -250,11 +250,40 @@ obj_each(id, value, arg)
}
static void
-w_uclass(obj, klass, arg)
- VALUE obj, klass;
+w_class(obj, arg)
+ VALUE obj;
struct dump_arg *arg;
{
- if (rb_obj_class(obj) != klass) {
+ 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");
+ }
+ }
+ 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 3c9a20e..1bc23a7 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 c223c58..cbc3794 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 5fb39a3..b7d921f 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 a8e4cc3..87c06d6 100644
--- a/re.c
+++ b/re.c
@@ -545,6 +545,23 @@ match_clone(match)
}
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 7488940..a4f597f 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 a15555c..1a378c8 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 3b80965..40e565c 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
@@ -863,21 +880,6 @@ time_gmtime(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 6ba60b6..5f448bc 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