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
122
struct.c
122
struct.c
@ -816,16 +816,57 @@ rb_struct_init_copy(VALUE copy, VALUE s)
|
|||||||
return copy;
|
return copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
static VALUE
|
static int
|
||||||
rb_struct_aref_sym(VALUE s, VALUE name)
|
rb_struct_pos(VALUE s, VALUE *name)
|
||||||
{
|
{
|
||||||
int pos = struct_member_pos(s, name);
|
long i;
|
||||||
if (pos != -1) {
|
VALUE idx = *name;
|
||||||
return RSTRUCT_GET(s, pos);
|
|
||||||
}
|
|
||||||
rb_name_err_raise("no member '%1$s' in struct", s, 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
|
VALUE
|
||||||
rb_struct_aref(VALUE s, VALUE idx)
|
rb_struct_aref(VALUE s, VALUE idx)
|
||||||
{
|
{
|
||||||
long i;
|
int i = rb_struct_pos(s, &idx);
|
||||||
|
if (i < 0) invalid_struct_pos(s, idx);
|
||||||
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));
|
|
||||||
return RSTRUCT_GET(s, i);
|
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:
|
* call-seq:
|
||||||
* struct[name] = obj -> obj
|
* struct[name] = obj -> obj
|
||||||
@ -910,30 +916,8 @@ rb_struct_aset_sym(VALUE s, VALUE name, VALUE val)
|
|||||||
VALUE
|
VALUE
|
||||||
rb_struct_aset(VALUE s, VALUE idx, VALUE val)
|
rb_struct_aset(VALUE s, VALUE idx, VALUE val)
|
||||||
{
|
{
|
||||||
long i;
|
int i = rb_struct_pos(s, &idx);
|
||||||
|
if (i < 0) invalid_struct_pos(s, idx);
|
||||||
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));
|
|
||||||
}
|
|
||||||
rb_struct_modify(s);
|
rb_struct_modify(s);
|
||||||
RSTRUCT_SET(s, i, val);
|
RSTRUCT_SET(s, i, val);
|
||||||
return val;
|
return val;
|
||||||
|
@ -155,8 +155,8 @@ module TestStruct
|
|||||||
klass = @Struct.new(:a)
|
klass = @Struct.new(:a)
|
||||||
o = klass.new(1)
|
o = klass.new(1)
|
||||||
assert_equal(1, o[0])
|
assert_equal(1, o[0])
|
||||||
assert_raise(IndexError) { o[-2] }
|
assert_raise_with_message(IndexError, /offset -2\b/) {o[-2]}
|
||||||
assert_raise(IndexError) { o[1] }
|
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"]}
|
||||||
assert_raise_with_message(NameError, /foo/) {o[:foo]}
|
assert_raise_with_message(NameError, /foo/) {o[:foo]}
|
||||||
end
|
end
|
||||||
@ -166,8 +166,8 @@ module TestStruct
|
|||||||
o = klass.new(1)
|
o = klass.new(1)
|
||||||
o[0] = 2
|
o[0] = 2
|
||||||
assert_equal(2, o[:a])
|
assert_equal(2, o[:a])
|
||||||
assert_raise(IndexError) { o[-2] = 3 }
|
assert_raise_with_message(IndexError, /offset -2\b/) {o[-2] = 3}
|
||||||
assert_raise(IndexError) { o[1] = 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}
|
||||||
assert_raise_with_message(NameError, /foo/) {o[:foo] = 3}
|
assert_raise_with_message(NameError, /foo/) {o[:foo] = 3}
|
||||||
end
|
end
|
||||||
|
Loading…
x
Reference in New Issue
Block a user