mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* string.c (rb_str_sum): check was done with false pointer.
[ruby-dev:24383] * string.c (rb_str_sum): string may be altered. [ruby-dev:24381] * eval.c (rb_f_eval): defer pointer retrieval to prevent unsafe sourcefile string modification. [ruby-dev:24373] * io.c (io_read): block string buffer modification during rb_io_fread() by freezing it temporarily. [ruby-dev:24366] * io.c (rb_io_s_popen): mode argument may be altered. [ruby-dev:24375] * file.c (rb_file_s_basename): ext argument may be altered. [ruby-dev:24377] * enum.c (enum_sort_by): use NODE instead of 2 element arrays. [ruby-dev:24378] * string.c (rb_str_chomp_bang): StringValue() may change the receiver. [ruby-dev:24371] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_8@6979 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
d57bbd48f8
commit
6f9dcadf6e
16 changed files with 328 additions and 160 deletions
57
ChangeLog
57
ChangeLog
|
@ -1,3 +1,30 @@
|
|||
Sat Oct 2 00:42:20 2004 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* string.c (rb_str_sum): check was done with false pointer.
|
||||
[ruby-dev:24383]
|
||||
|
||||
* string.c (rb_str_sum): string may be altered. [ruby-dev:24381]
|
||||
|
||||
Fri Oct 1 11:40:14 2004 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* eval.c (rb_f_eval): defer pointer retrieval to prevent unsafe
|
||||
sourcefile string modification. [ruby-dev:24373]
|
||||
|
||||
* io.c (io_read): block string buffer modification during
|
||||
rb_io_fread() by freezing it temporarily. [ruby-dev:24366]
|
||||
|
||||
* io.c (rb_io_s_popen): mode argument may be altered.
|
||||
[ruby-dev:24375]
|
||||
|
||||
* file.c (rb_file_s_basename): ext argument may be altered.
|
||||
[ruby-dev:24377]
|
||||
|
||||
* enum.c (enum_sort_by): use NODE instead of 2 element arrays.
|
||||
[ruby-dev:24378]
|
||||
|
||||
* string.c (rb_str_chomp_bang): StringValue() may change the
|
||||
receiver. [ruby-dev:24371]
|
||||
|
||||
Fri Oct 1 11:25:20 2004 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
|
||||
|
||||
* ext/tk/lib/tk/grid.rb: revive TkGrid.grid
|
||||
|
@ -22,6 +49,36 @@ Wed Sep 29 10:58:07 2004 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
|||
* enum.c (sort_by_i): internally used object must not be changed
|
||||
outside. [ruby-dev:24368]
|
||||
|
||||
Mon Sep 27 09:14:03 2004 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* ext/socket/socket.c (s_accept): don't retry for EWOULDBLOCK.
|
||||
[ruby-talk:113807]
|
||||
|
||||
Fri Sep 24 16:09:42 2004 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* eval.c (proc_invoke): propagate DVAR_DONT_RECYCLE on termination
|
||||
to avoid double call to rb_gc_force_recycle(). [ruby-dev:24311]
|
||||
|
||||
Fri Sep 24 08:29:45 2004 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* array.c (rb_ary_subseq): original object might be modified after
|
||||
sharing data creation. [ruby-dev:24327]
|
||||
|
||||
* array.c (rb_ary_replace): ditto.
|
||||
|
||||
* array.c (ary_make_shared): freeze shared array. [ruby-dev:24325]
|
||||
|
||||
* struct.c (struct_members): always check struct size and size of
|
||||
members list in the class. [ruby-dev:24320]
|
||||
|
||||
Thu Sep 23 09:29:14 2004 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* string.c (rb_str_sub_bang): check if string is not modified
|
||||
during iteration. [ruby-dev:24315]
|
||||
|
||||
* hash.c (rb_hash_rehash): replace st_foreach() by its deep
|
||||
checking counterpart. [ruby-dev:24310]
|
||||
|
||||
Wed Sep 22 13:38:12 2004 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* hash.c (rb_hash_rehash): add iteration check. [ruby-dev:24301]
|
||||
|
|
57
array.c
57
array.c
|
@ -459,7 +459,7 @@ rb_ary_pop(ary)
|
|||
return RARRAY(ary)->ptr[--RARRAY(ary)->len];
|
||||
}
|
||||
|
||||
static void
|
||||
static VALUE
|
||||
ary_make_shared(ary)
|
||||
VALUE ary;
|
||||
{
|
||||
|
@ -472,6 +472,11 @@ ary_make_shared(ary)
|
|||
shared->aux.capa = RARRAY(ary)->aux.capa;
|
||||
RARRAY(ary)->aux.shared = (VALUE)shared;
|
||||
FL_SET(ary, ELTS_SHARED);
|
||||
OBJ_FREEZE(shared);
|
||||
return (VALUE)shared;
|
||||
}
|
||||
else {
|
||||
return RARRAY(ary)->aux.shared;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -591,7 +596,8 @@ rb_ary_subseq(ary, beg, len)
|
|||
VALUE ary;
|
||||
long beg, len;
|
||||
{
|
||||
VALUE klass, ary2;
|
||||
VALUE klass, ary2, shared;
|
||||
VALUE *ptr;
|
||||
|
||||
if (beg > RARRAY(ary)->len) return Qnil;
|
||||
if (beg < 0 || len < 0) return Qnil;
|
||||
|
@ -604,11 +610,12 @@ rb_ary_subseq(ary, beg, len)
|
|||
klass = rb_obj_class(ary);
|
||||
if (len == 0) return ary_new(klass, 0);
|
||||
|
||||
ary_make_shared(ary);
|
||||
shared = ary_make_shared(ary);
|
||||
ptr = RARRAY(ary)->ptr;
|
||||
ary2 = ary_alloc(klass);
|
||||
RARRAY(ary2)->ptr = RARRAY(ary)->ptr + beg;
|
||||
RARRAY(ary2)->ptr = ptr + beg;
|
||||
RARRAY(ary2)->len = len;
|
||||
RARRAY(ary2)->aux.shared = RARRAY(ary)->aux.shared;
|
||||
RARRAY(ary2)->aux.shared = shared;
|
||||
FL_SET(ary2, ELTS_SHARED);
|
||||
|
||||
return ary2;
|
||||
|
@ -1562,9 +1569,10 @@ sort_1(a, b, data)
|
|||
struct ary_sort_data *data;
|
||||
{
|
||||
VALUE retval = rb_yield_values(2, *a, *b);
|
||||
int n;
|
||||
|
||||
ary_sort_check(data);
|
||||
return rb_cmpint(retval, *a, *b);
|
||||
n = rb_cmpint(retval, *a, *b);
|
||||
return n;
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -1573,11 +1581,12 @@ sort_2(ap, bp, data)
|
|||
struct ary_sort_data *data;
|
||||
{
|
||||
VALUE retval;
|
||||
long a = (long)*ap, b = (long)*bp;
|
||||
VALUE a = *ap, b = *bp;
|
||||
int n;
|
||||
|
||||
if (FIXNUM_P(a) && FIXNUM_P(b)) {
|
||||
if (a > b) return 1;
|
||||
if (a < b) return -1;
|
||||
if ((long)a > (long)b) return 1;
|
||||
if ((long)a < (long)b) return -1;
|
||||
return 0;
|
||||
}
|
||||
if (TYPE(a) == T_STRING && TYPE(b) == T_STRING) {
|
||||
|
@ -1585,8 +1594,9 @@ sort_2(ap, bp, data)
|
|||
}
|
||||
|
||||
retval = rb_funcall(a, id_cmp, 1, b);
|
||||
ary_sort_check(data);
|
||||
return rb_cmpint(retval, a, b);
|
||||
n = rb_cmpint(retval, a, b);
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
|
@ -2150,15 +2160,17 @@ static VALUE
|
|||
rb_ary_replace(copy, orig)
|
||||
VALUE copy, orig;
|
||||
{
|
||||
VALUE shared;
|
||||
|
||||
rb_ary_modify(copy);
|
||||
orig = to_ary(orig);
|
||||
if (copy == orig) return copy;
|
||||
ary_make_shared(orig);
|
||||
shared = ary_make_shared(orig);
|
||||
if (RARRAY(copy)->ptr && !FL_TEST(copy, ELTS_SHARED))
|
||||
free(RARRAY(copy)->ptr);
|
||||
RARRAY(copy)->ptr = RARRAY(orig)->ptr;
|
||||
RARRAY(copy)->len = RARRAY(orig)->len;
|
||||
RARRAY(copy)->aux.shared = RARRAY(orig)->aux.shared;
|
||||
RARRAY(copy)->ptr = RARRAY(shared)->ptr;
|
||||
RARRAY(copy)->len = RARRAY(shared)->len;
|
||||
RARRAY(copy)->aux.shared = shared;
|
||||
FL_SET(copy, ELTS_SHARED);
|
||||
|
||||
return copy;
|
||||
|
@ -2874,8 +2886,11 @@ flatten(ary, idx, ary2, memo)
|
|||
rb_ary_push(memo, id);
|
||||
rb_ary_update(ary, idx, 1, ary2);
|
||||
while (i < lim) {
|
||||
if (TYPE(RARRAY(ary)->ptr[i]) == T_ARRAY) {
|
||||
n = flatten(ary, i, RARRAY(ary)->ptr[i], memo);
|
||||
VALUE tmp;
|
||||
|
||||
tmp = rb_check_array_type(RARRAY(ary)->ptr[i]);
|
||||
if (!NIL_P(tmp)) {
|
||||
n = flatten(ary, i, tmp, memo);
|
||||
i += n; lim += n;
|
||||
}
|
||||
i++;
|
||||
|
@ -2910,12 +2925,14 @@ rb_ary_flatten_bang(ary)
|
|||
rb_ary_modify(ary);
|
||||
while (i<RARRAY(ary)->len) {
|
||||
VALUE ary2 = RARRAY(ary)->ptr[i];
|
||||
VALUE tmp;
|
||||
|
||||
if (TYPE(ary2) == T_ARRAY) {
|
||||
tmp = rb_check_array_type(ary2);
|
||||
if (!NIL_P(tmp)) {
|
||||
if (NIL_P(memo)) {
|
||||
memo = rb_ary_new();
|
||||
}
|
||||
i += flatten(ary, i, ary2, memo);
|
||||
i += flatten(ary, i, tmp, memo);
|
||||
mod = 1;
|
||||
}
|
||||
i++;
|
||||
|
|
25
enum.c
25
enum.c
|
@ -389,26 +389,26 @@ static VALUE
|
|||
sort_by_i(i, ary)
|
||||
VALUE i, ary;
|
||||
{
|
||||
VALUE v, e;
|
||||
VALUE v;
|
||||
NODE *memo;
|
||||
|
||||
v = rb_yield(i);
|
||||
e = rb_assoc_new(v, i);
|
||||
OBJ_FREEZE(e);
|
||||
rb_ary_push(ary, e);
|
||||
memo = rb_node_newnode(NODE_MEMO, v, i, 0);
|
||||
rb_ary_push(ary, (VALUE)memo);
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
sort_by_cmp(values, ary)
|
||||
VALUE values;
|
||||
VALUE values, ary;
|
||||
{
|
||||
VALUE a = RARRAY(values)->ptr[0];
|
||||
VALUE b = RARRAY(values)->ptr[1];
|
||||
NODE *a = (NODE*)RARRAY(values)->ptr[0];
|
||||
NODE *b = (NODE*)RARRAY(values)->ptr[1];
|
||||
|
||||
/* pedantic check; they must be arrays */
|
||||
Check_Type(a, T_ARRAY);
|
||||
Check_Type(b, T_ARRAY);
|
||||
return rb_funcall(RARRAY(a)->ptr[0], id_cmp, 1, RARRAY(b)->ptr[0]);
|
||||
/* pedantic check; they must be memo nodes */
|
||||
Check_Type(a, T_NODE);
|
||||
Check_Type(b, T_NODE);
|
||||
return rb_funcall(a->u1.value, id_cmp, 1, b->u1.value);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -498,8 +498,7 @@ enum_sort_by(obj)
|
|||
rb_iterate(rb_ary_sort_bang, ary, sort_by_cmp, ary);
|
||||
}
|
||||
for (i=0; i<RARRAY(ary)->len; i++) {
|
||||
VALUE e = RARRAY(ary)->ptr[i];
|
||||
RARRAY(ary)->ptr[i] = RARRAY(e)->ptr[1];
|
||||
RARRAY(ary)->ptr[i] = RNODE(RARRAY(ary)->ptr[i])->u2.value;
|
||||
}
|
||||
return ary;
|
||||
}
|
||||
|
|
15
eval.c
15
eval.c
|
@ -6187,12 +6187,13 @@ rb_f_eval(argc, argv, self)
|
|||
SafeStringValue(src);
|
||||
}
|
||||
if (argc >= 3) {
|
||||
file = StringValuePtr(vfile);
|
||||
StringValue(vfile);
|
||||
}
|
||||
if (argc >= 4) {
|
||||
line = NUM2INT(vline);
|
||||
}
|
||||
|
||||
if (!NIL_P(vfile)) file = RSTRING(vfile)->ptr;
|
||||
if (NIL_P(scope) && ruby_frame->prev) {
|
||||
struct FRAME *prev;
|
||||
VALUE val;
|
||||
|
@ -8096,6 +8097,14 @@ proc_invoke(proc, args, self, klass)
|
|||
POP_ITER();
|
||||
ruby_block = old_block;
|
||||
ruby_wrapper = old_wrapper;
|
||||
if (FL_TEST(ruby_dyna_vars, DVAR_DONT_RECYCLE)) {
|
||||
struct RVarmap *vars;
|
||||
|
||||
for (vars = old_dvars; vars; vars = vars->next) {
|
||||
if (FL_TEST(vars, DVAR_DONT_RECYCLE)) break;
|
||||
FL_SET(vars, DVAR_DONT_RECYCLE);
|
||||
}
|
||||
}
|
||||
ruby_dyna_vars = old_dvars;
|
||||
ruby_safe_level = safe;
|
||||
|
||||
|
@ -12076,6 +12085,7 @@ rb_callcc(self)
|
|||
volatile rb_thread_t th_save;
|
||||
struct tag *tag;
|
||||
struct RVarmap *vars;
|
||||
struct BLOCK *blk;
|
||||
|
||||
THREAD_ALLOC(th);
|
||||
cont = Data_Wrap_Struct(rb_cCont, thread_mark, thread_free, th);
|
||||
|
@ -12086,11 +12096,10 @@ rb_callcc(self)
|
|||
}
|
||||
th->thread = curr_thread->thread;
|
||||
|
||||
for (vars = th->dyna_vars; vars; vars = vars->next) {
|
||||
for (vars = ruby_dyna_vars; vars; vars = vars->next) {
|
||||
if (FL_TEST(vars, DVAR_DONT_RECYCLE)) break;
|
||||
FL_SET(vars, DVAR_DONT_RECYCLE);
|
||||
}
|
||||
|
||||
th_save = th;
|
||||
if (THREAD_SAVE_CONTEXT(th)) {
|
||||
return th_save->result;
|
||||
|
|
|
@ -1168,6 +1168,8 @@ s_accept(klass, fd, sockaddr, len)
|
|||
rb_gc();
|
||||
retry = 1;
|
||||
goto retry;
|
||||
case EWOULDBLOCK:
|
||||
break;
|
||||
default:
|
||||
if (!rb_io_wait_readable(fd)) break;
|
||||
retry = 0;
|
||||
|
|
11
file.c
11
file.c
|
@ -1644,8 +1644,7 @@ rb_file_s_lchmod(argc, argv)
|
|||
{
|
||||
VALUE vmode;
|
||||
VALUE rest;
|
||||
int mode;
|
||||
long n;
|
||||
long mode, n;
|
||||
|
||||
rb_secure(2);
|
||||
rb_scan_args(argc, argv, "1*", &vmode, &rest);
|
||||
|
@ -2560,11 +2559,11 @@ rb_file_s_basename(argc, argv)
|
|||
VALUE *argv;
|
||||
{
|
||||
VALUE fname, fext, basename;
|
||||
char *name, *p, *ext = NULL;
|
||||
char *name, *p;
|
||||
int f;
|
||||
|
||||
if (rb_scan_args(argc, argv, "11", &fname, &fext) == 2) {
|
||||
ext = StringValueCStr(fext);
|
||||
StringValue(fext);
|
||||
}
|
||||
StringValue(fname);
|
||||
if (RSTRING(fname)->len == 0 || !*(name = RSTRING(fname)->ptr))
|
||||
|
@ -2580,7 +2579,7 @@ rb_file_s_basename(argc, argv)
|
|||
#endif
|
||||
}
|
||||
else if (!(p = strrdirsep(name))) {
|
||||
if (NIL_P(fext) || !(f = rmext(name, ext))) {
|
||||
if (NIL_P(fext) || !(f = rmext(name, StringValueCStr(fext)))) {
|
||||
f = chompdirsep(name) - name;
|
||||
if (f == RSTRING(fname)->len) return fname;
|
||||
}
|
||||
|
@ -2588,7 +2587,7 @@ rb_file_s_basename(argc, argv)
|
|||
}
|
||||
else {
|
||||
while (isdirsep(*p)) p++; /* skip last / */
|
||||
if (NIL_P(fext) || !(f = rmext(p, ext))) {
|
||||
if (NIL_P(fext) || !(f = rmext(p, StringValueCStr(fext)))) {
|
||||
f = chompdirsep(p) - p;
|
||||
}
|
||||
}
|
||||
|
|
116
hash.c
116
hash.c
|
@ -114,16 +114,54 @@ static struct st_hash_type objhash = {
|
|||
rb_any_hash,
|
||||
};
|
||||
|
||||
struct rb_hash_foreach_arg {
|
||||
struct foreach_safe_arg {
|
||||
st_table *tbl;
|
||||
int (*func)();
|
||||
st_data_t arg;
|
||||
};
|
||||
|
||||
static int
|
||||
foreach_safe_i(key, value, arg, err)
|
||||
st_data_t key, value;
|
||||
struct foreach_safe_arg *arg;
|
||||
{
|
||||
int status;
|
||||
|
||||
if (err) {
|
||||
rb_raise(rb_eRuntimeError, "hash modified during iteration");
|
||||
}
|
||||
if (key == Qundef) return ST_CONTINUE;
|
||||
status = (*arg->func)(key, value, arg->arg, err);
|
||||
if (status == ST_CONTINUE) {
|
||||
return ST_CHECK;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
void
|
||||
st_foreach_safe(table, func, a)
|
||||
st_table *table;
|
||||
int (*func)();
|
||||
st_data_t a;
|
||||
{
|
||||
struct foreach_safe_arg arg;
|
||||
|
||||
arg.tbl = table;
|
||||
arg.func = func;
|
||||
arg.arg = a;
|
||||
st_foreach(table, foreach_safe_i, (st_data_t)&arg);
|
||||
}
|
||||
|
||||
struct hash_foreach_arg {
|
||||
VALUE hash;
|
||||
enum st_retval (*func)();
|
||||
int (*func)();
|
||||
VALUE arg;
|
||||
};
|
||||
|
||||
static int
|
||||
rb_hash_foreach_iter(key, value, arg, err)
|
||||
hash_foreach_iter(key, value, arg, err)
|
||||
VALUE key, value;
|
||||
struct rb_hash_foreach_arg *arg;
|
||||
struct hash_foreach_arg *arg;
|
||||
int err;
|
||||
{
|
||||
int status;
|
||||
|
@ -151,15 +189,7 @@ rb_hash_foreach_iter(key, value, arg, err)
|
|||
}
|
||||
|
||||
static VALUE
|
||||
rb_hash_foreach_call(arg)
|
||||
struct rb_hash_foreach_arg *arg;
|
||||
{
|
||||
st_foreach(RHASH(arg->hash)->tbl, rb_hash_foreach_iter, (st_data_t)arg);
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_hash_foreach_ensure(hash)
|
||||
hash_foreach_ensure(hash)
|
||||
VALUE hash;
|
||||
{
|
||||
RHASH(hash)->iter_lev--;
|
||||
|
@ -173,19 +203,27 @@ rb_hash_foreach_ensure(hash)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
static VALUE
|
||||
hash_foreach_call(arg)
|
||||
struct hash_foreach_arg *arg;
|
||||
{
|
||||
st_foreach(RHASH(arg->hash)->tbl, hash_foreach_iter, (st_data_t)arg);
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
void
|
||||
rb_hash_foreach(hash, func, farg)
|
||||
VALUE hash;
|
||||
enum st_retval (*func)();
|
||||
int (*func)();
|
||||
VALUE farg;
|
||||
{
|
||||
struct rb_hash_foreach_arg arg;
|
||||
struct hash_foreach_arg arg;
|
||||
|
||||
RHASH(hash)->iter_lev++;
|
||||
arg.hash = hash;
|
||||
arg.func = func;
|
||||
arg.arg = farg;
|
||||
return rb_ensure(rb_hash_foreach_call, (VALUE)&arg, rb_hash_foreach_ensure, hash);
|
||||
rb_ensure(hash_foreach_call, (VALUE)&arg, hash_foreach_ensure, hash);
|
||||
}
|
||||
|
||||
static VALUE hash_alloc _((VALUE));
|
||||
|
@ -354,7 +392,7 @@ rb_hash_rehash(hash)
|
|||
|
||||
rb_hash_modify(hash);
|
||||
tbl = st_init_table_with_size(&objhash, RHASH(hash)->tbl->num_entries);
|
||||
st_foreach(RHASH(hash)->tbl, rb_hash_rehash_i, (st_data_t)tbl);
|
||||
rb_hash_foreach(hash, rb_hash_rehash_i, (st_data_t)tbl);
|
||||
st_free_table(RHASH(hash)->tbl);
|
||||
RHASH(hash)->tbl = tbl;
|
||||
|
||||
|
@ -566,7 +604,7 @@ rb_hash_index(hash, value)
|
|||
args[0] = value;
|
||||
args[1] = Qnil;
|
||||
|
||||
st_foreach(RHASH(hash)->tbl, index_i, (st_data_t)args);
|
||||
rb_hash_foreach(hash, index_i, (st_data_t)args);
|
||||
|
||||
return args[1];
|
||||
}
|
||||
|
@ -678,7 +716,7 @@ rb_hash_shift(hash)
|
|||
|
||||
rb_hash_modify(hash);
|
||||
var.stop = 0;
|
||||
st_foreach(RHASH(hash)->tbl, shift_i, (st_data_t)&var);
|
||||
rb_hash_foreach(hash, shift_i, (st_data_t)&var);
|
||||
|
||||
if (var.stop) {
|
||||
return rb_assoc_new(var.key, var.val);
|
||||
|
@ -691,7 +729,7 @@ rb_hash_shift(hash)
|
|||
}
|
||||
}
|
||||
|
||||
static enum st_retval
|
||||
static int
|
||||
delete_if_i(key, value, hash)
|
||||
VALUE key, value, hash;
|
||||
{
|
||||
|
@ -758,7 +796,7 @@ rb_hash_reject(hash)
|
|||
return rb_hash_delete_if(rb_obj_dup(hash));
|
||||
}
|
||||
|
||||
static enum st_retval
|
||||
static int
|
||||
select_i(key, value, result)
|
||||
VALUE key, value, result;
|
||||
{
|
||||
|
@ -849,7 +887,7 @@ rb_hash_clear(hash)
|
|||
|
||||
rb_hash_modify(hash);
|
||||
if (RHASH(hash)->tbl->num_entries > 0) {
|
||||
st_foreach(RHASH(hash)->tbl, clear_i, 0);
|
||||
rb_hash_foreach(hash, clear_i, 0);
|
||||
}
|
||||
|
||||
return hash;
|
||||
|
@ -917,7 +955,7 @@ rb_hash_replace(hash, hash2)
|
|||
hash2 = to_hash(hash2);
|
||||
if (hash == hash2) return hash;
|
||||
rb_hash_clear(hash);
|
||||
st_foreach(RHASH(hash2)->tbl, replace_i, hash);
|
||||
rb_hash_foreach(hash2, replace_i, hash);
|
||||
RHASH(hash)->ifnone = RHASH(hash2)->ifnone;
|
||||
if (FL_TEST(hash2, HASH_PROC_DEFAULT)) {
|
||||
FL_SET(hash, HASH_PROC_DEFAULT);
|
||||
|
@ -969,7 +1007,7 @@ rb_hash_empty_p(hash)
|
|||
return Qfalse;
|
||||
}
|
||||
|
||||
static enum st_retval
|
||||
static int
|
||||
each_value_i(key, value)
|
||||
VALUE key, value;
|
||||
{
|
||||
|
@ -1002,7 +1040,7 @@ rb_hash_each_value(hash)
|
|||
return hash;
|
||||
}
|
||||
|
||||
static enum st_retval
|
||||
static int
|
||||
each_key_i(key, value)
|
||||
VALUE key, value;
|
||||
{
|
||||
|
@ -1034,7 +1072,7 @@ rb_hash_each_key(hash)
|
|||
return hash;
|
||||
}
|
||||
|
||||
static enum st_retval
|
||||
static int
|
||||
each_pair_i(key, value)
|
||||
VALUE key, value;
|
||||
{
|
||||
|
@ -1068,7 +1106,7 @@ rb_hash_each_pair(hash)
|
|||
return hash;
|
||||
}
|
||||
|
||||
static enum st_retval
|
||||
static int
|
||||
each_i(key, value)
|
||||
VALUE key, value;
|
||||
{
|
||||
|
@ -1132,7 +1170,7 @@ rb_hash_to_a(hash)
|
|||
VALUE ary;
|
||||
|
||||
ary = rb_ary_new();
|
||||
st_foreach(RHASH(hash)->tbl, to_a_i, ary);
|
||||
rb_hash_foreach(hash, to_a_i, ary);
|
||||
if (OBJ_TAINTED(hash)) OBJ_TAINT(ary);
|
||||
|
||||
return ary;
|
||||
|
@ -1190,7 +1228,7 @@ inspect_hash(hash)
|
|||
VALUE str;
|
||||
|
||||
str = rb_str_buf_new2("{");
|
||||
st_foreach(RHASH(hash)->tbl, inspect_i, str);
|
||||
rb_hash_foreach(hash, inspect_i, str);
|
||||
rb_str_buf_cat2(str, "}");
|
||||
OBJ_INFECT(str, hash);
|
||||
|
||||
|
@ -1284,7 +1322,7 @@ rb_hash_keys(hash)
|
|||
VALUE ary;
|
||||
|
||||
ary = rb_ary_new();
|
||||
st_foreach(RHASH(hash)->tbl, keys_i, ary);
|
||||
rb_hash_foreach(hash, keys_i, ary);
|
||||
|
||||
return ary;
|
||||
}
|
||||
|
@ -1317,7 +1355,7 @@ rb_hash_values(hash)
|
|||
VALUE ary;
|
||||
|
||||
ary = rb_ary_new();
|
||||
st_foreach(RHASH(hash)->tbl, values_i, ary);
|
||||
rb_hash_foreach(hash, values_i, ary);
|
||||
|
||||
return ary;
|
||||
}
|
||||
|
@ -1382,7 +1420,7 @@ rb_hash_has_value(hash, val)
|
|||
|
||||
data[0] = Qfalse;
|
||||
data[1] = val;
|
||||
st_foreach(RHASH(hash)->tbl, rb_hash_search_value, (st_data_t)data);
|
||||
rb_hash_foreach(hash, rb_hash_search_value, (st_data_t)data);
|
||||
return data[0];
|
||||
}
|
||||
|
||||
|
@ -1434,7 +1472,7 @@ hash_equal(hash1, hash2, eql)
|
|||
|
||||
data.tbl = RHASH(hash2)->tbl;
|
||||
data.result = Qtrue;
|
||||
st_foreach(RHASH(hash1)->tbl, equal_i, (st_data_t)&data);
|
||||
rb_hash_foreach(hash1, equal_i, (st_data_t)&data);
|
||||
|
||||
return data.result;
|
||||
}
|
||||
|
@ -1509,7 +1547,7 @@ rb_hash_invert(hash)
|
|||
{
|
||||
VALUE h = rb_hash_new();
|
||||
|
||||
st_foreach(RHASH(hash)->tbl, rb_hash_invert_i, h);
|
||||
rb_hash_foreach(hash, rb_hash_invert_i, h);
|
||||
return h;
|
||||
}
|
||||
|
||||
|
@ -1555,10 +1593,10 @@ rb_hash_update(hash1, hash2)
|
|||
{
|
||||
hash2 = to_hash(hash2);
|
||||
if (rb_block_given_p()) {
|
||||
st_foreach(RHASH(hash2)->tbl, rb_hash_update_block_i, hash1);
|
||||
rb_hash_foreach(hash2, rb_hash_update_block_i, hash1);
|
||||
}
|
||||
else {
|
||||
st_foreach(RHASH(hash2)->tbl, rb_hash_update_i, hash1);
|
||||
rb_hash_foreach(hash2, rb_hash_update_i, hash1);
|
||||
}
|
||||
return hash1;
|
||||
}
|
||||
|
@ -2345,7 +2383,7 @@ env_replace(env, hash)
|
|||
|
||||
if (env == hash) return env;
|
||||
hash = to_hash(hash);
|
||||
st_foreach(RHASH(hash)->tbl, env_replace_i, keys);
|
||||
rb_hash_foreach(hash, env_replace_i, keys);
|
||||
|
||||
for (i=0; i<RARRAY(keys)->len; i++) {
|
||||
env_delete(env, RARRAY(keys)->ptr[i]);
|
||||
|
@ -2372,7 +2410,7 @@ env_update(env, hash)
|
|||
{
|
||||
if (env == hash) return env;
|
||||
hash = to_hash(hash);
|
||||
st_foreach(RHASH(hash)->tbl, env_update_i, 0);
|
||||
rb_hash_foreach(hash, env_update_i, 0);
|
||||
return env;
|
||||
}
|
||||
|
||||
|
|
2
intern.h
2
intern.h
|
@ -245,6 +245,8 @@ VALUE rb_gc_enable _((void));
|
|||
VALUE rb_gc_disable _((void));
|
||||
VALUE rb_gc_start _((void));
|
||||
/* hash.c */
|
||||
void st_foreach _((struct st_table *, int (*)(), unsigned long));
|
||||
void rb_hash_foreach _((VALUE, int (*)(), VALUE));
|
||||
VALUE rb_hash _((VALUE));
|
||||
VALUE rb_hash_new _((void));
|
||||
VALUE rb_hash_freeze _((VALUE));
|
||||
|
|
6
io.c
6
io.c
|
@ -1067,11 +1067,13 @@ io_read(argc, argv, io)
|
|||
StringValue(str);
|
||||
rb_str_modify(str);
|
||||
rb_str_resize(str,len);
|
||||
FL_SET(str, FL_FREEZE);
|
||||
}
|
||||
if (len == 0) return str;
|
||||
|
||||
READ_CHECK(fptr->f);
|
||||
n = rb_io_fread(RSTRING(str)->ptr, len, fptr->f);
|
||||
FL_UNSET(str, FL_FREEZE);
|
||||
if (n == 0) {
|
||||
rb_str_resize(str,0);
|
||||
if (!fptr->f) return Qnil;
|
||||
|
@ -2721,7 +2723,9 @@ rb_io_popen(str, argc, argv, klass)
|
|||
mode = rb_io_modenum_mode(FIX2INT(pmode), mbuf);
|
||||
}
|
||||
else {
|
||||
mode = StringValuePtr(pmode);
|
||||
strncpy(mbuf, StringValuePtr(pmode), sizeof(mbuf) - 1);
|
||||
mbuf[sizeof(mbuf) - 1] = 0;
|
||||
mode = mbuf;
|
||||
}
|
||||
SafeStringValue(pname);
|
||||
port = pipe_open(str, mode);
|
||||
|
|
|
@ -437,7 +437,7 @@ w_ivar(tbl, arg)
|
|||
{
|
||||
if (tbl) {
|
||||
w_long(tbl->num_entries, arg->arg);
|
||||
st_foreach(tbl, w_obj_each, (st_data_t)arg);
|
||||
st_foreach_safe(tbl, w_obj_each, (st_data_t)arg);
|
||||
}
|
||||
else {
|
||||
w_long(0, arg->arg);
|
||||
|
@ -621,7 +621,7 @@ w_object(obj, arg, limit)
|
|||
w_byte(TYPE_HASH_DEF, arg);
|
||||
}
|
||||
w_long(RHASH(obj)->tbl->num_entries, arg);
|
||||
st_foreach(RHASH(obj)->tbl, hash_each, (st_data_t)&c_arg);
|
||||
rb_hash_foreach(obj, hash_each, (st_data_t)&c_arg);
|
||||
if (!NIL_P(RHASH(obj)->ifnone)) {
|
||||
w_object(RHASH(obj)->ifnone, arg, limit);
|
||||
}
|
||||
|
|
2
object.c
2
object.c
|
@ -404,7 +404,7 @@ static VALUE
|
|||
inspect_obj(obj, str)
|
||||
VALUE obj, str;
|
||||
{
|
||||
st_foreach(ROBJECT(obj)->iv_tbl, inspect_i, str);
|
||||
st_foreach_safe(ROBJECT(obj)->iv_tbl, inspect_i, str);
|
||||
rb_str_cat2(str, ">");
|
||||
RSTRING(str)->ptr[0] = '#';
|
||||
OBJ_INFECT(str, obj);
|
||||
|
|
|
@ -1214,8 +1214,8 @@ rb_f_exec(argc, argv)
|
|||
rb_raise(rb_eArgError, "wrong first argument");
|
||||
}
|
||||
prog = RARRAY(tmp)->ptr[0];
|
||||
SafeStringValue(prog);
|
||||
argv[0] = RARRAY(tmp)->ptr[1];
|
||||
SafeStringValue(prog);
|
||||
}
|
||||
if (argc == 1 && prog == 0) {
|
||||
VALUE cmd = argv[0];
|
||||
|
|
4
re.c
4
re.c
|
@ -1681,8 +1681,6 @@ rb_reg_initialize_m(argc, argv, self)
|
|||
len = RREGEXP(argv[0])->len;
|
||||
}
|
||||
else {
|
||||
s = StringValuePtr(argv[0]);
|
||||
len = RSTRING(argv[0])->len;
|
||||
if (argc >= 2) {
|
||||
if (FIXNUM_P(argv[1])) flags = FIX2INT(argv[1]);
|
||||
else if (RTEST(argv[1])) flags = RE_OPTION_IGNORECASE;
|
||||
|
@ -1708,6 +1706,8 @@ rb_reg_initialize_m(argc, argv, self)
|
|||
break;
|
||||
}
|
||||
}
|
||||
s = StringValuePtr(argv[0]);
|
||||
len = RSTRING(argv[0])->len;
|
||||
}
|
||||
rb_reg_initialize(self, s, len, flags);
|
||||
return self;
|
||||
|
|
48
string.c
48
string.c
|
@ -1913,8 +1913,13 @@ rb_str_sub_bang(argc, argv, str)
|
|||
regs = RMATCH(match)->regs;
|
||||
|
||||
if (iter) {
|
||||
char *p = RSTRING(str)->ptr; long len = RSTRING(str)->len;
|
||||
|
||||
rb_match_busy(match);
|
||||
repl = rb_obj_as_string(rb_yield(rb_reg_nth_match(0, match)));
|
||||
if (RSTRING(str)->ptr != p || RSTRING(str)->len != len) {
|
||||
rb_raise(rb_eRuntimeError, "string modified");
|
||||
}
|
||||
rb_backref_set(match);
|
||||
}
|
||||
else {
|
||||
|
@ -3095,7 +3100,7 @@ tr_setup_table(str, table, init)
|
|||
buf[c & 0xff] = !cflag;
|
||||
}
|
||||
for (i=0; i<256; i++) {
|
||||
table[i] = table[i]&&buf[i];
|
||||
table[i] = table[i] && buf[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3554,6 +3559,17 @@ rb_f_split(argc, argv)
|
|||
}
|
||||
|
||||
|
||||
static inline void
|
||||
str_mod_check(s, p, len)
|
||||
VALUE s;
|
||||
char *p;
|
||||
long len;
|
||||
{
|
||||
if (RSTRING(s)->ptr != p || RSTRING(s)->len != len) {
|
||||
rb_raise(rb_eRuntimeError, "string modified");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* str.each(separator=$/) {|substr| block } => str
|
||||
|
@ -3628,8 +3644,7 @@ rb_str_each_line(argc, argv, str)
|
|||
line = rb_str_new5(str, s, p - s);
|
||||
OBJ_INFECT(line, str);
|
||||
rb_yield(line);
|
||||
if (RSTRING(str)->ptr != ptr || RSTRING(str)->len != len)
|
||||
rb_raise(rb_eArgError, "string modified");
|
||||
str_mod_check(str, ptr, len);
|
||||
s = p;
|
||||
}
|
||||
}
|
||||
|
@ -3799,11 +3814,13 @@ rb_str_chomp_bang(argc, argv, str)
|
|||
{
|
||||
VALUE rs;
|
||||
int newline;
|
||||
char *p = RSTRING(str)->ptr;
|
||||
long len = RSTRING(str)->len, rslen;
|
||||
char *p;
|
||||
long len, rslen;
|
||||
|
||||
if (rb_scan_args(argc, argv, "01", &rs) == 0) {
|
||||
len = RSTRING(str)->len;
|
||||
if (len == 0) return Qnil;
|
||||
p = RSTRING(str)->ptr;
|
||||
rs = rb_rs;
|
||||
if (rs == rb_default_rs) {
|
||||
smart_chomp:
|
||||
|
@ -3827,9 +3844,10 @@ rb_str_chomp_bang(argc, argv, str)
|
|||
}
|
||||
}
|
||||
if (NIL_P(rs)) return Qnil;
|
||||
if (len == 0) return Qnil;
|
||||
|
||||
StringValue(rs);
|
||||
len = RSTRING(str)->len;
|
||||
if (len == 0) return Qnil;
|
||||
p = RSTRING(str)->ptr;
|
||||
rslen = RSTRING(rs)->len;
|
||||
if (rslen == 0) {
|
||||
while (len>0 && p[len-1] == '\n') {
|
||||
|
@ -4277,7 +4295,7 @@ rb_str_crypt(str, salt)
|
|||
{
|
||||
extern char *crypt();
|
||||
VALUE result;
|
||||
char *s;
|
||||
char *s, *cr;
|
||||
|
||||
StringValue(salt);
|
||||
if (RSTRING(salt)->len < 2)
|
||||
|
@ -4285,7 +4303,10 @@ rb_str_crypt(str, salt)
|
|||
|
||||
if (RSTRING(str)->ptr) s = RSTRING(str)->ptr;
|
||||
else s = "";
|
||||
result = rb_str_new2(crypt(s, RSTRING(salt)->ptr));
|
||||
cr = crypt(s, RSTRING(salt)->ptr);
|
||||
s = ALLOCA_N(char, strlen(cr));
|
||||
strcpy(s, cr);
|
||||
result = rb_str_new2(s);
|
||||
OBJ_INFECT(result, str);
|
||||
OBJ_INFECT(result, salt);
|
||||
return result;
|
||||
|
@ -4348,14 +4369,17 @@ rb_str_sum(argc, argv, str)
|
|||
{
|
||||
VALUE vbits;
|
||||
int bits;
|
||||
char *p, *pend;
|
||||
char *ptr, *p, *pend;
|
||||
long len;
|
||||
|
||||
if (rb_scan_args(argc, argv, "01", &vbits) == 0) {
|
||||
bits = 16;
|
||||
}
|
||||
else bits = NUM2INT(vbits);
|
||||
|
||||
p = RSTRING(str)->ptr; pend = p + RSTRING(str)->len;
|
||||
ptr = p = RSTRING(str)->ptr;
|
||||
len = RSTRING(str)->len;
|
||||
pend = p + len;
|
||||
if (bits > sizeof(long)*CHAR_BIT) {
|
||||
VALUE res = INT2FIX(0);
|
||||
VALUE mod;
|
||||
|
@ -4364,6 +4388,7 @@ rb_str_sum(argc, argv, str)
|
|||
mod = rb_funcall(mod, '-', 1, INT2FIX(1));
|
||||
|
||||
while (p < pend) {
|
||||
str_mod_check(str, ptr, len);
|
||||
res = rb_funcall(res, '+', 1, INT2FIX((unsigned int)*p));
|
||||
p++;
|
||||
}
|
||||
|
@ -4378,6 +4403,7 @@ rb_str_sum(argc, argv, str)
|
|||
mod = -1;
|
||||
}
|
||||
while (p < pend) {
|
||||
str_mod_check(str, ptr, len);
|
||||
res += (unsigned int)*p;
|
||||
p++;
|
||||
}
|
||||
|
|
123
struct.c
123
struct.c
|
@ -34,18 +34,43 @@ rb_struct_iv_get(c, name)
|
|||
}
|
||||
|
||||
static VALUE
|
||||
rb_struct_s_members(obj)
|
||||
VALUE obj;
|
||||
struct_s_members(klass)
|
||||
VALUE klass;
|
||||
{
|
||||
VALUE member, ary;
|
||||
VALUE members = rb_struct_iv_get(klass, "__members__");
|
||||
|
||||
if (NIL_P(members)) {
|
||||
rb_bug("non-initialized struct");
|
||||
}
|
||||
return members;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
struct_members(s)
|
||||
VALUE s;
|
||||
{
|
||||
VALUE members = struct_s_members(rb_obj_class(s));
|
||||
|
||||
if (NIL_P(members)) {
|
||||
rb_bug("non-initialized struct");
|
||||
}
|
||||
if (RSTRUCT(s)->len != RARRAY(members)->len) {
|
||||
rb_raise(rb_eTypeError, "struct size differs (%d required %d given)",
|
||||
RARRAY(members)->len, RSTRUCT(s)->len);
|
||||
}
|
||||
return members;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_struct_s_members(klass)
|
||||
VALUE klass;
|
||||
{
|
||||
VALUE members, ary;
|
||||
VALUE *p, *pend;
|
||||
|
||||
member = rb_struct_iv_get(obj, "__member__");
|
||||
if (NIL_P(member)) {
|
||||
rb_bug("uninitialized struct");
|
||||
}
|
||||
ary = rb_ary_new2(RARRAY(member)->len);
|
||||
p = RARRAY(member)->ptr; pend = p + RARRAY(member)->len;
|
||||
members = struct_s_members(klass);
|
||||
ary = rb_ary_new2(RARRAY(members)->len);
|
||||
p = RARRAY(members)->ptr; pend = p + RARRAY(members)->len;
|
||||
while (p < pend) {
|
||||
rb_ary_push(ary, rb_str_new2(rb_id2name(SYM2ID(*p))));
|
||||
p++;
|
||||
|
@ -78,16 +103,16 @@ rb_struct_getmember(obj, id)
|
|||
VALUE obj;
|
||||
ID id;
|
||||
{
|
||||
VALUE member, slot;
|
||||
VALUE members, slot;
|
||||
long i;
|
||||
|
||||
member = rb_struct_iv_get(rb_obj_class(obj), "__member__");
|
||||
if (NIL_P(member)) {
|
||||
members = rb_struct_iv_get(rb_obj_class(obj), "__members__");
|
||||
if (NIL_P(members)) {
|
||||
rb_bug("uninitialized struct");
|
||||
}
|
||||
slot = ID2SYM(id);
|
||||
for (i=0; i<RARRAY(member)->len; i++) {
|
||||
if (RARRAY(member)->ptr[i] == slot) {
|
||||
for (i=0; i<RARRAY(members)->len; i++) {
|
||||
if (RARRAY(members)->ptr[i] == slot) {
|
||||
return RSTRUCT(obj)->ptr[i];
|
||||
}
|
||||
}
|
||||
|
@ -139,16 +164,16 @@ static VALUE
|
|||
rb_struct_set(obj, val)
|
||||
VALUE obj, val;
|
||||
{
|
||||
VALUE member, slot;
|
||||
VALUE members, slot;
|
||||
long i;
|
||||
|
||||
member = rb_struct_iv_get(rb_obj_class(obj), "__member__");
|
||||
if (NIL_P(member)) {
|
||||
members = rb_struct_iv_get(rb_obj_class(obj), "__members__");
|
||||
if (NIL_P(members)) {
|
||||
rb_bug("uninitialized struct");
|
||||
}
|
||||
rb_struct_modify(obj);
|
||||
for (i=0; i<RARRAY(member)->len; i++) {
|
||||
slot = RARRAY(member)->ptr[i];
|
||||
for (i=0; i<RARRAY(members)->len; i++) {
|
||||
slot = RARRAY(members)->ptr[i];
|
||||
if (rb_id_attrset(SYM2ID(slot)) == rb_frame_last_func()) {
|
||||
return RSTRUCT(obj)->ptr[i] = val;
|
||||
}
|
||||
|
@ -159,13 +184,14 @@ rb_struct_set(obj, val)
|
|||
}
|
||||
|
||||
static VALUE
|
||||
make_struct(name, member, klass)
|
||||
VALUE name, member, klass;
|
||||
make_struct(name, members, klass)
|
||||
VALUE name, members, klass;
|
||||
{
|
||||
VALUE nstr;
|
||||
ID id;
|
||||
long i;
|
||||
|
||||
OBJ_FREEZE(members);
|
||||
if (NIL_P(name)) {
|
||||
nstr = rb_class_new(klass);
|
||||
rb_make_metaclass(nstr, RBASIC(klass)->klass);
|
||||
|
@ -183,15 +209,15 @@ make_struct(name, member, klass)
|
|||
}
|
||||
nstr = rb_define_class_under(klass, cname, klass);
|
||||
}
|
||||
rb_iv_set(nstr, "__size__", LONG2NUM(RARRAY(member)->len));
|
||||
rb_iv_set(nstr, "__member__", member);
|
||||
rb_iv_set(nstr, "__size__", LONG2NUM(RARRAY(members)->len));
|
||||
rb_iv_set(nstr, "__members__", members);
|
||||
|
||||
rb_define_alloc_func(nstr, struct_alloc);
|
||||
rb_define_singleton_method(nstr, "new", rb_class_new_instance, -1);
|
||||
rb_define_singleton_method(nstr, "[]", rb_class_new_instance, -1);
|
||||
rb_define_singleton_method(nstr, "members", rb_struct_s_members, 0);
|
||||
for (i=0; i< RARRAY(member)->len; i++) {
|
||||
ID id = SYM2ID(RARRAY(member)->ptr[i]);
|
||||
for (i=0; i< RARRAY(members)->len; i++) {
|
||||
ID id = SYM2ID(RARRAY(members)->ptr[i]);
|
||||
if (i<10) {
|
||||
rb_define_method_id(nstr, id, ref_func[i], 0);
|
||||
}
|
||||
|
@ -427,15 +453,12 @@ static VALUE
|
|||
rb_struct_each_pair(s)
|
||||
VALUE s;
|
||||
{
|
||||
VALUE member;
|
||||
VALUE members;
|
||||
long i;
|
||||
|
||||
member = rb_struct_iv_get(rb_obj_class(s), "__member__");
|
||||
if (NIL_P(member)) {
|
||||
rb_bug("non-initialized struct");
|
||||
}
|
||||
members = struct_members(s);
|
||||
for (i=0; i<RSTRUCT(s)->len; i++) {
|
||||
rb_yield_values(2, RARRAY(member)->ptr[i], RSTRUCT(s)->ptr[i]);
|
||||
rb_yield_values(2, rb_ary_entry(members, i), RSTRUCT(s)->ptr[i]);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
@ -445,14 +468,10 @@ inspect_struct(s)
|
|||
VALUE s;
|
||||
{
|
||||
char *cname = rb_class2name(rb_obj_class(s));
|
||||
VALUE str, member;
|
||||
VALUE str, members;
|
||||
long i;
|
||||
|
||||
member = rb_struct_iv_get(rb_obj_class(s), "__member__");
|
||||
if (NIL_P(member)) {
|
||||
rb_bug("non-initialized struct");
|
||||
}
|
||||
|
||||
members = struct_members(s);
|
||||
str = rb_str_buf_new2("#<struct ");
|
||||
rb_str_cat2(str, cname);
|
||||
rb_str_cat2(str, " ");
|
||||
|
@ -463,7 +482,7 @@ inspect_struct(s)
|
|||
if (i > 0) {
|
||||
rb_str_cat2(str, ", ");
|
||||
}
|
||||
slot = RARRAY(member)->ptr[i];
|
||||
slot = RARRAY(members)->ptr[i];
|
||||
p = rb_id2name(SYM2ID(slot));
|
||||
rb_str_cat2(str, p);
|
||||
rb_str_cat2(str, "=");
|
||||
|
@ -539,17 +558,13 @@ rb_struct_aref_id(s, id)
|
|||
VALUE s;
|
||||
ID id;
|
||||
{
|
||||
VALUE member;
|
||||
VALUE members;
|
||||
long i, len;
|
||||
|
||||
member = rb_struct_iv_get(rb_obj_class(s), "__member__");
|
||||
if (NIL_P(member)) {
|
||||
rb_bug("non-initialized struct");
|
||||
}
|
||||
|
||||
len = RARRAY(member)->len;
|
||||
members = struct_members(s);
|
||||
len = RARRAY(members)->len;
|
||||
for (i=0; i<len; i++) {
|
||||
if (SYM2ID(RARRAY(member)->ptr[i]) == id) {
|
||||
if (SYM2ID(RARRAY(members)->ptr[i]) == id) {
|
||||
return RSTRUCT(s)->ptr[i];
|
||||
}
|
||||
}
|
||||
|
@ -602,18 +617,18 @@ rb_struct_aset_id(s, id, val)
|
|||
VALUE s, val;
|
||||
ID id;
|
||||
{
|
||||
VALUE member;
|
||||
VALUE members;
|
||||
long i, len;
|
||||
|
||||
member = rb_struct_iv_get(rb_obj_class(s), "__member__");
|
||||
if (NIL_P(member)) {
|
||||
rb_bug("non-initialized struct");
|
||||
}
|
||||
|
||||
members = struct_members(s);
|
||||
rb_struct_modify(s);
|
||||
len = RARRAY(member)->len;
|
||||
len = RARRAY(members)->len;
|
||||
if (RSTRUCT(s)->len != RARRAY(members)->len) {
|
||||
rb_raise(rb_eTypeError, "struct size differs (%d required %d given)",
|
||||
RARRAY(members)->len, RSTRUCT(s)->len);
|
||||
}
|
||||
for (i=0; i<len; i++) {
|
||||
if (SYM2ID(RARRAY(member)->ptr[i]) == id) {
|
||||
if (SYM2ID(RARRAY(members)->ptr[i]) == id) {
|
||||
RSTRUCT(s)->ptr[i] = val;
|
||||
return val;
|
||||
}
|
||||
|
|
14
variable.c
14
variable.c
|
@ -98,7 +98,7 @@ fc_i(key, value, res)
|
|||
arg.klass = res->klass;
|
||||
arg.track = value;
|
||||
arg.prev = res;
|
||||
st_foreach(RCLASS(value)->iv_tbl, fc_i, (st_data_t)&arg);
|
||||
st_foreach_safe(RCLASS(value)->iv_tbl, fc_i, (st_data_t)&arg);
|
||||
if (arg.path) {
|
||||
res->path = arg.path;
|
||||
return ST_STOP;
|
||||
|
@ -124,7 +124,7 @@ find_class_path(klass)
|
|||
arg.track = rb_cObject;
|
||||
arg.prev = 0;
|
||||
if (RCLASS(rb_cObject)->iv_tbl) {
|
||||
st_foreach(RCLASS(rb_cObject)->iv_tbl, fc_i, (st_data_t)&arg);
|
||||
st_foreach_safe(RCLASS(rb_cObject)->iv_tbl, fc_i, (st_data_t)&arg);
|
||||
}
|
||||
if (arg.path == 0) {
|
||||
st_foreach(rb_class_tbl, fc_i, (st_data_t)&arg);
|
||||
|
@ -958,7 +958,7 @@ rb_mark_generic_ivar_tbl()
|
|||
{
|
||||
if (!generic_iv_tbl) return;
|
||||
if (special_generic_ivar == 0) return;
|
||||
st_foreach(generic_iv_tbl, givar_i, 0);
|
||||
st_foreach_safe(generic_iv_tbl, givar_i, 0);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1118,7 +1118,7 @@ rb_obj_instance_variables(obj)
|
|||
case T_CLASS:
|
||||
case T_MODULE:
|
||||
if (ROBJECT(obj)->iv_tbl) {
|
||||
st_foreach(ROBJECT(obj)->iv_tbl, ivar_i, ary);
|
||||
st_foreach_safe(ROBJECT(obj)->iv_tbl, ivar_i, ary);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
@ -1127,7 +1127,7 @@ rb_obj_instance_variables(obj)
|
|||
st_table *tbl;
|
||||
|
||||
if (st_lookup(generic_iv_tbl, obj, (st_data_t *)&tbl)) {
|
||||
st_foreach(tbl, ivar_i, ary);
|
||||
st_foreach_safe(tbl, ivar_i, ary);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -1511,7 +1511,7 @@ rb_mod_const_at(mod, data)
|
|||
tbl = st_init_numtable();
|
||||
}
|
||||
if (RCLASS(mod)->iv_tbl) {
|
||||
st_foreach(RCLASS(mod)->iv_tbl, sv_i, (st_data_t)tbl);
|
||||
st_foreach_safe(RCLASS(mod)->iv_tbl, sv_i, (st_data_t)tbl);
|
||||
}
|
||||
return tbl;
|
||||
}
|
||||
|
@ -1875,7 +1875,7 @@ rb_mod_class_variables(obj)
|
|||
|
||||
for (;;) {
|
||||
if (RCLASS(obj)->iv_tbl) {
|
||||
st_foreach(RCLASS(obj)->iv_tbl, cv_i, ary);
|
||||
st_foreach_safe(RCLASS(obj)->iv_tbl, cv_i, ary);
|
||||
}
|
||||
obj = RCLASS(obj)->super;
|
||||
if (!obj) break;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue