summaryrefslogtreecommitdiff
path: root/vm_backtrace.c
diff options
context:
space:
mode:
authorko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-11-29 00:12:49 +0000
committerko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-11-29 00:12:49 +0000
commit3d47e7b2854a47878fd6346586d12cb6c312df82 (patch)
tree375dd906122266ce3af8db5eac75b022dab51364 /vm_backtrace.c
parentb76b6b5c98133da0e3d23318ab1dcc86c3f0074f (diff)
* 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.c59
1 files changed, 43 insertions, 16 deletions
diff --git a/vm_backtrace.c b/vm_backtrace.c
index 143552b..5b4ed10 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);
}
}