xref: /openbsd/gnu/usr.bin/perl/configpm (revision 8932bfb7)
1#!./miniperl -w
2#
3# configpm
4#
5# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
6# 2002, 2003, 2004, 2005, 2006, 2007 Larry Wall and others.
7#
8#
9# Regenerate the files
10#
11#    lib/Config.pm
12#    lib/Config_heavy.pl
13#    lib/Config.pod
14#    lib/Cross.pm (optionally)
15#
16#
17# from the contents of the static files
18#
19#    Porting/Glossary
20#    myconfig.SH
21#
22# and from the contents of the Configure-generated file
23#
24#    config.sh
25#
26# Note that output directory is xlib/[cross-name]/ for cross-compiling
27#
28# It will only update Config.pm and Config_heavy.pl if the contents of
29# either file would be different. Note that *both* files are updated in
30# this case, since for example an extension makefile that has a dependency
31# on Config.pm should trigger even if only Config_heavy.pl has changed.
32
33sub usage { die <<EOF }
34usage: $0  [ options ]
35    --cross=PLATFORM    cross-compile for a different platform
36    --no-glossary       don't include Porting/Glossary in lib/Config.pod
37    --chdir=dir         change directory before writing files
38EOF
39
40use strict;
41use vars qw(%Config $Config_SH_expanded);
42
43my $how_many_common = 22;
44
45# commonly used names to precache (and hence lookup fastest)
46my %Common;
47
48while ($how_many_common--) {
49    $_ = <DATA>;
50    chomp;
51    /^(\S+):\s*(\d+)$/ or die "Malformed line '$_'";
52    $Common{$1} = $1;
53}
54
55# names of things which may need to have slashes changed to double-colons
56my %Extensions = map {($_,$_)}
57                 qw(dynamic_ext static_ext extensions known_extensions);
58
59# libpaths that should be truncated after the first path element
60my %Libpathtrunc = map {($_,$_)}
61                   qw(archlib archlibexp privlib privlibexp sitearch sitearchexp
62                      sitelib sitelibexp);
63
64# allowed opts as well as specifies default and initial values
65my %Allowed_Opts = (
66    'cross'    => '', # --cross=PLATFORM - crosscompiling for PLATFORM
67    'glossary' => 1,  # --no-glossary  - no glossary file inclusion,
68                      #                  for compactness
69    'chdir'    => '', # --chdir=dir    - change directory before writing files
70);
71
72sub opts {
73    # user specified options
74    my %given_opts = (
75        # --opt=smth
76        (map {/^--([\-_\w]+)=(.*)$/} @ARGV),
77        # --opt --no-opt --noopt
78        (map {/^no-?(.*)$/i?($1=>0):($_=>1)} map {/^--([\-_\w]+)$/} @ARGV),
79    );
80
81    my %opts = (%Allowed_Opts, %given_opts);
82
83    for my $opt (grep {!exists $Allowed_Opts{$_}} keys %given_opts) {
84        warn "option '$opt' is not recognized";
85	usage;
86    }
87    @ARGV = grep {!/^--/} @ARGV;
88
89    return %opts;
90}
91
92
93my %Opts = opts();
94
95if ($Opts{chdir}) {
96    chdir $Opts{chdir} or die "$0: could not chdir $Opts{chdir}: $!"
97}
98
99my ($Config_SH, $Config_PM, $Config_heavy, $Config_POD);
100my $Glossary = 'Porting/Glossary';
101
102if ($Opts{cross}) {
103  # creating cross-platform config file
104  mkdir "xlib";
105  mkdir "xlib/$Opts{cross}";
106  $Config_PM = "xlib/$Opts{cross}/Config.pm";
107  $Config_POD = "xlib/$Opts{cross}/Config.pod";
108  $Config_SH = "Cross/config-$Opts{cross}.sh";
109}
110else {
111  $Config_PM = "lib/Config.pm";
112  $Config_POD = "lib/Config.pod";
113  $Config_SH = "config.sh";
114}
115($Config_heavy = $Config_PM) =~ s/\.pm$/_heavy.pl/;
116die "Can't automatically determine name for Config_heavy.pl from '$Config_PM'"
117  if $Config_heavy eq $Config_PM;
118
119my $config_txt;
120my $heavy_txt;
121
122$heavy_txt .= <<'ENDOFBEG';
123# This file was created by configpm when Perl was built. Any changes
124# made to this file will be lost the next time perl is built.
125
126package Config;
127use strict;
128# use warnings; Pulls in Carp
129# use vars pulls in Carp
130
131sub _V {
132    my ($bincompat, $non_bincompat, $date, @patches) = Internals::V();
133
134    my $opts = join ' ', sort split ' ', "$bincompat $non_bincompat";
135
136    # wrap at 76 columns.
137
138    $opts =~ s/(?=.{53})(.{1,53}) /$1\n                        /mg;
139
140    print Config::myconfig();
141    if ($^O eq 'VMS') {
142        print "\nCharacteristics of this PERLSHR image: \n";
143    } else {
144        print "\nCharacteristics of this binary (from libperl): \n";
145    }
146
147    print "  Compile-time options: $opts\n";
148
149    if (@patches) {
150        print "  Locally applied patches:\n";
151        print "\t$_\n" foreach @patches;
152    }
153
154    print "  Built under $^O\n";
155
156    print "  $date\n" if defined $date;
157
158    my @env = map { "$_=\"$ENV{$_}\"" } sort grep {/^PERL/} keys %ENV;
159    push @env, "CYGWIN=\"$ENV{CYGWIN}\"" if $^O eq 'cygwin';
160
161    if (@env) {
162        print "  \%ENV:\n";
163        print "    $_\n" foreach @env;
164    }
165    print "  \@INC:\n";
166    print "    $_\n" foreach @INC;
167}
168
169ENDOFBEG
170
171my $myver = sprintf "%vd", $^V;
172
173$config_txt .= sprintf <<'ENDOFBEG', ($myver) x 3;
174# This file was created by configpm when Perl was built. Any changes
175# made to this file will be lost the next time perl is built.
176
177# for a description of the variables, please have a look at the
178# Glossary file, as written in the Porting folder, or use the url:
179# http://perl5.git.perl.org/perl.git/blob/HEAD:/Porting/Glossary
180
181package Config;
182use strict;
183# use warnings; Pulls in Carp
184# use vars pulls in Carp
185@Config::EXPORT = qw(%%Config);
186@Config::EXPORT_OK = qw(myconfig config_sh config_vars config_re);
187
188# Need to stub all the functions to make code such as print Config::config_sh
189# keep working
190
191sub myconfig;
192sub config_sh;
193sub config_vars;
194sub config_re;
195
196my %%Export_Cache = map {($_ => 1)} (@Config::EXPORT, @Config::EXPORT_OK);
197
198our %%Config;
199
200# Define our own import method to avoid pulling in the full Exporter:
201sub import {
202    my $pkg = shift;
203    @_ = @Config::EXPORT unless @_;
204
205    my @funcs = grep $_ ne '%%Config', @_;
206    my $export_Config = @funcs < @_ ? 1 : 0;
207
208    no strict 'refs';
209    my $callpkg = caller(0);
210    foreach my $func (@funcs) {
211	die sprintf qq{"%%s" is not exported by the %%s module\n},
212	    $func, __PACKAGE__ unless $Export_Cache{$func};
213	*{$callpkg.'::'.$func} = \&{$func};
214    }
215
216    *{"$callpkg\::Config"} = \%%Config if $export_Config;
217    return;
218}
219
220die "Perl lib version (%s) doesn't match executable version ($])"
221    unless $^V;
222
223$^V eq %s
224    or die "Perl lib version (%s) doesn't match executable version (" .
225	sprintf("v%%vd",$^V) . ")";
226
227ENDOFBEG
228
229
230my @non_v    = ();
231my @v_others = ();
232my $in_v     = 0;
233my %Data     = ();
234
235
236my %seen_quotes;
237{
238  my ($name, $val);
239  open(CONFIG_SH, $Config_SH) || die "Can't open $Config_SH: $!";
240  while (<CONFIG_SH>) {
241    next if m:^#!/bin/sh:;
242
243    # Catch PERL_CONFIG_SH=true and PERL_VERSION=n line from Configure.
244    s/^(\w+)=(true|\d+)\s*$/$1='$2'\n/ or m/^(\w+)='(.*)'$/;
245    my($k, $v) = ($1, $2);
246
247    # grandfather PATCHLEVEL and SUBVERSION and CONFIG
248    if ($k) {
249	if ($k eq 'PERL_VERSION') {
250	    push @v_others, "PATCHLEVEL='$v'\n";
251	}
252	elsif ($k eq 'PERL_SUBVERSION') {
253	    push @v_others, "SUBVERSION='$v'\n";
254	}
255	elsif ($k eq 'PERL_CONFIG_SH') {
256	    push @v_others, "CONFIG='$v'\n";
257	}
258    }
259
260    # We can delimit things in config.sh with either ' or ".
261    unless ($in_v or m/^(\w+)=(['"])(.*\n)/){
262	push(@non_v, "#$_"); # not a name='value' line
263	next;
264    }
265    my $quote = $2;
266    if ($in_v) {
267        $val .= $_;
268    }
269    else {
270        ($name,$val) = ($1,$3);
271    }
272    $in_v = $val !~ /$quote\n/;
273    next if $in_v;
274
275    # XXX - should use PERLLIB_SEP, not hard-code ':'
276    $val =~ s/^([^:]+).*${quote}\w*$/$1${quote}/ if $Libpathtrunc{$name};
277
278    s,/,::,g if $Extensions{$name};
279
280    $val =~ s/$quote\n?\z//;
281
282    my $line = "$name=$quote$val$quote\n";
283    push(@v_others, $line);
284    $seen_quotes{$quote}++;
285  }
286  close CONFIG_SH;
287}
288
289# This is somewhat grim, but I want the code for parsing config.sh here and
290# now so that I can expand $Config{ivsize} and $Config{ivtype}
291
292my $fetch_string = <<'EOT';
293
294# Search for it in the big string
295sub fetch_string {
296    my($self, $key) = @_;
297
298EOT
299
300if ($seen_quotes{'"'}) {
301    # We need the full ' and " code
302    $fetch_string .= <<'EOT';
303    my $quote_type = "'";
304    my $marker = "$key=";
305
306    # Check for the common case, ' delimited
307    my $start = index($Config_SH_expanded, "\n$marker$quote_type");
308    # If that failed, check for " delimited
309    if ($start == -1) {
310        $quote_type = '"';
311        $start = index($Config_SH_expanded, "\n$marker$quote_type");
312    }
313EOT
314} else {
315    $fetch_string .= <<'EOT';
316    # We only have ' delimted.
317    my $start = index($Config_SH_expanded, "\n$key=\'");
318EOT
319}
320$fetch_string .= <<'EOT';
321    # Start can never be -1 now, as we've rigged the long string we're
322    # searching with an initial dummy newline.
323    return undef if $start == -1;
324
325    $start += length($key) + 3;
326
327EOT
328if (!$seen_quotes{'"'}) {
329    # Don't need the full ' and " code, or the eval expansion.
330    $fetch_string .= <<'EOT';
331    my $value = substr($Config_SH_expanded, $start,
332                       index($Config_SH_expanded, "'\n", $start)
333		       - $start);
334EOT
335} else {
336    $fetch_string .= <<'EOT';
337    my $value = substr($Config_SH_expanded, $start,
338                       index($Config_SH_expanded, "$quote_type\n", $start)
339		       - $start);
340
341    # If we had a double-quote, we'd better eval it so escape
342    # sequences and such can be interpolated. Since the incoming
343    # value is supposed to follow shell rules and not perl rules,
344    # we escape any perl variable markers
345    if ($quote_type eq '"') {
346	$value =~ s/\$/\\\$/g;
347	$value =~ s/\@/\\\@/g;
348	eval "\$value = \"$value\"";
349    }
350EOT
351}
352$fetch_string .= <<'EOT';
353    # So we can say "if $Config{'foo'}".
354    $value = undef if $value eq 'undef';
355    $self->{$key} = $value; # cache it
356}
357EOT
358
359eval $fetch_string;
360die if $@;
361
362# Calculation for the keys for byteorder
363# This is somewhat grim, but I need to run fetch_string here.
364our $Config_SH_expanded = join "\n", '', @v_others;
365
366my $t = fetch_string ({}, 'ivtype');
367my $s = fetch_string ({}, 'ivsize');
368
369# byteorder does exist on its own but we overlay a virtual
370# dynamically recomputed value.
371
372# However, ivtype and ivsize will not vary for sane fat binaries
373
374my $f = $t eq 'long' ? 'L!' : $s == 8 ? 'Q': 'I';
375
376my $byteorder_code;
377if ($s == 4 || $s == 8) {
378    my $list = join ',', reverse(2..$s);
379    my $format = 'a'x$s;
380    $byteorder_code = <<"EOT";
381
382my \$i = 0;
383foreach my \$c ($list) { \$i |= ord(\$c); \$i <<= 8 }
384\$i |= ord(1);
385our \$byteorder = join('', unpack('$format', pack('$f', \$i)));
386EOT
387} else {
388    $byteorder_code = "our \$byteorder = '?'x$s;\n";
389}
390
391my @need_relocation;
392
393if (fetch_string({},'userelocatableinc')) {
394    foreach my $what (qw(prefixexp
395
396			 archlibexp
397			 html1direxp
398			 html3direxp
399			 man1direxp
400			 man3direxp
401			 privlibexp
402			 scriptdirexp
403			 sitearchexp
404			 sitebinexp
405			 sitehtml1direxp
406			 sitehtml3direxp
407			 sitelibexp
408			 siteman1direxp
409			 siteman3direxp
410			 sitescriptexp
411			 vendorarchexp
412			 vendorbinexp
413			 vendorhtml1direxp
414			 vendorhtml3direxp
415			 vendorlibexp
416			 vendorman1direxp
417			 vendorman3direxp
418			 vendorscriptexp
419
420			 siteprefixexp
421			 sitelib_stem
422			 vendorlib_stem
423
424			 installarchlib
425			 installhtml1dir
426			 installhtml3dir
427			 installman1dir
428			 installman3dir
429			 installprefix
430			 installprefixexp
431			 installprivlib
432			 installscript
433			 installsitearch
434			 installsitebin
435			 installsitehtml1dir
436			 installsitehtml3dir
437			 installsitelib
438			 installsiteman1dir
439			 installsiteman3dir
440			 installsitescript
441			 installvendorarch
442			 installvendorbin
443			 installvendorhtml1dir
444			 installvendorhtml3dir
445			 installvendorlib
446			 installvendorman1dir
447			 installvendorman3dir
448			 installvendorscript
449			 )) {
450	push @need_relocation, $what if fetch_string({}, $what) =~ m!^\.\.\./!;
451    }
452}
453
454my %need_relocation;
455@need_relocation{@need_relocation} = @need_relocation;
456
457# This can have .../ anywhere:
458if (fetch_string({}, 'otherlibdirs') =~ m!\.\.\./!) {
459    $need_relocation{otherlibdirs} = 'otherlibdirs';
460}
461
462my $relocation_code = <<'EOT';
463
464sub relocate_inc {
465  my $libdir = shift;
466  return $libdir unless $libdir =~ s!^\.\.\./!!;
467  my $prefix = $^X;
468  if ($prefix =~ s!/[^/]*$!!) {
469    while ($libdir =~ m!^\.\./!) {
470      # Loop while $libdir starts "../" and $prefix still has a trailing
471      # directory
472      last unless $prefix =~ s!/([^/]+)$!!;
473      # but bail out if the directory we picked off the end of $prefix is .
474      # or ..
475      if ($1 eq '.' or $1 eq '..') {
476	# Undo! This should be rare, hence code it this way rather than a
477	# check each time before the s!!! above.
478	$prefix = "$prefix/$1";
479	last;
480      }
481      # Remove that leading ../ and loop again
482      substr ($libdir, 0, 3, '');
483    }
484    $libdir = "$prefix/$libdir";
485  }
486  $libdir;
487}
488EOT
489
490if (%need_relocation) {
491  my $relocations_in_common;
492  # otherlibdirs only features in the hash
493  foreach (keys %need_relocation) {
494    $relocations_in_common++ if $Common{$_};
495  }
496  if ($relocations_in_common) {
497    $config_txt .= $relocation_code;
498  } else {
499    $heavy_txt .= $relocation_code;
500  }
501}
502
503$heavy_txt .= join('', @non_v) . "\n";
504
505# copy config summary format from the myconfig.SH script
506$heavy_txt .= "our \$summary = <<'!END!';\n";
507open(MYCONFIG,"<myconfig.SH") || die "open myconfig.SH failed: $!";
5081 while defined($_ = <MYCONFIG>) && !/^Summary of/;
509do { $heavy_txt .= $_ } until !defined($_ = <MYCONFIG>) || /^\s*$/;
510close(MYCONFIG);
511
512$heavy_txt .= "\n!END!\n" . <<'EOT';
513my $summary_expanded;
514
515sub myconfig {
516    return $summary_expanded if $summary_expanded;
517    ($summary_expanded = $summary) =~ s{\$(\w+)}
518		 {
519			my $c;
520			if ($1 eq 'git_ancestor_line') {
521				if ($Config::Config{git_ancestor}) {
522					$c= "\n  Ancestor: $Config::Config{git_ancestor}";
523				} else {
524					$c= "";
525				}
526			} else {
527                     		$c = $Config::Config{$1};
528			}
529			defined($c) ? $c : 'undef'
530		}ge;
531    $summary_expanded;
532}
533
534local *_ = \my $a;
535$_ = <<'!END!';
536EOT
537
538$heavy_txt .= join('', sort @v_others) . "!END!\n";
539
540# Only need the dynamic byteorder code in Config.pm if 'byteorder' is one of
541# the precached keys
542if ($Common{byteorder}) {
543    $config_txt .= $byteorder_code;
544} else {
545    $heavy_txt .= $byteorder_code;
546}
547
548if (@need_relocation) {
549$heavy_txt .= 'foreach my $what (qw(' . join (' ', @need_relocation) .
550      ")) {\n" . <<'EOT';
551    s/^($what=)(['"])(.*?)\2/$1 . $2 . relocate_inc($3) . $2/me;
552}
553EOT
554# Currently it only makes sense to do the ... relocation on Unix, so there's
555# no need to emulate the "which separator for this platform" logic in perl.c -
556# ':' will always be applicable
557if ($need_relocation{otherlibdirs}) {
558$heavy_txt .= << 'EOT';
559s{^(otherlibdirs=)(['"])(.*?)\2}
560 {$1 . $2 . join ':', map {relocate_inc($_)} split ':', $3 . $2}me;
561EOT
562}
563}
564
565$heavy_txt .= <<'EOT';
566s/(byteorder=)(['"]).*?\2/$1$2$Config::byteorder$2/m;
567
568my $config_sh_len = length $_;
569
570our $Config_SH_expanded = "\n$_" . << 'EOVIRTUAL';
571EOT
572
573foreach my $prefix (qw(ccflags ldflags)) {
574    my $value = fetch_string ({}, $prefix);
575    my $withlargefiles = fetch_string ({}, $prefix . "_uselargefiles");
576    if (defined $withlargefiles) {
577        $value =~ s/\Q$withlargefiles\E\b//;
578        $heavy_txt .= "${prefix}_nolargefiles='$value'\n";
579    }
580}
581
582foreach my $prefix (qw(libs libswanted)) {
583    my $value = fetch_string ({}, $prefix);
584    my $withlf = fetch_string ({}, 'libswanted_uselargefiles');
585    next unless defined $withlf;
586    my @lflibswanted
587       = split(' ', fetch_string ({}, 'libswanted_uselargefiles'));
588    if (@lflibswanted) {
589	my %lflibswanted;
590	@lflibswanted{@lflibswanted} = ();
591	if ($prefix eq 'libs') {
592	    my @libs = grep { /^-l(.+)/ &&
593                            not exists $lflibswanted{$1} }
594		                    split(' ', fetch_string ({}, 'libs'));
595	    $value = join(' ', @libs);
596	} else {
597	    my @libswanted = grep { not exists $lflibswanted{$_} }
598	                          split(' ', fetch_string ({}, 'libswanted'));
599	    $value = join(' ', @libswanted);
600	}
601    }
602    $heavy_txt .= "${prefix}_nolargefiles='$value'\n";
603}
604
605$heavy_txt .= "EOVIRTUAL\n";
606
607$heavy_txt .= <<'ENDOFGIT';
608eval {
609	# do not have hairy conniptions if this isnt available
610	require 'Config_git.pl';
611	$Config_SH_expanded .= $Config::Git_Data;
612	1;
613} or warn "Warning: failed to load Config_git.pl, something strange about this perl...\n";
614ENDOFGIT
615
616$heavy_txt .= $fetch_string;
617
618$config_txt .= <<'ENDOFEND';
619
620sub FETCH {
621    my($self, $key) = @_;
622
623    # check for cached value (which may be undef so we use exists not defined)
624    return $self->{$key} if exists $self->{$key};
625
626    return $self->fetch_string($key);
627}
628ENDOFEND
629
630$heavy_txt .= <<'ENDOFEND';
631
632my $prevpos = 0;
633
634sub FIRSTKEY {
635    $prevpos = 0;
636    substr($Config_SH_expanded, 1, index($Config_SH_expanded, '=') - 1 );
637}
638
639sub NEXTKEY {
640ENDOFEND
641if ($seen_quotes{'"'}) {
642$heavy_txt .= <<'ENDOFEND';
643    # Find out how the current key's quoted so we can skip to its end.
644    my $quote = substr($Config_SH_expanded,
645		       index($Config_SH_expanded, "=", $prevpos)+1, 1);
646    my $pos = index($Config_SH_expanded, qq($quote\n), $prevpos) + 2;
647ENDOFEND
648} else {
649    # Just ' quotes, so it's much easier.
650$heavy_txt .= <<'ENDOFEND';
651    my $pos = index($Config_SH_expanded, qq('\n), $prevpos) + 2;
652ENDOFEND
653}
654$heavy_txt .= <<'ENDOFEND';
655    my $len = index($Config_SH_expanded, "=", $pos) - $pos;
656    $prevpos = $pos;
657    $len > 0 ? substr($Config_SH_expanded, $pos, $len) : undef;
658}
659
660sub EXISTS {
661    return 1 if exists($_[0]->{$_[1]});
662
663    return(index($Config_SH_expanded, "\n$_[1]='") != -1
664ENDOFEND
665if ($seen_quotes{'"'}) {
666$heavy_txt .= <<'ENDOFEND';
667           or index($Config_SH_expanded, "\n$_[1]=\"") != -1
668ENDOFEND
669}
670$heavy_txt .= <<'ENDOFEND';
671          );
672}
673
674sub STORE  { die "\%Config::Config is read-only\n" }
675*DELETE = \&STORE;
676*CLEAR  = \&STORE;
677
678
679sub config_sh {
680    substr $Config_SH_expanded, 1, $config_sh_len;
681}
682
683sub config_re {
684    my $re = shift;
685    return map { chomp; $_ } grep eval{ /^(?:$re)=/ }, split /^/,
686    $Config_SH_expanded;
687}
688
689sub config_vars {
690    # implements -V:cfgvar option (see perlrun -V:)
691    foreach (@_) {
692	# find optional leading, trailing colons; and query-spec
693	my ($notag,$qry,$lncont) = m/^(:)?(.*?)(:)?$/;	# flags fore and aft,
694	# map colon-flags to print decorations
695	my $prfx = $notag ? '': "$qry=";		# tag-prefix for print
696	my $lnend = $lncont ? ' ' : ";\n";		# line ending for print
697
698	# all config-vars are by definition \w only, any \W means regex
699	if ($qry =~ /\W/) {
700	    my @matches = config_re($qry);
701	    print map "$_$lnend", @matches ? @matches : "$qry: not found"		if !$notag;
702	    print map { s/\w+=//; "$_$lnend" } @matches ? @matches : "$qry: not found"	if  $notag;
703	} else {
704	    my $v = (exists $Config::Config{$qry}) ? $Config::Config{$qry}
705						   : 'UNKNOWN';
706	    $v = 'undef' unless defined $v;
707	    print "${prfx}'${v}'$lnend";
708	}
709    }
710}
711
712# Called by the real AUTOLOAD
713sub launcher {
714    undef &AUTOLOAD;
715    goto \&$Config::AUTOLOAD;
716}
717
7181;
719ENDOFEND
720
721if ($^O eq 'os2') {
722    $config_txt .= <<'ENDOFSET';
723my %preconfig;
724if ($OS2::is_aout) {
725    my ($value, $v) = $Config_SH_expanded =~ m/^used_aout='(.*)'\s*$/m;
726    for (split ' ', $value) {
727        ($v) = $Config_SH_expanded =~ m/^aout_$_='(.*)'\s*$/m;
728        $preconfig{$_} = $v eq 'undef' ? undef : $v;
729    }
730}
731$preconfig{d_fork} = undef unless $OS2::can_fork; # Some funny cases can't
732sub TIEHASH { bless {%preconfig} }
733ENDOFSET
734    # Extract the name of the DLL from the makefile to avoid duplication
735    my ($f) = grep -r, qw(GNUMakefile Makefile);
736    my $dll;
737    if (open my $fh, '<', $f) {
738	while (<$fh>) {
739	    $dll = $1, last if /^PERL_DLL_BASE\s*=\s*(\S*)\s*$/;
740	}
741    }
742    $config_txt .= <<ENDOFSET if $dll;
743\$preconfig{dll_name} = '$dll';
744ENDOFSET
745} else {
746    $config_txt .= <<'ENDOFSET';
747sub TIEHASH {
748    bless $_[1], $_[0];
749}
750ENDOFSET
751}
752
753foreach my $key (keys %Common) {
754    my $value = fetch_string ({}, $key);
755    # Is it safe on the LHS of => ?
756    my $qkey = $key =~ /^[A-Za-z_][A-Za-z0-9_]*$/ ? $key : "'$key'";
757    if (defined $value) {
758	# Quote things for a '' string
759	$value =~ s!\\!\\\\!g;
760	$value =~ s!'!\\'!g;
761	$value = "'$value'";
762	if ($key eq 'otherlibdirs') {
763	    $value = "join (':', map {relocate_inc(\$_)} split (':', $value))";
764	} elsif ($need_relocation{$key}) {
765	    $value = "relocate_inc($value)";
766	}
767    } else {
768	$value = "undef";
769    }
770    $Common{$key} = "$qkey => $value";
771}
772
773if ($Common{byteorder}) {
774    $Common{byteorder} = 'byteorder => $byteorder';
775}
776my $fast_config = join '', map { "    $_,\n" } sort values %Common;
777
778# Sanity check needed to stop an infite loop if Config_heavy.pl fails to define
779# &launcher for some reason (eg it got truncated)
780$config_txt .= sprintf <<'ENDOFTIE', $fast_config;
781
782sub DESTROY { }
783
784sub AUTOLOAD {
785    require 'Config_heavy.pl';
786    goto \&launcher unless $Config::AUTOLOAD =~ /launcher$/;
787    die "&Config::AUTOLOAD failed on $Config::AUTOLOAD";
788}
789
790# tie returns the object, so the value returned to require will be true.
791tie %%Config, 'Config', {
792%s};
793ENDOFTIE
794
795
796open(CONFIG_POD, ">$Config_POD") or die "Can't open $Config_POD: $!";
797print CONFIG_POD <<'ENDOFTAIL';
798=head1 NAME
799
800Config - access Perl configuration information
801
802=head1 SYNOPSIS
803
804    use Config;
805    if ($Config{usethreads}) {
806	print "has thread support\n"
807    }
808
809    use Config qw(myconfig config_sh config_vars config_re);
810
811    print myconfig();
812
813    print config_sh();
814
815    print config_re();
816
817    config_vars(qw(osname archname));
818
819
820=head1 DESCRIPTION
821
822The Config module contains all the information that was available to
823the C<Configure> program at Perl build time (over 900 values).
824
825Shell variables from the F<config.sh> file (written by Configure) are
826stored in the readonly-variable C<%Config>, indexed by their names.
827
828Values stored in config.sh as 'undef' are returned as undefined
829values.  The perl C<exists> function can be used to check if a
830named variable exists.
831
832For a description of the variables, please have a look at the
833Glossary file, as written in the Porting folder, or use the url:
834http://perl5.git.perl.org/perl.git/blob/HEAD:/Porting/Glossary
835
836=over 4
837
838=item myconfig()
839
840Returns a textual summary of the major perl configuration values.
841See also C<-V> in L<perlrun/Switches>.
842
843=item config_sh()
844
845Returns the entire perl configuration information in the form of the
846original config.sh shell variable assignment script.
847
848=item config_re($regex)
849
850Like config_sh() but returns, as a list, only the config entries who's
851names match the $regex.
852
853=item config_vars(@names)
854
855Prints to STDOUT the values of the named configuration variable. Each is
856printed on a separate line in the form:
857
858  name='value';
859
860Names which are unknown are output as C<name='UNKNOWN';>.
861See also C<-V:name> in L<perlrun/Switches>.
862
863=back
864
865=head1 EXAMPLE
866
867Here's a more sophisticated example of using %Config:
868
869    use Config;
870    use strict;
871
872    my %sig_num;
873    my @sig_name;
874    unless($Config{sig_name} && $Config{sig_num}) {
875	die "No sigs?";
876    } else {
877	my @names = split ' ', $Config{sig_name};
878	@sig_num{@names} = split ' ', $Config{sig_num};
879	foreach (@names) {
880	    $sig_name[$sig_num{$_}] ||= $_;
881	}
882    }
883
884    print "signal #17 = $sig_name[17]\n";
885    if ($sig_num{ALRM}) {
886	print "SIGALRM is $sig_num{ALRM}\n";
887    }
888
889=head1 WARNING
890
891Because this information is not stored within the perl executable
892itself it is possible (but unlikely) that the information does not
893relate to the actual perl binary which is being used to access it.
894
895The Config module is installed into the architecture and version
896specific library directory ($Config{installarchlib}) and it checks the
897perl version number when loaded.
898
899The values stored in config.sh may be either single-quoted or
900double-quoted. Double-quoted strings are handy for those cases where you
901need to include escape sequences in the strings. To avoid runtime variable
902interpolation, any C<$> and C<@> characters are replaced by C<\$> and
903C<\@>, respectively. This isn't foolproof, of course, so don't embed C<\$>
904or C<\@> in double-quoted strings unless you're willing to deal with the
905consequences. (The slashes will end up escaped and the C<$> or C<@> will
906trigger variable interpolation)
907
908=head1 GLOSSARY
909
910Most C<Config> variables are determined by the C<Configure> script
911on platforms supported by it (which is most UNIX platforms).  Some
912platforms have custom-made C<Config> variables, and may thus not have
913some of the variables described below, or may have extraneous variables
914specific to that particular port.  See the port specific documentation
915in such cases.
916
917=cut
918
919ENDOFTAIL
920
921if ($Opts{glossary}) {
922  open(GLOS, "<$Glossary") or die "Can't open $Glossary: $!";
923}
924my %seen = ();
925my $text = 0;
926$/ = '';
927
928sub process {
929  if (s/\A(\w*)\s+\(([\w.]+)\):\s*\n(\t?)/=item C<$1>\n\nFrom F<$2>:\n\n/m) {
930    my $c = substr $1, 0, 1;
931    unless ($seen{$c}++) {
932      print CONFIG_POD <<EOF if $text;
933=back
934
935=cut
936
937EOF
938      print CONFIG_POD <<EOF;
939=head2 $c
940
941=over 4
942
943=cut
944
945EOF
946     $text = 1;
947    }
948  }
949  elsif (!$text || !/\A\t/) {
950    warn "Expected a Configure variable header",
951      ($text ? " or another paragraph of description" : () );
952  }
953  s/n't/n\00t/g;		# leave can't, won't etc untouched
954  s/^\t\s+(.*)/\n$1/gm;		# Indented lines ===> new paragraph
955  s/^(?<!\n\n)\t(.*)/$1/gm;	# Not indented lines ===> text
956  s{([\'\"])(?=[^\'\"\s]*[./][^\'\"\s]*\1)([^\'\"\s]+)\1}(F<$2>)g; # '.o'
957  s{([\'\"])([^\'\"\s]+)\1}(C<$2>)g; # "date" command
958  s{\'([A-Za-z_\- *=/]+)\'}(C<$1>)g; # 'ln -s'
959  s{
960     (?<! [\w./<\'\"] )		# Only standalone file names
961     (?! e \. g \. )		# Not e.g.
962     (?! \. \. \. )		# Not ...
963     (?! \d )			# Not 5.004
964     (?! read/ )		# Not read/write
965     (?! etc\. )		# Not etc.
966     (?! I/O )			# Not I/O
967     (
968	\$ ?			# Allow leading $
969	[\w./]* [./] [\w./]*	# Require . or / inside
970     )
971     (?<! \. (?= [\s)] ) )	# Do not include trailing dot
972     (?! [\w/] )		# Include all of it
973   }
974   (F<$1>)xg;			# /usr/local
975  s/((?<=\s)~\w*)/F<$1>/g;	# ~name
976  s/(?<![.<\'\"])\b([A-Z_]{2,})\b(?![\'\"])/C<$1>/g;	# UNISTD
977  s/(?<![.<\'\"])\b(?!the\b)(\w+)\s+macro\b/C<$1> macro/g; # FILE_cnt macro
978  s/n[\0]t/n't/g;		# undo can't, won't damage
979}
980
981if ($Opts{glossary}) {
982    <GLOS>;				# Skip the "DO NOT EDIT"
983    <GLOS>;				# Skip the preamble
984  while (<GLOS>) {
985    process;
986    print CONFIG_POD;
987  }
988}
989
990print CONFIG_POD <<'ENDOFTAIL';
991
992=back
993
994=head1 GIT DATA
995
996Information on the git commit from which the current perl binary was compiled
997can be found in the variable C<$Config::Git_Data>.  The variable is a
998structured string that looks something like this:
999
1000  git_commit_id='ea0c2dbd5f5ac6845ecc7ec6696415bf8e27bd52'
1001  git_describe='GitLive-blead-1076-gea0c2db'
1002  git_branch='smartmatch'
1003  git_uncommitted_changes=''
1004  git_commit_id_title='Commit id:'
1005  git_commit_date='2009-05-09 17:47:31 +0200'
1006
1007Its format is not guaranteed not to change over time.
1008
1009=head1 NOTE
1010
1011This module contains a good example of how to use tie to implement a
1012cache and an example of how to make a tied variable readonly to those
1013outside of it.
1014
1015=cut
1016
1017ENDOFTAIL
1018
1019close(GLOS) if $Opts{glossary};
1020close(CONFIG_POD);
1021print "written $Config_POD\n";
1022
1023my $orig_config_txt = "";
1024my $orig_heavy_txt = "";
1025{
1026    local $/;
1027    my $fh;
1028    $orig_config_txt = <$fh> if open $fh, "<", $Config_PM;
1029    $orig_heavy_txt  = <$fh> if open $fh, "<", $Config_heavy;
1030}
1031
1032if ($orig_config_txt ne $config_txt or $orig_heavy_txt ne $heavy_txt) {
1033    open CONFIG, ">", $Config_PM or die "Can't open $Config_PM: $!\n";
1034    open CONFIG_HEAVY, ">", $Config_heavy or die "Can't open $Config_heavy: $!\n";
1035    print CONFIG $config_txt;
1036    print CONFIG_HEAVY $heavy_txt;
1037    close(CONFIG_HEAVY);
1038    close(CONFIG);
1039    print "updated $Config_PM\n";
1040    print "updated $Config_heavy\n";
1041}
1042
1043
1044# Now create Cross.pm if needed
1045if ($Opts{cross}) {
1046  open CROSS, ">lib/Cross.pm" or die "Can not open >lib/Cross.pm: $!";
1047  my $cross = <<'EOS';
1048# typical invocation:
1049#   perl -MCross Makefile.PL
1050#   perl -MCross=wince -V:cc
1051package Cross;
1052
1053sub import {
1054  my ($package,$platform) = @_;
1055  unless (defined $platform) {
1056    # if $platform is not specified, then use last one when
1057    # 'configpm; was invoked with --cross option
1058    $platform = '***replace-marker***';
1059  }
1060  @INC = map {/\blib\b/?(do{local $_=$_;s/\blib\b/xlib\/$platform/;$_},$_):($_)} @INC;
1061  $::Cross::platform = $platform;
1062}
1063
10641;
1065EOS
1066  $cross =~ s/\*\*\*replace-marker\*\*\*/$Opts{cross}/g;
1067  print CROSS $cross;
1068  close CROSS;
1069  print "written lib/Cross.pm\n";
1070  unshift(@INC,"xlib/$Opts{cross}");
1071}
1072
1073# Now do some simple tests on the Config.pm file we have created
1074unshift(@INC,'lib');
1075unshift(@INC,'xlib/symbian') if $Opts{cross};
1076require $Config_PM;
1077require $Config_heavy;
1078import Config;
1079
1080die "$0: $Config_PM not valid"
1081	unless $Config{'PERL_CONFIG_SH'} eq 'true';
1082
1083die "$0: error processing $Config_PM"
1084	if defined($Config{'an impossible name'})
1085	or $Config{'PERL_CONFIG_SH'} ne 'true' # test cache
1086	;
1087
1088die "$0: error processing $Config_PM"
1089	if eval '$Config{"cc"} = 1'
1090	or eval 'delete $Config{"cc"}'
1091	;
1092
1093
1094exit 0;
1095# Popularity of various entries in %Config, based on a large build and test
1096# run of code in the Fotango build system:
1097__DATA__
1098path_sep:	8490
1099d_readlink:	7101
1100d_symlink:	7101
1101archlibexp:	4318
1102sitearchexp:	4305
1103sitelibexp:	4305
1104privlibexp:	4163
1105ldlibpthname:	4041
1106libpth:	2134
1107archname:	1591
1108exe_ext:	1256
1109scriptdir:	1155
1110version:	1116
1111useithreads:	1002
1112osvers:	982
1113osname:	851
1114inc_version_list:	783
1115dont_use_nlink:	779
1116intsize:	759
1117usevendorprefix:	642
1118dlsrc:	624
1119cc:	541
1120lib_ext:	520
1121so:	512
1122ld:	501
1123ccdlflags:	500
1124ldflags:	495
1125obj_ext:	495
1126cccdlflags:	493
1127lddlflags:	493
1128ar:	492
1129dlext:	492
1130libc:	492
1131ranlib:	492
1132full_ar:	491
1133vendorarchexp:	491
1134vendorlibexp:	491
1135installman1dir:	489
1136installman3dir:	489
1137installsitebin:	489
1138installsiteman1dir:	489
1139installsiteman3dir:	489
1140installvendorman1dir:	489
1141installvendorman3dir:	489
1142d_flexfnam:	474
1143eunicefix:	360
1144d_link:	347
1145installsitearch:	344
1146installscript:	341
1147installprivlib:	337
1148binexp:	336
1149installarchlib:	336
1150installprefixexp:	336
1151installsitelib:	336
1152installstyle:	336
1153installvendorarch:	336
1154installvendorbin:	336
1155installvendorlib:	336
1156man1ext:	336
1157man3ext:	336
1158sh:	336
1159siteprefixexp:	336
1160installbin:	335
1161usedl:	332
1162ccflags:	285
1163startperl:	232
1164optimize:	231
1165usemymalloc:	229
1166cpprun:	228
1167sharpbang:	228
1168perllibs:	225
1169usesfio:	224
1170usethreads:	220
1171perlpath:	218
1172extensions:	217
1173usesocks:	208
1174shellflags:	198
1175make:	191
1176d_pwage:	189
1177d_pwchange:	189
1178d_pwclass:	189
1179d_pwcomment:	189
1180d_pwexpire:	189
1181d_pwgecos:	189
1182d_pwpasswd:	189
1183d_pwquota:	189
1184gccversion:	189
1185libs:	186
1186useshrplib:	186
1187cppflags:	185
1188ptrsize:	185
1189shrpenv:	185
1190static_ext:	185
1191use5005threads:	185
1192uselargefiles:	185
1193alignbytes:	184
1194byteorder:	184
1195ccversion:	184
1196config_args:	184
1197cppminus:	184
1198