perl/regen-configure/dist/files/fixcpp

161 lines
4.6 KiB
Plaintext
Raw Normal View History

2022-05-14 02:40:32 +08:00
#!/usr/bin/perl
eval 'exec perl -S $0 "$@"'
if $runnning_under_some_shell;
# $Id: fixcpp.SH 19 2007-08-13 12:14:08Z rmanfredi $
#
# Copyright (c) 1991-1997, 2004-2006, Raphael Manfredi
#
# You may redistribute only under the terms of the Artistic Licence,
# as specified in the README file that comes with the distribution.
# You may reuse parts of this distribution only within the terms of
# that same Artistic Licence; a copy of which may be found at the root
# of the source tree for dist 4.0.
#
# $Log: fixcpp.SH,v $
# Revision 3.0.1.1 1995/03/21 08:35:37 ram
# patch52: created
#
# Thank you HP-UX for having a cpp that strips trailing backslashes in the
# text. As of today, you are the only reason for this program to exist.
# People designing such things should have their hands cut off to prevent
# them from doing further damage :-)
#
# This program is meant to be called from jmake. All it does is pre-process
# the file it is given as argument, focusing on #include directives and
# resolving them as cpp would (but without the #line stuff since we don't
# really care about it), escaping all the trailing \ into '\ ^A'. The resulting
# temporary file is then handed off to the real cpp for macro processing, and
# the output is printed on stdout, after restoration of any original trailing \.
# Again, thanks HP-UX for making this so challenging and exciting... :-)
#
# Note that we MUST leave alone all the trailing @!\ or @@\, since those appear
# in macros and must go away some way or the other. Also trailing backslashes
# on #define lines are really continuations and are left un-escaped.
$cpp = '/usr/bin/cpp -traditional';
$version = '3.5';
$patchlevel = '27';
while ($ARGV[0] =~ /^-/) {
$_ = shift;
last if /--/;
$cpp_opt .= "$_ ";
next unless s/-I//;
push(@lookpath, $_);
}
($file) = @ARGV;
$counter = 0; # Counter for temporary files
$SIG{'INT'} = 'PLUMBER'; # Install cleaner in case of an interrupt...
$result = &process($file); # Process file, result in a temporary
&cpp($result); # Pass resulting file with escaped \ to cpp
unlink $result;
exit 0;
# Cleanup any temporary files...
sub PLUMBER {
warn "Could not cleanup all temporaries.\n" if @tmps != unlink(@tmps);
exit 1;
}
# Compute a suitable temporary file name
sub mktmp {
$counter++;
local($tmp) = "/tmp/jmk.$counter.$$";
push(@tmps, $tmp); # Keep track of them for &PLUMBER...
$tmp;
}
# Process a given file, returning the name of the temporary file into which
# the result is left over.
# This routine is recursively called to process nested include directives.
sub process {
local($file) = @_;
local(*FILE, *TMP);
open(FILE, $file) || die "Can't read $file: $!\n";
local($tmpfile) = &mktmp;
open(TMP, ">$tmpfile") || die "Can't create $tmpfile: $!\n";
local($here, $include);
local($_);
while (<FILE>) {
if (s/^#\s*include\s*//) { # Ah, we found a #include something...
chop;
if (/"(\S+)"/) {
($include, $here) = ($1, 1);
} elsif (/<(\S+)\>/) {
($include, $here) = ($1, 0);
} else {
warn "Ignoring unkown include directive $_.\n";
next;
}
local($incfile) = &lookup($include, $here);
unless (defined $incfile) {
warn "Can't locate include file $include.\n";
next;
}
$include = &process($incfile); # Recursively process this file
&append($include, 'TMP'); # Append result to current tmp file
unlink $include;
} else {
&escape;
print TMP;
}
}
close FILE;
close TMP;
$tmpfile; # Return name of file where results has been left over
}
# Perform necessary escaping work on current line.
sub escape {
# Don't escape trailing backslashes in macro definition or cpp
# won't see them as macro continuation any longer, and also within
# macro definitions, all those @@ or @! continuations...
s/\\$/\\ \001/ unless /\@[!@]\\$/ || /^#define/;
}
# Append file to given (opened) file descriptor
sub append {
local($file, $fd) = @_;
local(*FILE);
open(FILE, $file) || die "Can't re-open $file: $!\n";
local($_);
while (<FILE>) {
&escape;
print $fd $_;
}
close FILE;
}
# Lookup file, returning its located name or undef if not found.
sub lookup {
local($file, $here) = @_;
unless ($here) {
foreach $dir (@lookpath) {
if (-r "$dir/$file") { # Use -r instead of -f for symlinks
$file = "$dir/$file";
last;
}
}
}
return undef unless -r $file;
$file;
}
# This is the final cpp processing. The output from cpp is filtered to un-escape
# all the trailing backslashes.
sub cpp {
local($file) = @_;
open(CPP, "$cpp $cpp_opt $file |") || die "Can't fork: $!\n";
while (<CPP>) {
s/\\ \001$/\\/; # Un-escape trailing \
print STDOUT;
}
close CPP;
}