diff options
author | ko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2012-11-29 00:12:49 +0000 |
---|---|---|
committer | ko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2012-11-29 00:12:49 +0000 |
commit | 3d47e7b2854a47878fd6346586d12cb6c312df82 (patch) | |
tree | 375dd906122266ce3af8db5eac75b022dab51364 /vm_backtrace.c | |
parent | b76b6b5c98133da0e3d23318ab1dcc86c3f0074f (diff) | |
download | ruby-3d47e7b2854a47878fd6346586d12cb6c312df82.tar.gz |
* vm_backtrace.c (vm_backtrace_to_ary): support range argument
like Array#[].
[ruby-core:50092] [ruby-trunk - Feature #7434]
Test and document is not available. Please help us.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37957 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'vm_backtrace.c')
-rw-r--r-- | vm_backtrace.c | 59 |
1 files changed, 43 insertions, 16 deletions
diff --git a/vm_backtrace.c b/vm_backtrace.c index 143552bcbb..5b4ed10e7e 100644 --- a/vm_backtrace.c +++ b/vm_backtrace.c @@ -699,33 +699,60 @@ vm_backtrace_to_ary(rb_thread_t *th, int argc, VALUE *argv, int lev_default, int { VALUE level, vn; int lev, n; + VALUE btval = backtrace_object(th); + rb_backtrace_t *bt; + GetCoreDataFromValue(btval, rb_backtrace_t, bt); rb_scan_args(argc, argv, "02", &level, &vn); - lev = NIL_P(level) ? lev_default : NUM2INT(level); - - if (NIL_P(vn)) { - n = 0; - } - else { - n = NUM2INT(vn); - if (n == 0) { - return rb_ary_new(); + switch (argc) { + case 0: + lev = lev_default + lev_plus; + n = bt->backtrace_size - lev; + break; + case 1: + { + long beg, len; + switch (rb_range_beg_len(level, &beg, &len, bt->backtrace_size - lev_plus, 0)) { + case Qfalse: + lev = NUM2LONG(level); + if (lev < 0) { + rb_raise(rb_eArgError, "negative level (%d)", lev); + } + lev += lev_plus; + n = bt->backtrace_size - lev; + break; + case Qnil: + return Qnil; + default: + lev = beg + lev_plus; + n = len; + break; + } + break; } + case 2: + lev = NUM2LONG(level); + if (lev < 0) { + rb_raise(rb_eArgError, "negative level (%d)", lev); + } + lev += lev_plus; + n = NUM2LONG(vn); + break; + default: + lev = n = 0; /* to avoid warning */ + break; } - if (lev < 0) { - rb_raise(rb_eArgError, "negative level (%d)", lev); - } - if (n < 0) { - rb_raise(rb_eArgError, "negative n (%d)", n); + if (n == 0) { + return rb_ary_new(); } if (to_str) { - return vm_backtrace_str_ary(th, lev+lev_plus, n); + return backtrace_to_str_ary(btval, lev, n); } else { - return vm_backtrace_location_ary(th, lev+lev_plus, n); + return backtrace_to_location_ary(btval, lev, n); } } |