&CORE::index() and &CORE::rindex()
authorFather Chrysostomos <sprout@cpan.org>
Fri, 26 Aug 2011 19:40:13 +0000 (12:40 -0700)
committerFather Chrysostomos <sprout@cpan.org>
Fri, 26 Aug 2011 19:40:13 +0000 (12:40 -0700)
This commit allows &CORE::index and &CORE::rindex to be called through
references and via ampersand syntax.  pp_index is modified to take
into account the nulls pushed on to the stack in pp_coreargs, which
happens because pp_coreargs has no other way to tell pp_index how many
arguments it’s actually getting.  See commit 0163043a for details.

gv.c
pp.c
t/op/coresubs.t

diff --git a/gv.c b/gv.c
index 46d5ce0..9dd2787 100644 (file)
--- a/gv.c
+++ b/gv.c
@@ -1354,12 +1354,12 @@ Perl_gv_fetchpvn_flags(pTHX_ const char *nambeg, STRLEN full_len, I32 flags,
            case KEY_chdir:
            case KEY_chomp: case KEY_chop:
            case KEY_each: case KEY_eof: case KEY_exec:
-           case KEY_index: case KEY_keys:
+           case KEY_keys:
            case KEY_lock: case KEY_lstat:
            case KEY_mkdir: case KEY_open: case KEY_pop:
            case KEY_push: case KEY_rand: case KEY_read:
            case KEY_recv: case KEY_reset:
-           case KEY_rindex: case KEY_select: case KEY_send:
+           case KEY_select: case KEY_send:
            case KEY_setpgrp: case KEY_shift: case KEY_sleep:
            case KEY_splice:
            case KEY_srand: case KEY_stat: case KEY_substr:
diff --git a/pp.c b/pp.c
index 156c4d3..de2b35c 100644 (file)
--- a/pp.c
+++ b/pp.c
@@ -3260,8 +3260,9 @@ PP(pp_index)
     bool big_utf8;
     bool little_utf8;
     const bool is_index = PL_op->op_type == OP_INDEX;
+    const bool threeargs = MAXARG >= 3 && (TOPs || ((void)POPs,0));
 
-    if (MAXARG >= 3) {
+    if (threeargs) {
        /* arybase is in characters, like offset, so combine prior to the
           UTF-8 to bytes calculation.  */
        offset = POPi - arybase;
@@ -3335,7 +3336,7 @@ PP(pp_index)
        little_p = SvPVX(little);
     }
 
-    if (MAXARG < 3)
+    if (!threeargs)
        offset = is_index ? 0 : biglen;
     else {
        if (big_utf8 && offset > 0)
index fcae6b8..7a00694 100644 (file)
@@ -375,6 +375,13 @@ test_proto 'gmtime';
 pass '&gmtime without args does not crash'; ++$tests;
 
 test_proto 'hex', ff=>255;
+
+test_proto 'index';
+$tests += 3;
+is &myindex("foffooo","o",2),4,'&index';
+lis [&myindex("foffooo","o",2)],[4],'&index in list context';
+is &myindex("foffooo","o"),1,'&index with 2 args';
+
 test_proto 'int', 1.5=>1;
 test_proto 'ioctl';
 
@@ -472,6 +479,13 @@ lis [&myreverse(qw 'dog bites man')], [qw 'man bites dog'],
   '&reverse in list context';
 
 test_proto 'rewinddir';
+
+test_proto 'rindex';
+$tests += 3;
+is &myrindex("foffooo","o",2),1,'&rindex';
+lis [&myrindex("foffooo","o",2)],[1],'&rindex in list context';
+is &myrindex("foffooo","o"),6,'&rindex with 2 args';
+
 test_proto 'rmdir';
 
 test_proto 'seek';