+ $pvm_executable =~ s|/|=|g; # make /s into =s
+ $pvm_executable_base = $pvm_executable;
+
+ $pvm_executable = $ENV{'PVM_ROOT'} . '/bin/' . $ENV{'PVM_ARCH'}
+ . "/$pvm_executable";
+
+ &run_something("$Rm -f $pvm_executable; $Cp -p $executable $pvm_executable && $Rm -f $executable", 'Moving binary to PVM land');
+
+ # OK, now create the magic script for "$executable"
+ open(EXEC, "> $executable") || &tidy_up_and_die(1,"$Pgm: couldn't open $executable to write!\n");
+ print EXEC <<EOSCRIPT1;
+eval 'exec perl -S \$0 \${1+"\$@"}'
+ if \$running_under_some_shell;
+# =!=!=!=!=!=!=!=!=!=!=!
+# This script is automatically generated: DO NOT EDIT!!!
+# Generated by Glasgow Haskell, version ${PROJECTVERSION} ${PROJECTPATCHLEVEL}
+#
+\$pvm_executable = '$pvm_executable';
+\$pvm_executable_base = '$pvm_executable_base';
+\$SysMan = '$SysMan';
+EOSCRIPT1
+
+ print EXEC <<\EOSCRIPT2;
+# first, some magical shortcuts to run "commands" on the binary
+# (which is hidden)
+if ($#ARGV == 1 && $ARGV[0] eq '+RTS' && $ARGV[1] =~ /^--((size|file|strip|rm|nm).*)/ ) {
+ local($cmd) = $1;
+ system("$cmd $pvm_executable");
+ exit(0); # all done
+}
+
+# OK, really run it; process the args first
+$ENV{'PE'} = $pvm_executable_base;
+$debug = '';
+$nprocessors = 2; # the default
+@nonPVM_args = ();
+$in_RTS_args = 0;
+
+# ToDo: handle --RTS
+args: while ($a = shift(@ARGV)) {
+ if ( $a eq '+RTS' ) {
+ $in_RTS_args = 1;
+ } elsif ( $a eq '-RTS' ) {
+ $in_RTS_args = 0;
+ }
+ if ( $a eq '-d' && $in_RTS_args ) {
+ $debug = '-';
+ } elsif ( $a =~ /^-N(\d+)/ && $in_RTS_args ) {
+ $nprocessors = $1;
+ } else {
+ push(@nonPVM_args, $a);
+ }
+}
+
+local($return_val) = 0;
+system("$SysMan $debug $pvm_executable $nprocessors @nonPVM_args");
+$return_val = $?;
+system("mv $ENV{'HOME'}/$pvm_executable_base.???.gr .") if -f "$ENV{'HOME'}/$pvm_executable_base.001.gr";
+exit($return_val);
+EOSCRIPT2
+ close(EXEC) || die "Failed closing $executable\n";
+ chmod 0755, $executable;
+ }
+}
+
+# that... that's all, folks!
+&tidy_up();
+exit $Status; # will still be 0 if all went well
+\end{code}
+
+%************************************************************************
+%* *
+\section[Driver-do-one-file]{How to process a single input file}
+%* *
+%************************************************************************
+
+\begin{code}
+sub ProcessInputFile {
+ local($ifile) = @_; # input file name
+ local($ifile_root); # root of or basename of input file
+ local($ofile_target); # ultimate output file we hope to produce
+ # from input file (need to know for recomp
+ # checking purposes)
+ local($hifile_target);# ditto (but .hi file)
+\end{code}
+
+Handle the weirdity of input from stdin.
+\begin{code}
+ if ($ifile ne '-') {
+ ($ifile_root = $ifile) =~ s/\.[^\.\/]+$//;
+ $ofile_target = # may be reset later...
+ ($Specific_output_file ne '' && ! $Do_lnkr)
+ ? $Specific_output_file
+ : &odir_ify($ifile_root, 'o');
+ $hifile_target= ($Specific_hi_file ne '')
+ ? $Specific_hi_file
+ : "$ifile_root.$HiSuffix"; # ToDo: odirify?
+ # NB: may change if $ifile_root isn't module name (??)
+ } else {
+ $ifile = "$Tmp_prefix.hs"; # we know that's where we put the input
+ $ifile_root = '_stdin';
+ $ofile_target = '_stdout'; # gratuitous?
+ $hifile_target= '_stdout'; # ditto?
+ }
+\end{code}
+
+We need to decide what phases of the compilation system we will run
+over this file. The defaults are the ones established when processing
+flags. (That established what the last phase run for all files is.)
+
+We do the pre-recompilation-checker phases here; the rest later.
+\begin{code}
+\end{code}
+
+Look at the suffix and decide what initial phases of compilation may
+be dropped off for this file. Also the rather boring business of
+which files are coming-in/going-out.
+
+Again, we'll do the post-recompilation-checker parts of this later.
+\begin{code}
+ local($do_lit2pgm) = ($ifile =~ /\.lhs$/) ? 1 : 0;
+ local($do_hscpp) = 1; # but "hscpp" might really be "cat"
+ local($do_hsc) = 1;
+
+ # names of the files to stuff between phases
+ # defaults are temporaries
+ local($in_lit2pgm) = $ifile;
+ local($lit2pgm_hscpp) = "$Tmp_prefix.lpp";
+ local($hscpp_hsc) = "$Tmp_prefix.cpp";
+ local($hsc_hi) = "$Tmp_prefix.hi";
+ local($cc_as_o) = "${Tmp_prefix}_o.s"; # temporary for raw .s file if opt C
+ local($cc_as) = "$Tmp_prefix.s"; # mangled or hsc-produced .s code
+ local($as_out) = $ofile_target;
+
+ local($is_hc_file) = 1; #Is the C code .hc or .c? Assume .hc for now
+
+ # OK, let's strip off some literate junk..
+ if ($do_lit2pgm) {
+ &runLit2pgm($in_lit2pgm, $lit2pgm_hscpp)
+ } else {
+ $lit2pgm_hscpp = $ifile;
+ }
+
+ #
+ @File_options = ();
+
+ # Scan the top of the de-litted file for {-# OPTIONS #-} pragmas
+ &check_for_source_options($lit2pgm_hscpp,$ifile);
+
+ # Options found in the source file take a back seat, i.e., we scan
+ # them first. Only process the command line again if source file
+ # contained anything of interest *or* there's more than one
+ # input file (we have to reset the options).
+ #
+ if ( $#Input_file >= 0 || $#File_options >= 0) {
+ #@File_options = (@File_options, @Cmd_opts);
+
+ # Now process the command line
+ &initDriverGlobals();
+ &processArgs((@File_options,@Cmd_opts));
+ print STDERR "\nEffective command line: " .
+ join(' ',(@File_options,@Cmd_opts)) . "\n" if $Verbose;
+ }
+ #
+ # Having got the effective command line scanned, set up
+ # the various options in prep for some real work.
+ #
+ # check the sanity of the BuildTag we're about to use,
+ # and if needs be, add some more flags and setup to
+ # the different phases.
+ #
+ &setupBuildFlags();
+ &setupOptimiseFlags();
+ &setupMachOpts();
+ &setupIncPaths();
+ &setupHeapStackSize();
+
+ #
+ # These two variables need to be set after the
+ # command-line has been processed and the build options
+ # have be seen set up. This is because command-line options
+ # can control whether to compile vias C or not.
+ #
+ local($do_cc) = ( $Do_cc != -1) # i.e., it was set explicitly
+ ? $Do_cc
+ : ( ($HscOut eq '-C=') ? 1 : 0 );
+ local($do_as) = $Do_as;
+ local($hsc_out) = ( $HscOut eq '-C=' ) ? "$Tmp_prefix.hc" : "$Tmp_prefix.s" ;
+
+ if ($Only_preprocess_hc) { # stop after having run $Cc -E
+ $do_as=0;
+ }
+ if ($Only_preprocess_C) { # stop after having run $hscpp
+ $do_hsc=0; $do_cc = 0; $do_as=0;
+ } elsif ($ifile =~ /.lhs$/ || $ifile =~ /.hs$/ ) {
+ ;
+ } elsif ($ifile =~ /\.hc$/ || $ifile =~ /_hc$/ ) { # || $ifile =~ /\.$Isuffix$/o) # ToDo: better
+ $do_hscpp = 0; $do_hsc = 0; $do_cc = 1;
+ $hsc_out = $ifile;
+ } elsif ($ifile =~ /\.c$/) {
+ $do_hscpp = 0; $do_hsc = 0; $do_cc = 1;
+ $hsc_out = $ifile; $is_hc_file = 0;
+ } elsif ($ifile =~ /\.s$/) {
+ $do_hscpp = 0; $do_hsc = 0; $do_cc = 0;
+ $cc_as = $ifile;
+ } else { # don't know what it is, but nothing to do herein...
+ $do_hscpp = 0; $do_hsc = 0; $do_cc = 0; $do_as = 0;
+ }
+
+ # hack to avoid running hscpp
+ $HsCpp = $Cat if ! $Cpp_flag_set;
+
+ &runHscpp($in_lit2pgm, $lit2pgm_hscpp, $hscpp_hsc) if $do_hscpp;
+
+\end{code}
+
+We now think about whether to run hsc/cc or not (when hsc produces .s
+stuff, it effectively takes the place of both phases).
+
+To get the output file name right: for each phase that we are {\em
+not} going to run, set its input (i.e., the output of its preceding
+phase) to @"$ifile_root.<suffix>"@.
+
+\begin{code}
+ local($going_interactive) = $HscOut eq '-N=' || $ifile_root eq '_stdin';
+
+ #
+ # Warning issued if -keep-hc-file-too is used without
+ # -fvia-C (or the equivalent)
+ #
+ if ( $HscOut ne '-C=' && $Keep_hc_file_too ) {
+ print STDERR "$Pgm: warning: Native code generator to be used, -keep-hc-file-too will be ignored\n";
+ }
+
+ if (! $do_cc && ! $do_as) { # stopping after hsc
+ $hsc_out = ($Specific_output_file ne '')
+ ? $Specific_output_file
+ : &odir_ify($ifile_root, ($HscOut eq '-C=') ? 'hc' : 's');
+
+ $ofile_target = $hsc_out; # reset
+ }
+
+ if (! $do_as) { # stopping after gcc (or hsc)
+ $cc_as = ($Specific_output_file ne '')
+ ? $Specific_output_file
+ : &odir_ify($ifile_root, ( $Only_preprocess_hc ) ? 'i' : 's');
+
+ $ofile_target = $cc_as; # reset
+ }
+
+\end{code}
+
+
+Now the Haskell compiler, C compiler, and assembler
+
+\begin{code}
+ if ($do_hsc) {
+ &runHscAndProcessInterfaces( $ifile, $hscpp_hsc, $ifile_root,
+ $ofile_target, $hifile_target);
+ }
+
+ if ($do_cc) {
+ &runGcc ($is_hc_file, $hsc_out, $cc_as_o);
+ &runMangler($is_hc_file, $cc_as_o, $cc_as, $ifile_root) if ! $Only_preprocess_hc;
+ }
+
+ &split_asm_file($cc_as) if $do_as && $SplitObjFiles;
+
+ # save a copy of the .s file..
+ &saveIntermediate($ifile_root , "s" , $cc_as) if ($do_as && $Keep_s_file_too);
+ &runAs($as_out, $ifile_root) if $do_as;
+\end{code}
+
+Finally, decide what to queue up for linker input.
+\begin{code}
+ # tentatively assume we will eventually produce linker input:
+ push(@Link_file, &odir_ify($ifile_root, 'o'));