This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
regen/mk_PL_charclass.pl: Use mktables table for charname
[perl5.git] / regen / feature.pl
index 05643d9..e1f30df 100755 (executable)
@@ -28,32 +28,41 @@ my %feature = (
     evalbytes       => 'evalbytes',
     array_base      => 'arybase',
     current_sub     => '__SUB__',
+    lexical_subs    => 'lexsubs',
     unicode_eval    => 'unieval',
     unicode_strings => 'unicode',
+    fc              => 'fc',
 );
 
 # NOTE: If a feature is ever enabled in a non-contiguous range of Perl
 #       versions, any code below that uses %BundleRanges will have to
 #       be changed to account.
 
+# 5.odd implies the next 5.even, but an explicit 5.even can override it.
 my %feature_bundle = (
+     all     => [ keys %feature ],
      default =>        [qw(array_base)],
     "5.9.5"  =>        [qw(say state switch array_base)],
     "5.10"   =>        [qw(say state switch array_base)],
     "5.11"   =>        [qw(say state switch unicode_strings array_base)],
-    "5.12"   =>        [qw(say state switch unicode_strings array_base)],
     "5.13"   =>        [qw(say state switch unicode_strings array_base)],
-    "5.14"   =>        [qw(say state switch unicode_strings array_base)],
     "5.15"   =>        [qw(say state switch unicode_strings unicode_eval
-                   evalbytes current_sub)],
-    "5.16"   =>        [qw(say state switch unicode_strings unicode_eval
-                   evalbytes current_sub)],
+                   evalbytes current_sub fc)],
+    "5.17"   =>        [qw(say state switch unicode_strings unicode_eval
+                   evalbytes current_sub fc)],
 );
 
+my @experimental = qw( lexical_subs );
+
 
 ###########################################################################
 # More data generated from the above
 
+for (keys %feature_bundle) {
+    next unless /^5\.(\d*[13579])\z/;
+    $feature_bundle{"5.".($1+1)} ||= $feature_bundle{$_};
+}
+
 my %UniqueBundles; # "say state switch" => 5.10
 my %Aliases;       #  5.12 => 5.11
 for( sort keys %feature_bundle ) {
@@ -104,7 +113,7 @@ while (readline "perl.h") {
            length sprintf "%b", scalar keys %UniqueBundles;
        $bits =~ /1{$bits_needed}/
            or die "Not enough bits (need $bits_needed)"
-                . " in $bits (binary for $hex):\n\n$_\n";
+                . " in $bits (binary for $hex):\n\n$_\n ";
     }
     if ($Uni8Bit && $HintMask) { last }
 }
@@ -145,7 +154,7 @@ sub longest {
 
 print $pm "our %feature = (\n";
 my $width = length longest keys %feature;
-for(sort { length $a <=> length $b } keys %feature) {
+for(sort { length $a <=> length $b || $a cmp $b } keys %feature) {
     print $pm "    $_" . " "x($width-length)
            . " => 'feature_$feature{$_}',\n";
 }
@@ -166,6 +175,10 @@ for (sort keys %Aliases) {
        qq'\$feature_bundle{"$_"} = \$feature_bundle{"$Aliases{$_}"};\n';
 };
 
+print $pm "my \%experimental = (\n";
+print $pm "    $_ => 1,\n", for @experimental;
+print $pm ");\n";
+
 print $pm <<EOPM;
 
 our \$hint_shift   = $HintShift;
@@ -226,12 +239,15 @@ print $h <<'EOH';
 
 #define CURRENT_HINTS \
     (PL_curcop == &PL_compiling ? PL_hints : PL_curcop->cop_hints)
-#define CURRENT_FEATURE_BUNDLE (CURRENT_HINTS >> HINT_FEATURE_SHIFT)
+#define CURRENT_FEATURE_BUNDLE \
+    ((CURRENT_HINTS & HINT_FEATURE_MASK) >> HINT_FEATURE_SHIFT)
 
+/* Avoid using ... && Perl_feature_is_enabled(...) as that triggers a bug in
+   the HP-UX cc on PA-RISC */
 #define FEATURE_IS_ENABLED(name)                                       \
        ((CURRENT_HINTS                                                  \
           & HINT_LOCALIZE_HH)                                            \
-           && Perl_feature_is_enabled(aTHX_ STR_WITH_LEN(name)))
+           ? Perl_feature_is_enabled(aTHX_ STR_WITH_LEN(name)) : FALSE)
 /* The longest string we pass in.  */
 EOH
 
@@ -242,7 +258,7 @@ print $h <<EOL;
 EOL
 
 for (
-    sort { length $a <=> length $b } keys %feature
+    sort { length $a <=> length $b || $a cmp $b } keys %feature
 ) {
     my($first,$last) =
        map { (my $__ = uc) =~ y/.//d; $__ } @{$BundleRanges{$_}};
@@ -271,7 +287,7 @@ EOI
 
 EOH3
     }
-    else {
+    elsif ($first) {
        print $h <<EOH4;
 #define FEATURE_$NAME\_IS_ENABLED \\
     ( \\
@@ -282,6 +298,16 @@ EOH3
 
 EOH4
     }
+    else {
+       print $h <<EOH5;
+#define FEATURE_$NAME\_IS_ENABLED \\
+    ( \\
+       CURRENT_FEATURE_BUNDLE == FEATURE_BUNDLE_CUSTOM && \\
+        FEATURE_IS_ENABLED("$name") \\
+    )
+
+EOH5
+    }
 }
 
 print $h <<EOH;
@@ -329,7 +355,7 @@ read_only_bottom_close_and_rename($h);
 __END__
 package feature;
 
-our $VERSION = '1.25';
+our $VERSION = '1.31';
 
 FEATURES
 
@@ -368,7 +394,7 @@ pragma.)
 =head2 Lexical effect
 
 Like other pragmas (C<use strict>, for example), features have a lexical
-effect. C<use feature qw(foo)> will only make the feature "foo" available
+effect.  C<use feature qw(foo)> will only make the feature "foo" available
 from that point to the end of the enclosing block.
 
     {
@@ -390,7 +416,8 @@ has lexical effect.
     }
     say "Yet it is here.";
 
-C<no feature> with no features specified will turn off all features.
+C<no feature> with no features specified will reset to the default group.  To
+disable I<all> features (an unusual request!) use C<no feature ':all'>.
 
 =head1 AVAILABLE FEATURES
 
@@ -427,7 +454,8 @@ C<use feature 'unicode_strings'> tells the compiler to use Unicode semantics
 in all string operations executed within its scope (unless they are also
 within the scope of either C<use locale> or C<use bytes>).  The same applies
 to all regular expressions compiled within the scope, even if executed outside
-it.
+it.  It does not change the internal representation of strings, but only how
+they are interpreted.
 
 C<no feature 'unicode_strings'> tells the compiler to use the traditional
 Perl semantics wherein the native character set semantics is used unless it is
@@ -437,8 +465,8 @@ L<perlunicode/The "Unicode Bug"> for details.)  For this reason, if you are
 potentially using Unicode in your program, the
 C<use feature 'unicode_strings'> subpragma is B<strongly> recommended.
 
-This feature is available starting with Perl 5.12, but was not fully
-implemented until Perl 5.14.
+This feature is available starting with Perl 5.12; was almost fully
+implemented in Perl 5.14; and extended in Perl 5.16 to cover C<quotemeta>.
 
 =head2 The 'unicode_eval' and 'evalbytes' features
 
@@ -504,6 +532,29 @@ This feature is available under this name starting with Perl 5.16.  In
 previous versions, it was simply on all the time, and this pragma knew
 nothing about it.
 
+=head2 The 'fc' feature
+
+C<use feature 'fc'> tells the compiler to enable the C<fc> function,
+which implements Unicode casefolding.
+
+See L<perlfunc/fc> for details.
+
+This feature is available from Perl 5.16 onwards.
+
+=head2 The 'lexical_subs' feature
+
+B<WARNING>: This feature is still experimental and the implementation may
+change in future versions of Perl.  For this reason, F<feature.pm> will
+warn when you enable the feature, unless you have explicitly disabled the
+warning:
+
+    no warnings "experimental::lexical_subs";
+
+This enables declaration of subroutines via C<my sub foo>, C<state sub foo>
+and C<our sub foo> syntax.  See L<perlsub/Lexical Subroutines> for details.
+
+This feature is available from Perl 5.18 onwards.
+
 =head1 FEATURE BUNDLES
 
 It's possible to load multiple features together, using
@@ -550,7 +601,7 @@ the C<use VERSION> construct.  That is,
 
 will do an implicit
 
-    no feature;
+    no feature ':all';
     use feature ':5.10';
 
 and so on.  Note how the trailing sub-version
@@ -570,67 +621,44 @@ bundle is automatically loaded instead.
 
 =cut
 
-sub current_bundle {
-    my $bundle_number = $^H & $hint_mask;
-    return if $bundle_number == $hint_mask;
-    return $feature_bundle{@hint_bundles[$bundle_number >> $hint_shift]};
-}
-
-sub normalise_hints {
-    # Delete any keys that may be left over from last time.
-    delete @^H{ values(%feature) };
-    $^H |= $hint_mask;
-    for (@{+shift}) {
-       $^H{$feature{$_}} = 1;
-       $^H |= $hint_uni8bit if $_ eq 'unicode_strings';
-    }
-}
-
 sub import {
     my $class = shift;
-    if (@_ == 0) {
+
+    if (!@_) {
         croak("No features specified");
     }
-    if (my $features = current_bundle) {
-       # Features are enabled implicitly via bundle hints.
-       normalise_hints $features;
-    }
-    while (@_) {
-        my $name = shift(@_);
-        if (substr($name, 0, 1) eq ":") {
-            my $v = substr($name, 1);
-            if (!exists $feature_bundle{$v}) {
-                $v =~ s/^([0-9]+)\.([0-9]+).[0-9]+$/$1.$2/;
-                if (!exists $feature_bundle{$v}) {
-                    unknown_feature_bundle(substr($name, 1));
-                }
-            }
-            unshift @_, @{$feature_bundle{$v}};
-            next;
-        }
-        if (!exists $feature{$name}) {
-            unknown_feature($name);
-        }
-        $^H{$feature{$name}} = 1;
-        $^H |= $hint_uni8bit if $name eq 'unicode_strings';
-    }
+
+    __common(1, @_);
 }
 
 sub unimport {
     my $class = shift;
 
-    if (my $features = current_bundle) {
-       # Features are enabled implicitly via bundle hints.
-       normalise_hints $features;
-    }
-
-    # A bare C<no feature> should disable *all* features
+    # A bare C<no feature> should reset to the default bundle
     if (!@_) {
-        delete @^H{ values(%feature) };
-        $^H &= ~ $hint_uni8bit;
-        return;
+       $^H &= ~($hint_uni8bit|$hint_mask);
+       return;
     }
 
+    __common(0, @_);
+}
+
+
+sub __common {
+    my $import = shift;
+    my $bundle_number = $^H & $hint_mask;
+    my $features = $bundle_number != $hint_mask
+       && $feature_bundle{$hint_bundles[$bundle_number >> $hint_shift]};
+    if ($features) {
+       # Features are enabled implicitly via bundle hints.
+       # Delete any keys that may be left over from last time.
+       delete @^H{ values(%feature) };
+       $^H |= $hint_mask;
+       for (@$features) {
+           $^H{$feature{$_}} = 1;
+           $^H |= $hint_uni8bit if $_ eq 'unicode_strings';
+       }
+    }
     while (@_) {
         my $name = shift;
         if (substr($name, 0, 1) eq ":") {
@@ -644,10 +672,18 @@ sub unimport {
             unshift @_, @{$feature_bundle{$v}};
             next;
         }
-        if (!exists($feature{$name})) {
+        if (!exists $feature{$name}) {
             unknown_feature($name);
         }
-        else {
+       if ($import) {
+           $^H{$feature{$name}} = 1;
+           $^H |= $hint_uni8bit if $name eq 'unicode_strings';
+           if ($experimental{$name}) {
+               require warnings;
+               warnings::warnif("experimental::$name",
+                                "The $name feature is experimental");
+           }
+       } else {
             delete $^H{$feature{$name}};
             $^H &= ~ $hint_uni8bit if $name eq 'unicode_strings';
         }