mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* 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
This commit is contained in:
parent
cd3d4a01f2
commit
c45908e41f
18 changed files with 268 additions and 255 deletions
44
ChangeLog
44
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.
|
||||
|
|
49
array.c
49
array.c
|
@ -796,41 +796,23 @@ rb_ary_empty_p(ary)
|
|||
}
|
||||
|
||||
static VALUE
|
||||
ary_copy(ary, clone)
|
||||
VALUE ary;
|
||||
int clone;
|
||||
rb_ary_become(copy, orig)
|
||||
VALUE copy, orig;
|
||||
{
|
||||
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;
|
||||
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);
|
||||
|
|
5
class.c
5
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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*)
|
||||
|
|
2
eval.c
2
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) {
|
||||
|
|
37
file.c
37
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);
|
||||
|
||||
|
|
54
hash.c
54
hash.c
|
@ -247,33 +247,6 @@ rb_hash_s_create(argc, argv, klass)
|
|||
return hash;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_hash_clone(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;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_hash_dup(hash)
|
||||
VALUE hash;
|
||||
{
|
||||
VALUE dup = rb_obj_dup(hash);
|
||||
|
||||
if (FL_TEST(hash, HASH_PROC_DEFAULT)) {
|
||||
FL_SET(dup, HASH_PROC_DEFAULT);
|
||||
}
|
||||
if (FL_TEST(hash, HASH_DELETED)) {
|
||||
FL_SET(dup, HASH_DELETED);
|
||||
}
|
||||
return dup;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
to_hash(hash)
|
||||
VALUE hash;
|
||||
|
@ -281,6 +254,24 @@ to_hash(hash)
|
|||
return rb_convert_type(hash, T_HASH, "Hash", "to_hash");
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_hash_become(copy, orig)
|
||||
VALUE copy, orig;
|
||||
{
|
||||
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(orig, HASH_DELETED)) {
|
||||
FL_SET(copy, HASH_DELETED);
|
||||
}
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
static int
|
||||
rb_hash_rehash_i(key, value, tbl)
|
||||
VALUE key, value;
|
||||
|
@ -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);
|
||||
|
|
10
io.c
10
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);
|
||||
|
|
|
@ -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
|
||||
|
|
66
marshal.c
66
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'",
|
||||
|
|
|
@ -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);
|
||||
|
|
49
object.c
49
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");
|
||||
}
|
||||
|
|
4
range.c
4
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;
|
||||
|
|
47
re.c
47
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);
|
||||
|
|
52
string.c
52
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);
|
||||
VALUE dup = rb_str_s_alloc(rb_cString);
|
||||
rb_str_replace(dup, str);
|
||||
return dup;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_str_clone(str)
|
||||
VALUE str;
|
||||
{
|
||||
return str_copy(str, Qtrue);
|
||||
}
|
||||
|
||||
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);
|
||||
|
|
11
struct.c
11
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);
|
||||
|
||||
|
|
71
time.c
71
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)
|
||||
time_become(copy, time)
|
||||
VALUE copy, time;
|
||||
{
|
||||
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);
|
||||
GetTimeval(copy, tcopy);
|
||||
MEMCPY(tcopy, tobj, struct time_object, 1);
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
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);
|
||||
CLONESETUP(clone, time);
|
||||
MEMCPY(tclone, tobj, struct time_object, 1);
|
||||
|
||||
return clone;
|
||||
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);
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue