perl
view release on metacpan or search on metacpan
ext/re/re.pm view on Meta::CPAN
}
sub bits {
my $on = shift;
my $bits = 0;
my $turning_all_off = ! @_ && ! $on;
my $seen_Debug = 0;
my $seen_debug = 0;
if ($turning_all_off) {
# Pretend were called with certain parameters, which are best dealt
# with that way.
push @_, keys %bitmask; # taint and eval
push @_, 'strict';
}
# Process each subpragma parameter
ARG:
foreach my $idx (0..$#_){
my $s=$_[$idx];
if ($s eq 'Debug' or $s eq 'Debugcolor') {
if (! $seen_Debug) {
$seen_Debug = 1;
# Reset to nothing, and then add what follows. $seen_Debug
# allows, though unlikely someone would do it, more than one
# Debug and flags in the arguments
${^RE_DEBUG_FLAGS} = 0;
}
setcolor() if $s =~/color/i;
for my $idx ($idx+1..$#_) {
if ($flags{$_[$idx]}) {
if ($on) {
${^RE_DEBUG_FLAGS} |= $flags{$_[$idx]};
} else {
${^RE_DEBUG_FLAGS} &= ~ $flags{$_[$idx]};
}
} else {
require Carp;
Carp::carp("Unknown \"re\" Debug flag '$_[$idx]', possible flags: ",
join(", ",sort keys %flags ) );
}
}
_load_unload($on ? 1 : ${^RE_DEBUG_FLAGS});
last;
} elsif ($s eq 'debug' or $s eq 'debugcolor') {
# These default flags should be kept in sync with the same values
# in regcomp.h
${^RE_DEBUG_FLAGS} = $flags{'EXECUTE'} | $flags{'DUMP'};
setcolor() if $s =~/color/i;
_load_unload($on);
$seen_debug = 1;
} elsif (exists $bitmask{$s}) {
$bits |= $bitmask{$s};
} elsif ($EXPORT_OK{$s}) {
require Exporter;
re->export_to_level(2, 're', $s);
} elsif ($s eq 'strict') {
if ($on) {
$^H{reflags} |= $reflags{$s};
warnings::warnif('experimental::re_strict',
"\"use re 'strict'\" is experimental");
# Turn on warnings if not already done.
if (! warnings::enabled('regexp')) {
require warnings;
warnings->import('regexp');
$^H{re_strict} = 1;
}
}
else {
$^H{reflags} &= ~$reflags{$s} if $^H{reflags};
# Turn off warnings if we turned them on.
warnings->unimport('regexp') if $^H{re_strict};
}
if ($^H{reflags}) {
$^H |= $flags_hint;
}
else {
$^H &= ~$flags_hint;
}
} elsif ($s =~ s/^\///) {
my $reflags = $^H{reflags} || 0;
my $seen_charset;
my $x_count = 0;
while ($s =~ m/( . )/gx) {
local $_ = $1;
if (/[adul]/) {
# The 'a' may be repeated; hide this from the rest of the
# code by counting and getting rid of all of them, then
# changing to 'aa' if there is a repeat.
if ($_ eq 'a') {
my $sav_pos = pos $s;
my $a_count = $s =~ s/a//g;
pos $s = $sav_pos - 1; # -1 because got rid of the 'a'
if ($a_count > 2) {
require Carp;
Carp::carp(
qq 'The "a" flag may only appear a maximum of twice'
);
}
elsif ($a_count == 2) {
$_ = 'aa';
}
}
if ($on) {
if ($seen_charset) {
require Carp;
if ($seen_charset ne $_) {
Carp::carp(
qq 'The "$seen_charset" and "$_" flags '
.qq 'are exclusive'
);
}
else {
Carp::carp(
qq 'The "$seen_charset" flag may not appear '
.qq 'twice'
);
}
}
$^H{reflags_charset} = $reflags{$_};
$seen_charset = $_;
}
else {
delete $^H{reflags_charset}
if defined $^H{reflags_charset}
&& $^H{reflags_charset} == $reflags{$_};
}
} elsif (exists $reflags{$_}) {
if ($_ eq 'x') {
$x_count++;
if ($x_count > 2) {
require Carp;
Carp::carp(
qq 'The "x" flag may only appear a maximum of twice'
);
}
elsif ($x_count == 2) {
$_ = 'xx'; # First time through got the /x
}
}
$on
? $reflags |= $reflags{$_}
: ($reflags &= ~$reflags{$_});
} else {
require Carp;
Carp::carp(
qq'Unknown regular expression flag "$_"'
);
next ARG;
}
}
($^H{reflags} = $reflags or defined $^H{reflags_charset})
? $^H |= $flags_hint
: ($^H &= ~$flags_hint);
} else {
require Carp;
if ($seen_debug && defined $flags{$s}) {
Carp::carp("Use \"Debug\" not \"debug\", to list debug types"
. " in \"re\". \"$s\" ignored");
}
else {
Carp::carp("Unknown \"re\" subpragma '$s' (known ones are: ",
join(', ', map {qq('$_')} 'debug', 'debugcolor', sort keys %bitmask),
")");
}
}
}
if ($turning_all_off) {
_load_unload(0);
$^H{reflags} = 0;
$^H{reflags_charset} = 0;
$^H &= ~$flags_hint;
}
$bits;
}
sub import {
shift;
$^H |= bits(1, @_);
}
sub unimport {
shift;
$^H &= ~ bits(0, @_);
}
1;
__END__
=head1 NAME
re - Perl pragma to alter regular expression behaviour
=head1 SYNOPSIS
use re 'taint';
($x) = ($^X =~ /^(.*)$/s); # $x is tainted here
$pat = '(?{ $foo = 1 })';
use re 'eval';
/foo${pat}bar/; # won't fail (when not under -T
# switch)
{
no re 'taint'; # the default
($x) = ($^X =~ /^(.*)$/s); # $x is not tainted here
no re 'eval'; # the default
/foo${pat}bar/; # disallowed (with or without -T
( run in 2.821 seconds using v1.01-cache-2.11-cpan-d01c6094234 )