case $CONFIG in '') if test -f config.sh; then TOP=.; elif test -f ../config.sh; then TOP=..; elif test -f ../../config.sh; then TOP=../..; elif test -f ../../../config.sh; then TOP=../../..; elif test -f ../../../../config.sh; then TOP=../../../..; else echo "Can't find config.sh."; exit 1 fi . $TOP/config.sh ;; esac REVISION=`grep REVISION $TOP/revision.h | head -n1 | cut -d' ' -f4` case "$0" in */*) cd `expr X$0 : 'X\(.*\)/'` ;; esac echo "Extracting jmake/fixcpp (with variable substitutions)" $spitshell >fixcpp <>fixcpp <<'!NO!SUBS!' 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 () { 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 () { &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 () { s/\\ \001$/\\/; # Un-escape trailing \ print STDOUT; } close CPP; } !NO!SUBS! chmod 755 fixcpp $eunicefix fixcpp