(perl #131836) avoid a use-after-free after parsing a "sub" keyword
[perl.git] / Porting / manifest_lib.pl
1 #!/usr/bin/perl
2
3 use strict;
4
5 =head1 NAME
6
7 Porting/manifest_lib.pl - functions for managing manifests
8
9 =head1 SYNOPSIS
10
11     require './Porting/manifest_lib.pl';
12
13 =head1 DESCRIPTION
14
15 =head2 C<sort_manifest>
16
17 Treats its arguments as (chomped) lines from a MANIFEST file, and returns that
18 listed sorted appropriately.
19
20 =cut
21
22 # Try to get a sane sort. case insensitive, more or less
23 # sorted such that path components are compared independently,
24 # and so that lib/Foo/Bar sorts before lib/Foo-Alpha/Baz
25 # and so that lib/Foo/Bar.pm sorts before lib/Foo/Bar/Alpha.pm
26 # and so that configure and Configure sort together.
27 sub sort_manifest {
28     return
29     # case insensitive sorting of directory components independently.
30     map { $_->[0] } # extract the full line
31     sort {
32         $a->[1] cmp $b->[1] || # sort in order of munged filename
33         $a->[0] cmp $b->[0]    # then by the exact text in full line
34     }
35     map {
36         # split out the filename and the description
37         my ($f) = split /\s+/, $_, 2;
38         # lc the filename so Configure and configure sort together in the list
39         my $m= lc $f; # $m for munged
40         # replace slashes by nulls, this makes short directory names sort before
41         # longer ones, such as "foo/" sorting before "foo-bar/"
42         $m =~ s!/!\0!g;
43         # replace the extension (only one) by null null extension.
44         # this puts any foo/blah.ext before any files in foo/blah/
45         $m =~ s!(\.[^.]+\z)!\0\0$1!;
46         # return the original string, and the munged filename
47         [ $_, $m ];
48     } @_;
49 }
50
51 1;
52
53 # ex: set ts=8 sts=4 sw=4 et: