* 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:
matz 2002-08-27 08:31:08 +00:00
Родитель cd3d4a01f2
Коммит c45908e41f
18 изменённых файлов: 268 добавлений и 255 удалений

Просмотреть файл

@ -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
Просмотреть файл

@ -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);

Просмотреть файл

@ -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
Просмотреть файл

@ -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
Просмотреть файл

@ -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
Просмотреть файл

@ -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
Просмотреть файл

@ -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

Просмотреть файл

@ -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);

Просмотреть файл

@ -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");
}

Просмотреть файл

@ -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
Просмотреть файл

@ -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);

Просмотреть файл

@ -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);

Просмотреть файл

@ -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
Просмотреть файл

@ -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