mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
struct.c: fix index in message
* struct.c (rb_struct_aref, rb_struct_aset): show the given index, not offset index, in the error messages when the offset is out of the range. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@52584 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
f4fbc7d2a6
commit
9044b126e5
2 changed files with 57 additions and 73 deletions
122
struct.c
122
struct.c
|
@ -816,16 +816,57 @@ rb_struct_init_copy(VALUE copy, VALUE s)
|
|||
return copy;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_struct_aref_sym(VALUE s, VALUE name)
|
||||
static int
|
||||
rb_struct_pos(VALUE s, VALUE *name)
|
||||
{
|
||||
int pos = struct_member_pos(s, name);
|
||||
if (pos != -1) {
|
||||
return RSTRUCT_GET(s, pos);
|
||||
}
|
||||
rb_name_err_raise("no member '%1$s' in struct", s, name);
|
||||
long i;
|
||||
VALUE idx = *name;
|
||||
|
||||
UNREACHABLE;
|
||||
if (RB_TYPE_P(idx, T_SYMBOL)) {
|
||||
return struct_member_pos(s, idx);
|
||||
}
|
||||
else if (RB_TYPE_P(idx, T_STRING)) {
|
||||
idx = rb_check_symbol(name);
|
||||
if (NIL_P(idx)) return -1;
|
||||
return struct_member_pos(s, idx);
|
||||
}
|
||||
else {
|
||||
long len;
|
||||
i = NUM2LONG(idx);
|
||||
len = RSTRUCT_LEN(s);
|
||||
if (i < 0) {
|
||||
if (i + len < 0) {
|
||||
*name = LONG2FIX(i);
|
||||
return -1;
|
||||
}
|
||||
i += len;
|
||||
}
|
||||
else if (len <= i) {
|
||||
*name = LONG2FIX(i);
|
||||
return -1;
|
||||
}
|
||||
return (int)i;
|
||||
}
|
||||
}
|
||||
|
||||
NORETURN(static void invalid_struct_pos(VALUE s, VALUE idx));
|
||||
static void
|
||||
invalid_struct_pos(VALUE s, VALUE idx)
|
||||
{
|
||||
if (FIXNUM_P(idx)) {
|
||||
long i = FIX2INT(idx), len = RSTRUCT_LEN(s);
|
||||
if (i < 0) {
|
||||
rb_raise(rb_eIndexError, "offset %ld too small for struct(size:%ld)",
|
||||
i, len);
|
||||
}
|
||||
else {
|
||||
rb_raise(rb_eIndexError, "offset %ld too large for struct(size:%ld)",
|
||||
i, len);
|
||||
}
|
||||
}
|
||||
else {
|
||||
rb_name_err_raise("no member '%1$s' in struct", s, idx);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -848,46 +889,11 @@ rb_struct_aref_sym(VALUE s, VALUE name)
|
|||
VALUE
|
||||
rb_struct_aref(VALUE s, VALUE idx)
|
||||
{
|
||||
long i;
|
||||
|
||||
if (RB_TYPE_P(idx, T_SYMBOL)) {
|
||||
return rb_struct_aref_sym(s, idx);
|
||||
}
|
||||
else if (RB_TYPE_P(idx, T_STRING)) {
|
||||
ID id = rb_check_id(&idx);
|
||||
if (!id) {
|
||||
rb_name_err_raise("no member '%1$s' in struct",
|
||||
s, idx);
|
||||
}
|
||||
return rb_struct_aref_sym(s, ID2SYM(id));
|
||||
}
|
||||
|
||||
i = NUM2LONG(idx);
|
||||
if (i < 0) i = RSTRUCT_LEN(s) + i;
|
||||
if (i < 0)
|
||||
rb_raise(rb_eIndexError, "offset %ld too small for struct(size:%ld)",
|
||||
i, RSTRUCT_LEN(s));
|
||||
if (RSTRUCT_LEN(s) <= i)
|
||||
rb_raise(rb_eIndexError, "offset %ld too large for struct(size:%ld)",
|
||||
i, RSTRUCT_LEN(s));
|
||||
int i = rb_struct_pos(s, &idx);
|
||||
if (i < 0) invalid_struct_pos(s, idx);
|
||||
return RSTRUCT_GET(s, i);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_struct_aset_sym(VALUE s, VALUE name, VALUE val)
|
||||
{
|
||||
int pos = struct_member_pos(s, name);
|
||||
if (pos != -1) {
|
||||
rb_struct_modify(s);
|
||||
RSTRUCT_SET(s, pos, val);
|
||||
return val;
|
||||
}
|
||||
|
||||
rb_name_err_raise("no member '%1$s' in struct", s, name);
|
||||
|
||||
UNREACHABLE;
|
||||
}
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* struct[name] = obj -> obj
|
||||
|
@ -910,30 +916,8 @@ rb_struct_aset_sym(VALUE s, VALUE name, VALUE val)
|
|||
VALUE
|
||||
rb_struct_aset(VALUE s, VALUE idx, VALUE val)
|
||||
{
|
||||
long i;
|
||||
|
||||
if (RB_TYPE_P(idx, T_SYMBOL)) {
|
||||
return rb_struct_aset_sym(s, idx, val);
|
||||
}
|
||||
if (RB_TYPE_P(idx, T_STRING)) {
|
||||
ID id = rb_check_id(&idx);
|
||||
if (!id) {
|
||||
rb_name_err_raise("no member '%1$s' in struct",
|
||||
s, idx);
|
||||
}
|
||||
return rb_struct_aset_sym(s, ID2SYM(id), val);
|
||||
}
|
||||
|
||||
i = NUM2LONG(idx);
|
||||
if (i < 0) i = RSTRUCT_LEN(s) + i;
|
||||
if (i < 0) {
|
||||
rb_raise(rb_eIndexError, "offset %ld too small for struct(size:%ld)",
|
||||
i, RSTRUCT_LEN(s));
|
||||
}
|
||||
if (RSTRUCT_LEN(s) <= i) {
|
||||
rb_raise(rb_eIndexError, "offset %ld too large for struct(size:%ld)",
|
||||
i, RSTRUCT_LEN(s));
|
||||
}
|
||||
int i = rb_struct_pos(s, &idx);
|
||||
if (i < 0) invalid_struct_pos(s, idx);
|
||||
rb_struct_modify(s);
|
||||
RSTRUCT_SET(s, i, val);
|
||||
return val;
|
||||
|
|
|
@ -155,8 +155,8 @@ module TestStruct
|
|||
klass = @Struct.new(:a)
|
||||
o = klass.new(1)
|
||||
assert_equal(1, o[0])
|
||||
assert_raise(IndexError) { o[-2] }
|
||||
assert_raise(IndexError) { o[1] }
|
||||
assert_raise_with_message(IndexError, /offset -2\b/) {o[-2]}
|
||||
assert_raise_with_message(IndexError, /offset 1\b/) {o[1]}
|
||||
assert_raise_with_message(NameError, /foo/) {o["foo"]}
|
||||
assert_raise_with_message(NameError, /foo/) {o[:foo]}
|
||||
end
|
||||
|
@ -166,8 +166,8 @@ module TestStruct
|
|||
o = klass.new(1)
|
||||
o[0] = 2
|
||||
assert_equal(2, o[:a])
|
||||
assert_raise(IndexError) { o[-2] = 3 }
|
||||
assert_raise(IndexError) { o[1] = 3 }
|
||||
assert_raise_with_message(IndexError, /offset -2\b/) {o[-2] = 3}
|
||||
assert_raise_with_message(IndexError, /offset 1\b/) {o[1] = 3}
|
||||
assert_raise_with_message(NameError, /foo/) {o["foo"] = 3}
|
||||
assert_raise_with_message(NameError, /foo/) {o[:foo] = 3}
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue