This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Deprecate wide chars in logical string ops
[perl5.git] / Porting / corelist-perldelta.pl
index d34766c..048d571 100755 (executable)
@@ -34,6 +34,7 @@ corelist sections of the last perldelta and the next perldelta.
 
 Currently no information about Removed Modules is displayed in any of the
 modes.
+
 =cut
 
 my %sections = (
@@ -58,9 +59,7 @@ sub run {
   );
 
   # by default, compare latest two version in CoreList;
-  my @versions = sort keys %Module::CoreList::version;
-  my $old = $versions[-2];
-  my $new = $versions[-1];
+  my ($old, $new) = latest_two_perl_versions();
 
   # use the provided versions if present
   # @ARGV >=2 means [old_version] [new_version] [path/to/file]
@@ -68,7 +67,7 @@ sub run {
     ($old, $new) = (shift @ARGV, shift @ARGV);
     die "$old is an invalid version\n" if not exists
       $Module::CoreList::version{$old};
-    die "$new is an invalid verison\n" if not exists
+    die "$new is an invalid version\n" if not exists
       $Module::CoreList::version{$new};
   }
 
@@ -88,20 +87,37 @@ sub run {
   exit 0;
 }
 
+sub latest_two_perl_versions {
+
+  my @versions = sort keys %Module::CoreList::version;
+
+  my $new = pop @versions;
+
+  # If a fully-padded version number ends in a zero (as in "5.019010"), that
+  # version shows up in %Module::CoreList::version both with and without its
+  # trailing zeros. So skip all versions that are numerically equal to $new.
+  pop @versions while @versions && $versions[-1] == $new;
+
+  die "Too few distinct core versions in %Module::CoreList::version ?!\n"
+    if !@versions;
+
+  return $versions[-1], $new;
+}
+
 # Given two perl versions, it returns a list describing the core distributions that have changed.
 # The first three elements are hashrefs corresponding to new, updated, and removed modules
 # and are of the form (mostly, see the special remarks about removed):
 #   'Distribution Name' => ['Distribution Name', previous version number, current version number]
-# where the version number is undef if the distribution did not exist the fourth element is
-# an arrayref of core distribution names of those distribution for which it is unknown whether
-# they have changed and therefore need to be manually checked.
+# where the version number is undef if the distribution did not exist.
+# The fourth element is an arrayref of core distribution names of those distribution for which it
+# is unknown whether they have changed and therefore need to be manually checked.
 #
 # In most cases, the distribution name in %Modules corresponds to the module that is representative
 # of the distribution as listed in Module::CoreList. However, there are a few distribution names
-# that do not correspond to a module. %distToModules, has been created which maps the distribution
+# that do not correspond to a module. %distToModules has been created which maps the distribution
 # name to a representative module. The representative module was chosen by either looking at the
 # Makefile of the distribution or by seeing which module the distribution has been traditionally
-# listed under in past perldelta.
+# listed under in past perldeltas.
 #
 # There are a few distributions for which there is no single representative module (e.g. libnet).
 # These distributions are returned as the last element of the list.
@@ -109,7 +125,7 @@ sub run {
 # %Modules contains a final key, _PERLLIB, which contains a list of modules that are owned by p5p.
 # This list contains modules and pragmata that may also be present in Module::CoreList.
 # A list of modules are in the list @unclaimedModules, which were manually listed based on whether
-# they were independent modules and whether they have been listed in past perldelta.
+# they were independent modules and whether they have been listed in past perldeltas.
 # The pragmata were found by doing something like:
 #   say for sort grep { $_ eq lc $_ and !exists $Modules{$_}}
 #     keys %{$Module::CoreList::version{'5.019003'}}
@@ -140,7 +156,7 @@ sub corelist_delta {
   };
 
   my @unclaimedModules = qw/AnyDBM_File B B::Concise B::Deparse Benchmark Class::Struct Config::Extensions DB DBM_Filter Devel::Peek DirHandle DynaLoader English Errno ExtUtils::Embed ExtUtils::Miniperl ExtUtils::Typemaps ExtUtils::XSSymSet Fcntl File::Basename File::Compare File::Copy File::DosGlob File::Find File::Glob File::stat FileCache FileHandle FindBin GDBM_File Getopt::Std Hash::Util Hash::Util::FieldHash I18N::Langinfo IPC::Open3 NDBM_File ODBM_File Opcode PerlIO PerlIO::encoding PerlIO::mmap PerlIO::scalar PerlIO::via Pod::Functions Pod::Html POSIX SDBM_File SelectSaver Symbol Sys::Hostname Thread Tie::Array Tie::Handle Tie::Hash Tie::Hash::NamedCapture Tie::Memoize Tie::Scalar Tie::StdHandle Tie::SubstrHash Time::gmtime Time::localtime Time::tm Unicode::UCD UNIVERSAL User::grent User::pwent VMS::DCLsym VMS::Filespec VMS::Stdio XS::Typemap Win32CORE/;
-  my @unclaimedPragmata = qw/_charnames arybase attributes blib bytes charnames deprecate diagnostics encoding feature fields filetest inc::latest integer less locale mro open ops overload overloading re sigtrap sort strict subs utf8 vars vmsish/;
+  my @unclaimedPragmata = qw/arybase attributes blib bytes charnames deprecate diagnostics encoding feature fields filetest inc::latest integer less locale mro open ops overload overloading re sigtrap sort strict subs utf8 vars vmsish/;
   my @unclaimed = (@unclaimedModules, @unclaimedPragmata);
 
   my %distToModules = (
@@ -430,7 +446,7 @@ sub do_check {
   sub add_to_section {
     my ( $section, $data, $title ) = @_;
 
-    #undef is a valid version name in Module::CoreList so supress warnings about concatenating undef values
+    #undef is a valid version name in Module::CoreList so suppress warnings about concatenating undef values
     no warnings 'uninitialized';
     for ( values %{ $data->{$title} } ) {
       my ( $mod, $old_v, $new_v ) = @{$_};
@@ -463,7 +479,7 @@ sub do_check {
 
     # if we could not parse the module name, it will be uninitalized
     # in sort. This is not a problem as it will just result in these
-    # sections being placed near the begining of the section
+    # sections being placed near the beginning of the section
     no warnings 'uninitialized';
     $section->{items} =
       [ sort { lc $a->{name} cmp lc $b->{name} } @{ $section->{items} } ];
@@ -489,11 +505,11 @@ sub do_check {
       my ( $section_name, $title ) = @{$_};
 
       my $section = $sections{$section_name} // {
-          name            => $section_name,
-          preceeding_text => "=head2 $_->[0]\n=over 4\n",
-          following_text  => "=back\n",
-          items           => [],
-          manual          => 1
+          name           => $section_name,
+          preceding_text => "=head2 $_->[0]\n=over 4\n",
+          following_text => "=back\n",
+          items          => [],
+          manual         => 1
       };
 
       $section = update_section( $section, $data, $title );
@@ -505,7 +521,7 @@ sub do_check {
       my $items = reduce { no warnings 'once'; $a . $b->{text} }
         ( '', @{ $section->{items} } );
       $out .=
-        ( $section->{preceeding_text} // '' )
+        ( $section->{preceding_text} // '' )
         . $items
         . ( $section->{following_text} // '' );
     }
@@ -522,31 +538,34 @@ sub do_check {
     # will contain hashrefs corresponding to new, updated and removed
     # modules and pragmata keyed by section name
     # each section is hashref of the structure
-    #   preceeding_text => Text occuring before and including the over
-    #                      region containing the list of modules,
-    #   items           => [Arrayref of hashrefs corresponding to a module
-    #                       entry],
+    #   preceding_text => Text occurring before and including the over
+    #                     region containing the list of modules,
+    #   items          => [Arrayref of hashrefs corresponding to a module
+    #                      entry],
     #     an entry has the form:
     #       name => Module name or undef if the name could not be determined
     #       text => The text of the entry, including the item heading
     #
-    #   following_text  => Any text not corresponding to a module
-    #                      that occurs after the first module
+    #   following_text => Any text not corresponding to a module
+    #                     that occurs after the first module
     #
     # the sections are converted to a pod string by calling sections_to_pod()
     my %sections;
 
     # we are in the Modules_and_Pragmata's section
     my $in_Modules_and_Pragmata;
+
     # we are the Modules_and_Pragmata's section but have not
     # encountered any of the desired sections. We use this
     # flag to determine whether we should append the text to $out
     # or we need to delay appending until the module listings are
     # processed and instead append to $append_to_out
     my $in_Modules_and_Pragmata_preamble;
+
     my $done_processing_Modules_and_Pragmata;
 
     my $current_section;
+
     # $nested_element_level == 0 : not in an over region, treat lines as text
     # $nested_element_level == 1 : presumably in the top over region that
     #                              corresponds to the module listing. Treat
@@ -554,6 +573,7 @@ sub do_check {
     # $nested_element_level > 1  : we only consider these values when we are in an item
     #                              We treat lines as the text of the current item.
     my $nested_element_level = 0;
+
     my $current_item;
     my $need_to_parse_module_name;
 
@@ -610,13 +630,13 @@ sub do_check {
           }
           my $title = get_section_name_from_heading($name);
           if ( exists $sections{$title} ) {
-            die "$name occured twice at line no. $.";
+            die "$name occurred twice at line no. $.";
           }
-          $current_section                    = {};
-          $current_section->{name}            = $title;
-          $current_section->{preceeding_text} = $_;
-          $current_section->{items}           = [];
-          $nested_element_level               = 0;
+          $current_section                   = {};
+          $current_section->{name}           = $title;
+          $current_section->{preceding_text} = $_;
+          $current_section->{items}          = [];
+         $nested_element_level               = 0;
           next;
         }
 
@@ -643,7 +663,7 @@ sub do_check {
             $current_section->{following_text} .= $_;
           }
           else {
-            $current_section->{preceeding_text} .= $_;
+            $current_section->{preceding_text} .= $_;
           }
           next;
         }
@@ -705,7 +725,7 @@ sub do_check {
         }
 
         if ( scalar @{ $current_section->{items} } == 0 ) {
-          $current_section->{preceeding_text} .= $_;
+          $current_section->{preceding_text} .= $_;
         }
         else {
           $current_section->{following_text} .= $_;
@@ -813,7 +833,7 @@ sub do_check {
       #   from VERSION_NUMBER to VERSION_NUMBER and MODULE from VERSION_NUMBER to VERSION_NUMBER
       #   from VERSION_NUMBER to VERSION_NUMBER, and MODULE from VERSION_NUMBER to VERSION_NUMBER
       #
-      # some perldelta contain more than one module listed in an entry, this only attempts to match the
+      # some perldeltas contain more than one module listed in an entry, this only attempts to match the
       # first module
       my ($old, $new) = $second =~
           /from\s+(?:version\s+)?(\d[^\s]+)\s+to\s+(?:version\s+)?(\d[^\s,]+?)(?=[\s,]|\.\s|\.$|$).*/s;