ruby-changes:40503
From: nobu <ko1@a...>
Date: Mon, 16 Nov 2015 14:47:26 +0900 (JST)
Subject: [ruby-changes:40503] nobu:r52584 (trunk): struct.c: fix index in message
nobu 2015-11-16 14:46:50 +0900 (Mon, 16 Nov 2015) New Revision: 52584 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=52584 Log: 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. Modified files: trunk/struct.c trunk/test/ruby/test_struct.rb Index: struct.c =================================================================== --- struct.c (revision 52583) +++ struct.c (revision 52584) @@ -816,16 +816,57 @@ rb_struct_init_copy(VALUE copy, VALUE s) https://github.com/ruby/ruby/blob/trunk/struct.c#L816 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); + long i; + VALUE idx = *name; + + if (RB_TYPE_P(idx, T_SYMBOL)) { + return struct_member_pos(s, idx); } - rb_name_err_raise("no member '%1$s' in struct", s, name); + 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; + } +} - UNREACHABLE; +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) https://github.com/ruby/ruby/blob/trunk/struct.c#L889 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, https://github.com/ruby/ruby/blob/trunk/struct.c#L916 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; Index: test/ruby/test_struct.rb =================================================================== --- test/ruby/test_struct.rb (revision 52583) +++ test/ruby/test_struct.rb (revision 52584) @@ -155,8 +155,8 @@ module TestStruct https://github.com/ruby/ruby/blob/trunk/test/ruby/test_struct.rb#L155 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 https://github.com/ruby/ruby/blob/trunk/test/ruby/test_struct.rb#L166 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 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/