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