From: Nicholas Clark <nick@ccl4.org>
Date: Tue, 29 Oct 2002 23:00:05 +0000 (+0000)
Subject: regen_headers outside Makefile (was Re: [PATCH] embed.pl doc)
X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=36bb303b6ac55df9c2780b48d374c505;p=p5sagit%2Fp5-mst-13.2.git

regen_headers outside Makefile (was Re: [PATCH] embed.pl doc)
Message-ID: <20021029230003.GF287@Bagpuss.unfortu.net>

p4raw-id: //depot/perl@18160
---

diff --git a/MANIFEST b/MANIFEST
index 69dbb07..aee5fa4 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -95,7 +95,7 @@ ext/B/ramblings/curcop.runtime	Compiler ramblings: notes on curcop use
 ext/B/ramblings/flip-flop	Compiler ramblings: notes on flip-flop
 ext/B/ramblings/magic		Compiler ramblings: notes on magic
 ext/B/ramblings/reg.alloc	Compiler ramblings: register allocation
-ext/B/ramblings/runtime.porting Compiler ramblings: porting PP enging
+ext/B/ramblings/runtime.porting Compiler ramblings: porting PP engine
 ext/B/README		Compiler backend README
 ext/B/t/asmdata.t	See if B::Asmdata works
 ext/B/t/assembler.t	See if B::Assembler, B::Disassembler comply
@@ -226,7 +226,7 @@ ext/Encode/Encode/Makefile_PL.e2x	Skeleton file for enc2xs
 ext/Encode/Encode/README.e2x	Skeleton file for enc2xs
 ext/Encode/Encode/_PM.e2x	Skeleton file for enc2xs
 ext/Encode/Encode/_T.e2x	Skeleton file for enc2xs
-ext/Encode/encoding.pm		Perl Pragmactic Module
+ext/Encode/encoding.pm		Perl Pragmatic Module
 ext/Encode/JP/JP.pm		Encode extension
 ext/Encode/JP/Makefile.PL	Encode extension
 ext/Encode/KR/KR.pm		Encode extension
@@ -625,7 +625,7 @@ ext/Storable/t/downgrade.t	See if Storable works
 ext/Storable/t/forgive.t	See if Storable works
 ext/Storable/t/freeze.t		See if Storable works
 ext/Storable/t/integer.t	See if Storable works
-ext/Storable/t/interwork56.t	Test combatibility kludge for 64bit data under 5.6.x
+ext/Storable/t/interwork56.t	Test compatibility kludge for 64bit data under 5.6.x
 ext/Storable/t/lock.t		See if Storable works
 ext/Storable/t/make_56_interwork.pl	Make test data for interwork56.t
 ext/Storable/t/make_downgrade.pl	Make test data for downgrade.t
@@ -697,7 +697,7 @@ ext/threads/shared/typemap	thread::shared types
 ext/threads/t/basic.t		ithreads
 ext/threads/t/end.t		Test end functions
 ext/threads/t/join.t		Testing the join function
-ext/threads/t/libc.t		testing libc functions for threadsafetyness
+ext/threads/t/libc.t		testing libc functions for threadsafety
 ext/threads/t/list.t		Test threads->list()
 ext/threads/t/stress_cv.t	Test with multiple threads, coderef cv argument.
 ext/threads/t/stress_re.t	Test with multiple threads, string cv argument and regexes.
@@ -1250,8 +1250,8 @@ lib/Math/BigInt/t/constant.t	Test Math::BigInt/BigFloat under :constant
 lib/Math/BigInt/t/downgrade.t	Test if use Math::BigInt(); under downgrade works
 lib/Math/BigInt/t/inf_nan.t	Special tests for inf and NaN handling
 lib/Math/BigInt/t/isa.t		Test for Math::BigInt inheritance
-lib/Math/BigInt/t/mbimbf.inc	Actual BigInt/BigFloat accuracy, precicion and fallback, round_mode tests
-lib/Math/BigInt/t/mbimbf.t	BigInt/BigFloat accuracy, precicion and fallback, round_mode
+lib/Math/BigInt/t/mbimbf.inc	Actual BigInt/BigFloat accuracy, precision and fallback, round_mode tests
+lib/Math/BigInt/t/mbimbf.t	BigInt/BigFloat accuracy, precision and fallback, round_mode
 lib/Math/BigInt/t/mbi_rand.t	Test Math::BigInt randomly
 lib/Math/BigInt/t/require.t	Test if require Math::BigInt works
 lib/Math/BigInt/t/sub_mbf.t	Empty subclass test of BigFloat
@@ -1963,7 +1963,7 @@ lib/utf8.t			See if utf8 operations work
 lib/utf8_heavy.pl		Support routines for utf8 pragma
 lib/validate.pl			Perl library supporting wholesale file mode validation
 lib/vars.pm			Declare pseudo-imported global variables
-lib/vars.t			See if "use vars" work
+lib/vars.t			See if "use vars" works
 lib/version.pm			Support for version objects
 lib/version.t			Tests for version objects
 lib/vmsish.pm			Control VMS-specific behavior of Perl core
@@ -2058,7 +2058,7 @@ numeric.c			Miscellaneous numeric conversion routines
 op.c				Opcode syntax tree code
 op.h				Opcode syntax tree header
 opcode.h			Automatically generated opcode header
-opcode.pl			Opcode header generatore
+opcode.pl			Opcode header generator
 opnames.h			Automatically generated opcode header
 os2/Changes			Changelog for OS/2 port
 os2/diff.configure		Patches to Configure
@@ -2151,7 +2151,7 @@ plan9/setup.rc			Plan9 port: script for easy build+install
 plan9/versnum			Plan9 port: script to print version number
 pod/buildtoc.PL			generate buildtoc which generates perltoc.pod
 pod/checkpods.PL		Tool to check for common errors in pods
-pod/Makefile.SH			generate Makefile whichs makes pods into something else
+pod/Makefile.SH			generate Makefile which makes pods into something else
 pod/perl.pod			Top level perl documentation
 pod/perl5004delta.pod		Changes from 5.003 to 5.004
 pod/perl5005delta.pod		Changes from 5.004 to 5.005
@@ -2197,7 +2197,7 @@ pod/perlfunc.pod		Function info
 pod/perlguts.pod		Internals info
 pod/perlhack.pod		Perl hackers guide
 pod/perlhist.pod		Perl history info
-pod/perlintern.pod		Perl internal function docs (autogenrated)
+pod/perlintern.pod		Perl internal function docs (autogenerated)
 pod/perlintro.pod		Perl introduction for beginners
 pod/perliol.pod			Internals of PerlIO with layers.
 pod/perlipc.pod			IPC info
@@ -2332,6 +2332,8 @@ regcomp.c			Regular expression compiler
 regcomp.h			Private declarations for above
 regcomp.pl			Builder of regnodes.h
 regcomp.sym			Data for regnodes.h
+regen.pl			Common file routines for generator scripts
+regen_headers.pl		Run all scripts that (re)generate files
 regexec.c			Regular expression evaluator
 regexp.h			Public declarations for the above
 regnodes.h			Description of nodes of RE engine
@@ -2366,9 +2368,9 @@ t/comp/package.t		See if packages work
 t/comp/proto.t			See if function prototypes work
 t/comp/redef.t			See if we get correct warnings on redefined subs
 t/comp/require.t		See if require works
-t/comp/script.t			See if script invokation works
+t/comp/script.t			See if script invocation works
 t/comp/term.t			See if more terms work
-t/comp/use.t			See if pragmas work
+t/comp/use.t			See if pragmata work
 t/harness			Finer diagnostics from test suite
 t/io/argv.t			See if ARGV stuff works
 t/io/binmode.t			See if binmode() works
@@ -2724,7 +2726,7 @@ vms/ext/DCLsym/DCLsym.xs	Perl access to CLI symbols
 vms/ext/DCLsym/Makefile.PL	MakeMaker driver for VMS::DCLsym
 vms/ext/DCLsym/test.pl		regression tests for VMS::DCLsym
 vms/ext/Filespec.pm		VMS-Unix file syntax interconversion
-vms/ext/filespec.t		See if VMS::Filespec funtions work
+vms/ext/filespec.t		See if VMS::Filespec functions work
 vms/ext/Stdio/0README.txt	ReadMe file for VMS::Stdio
 vms/ext/Stdio/Makefile.PL	MakeMaker driver for VMS::Stdio
 vms/ext/Stdio/Stdio.pm		VMS options to stdio routines
@@ -2843,7 +2845,7 @@ writemain.SH			Generate perlmain.c from miniperlmain.c+extensions
 x2p/a2p.c			Output of a2p.y run through byacc
 x2p/a2p.h			Global declarations
 x2p/a2p.pod			Pod for awk to perl translator
-x2p/a2p.y			A yacc grammer for awk
+x2p/a2p.y			A yacc grammar for awk
 x2p/a2py.c			Awk compiler, sort of
 x2p/cflags.SH			A script that emits C compilation flags per file
 x2p/EXTERN.h			Same as above
diff --git a/Makefile.SH b/Makefile.SH
index 0d4bb3d..cd18ffb 100644
--- a/Makefile.SH
+++ b/Makefile.SH
@@ -824,8 +824,10 @@ CHMOD_W = chmod +w
 #	warnings.pl:	warnings.h lib/warnings.pm
 # The correct versions should be already supplied with the perl kit,
 # in case you don't have perl available.
-# To force them to be regenerated, type
-#	make regen_headers
+# To force them to be regenerated, run
+#       perl regen_headers.pl
+# with your existing copy of perl
+# (make regen_headers is kept for backwards compatibility)
 
 AUTOGEN_FILES = keywords.h opcode.h opnames.h pp_proto.h pp.sym proto.h \
 		embed.h embedvar.h global.sym \
@@ -837,14 +839,7 @@ AUTOGEN_FILES = keywords.h opcode.h opnames.h pp_proto.h pp.sym proto.h \
 .PHONY: regen_headers regen_pods regen_all
 
 regen_headers:	FORCE
-	-$(CHMOD_W) $(AUTOGEN_FILES)
-	-perl keywords.pl
-	-perl opcode.pl
-	-perl embed.pl
-	-perl bytecode.pl
-	-perl regcomp.pl
-	-perl warnings.pl
-	-perl autodoc.pl
+	-perl regen_headers.pl
 
 regen_pods:	FORCE
 	-cd pod; $(LDLIBPTH) $(MAKE) regen_pods
diff --git a/autodoc.pl b/autodoc.pl
index c898c85..2044dab 100644
--- a/autodoc.pl
+++ b/autodoc.pl
@@ -3,7 +3,10 @@
 require 5.003;	# keep this compatible, an old perl is all we may have before
                 # we build the new one
 
-BEGIN {  push @INC, 'lib' }	# glob() below requires File::Glob
+BEGIN {
+  push @INC, 'lib';
+  require 'regen.pl';
+}	# glob() below requires File::Glob
 
 
 #
@@ -28,6 +31,7 @@ sub walk_table (&@) {
 	$F = $filename;
     }
     else {
+	safer_unlink $filename;
 	open F, ">$filename" or die "Can't open $filename: $!";
 	$F = \*F;
     }
@@ -50,7 +54,9 @@ sub walk_table (&@) {
 	print $F $function->(@args);
     }
     print $F $trailer if $trailer;
-    close $F unless ref $filename;
+    unless (ref $filename) {
+	close $F or die "Error closing $filename: $!";
+    }
 }
 
 my %apidocs;
@@ -145,7 +151,7 @@ for $file (glob('*.c'), glob('*.h')) {
     close F or die "Error closing $file: $!\n";
 }
 
-unlink "pod/perlapi.pod";
+safer_unlink "pod/perlapi.pod";
 open (DOC, ">pod/perlapi.pod") or
 	die "Can't create pod/perlapi.pod: $!\n";
 
@@ -235,8 +241,9 @@ perlguts(1), perlxs(1), perlxstut(1), perlintern(1)
 _EOE_
 
 
-close(DOC);
+close(DOC) or die "Error closing pod/perlapi.pod: $!";
 
+safer_unlink "pod/perlintern.pod";
 open(GUTS, ">pod/perlintern.pod") or
 		die "Unable to create pod/perlintern.pod: $!\n";
 print GUTS <<'END';
@@ -277,5 +284,4 @@ perlguts(1), perlapi(1)
 
 END
 
-close GUTS;
-
+close GUTS or die "Error closing pod/perlintern.pod: $!";
diff --git a/bytecode.pl b/bytecode.pl
index fc16f17..0c921d4 100644
--- a/bytecode.pl
+++ b/bytecode.pl
@@ -1,5 +1,6 @@
 BEGIN {
   push @INC, './lib';
+  require 'regen.pl';
 }
 use strict;
 my %alias_to = (
@@ -36,7 +37,7 @@ EOT
 my $perl_header;
 ($perl_header = $c_header) =~ s{[/ ]?\*/?}{#}g;
 
-unlink "ext/ByteLoader/byterun.c", "ext/ByteLoader/byterun.h", "ext/B/B/Asmdata.pm";
+safer_unlink "ext/ByteLoader/byterun.c", "ext/ByteLoader/byterun.h", "ext/B/B/Asmdata.pm";
 
 #
 # Start with boilerplate for Asmdata.pm
@@ -312,6 +313,11 @@ Malcolm Beattie, C<mbeattie@sable.ox.ac.uk>
 =cut
 EOT
 
+
+close ASMDATA_PM or die "Error closing ASMDATA_PM: $!";
+close BYTERUN_H or die "Error closing BYTERUN_H: $!";
+close BYTERUN_C or die "Error closing BYTERUN_C: $!";
+
 __END__
 # First set instruction ord("#") to read comment to end-of-line (sneaky)
 %number 35
diff --git a/embed.pl b/embed.pl
index d66311b..bec3ca1 100755
--- a/embed.pl
+++ b/embed.pl
@@ -3,6 +3,11 @@
 require 5.003;	# keep this compatible, an old perl is all we may have before
                 # we build the new one
 
+BEGIN {
+    # Get function prototypes
+    require 'regen.pl';
+}
+
 #
 # See database of global and static function prototypes in embed.fnc
 # This is used to generate prototype headers under various configurations,
@@ -60,7 +65,7 @@ sub walk_table (&@) {
 	$F = $filename;
     }
     else {
-	unlink $filename;
+	safer_unlink $filename;
 	open F, ">$filename" or die "Can't open $filename: $!";
 	$F = \*F;
     }
@@ -84,7 +89,9 @@ sub walk_table (&@) {
         print $F @outs; # $function->(@args) is not 5.003
     }
     print $F $trailer if $trailer;
-    close $F unless ref $filename;
+    unless (ref $filename) {
+	close $F or die "Error closing $filename: $!";
+    }
 }
 
 sub munge_c_files () {
@@ -302,7 +309,7 @@ sub multoff ($$) {
     return hide("PL_$pre$sym", "PL_$sym");
 }
 
-unlink 'embed.h';
+safer_unlink 'embed.h';
 open(EM, '> embed.h') or die "Can't create embed.h: $!\n";
 
 print EM do_not_edit ("embed.h"), <<'END';
@@ -488,9 +495,9 @@ print EM <<'END';
 
 END
 
-close(EM);
+close(EM) or die "Error closing EM: $!";
 
-unlink 'embedvar.h';
+safer_unlink 'embedvar.h';
 open(EM, '> embedvar.h')
     or die "Can't create embedvar.h: $!\n";
 
@@ -595,10 +602,10 @@ print EM <<'END';
 #endif /* PERL_POLLUTE */
 END
 
-close(EM);
+close(EM) or die "Error closing EM: $!";
 
-unlink 'perlapi.h';
-unlink 'perlapi.c';
+safer_unlink 'perlapi.h';
+safer_unlink 'perlapi.c';
 open(CAPI, '> perlapi.c') or die "Can't create perlapi.c: $!\n";
 open(CAPIH, '> perlapi.h') or die "Can't create perlapi.h: $!\n";
 
@@ -696,7 +703,7 @@ print CAPIH <<'EOT';
 #endif /* __perlapi_h__ */
 
 EOT
-close CAPIH;
+close CAPIH or die "Error closing CAPIH: $!";
 
 print CAPI do_not_edit ("perlapi.c"), <<'EOT';
 
@@ -746,7 +753,7 @@ END_EXTERN_C
 #endif /* MULTIPLICITY */
 EOT
 
-close(CAPI);
+close(CAPI) or die "Error closing CAPI: $!";
 
 # functions that take va_list* for implementing vararg functions
 # NOTE: makedef.pl must be updated if you add symbols to %vfuncs
diff --git a/keywords.pl b/keywords.pl
index d5903fa..c804620 100755
--- a/keywords.pl
+++ b/keywords.pl
@@ -1,6 +1,7 @@
 #!/usr/bin/perl
 
-unlink "keywords.h";
+require 'regen.pl';
+safer_unlink ("keywords.h");
 open(KW, ">keywords.h") || die "Can't create keywords.h: $!\n";
 select KW;
 
@@ -30,6 +31,8 @@ while (<DATA>) {
     print &tab(5, "#define KEY_$keyword"), $keynum++, "\n";
 }
 
+close KW or die "Error closing keywords.h: $!";
+
 ###########################################################################
 sub tab {
     local($l, $t) = @_;
diff --git a/opcode.pl b/opcode.pl
index 03e7dc7..d055f58 100755
--- a/opcode.pl
+++ b/opcode.pl
@@ -1,4 +1,8 @@
 #!/usr/bin/perl
+BEGIN {
+    # Get function prototypes
+    require 'regen.pl';
+}
 
 $opcode_new = 'opcode.h-new';
 $opname_new = 'opnames.h-new';
@@ -278,15 +282,11 @@ if (keys %OP_IS_FILETEST) {
 close OC or die "Error closing opcode.h: $!";
 close ON or die "Error closing opnames.h: $!";
 
-chmod 0600, 'opcode.h';  # required by dosish filesystems
-chmod 0600, 'opnames.h'; # required by dosish filesystems
-
-# Some dosish systems can't rename over an existing file:
-unlink		"$_-old"	for qw(opcode.h opnames.h);
-rename $_,	"$_-old"	for qw(opcode.h opnames.h);
-
-rename $opcode_new, 'opcode.h' or die "renaming opcode.h: $!\n";
-rename $opname_new, 'opnames.h' or die "renaming opnames.h: $!\n";
+foreach ('opcode.h', 'opnames.h') {
+    safer_rename_silent $_, "$_-old";
+}
+safer_rename $opcode_new, 'opcode.h';
+safer_rename $opname_new, 'opnames.h';
 
 $pp_proto_new = 'pp_proto.h-new';
 $pp_sym_new  = 'pp.sym-new';
@@ -330,15 +330,11 @@ for (@ops) {
 close PP or die "Error closing pp_proto.h: $!";
 close PPSYM or die "Error closing pp.sym: $!";
 
-chmod 0600, 'pp_proto.h'; # required by dosish filesystems
-chmod 0600, 'pp.sym';     # required by dosish filesystems
-
-# Some dosish systems can't rename over an existing file:
-unlink		"$_-old"	for qw(pp_proto.h pp.sym);
-rename $_,	"$_-old"	for qw(pp_proto.h pp.sym);
-
-rename $pp_proto_new, 'pp_proto.h' or die "rename pp_proto.h: $!\n";
-rename $pp_sym_new, 'pp.sym' or die "rename pp.sym: $!\n";
+foreach ('pp_proto.h', 'pp.sym') {
+    safer_rename_silent $_, "$_-old";
+}
+safer_rename $pp_proto_new, 'pp_proto.h';
+safer_rename $pp_sym_new, 'pp.sym';
 
 ###########################################################################
 sub tab {
diff --git a/regcomp.pl b/regcomp.pl
index 6ae8478..225882a 100644
--- a/regcomp.pl
+++ b/regcomp.pl
@@ -1,3 +1,7 @@
+BEGIN {
+    # Get function prototypes
+    require 'regen.pl';
+}
 #use Fatal qw(open close rename chmod unlink);
 open DESC, 'regcomp.sym';
 $ind = 0;
@@ -112,8 +116,6 @@ static const int reg_num = $tot;
 
 EOP
 
-close OUT;
+close OUT or die "close $tmp_h: $!";
 
-chmod 0666, 'regnodes.h';
-unlink 'regnodes.h';
-rename $tmp_h, 'regnodes.h';
+safer_rename $tmp_h, 'regnodes.h';
diff --git a/regen.pl b/regen.pl
new file mode 100644
index 0000000..1c830a2
--- /dev/null
+++ b/regen.pl
@@ -0,0 +1,45 @@
+#!/usr/bin/perl -w
+use strict;
+use vars qw($Is_W32 $Is_OS2 $Is_Cygwin $Is_NetWare $Needs_Write);
+use Config; # Remember, this is running using an existing perl
+
+# Common functions needed by the regen scripts
+
+$Is_W32 = $^O eq 'MSWin32';
+$Is_OS2 = $^O eq 'os2';
+$Is_Cygwin = $^O eq 'cygwin';
+$Is_NetWare = $Config{osname} eq 'NetWare';
+if ($Is_NetWare) {
+  $Is_W32 = 0;
+}
+
+$Needs_Write = $Is_OS2 || $Is_W32 || $Is_Cygwin || $Is_NetWare;
+
+sub safer_unlink {
+  my @names = @_;
+  my $cnt = 0;
+
+  my $name;
+  foreach $name (@names) {
+    next unless -e $name;
+    chmod 0777, $name if $Needs_Write;
+    ( CORE::unlink($name) and ++$cnt
+      or warn "Couldn't unlink $name: $!\n" );
+  }
+  return $cnt;
+}
+
+sub safer_rename_silent {
+  my ($from, $to) = @_;
+
+  # Some dosish systems can't rename over an existing file:
+  safer_unlink $to;
+  chmod 0600, $from if $Needs_Write;
+  rename $from, $to;
+}
+
+sub safer_rename {
+  my ($from, $to) = @_;
+  safer_rename_silent($from, $to) or die "renaming $from to $to: $!";
+}
+1;
diff --git a/regen_headers.pl b/regen_headers.pl
new file mode 100644
index 0000000..2f405bb
--- /dev/null
+++ b/regen_headers.pl
@@ -0,0 +1,23 @@
+#!/usr/bin/perl -w
+require 5.003;	# keep this compatible, an old perl is all we may have before
+                # we build the new one
+
+# The idea is to move the regen_headers target out of the Makefile so that
+# it is possible to rebuild the headers before the Makefile is available.
+# (and the Makefile is unavailable until after Configure is run, and we may
+# wish to make a clean source tree but with current headers without running
+# anything else.
+
+use strict;
+my $perl = $^X;
+
+require 'regen.pl';
+# keep warnings.pl in sync with the CPAN distribution by not requiring core
+# changes
+safer_unlink ("warnings.h", "lib/warnings.pm");
+
+foreach (qw (keywords.pl opcode.pl embed.pl bytecode.pl regcomp.pl
+	     warnings.pl autodoc.pl)) {
+  print "$^X $_\n";
+  system "$^X $_";
+}