summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Mitchell <davem@iabyn.com>2012-06-22 12:36:03 +0100
committerDavid Mitchell <davem@iabyn.com>2012-09-08 15:42:06 +0100
commitd3b97530399d61590a1500b52bdba553d657bda5 (patch)
tree0ad370f9d3c601b62e19d31ef7c20290098ce23d
parent8fd1a95029bf0ff87a3064dec7d6645f40359f2c (diff)
downloadperl-d3b97530399d61590a1500b52bdba553d657bda5.tar.gz
PL_sawampersand: use 3 bit flags rather than bool
Set a separate flag for each of $`, $& and $'. It still works fine in boolean context. This will allow us to have more refined control over what parts of a match string to copy (we currently copy the whole string).
-rw-r--r--gv.c31
-rw-r--r--intrpvar.h2
-rw-r--r--perl.c7
-rw-r--r--perl.h6
4 files changed, 35 insertions, 11 deletions
diff --git a/gv.c b/gv.c
index c6e474e580..e29f2fdfc2 100644
--- a/gv.c
+++ b/gv.c
@@ -1655,12 +1655,23 @@ Perl_gv_fetchpvn_flags(pTHX_ const char *nambeg, STRLEN full_len, I32 flags,
require_tie_mod(gv, name, newSVpvs("Tie::Hash::NamedCapture"), "TIEHASH", 0);
}
if (sv_type==SVt_PV || sv_type==SVt_PVGV) {
- if (*name == '[')
- require_tie_mod(gv,name,newSVpvs("arybase"),"FETCH",0);
- else if (*name == '&' || *name == '`' || *name == '\'') {
- PL_sawampersand = TRUE;
- (void)GvSVn(gv);
- }
+ switch (*name) {
+ case '[':
+ require_tie_mod(gv,name,newSVpvs("arybase"),"FETCH",0);
+ break;
+ case '`':
+ PL_sawampersand |= SAWAMPERSAND_LEFT;
+ (void)GvSVn(gv);
+ break;
+ case '&':
+ PL_sawampersand |= SAWAMPERSAND_MIDDLE;
+ (void)GvSVn(gv);
+ break;
+ case '\'':
+ PL_sawampersand |= SAWAMPERSAND_RIGHT;
+ (void)GvSVn(gv);
+ break;
+ }
}
}
else if (len == 3 && sv_type == SVt_PVAV
@@ -1866,7 +1877,13 @@ Perl_gv_fetchpvn_flags(pTHX_ const char *nambeg, STRLEN full_len, I32 flags,
sv_type == SVt_PVCV ||
sv_type == SVt_PVFM ||
sv_type == SVt_PVIO
- )) { PL_sawampersand = TRUE; }
+ )) { PL_sawampersand |=
+ (*name == '`')
+ ? SAWAMPERSAND_LEFT
+ : (*name == '&')
+ ? SAWAMPERSAND_MIDDLE
+ : SAWAMPERSAND_RIGHT;
+ }
goto magicalize;
case ':': /* $: */
diff --git a/intrpvar.h b/intrpvar.h
index f57fa7df62..94b7425c10 100644
--- a/intrpvar.h
+++ b/intrpvar.h
@@ -292,7 +292,7 @@ The C variable which corresponds to Perl's $^W warning variable.
*/
PERLVAR(I, dowarn, U8)
-PERLVAR(I, sawampersand, bool) /* must save all match strings */
+PERLVAR(I, sawampersand, U8) /* must save all match strings */
PERLVAR(I, unsafe, bool)
PERLVAR(I, exit_flags, U8) /* was exit() unexpected, etc. */
diff --git a/perl.c b/perl.c
index 8444218562..7d65719927 100644
--- a/perl.c
+++ b/perl.c
@@ -860,7 +860,7 @@ perl_destruct(pTHXx)
PL_minus_F = FALSE;
PL_doswitches = FALSE;
PL_dowarn = G_WARN_OFF;
- PL_sawampersand = FALSE; /* must save all match strings */
+ PL_sawampersand = 0; /* must save all match strings */
PL_unsafe = FALSE;
Safefree(PL_inplace);
@@ -2343,8 +2343,9 @@ STATIC void
S_run_body(pTHX_ I32 oldscope)
{
dVAR;
- DEBUG_r(PerlIO_printf(Perl_debug_log, "%s $` $& $' support.\n",
- PL_sawampersand ? "Enabling" : "Omitting"));
+ DEBUG_r(PerlIO_printf(Perl_debug_log, "%s $` $& $' support (0x%x).\n",
+ PL_sawampersand ? "Enabling" : "Omitting",
+ (unsigned int)(PL_sawampersand)));
if (!PL_restartop) {
#ifdef PERL_MAD
diff --git a/perl.h b/perl.h
index 2cc4e91c1a..b299432ec4 100644
--- a/perl.h
+++ b/perl.h
@@ -4854,6 +4854,12 @@ typedef enum {
#define HINT_SORT_MERGESORT 0x00000002
#define HINT_SORT_STABLE 0x00000100 /* sort styles (currently one) */
+/* flags for PL_sawampersand */
+
+#define SAWAMPERSAND_LEFT 1 /* saw $` */
+#define SAWAMPERSAND_MIDDLE 2 /* saw $& */
+#define SAWAMPERSAND_RIGHT 4 /* saw $' */
+
/* Various states of the input record separator SV (rs) */
#define RsSNARF(sv) (! SvOK(sv))
#define RsSIMPLE(sv) (SvOK(sv) && (! SvPOK(sv) || SvCUR(sv)))