This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
++substr $re::VERSION, -1
[perl5.git] / ext / re / re.pm
index 4f8d410..1ca2ae5 100644 (file)
@@ -1,34 +1,34 @@
 package re;
 
-# pragma for controlling the regex engine
+# pragma for controlling the regexp engine
 use strict;
 use warnings;
 
-our $VERSION     = "0.08";
+our $VERSION     = "0.15";
 our @ISA         = qw(Exporter);
-our @EXPORT_OK   = qw(is_regexp regexp_pattern regmust 
-                      regname regnames 
-                      regnames_count regnames_iterinit regnames_iternext);
+our @EXPORT_OK   = ('regmust',
+                    qw(is_regexp regexp_pattern
+                       regname regnames regnames_count));
 our %EXPORT_OK = map { $_ => 1 } @EXPORT_OK;
 
-# *** WARNING *** WARNING *** WARNING *** WARNING *** WARNING ***
-#
-# If you modify these values see comment below!
-
 my %bitmask = (
     taint   => 0x00100000, # HINT_RE_TAINT
     eval    => 0x00200000, # HINT_RE_EVAL
 );
 
-# - File::Basename contains a literal for 'taint' as a fallback.  If
-# taint is changed here, File::Basename must be updated as well.
-#
-# - ExtUtils::ParseXS uses a hardcoded 
-# BEGIN { $^H |= 0x00200000 } 
-# in it to allow re.xs to be built. So if 'eval' is changed here then
-# ExtUtils::ParseXS must be changed as well.
-#
-# *** WARNING *** WARNING *** WARNING *** WARNING *** WARNING ***
+my $flags_hint = 0x02000000; # HINT_RE_FLAGS
+my $PMMOD_SHIFT = 0;
+my %reflags = (
+    m => 1 << ($PMMOD_SHIFT + 0),
+    s => 1 << ($PMMOD_SHIFT + 1),
+    i => 1 << ($PMMOD_SHIFT + 2),
+    x => 1 << ($PMMOD_SHIFT + 3),
+    p => 1 << ($PMMOD_SHIFT + 4),
+# special cases:
+    l => 1 << ($PMMOD_SHIFT + 5),
+    u => 1 << ($PMMOD_SHIFT + 6),
+    d => 0,
+);
 
 sub setcolor {
  eval {                                # Ignore errors
@@ -54,6 +54,7 @@ my %flags = (
     OPTIMISE        => 0x000002,
     TRIEC           => 0x000004,
     DUMP            => 0x000008,
+    FLAGS           => 0x000010,
 
     EXECUTE         => 0x00FF00,
     INTUIT          => 0x000100,
@@ -67,42 +68,36 @@ my %flags = (
     STATE           => 0x080000,
     OPTIMISEM       => 0x100000,
     STACK           => 0x280000,
+    BUFFERS         => 0x400000,
+    GPOS            => 0x800000,
 );
-$flags{ALL} = -1;
+$flags{ALL} = -1 & ~($flags{OFFSETS}|$flags{OFFSETSDBG}|$flags{BUFFERS});
 $flags{All} = $flags{all} = $flags{DUMP} | $flags{EXECUTE};
-$flags{Extra} = $flags{EXECUTE} | $flags{COMPILE};
+$flags{Extra} = $flags{EXECUTE} | $flags{COMPILE} | $flags{GPOS};
 $flags{More} = $flags{MORE} = $flags{All} | $flags{TRIEC} | $flags{TRIEM} | $flags{STATE};
 $flags{State} = $flags{DUMP} | $flags{EXECUTE} | $flags{STATE};
 $flags{TRIE} = $flags{DUMP} | $flags{EXECUTE} | $flags{TRIEC};
 
-my $installed;
-my $installed_error;
-
-sub _do_install {
-    if ( ! defined($installed) ) {
-        require XSLoader;
-        $installed = eval { XSLoader::load('re', $VERSION) } || 0;
-        $installed_error = $@;
-    }
+if (defined &DynaLoader::boot_DynaLoader) {
+    require XSLoader;
+    XSLoader::load();
 }
+# else we're miniperl
+# We need to work for miniperl, because the XS toolchain uses Text::Wrap, which
+# uses re 'taint'.
 
 sub _load_unload {
     my ($on)= @_;
     if ($on) {
-        _do_install();        
-        if ( ! $installed ) {
-            die "'re' not installed!? ($installed_error)";
-       } else {
-           # We call install() every time, as if we didn't, we wouldn't
-           # "see" any changes to the color environment var since
-           # the last time it was called.
-
-           # install() returns an integer, which if casted properly
-           # in C resolves to a structure containing the regex
-           # hooks. Setting it to a random integer will guarantee
-           # segfaults.
-           $^H{regcomp} = install();
-        }
+       # We call install() every time, as if we didn't, we wouldn't
+       # "see" any changes to the color environment var since
+       # the last time it was called.
+
+       # install() returns an integer, which if casted properly
+       # in C resolves to a structure containing the regexp
+       # hooks. Setting it to a random integer will guarantee
+       # segfaults.
+       $^H{regcomp} = install();
     } else {
         delete $^H{regcomp};
     }
@@ -115,6 +110,7 @@ sub bits {
        require Carp;
        Carp::carp("Useless use of \"re\" pragma"); 
     }
+   ARG:
     foreach my $idx (0..$#_){
         my $s=$_[$idx];
         if ($s eq 'Debug' or $s eq 'Debugcolor') {
@@ -142,9 +138,35 @@ sub bits {
         } elsif (exists $bitmask{$s}) {
            $bits |= $bitmask{$s};
        } elsif ($EXPORT_OK{$s}) {
-           _do_install();
            require Exporter;
            re->export_to_level(2, 're', $s);
+       } elsif ($s =~ s/^\///) {
+           my $reflags = $^H{reflags} || 0;
+           for(split//, $s) {
+               if (/[dul]/) {
+                   if ($on) {
+                       $^H{reflags_dul} = $reflags{$_};
+                   }
+                   else {
+                       delete $^H{reflags_dul}
+                        if  defined $^H{reflags_dul}
+                         && $^H{reflags_dul} == $reflags{$_};
+                   }
+               } elsif (exists $reflags{$_}) {
+                   $on
+                     ? $reflags |= $reflags{$_}
+                     : ($reflags &= ~$reflags{$_});
+               } else {
+                   require Carp;
+                   Carp::carp(
+                    qq'Unknown regular expression flag "$_"'
+                   );
+                   next ARG;
+               }
+           }
+           ($^H{reflags} = $reflags or defined $^H{reflags_dul})
+            ? $^H |= $flags_hint
+            : ($^H &= ~$flags_hint);
        } else {
            require Carp;
            Carp::carp("Unknown \"re\" subpragma '$s' (known ones are: ",
@@ -190,6 +212,11 @@ re - Perl pragma to alter regular expression behaviour
        /foo${pat}bar/;            # disallowed (with or without -T switch)
     }
 
+    use re '/ix';
+    "FOO" =~ / foo /; # /ix implied
+    no re '/x';
+    "FOO" =~ /foo/; # just /i implied
+
     use re 'debug';               # output debugging info during
     /^(.*)$/s;                    #     compile and run time
 
@@ -215,19 +242,21 @@ re - Perl pragma to alter regular expression behaviour
 =head2 'taint' mode
 
 When C<use re 'taint'> is in effect, and a tainted string is the target
-of a regex, the regex memories (or values returned by the m// operator
-in list context) are tainted.  This feature is useful when regex operations
+of a regexp, the regexp memories (or values returned by the m// operator
+in list context) are tainted.  This feature is useful when regexp operations
 on tainted data aren't meant to extract safe substrings, but to perform
 other transformations.
 
 =head2 'eval' mode
 
-When C<use re 'eval'> is in effect, a regex is allowed to contain
-C<(?{ ... })> zero-width assertions even if regular expression contains
+When C<use re 'eval'> is in effect, a regexp is allowed to contain
+C<(?{ ... })> zero-width assertions and C<(??{ ... })> postponed
+subexpressions, even if the regular expression contains
 variable interpolation.  That is normally disallowed, since it is a
 potential security risk.  Note that this pragma is ignored when the regular
 expression is obtained from tainted data, i.e.  evaluation is always
-disallowed with tainted regular expressions.  See L<perlre/(?{ code })>.
+disallowed with tainted regular expressions.  See L<perlre/(?{ code })> 
+and L<perlre/(??{ code })>.
 
 For the purpose of this pragma, interpolation of precompiled regular
 expressions (i.e., the result of C<qr//>) is I<not> considered variable
@@ -236,7 +265,42 @@ interpolation.  Thus:
     /foo${pat}bar/
 
 I<is> allowed if $pat is a precompiled regular expression, even
-if $pat contains C<(?{ ... })> assertions.
+if $pat contains C<(?{ ... })> assertions or C<(??{ ... })> subexpressions.
+
+=head2 '/flags' mode
+
+When C<use re '/flags'> is specified, the given flags are automatically
+added to every regular expression till the end of the lexical scope.
+
+C<no re '/flags'> will turn off the effect of C<use re '/flags'> for the
+given flags.
+
+For example, if you want all your regular expressions to have /msx on by
+default, simply put
+
+    use re '/msx';
+
+at the top of your code.
+
+The /dul flags cancel each other out. So, in this example,
+
+    use re "/u";
+    "ss" =~ /\xdf/;
+    use re "/d";
+    "ss" =~ /\xdf/;
+
+The second C<use re> does an implicit C<no re '/u'>.
+
+Turning on the /l and /u flags with C<use re> takes precedence over the
+C<locale> pragma and the 'unicode_strings' C<feature>, for regular
+expressions. Turning off one of these flags when it is active reverts to
+the behaviour specified by whatever other pragmata are in scope. For
+example:
+
+    use feature "unicode_strings";
+    no re "/u"; # does nothing
+    use re "/l";
+    no re "/l"; # reverts to unicode_strings behaviour
 
 =head2 'debug' mode
 
@@ -323,6 +387,11 @@ Enable debugging of start point optimisations.
 
 Turns on all "extra" debugging options.
 
+=item BUFFERS
+
+Enable debugging the capture group storage during match. Warning,
+this can potentially produce extremely large output.
+
 =item TRIEM
 
 Enable enhanced TRIE debugging. Enhances both TRIEE
@@ -341,7 +410,7 @@ states as well. This output from this can be quite large.
 =item OPTIMISEM
 
 Enable enhanced optimisation debugging and start point optimisations.
-Probably not useful except when debugging the regex engine itself.
+Probably not useful except when debugging the regexp engine itself.
 
 =item OFFSETS
 
@@ -373,7 +442,7 @@ These are useful shortcuts to save on the typing.
 
 =item ALL
 
-Enable all compile and execute options at once.
+Enable all options at once except OFFSETS, OFFSETSDBG and BUFFERS
 
 =item All
 
@@ -410,7 +479,7 @@ by C<qr//>, false if it is not.
 
 This function will not be confused by overloading or blessing. In
 internals terms, this extracts the regexp pointer out of the
-PERL_MAGIC_qr structure so it it cannot be fooled.
+PERL_MAGIC_qr structure so it cannot be fooled.
 
 =item regexp_pattern($ref)
 
@@ -423,12 +492,12 @@ the pattern was compiled.
 
   my ($pat, $mods) = regexp_pattern($ref);
 
-In scalar context it returns the same as perl would when strigifying a raw
+In scalar context it returns the same as perl would when stringifying a raw
 C<qr//> with the same pattern inside.  If the argument is not a compiled
 reference then this routine returns false but defined in scalar context,
 and the empty list in list context. Thus the following
 
-    if (regexp_pattern($ref) eq '(?i-xsm:foo)')
+    if (regexp_pattern($ref) eq '(?^i:foo)')
 
 will be warning free regardless of what $ref actually is.
 
@@ -438,7 +507,7 @@ or blessing of the object.
 =item regmust($ref)
 
 If the argument is a compiled regular expression as returned by C<qr//>,
-then this function returns what the optimiser consiers to be the longest
+then this function returns what the optimiser considers to be the longest
 anchored fixed string and longest floating fixed string in the pattern.
 
 A I<fixed string> is defined as being a substring that must appear for the
@@ -467,45 +536,27 @@ floating string. This will be what the optimiser of the Perl that you
 are using thinks is the longest. If you believe that the result is wrong
 please report it via the L<perlbug> utility.
 
-=item regname($name,$qr,$all)
+=item regname($name,$all)
 
-Returns the contents of a named buffer. If $qr is missing, or is not the
-result of a qr// then returns the result of the last successful match. If
-$all is true then returns an array ref containing one entry per buffer,
+Returns the contents of a named buffer of the last successful match. If
+$all is true, then returns an array ref containing one entry per buffer,
 otherwise returns the first defined buffer.
 
-=item regnames($qr,$all)
-
-Returns a list of all of the named buffers defined in a pattern. If 
-$all is true then it returns all names defined, if not returns only 
-names which were involved in the last successful match. If $qr is omitted
-or is not the result of a qr// then returns the details for the last
-successful match.
-
-=item regnames_iterinit($qr)
-
-Initializes the internal hash iterator associated to a regexps named capture
-buffers. If $qr is omitted resets the iterator associated with the regexp used 
-in the last successful match.
-
-=item regnames_iternext($qr,$all)
+=item regnames($all)
 
-Gets the next key from the hash associated with a regexp. If $qr
-is omitted resets the iterator associated with the regexp used in the 
-last successful match. If $all is true returns the keys of all of the 
-distinct named buffers in the pattern, if not returns only those names
-used in the last successful match.
+Returns a list of all of the named buffers defined in the last successful
+match. If $all is true, then it returns all names defined, if not it returns
+only names which were involved in the match.
 
-=item regnames_count($qr)
+=item regnames_count()
 
-Returns the number of distinct names defined in the regexp $qr. If
-$qr is omitted or not a regexp returns the count of names in the 
-last successful match. 
+Returns the number of distinct names defined in the pattern used
+for the last successful match.
 
-B<Note:> that this result is always the actual  number of distinct 
-named buffers defined, it may not actually match that which is 
-returned by C<regnames()> and related routines when those routines 
-have not been called with the $all parameter set..
+B<Note:> this result is always the actual number of distinct
+named buffers defined, it may not actually match that which is
+returned by C<regnames()> and related routines when those routines
+have not been called with the $all parameter set.
 
 =back