This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
00967f223f7a0eeb41e0106443e784f78fdefb43
[perl5.git] / Porting / checkcfgvar.pl
1 #!/usr/bin/perl
2
3 # Check that the various config.sh-clones have (at least) all the
4 # same symbols as the top-level config_h.SH so that the (potentially)
5 # needed symbols are not lagging after how Configure thinks the world
6 # is laid out.
7 #
8 # VMS is probably not handled properly here, due to their own
9 # rather elaborate DCL scripting.
10 #
11
12 use strict;
13 use warnings;
14 use autodie;
15
16 sub usage
17 {
18     my $err = shift and select STDERR;
19     print "usage: $0 [--list] [--regen]\n";
20     exit $err;
21     } # usage
22
23 use Getopt::Long;
24 my $opt_l = 0;
25 my $opt_r = 0;
26 GetOptions (
27     "help|?"    => sub { usage (0); },
28     "l|list!"   => \$opt_l,
29     "regen"     => \$opt_r,
30     ) or usage (1);
31
32 require 'regen/regen_lib.pl' if $opt_r;
33
34 my $MASTER_CFG = "config_h.SH";
35 # Inclusive bounds on the main part of the file, $section == 1 below:
36 my $first = qr/^Author=/;
37 my $last = qr/^zip=/;
38
39 my @CFG = (
40            # we check from MANIFEST whether they are expected to be present.
41            # We can't base our check on $], because that's the version of the
42            # perl that we are running, not the version of the source tree.
43            "Cross/config.sh-arm-linux",
44            "epoc/config.sh",
45            "NetWare/config.wc",
46            "symbian/config.sh",
47            "uconfig.sh",
48            "uconfig64.sh",
49            "plan9/config_sh.sample",
50            "win32/config.gc",
51            "win32/config.gc64",
52            "win32/config.gc64nox",
53            "win32/config.vc",
54            "win32/config.vc64",
55            "win32/config.ce",
56            "configure.com",
57            "Porting/config.sh",
58           );
59
60 my @MASTER_CFG;
61 {
62     my %seen;
63     open my $fh, '<', $MASTER_CFG;
64     while (<$fh>) {
65         while (/[^\\]\$([a-z]\w+)/g) {
66             my $v = $1;
67             next if $v =~ /^(CONFIG_H|CONFIG_SH)$/;
68             $seen{$v}++;
69         }
70     }
71     close $fh;
72     @MASTER_CFG = sort keys %seen;
73 }
74
75 my %MANIFEST;
76
77 {
78     open my $fh, '<', 'MANIFEST';
79     while (<$fh>) {
80         $MANIFEST{$1}++ if /^(.+?)\t/;
81     }
82     close $fh;
83 }
84
85 for my $cfg (sort @CFG) {
86     unless (exists $MANIFEST{$cfg}) {
87         print STDERR "[skipping not-expected '$cfg']\n";
88         next;
89     }
90     my %cfg;
91     my $section = 0;
92     my @lines;
93
94     open my $fh, '<', $cfg;
95
96     if ($cfg eq 'configure.com') {
97         ++$cfg{startperl}; # Cheat.
98
99         while (<$fh>) {
100             next if /^\#/ || /^\s*$/ || /^\:/;
101             s/(\s*!.*|\s*)$//; # remove trailing comments or whitespace
102             ++$cfg{$1} if /^\$\s+WC "(\w+)='(?:.*)'"$/;
103         }
104     } else {
105         while (<$fh>) {
106             if ($_ =~ $first) {
107                 die "$cfg:$.:section=$section:$_" unless $section == 0;
108                 $section = 1;
109             }
110             push @{$lines[$section]}, $_;
111             next if /^\#/ || /^\s*$/ || /^\:/;
112             if ($_ =~ $last) {
113                 die "$cfg:$.:section=$section:$_" unless $section == 1;
114                 $section = 2;
115             }
116             # foo='bar'
117             # foo=bar
118             # (optionally with a trailing comment)
119             if (/^(\w+)=(?:'.*'|[^'].*)(?: #.*)?$/) {
120                 ++$cfg{$1};
121             } else {
122                 warn "$cfg:$.:$_";
123             }
124         }
125     }
126     close $fh;
127
128     my $problems;
129     if ($cfg ne 'configure.com') {
130         if (join("", @{$lines[1]}) ne join("", sort @{$lines[1]})) {
131             ++$problems;
132             if ($opt_r) {
133                 @{$lines[1]} = sort @{$lines[1]};
134             } elsif ($opt_l) {
135                 print "$cfg\n";
136             }
137             else {
138                 print "$cfg: unsorted\n";
139             }
140         }
141     }
142     for my $v (@MASTER_CFG) {
143         exists $cfg{$v} and next;
144         if ($opt_l) {
145             # print the name once, for the first problem we encounter.
146             print "$cfg\n" unless $problems++;
147         }
148         else {
149             print "$cfg: missing '$v'\n";
150         }
151     }
152     if ($problems && $opt_r) {
153         my $fh = open_new($cfg);
154         print $fh @{$_} foreach @lines;
155         close_and_rename($fh);
156     }
157 }