X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Futils%2FmkdependHS%2FmkdependHS.prl;h=b68cb08322d0530680e9f82471462913551a8eaf;hb=438596897ebbe25a07e1c82085cfbc5bdb00f09e;hp=e4a11c8f755e37c91f9fba74f601946faffaf641;hpb=e0befe921f5bbfa6daba3f8ff46cdf2a2abad1da;p=ghc-hetmet.git diff --git a/ghc/utils/mkdependHS/mkdependHS.prl b/ghc/utils/mkdependHS/mkdependHS.prl index e4a11c8..b68cb08 100644 --- a/ghc/utils/mkdependHS/mkdependHS.prl +++ b/ghc/utils/mkdependHS/mkdependHS.prl @@ -1,178 +1,212 @@ -# *** MSUB does some substitutions here *** -# *** grep for $( *** # -# tries to work like mkdependC +# perl script expect the following variables to be prepended: # +# RAWCPP TMPDIR TOP_PWD +# libdir libexecdir datadir INSTALLING +# SED +# +# tries to work like mkdependC - capable of dealing with: +# +# -literate Haskell code (Bird tracks or Glasgow literate style) (.lhs) +# -straight Haskell source (.hs) +# -literate or straight Happy specs (.ly) +# # ToDo: strip out all the .h junk # ($Pgm = $0) =~ s/.*\/([^\/]+)$/\1/; -$Usage = "usage: $Pgm: not done yet\n"; - -$Status = 0; # just used for exit() status -$Verbose = ''; +$Usage = < A cpp #define; usual meaning + -i Add (colon-separated) to list of directories + to search for "import"ed modules + -I Add to list of directories to search for + .h files (i.e., usual meaning) + -syslib This program uses this GHC system library; take + appropriate action (e.g., recognise when they are + "import"ing a module from that library). + +mkdependHS-specific options (not between --'s): + + -v Be verbose. + -v -v Be very verbose. + -w No warnings + -f blah Use "blah" as the makefile, rather than "makefile" + or "Makefile". + -cpp Wash the input files through cpp(1). + -o Use as the "object file" suffix ( default: o) + -s Make extra dependencies for files with + suffix ; thus, "-o hc -s _a" will + make dependencies both for .hc files and for .a_hc + files. (Useful in conjunction with NoFib "ways".) + --exclude-module= + Regard as "stable"; i.e., eXclude it from having + dependencies on it. + -x same as --exclude-module + --exclude-directory= + Regard : separated list of directories as containing stable, + don't generate any dependencies on modules therein. + -Xdirs same as --exclude-directory + --include-prelude + Regard prelude libraries as unstable, i.e., generate dependencies + on prelude modules. This option is normally only used by the + various system libraries. If a -syslib option is used, dependencies + will also be generated on the library's interfaces. + --include-module= + Regard as not "stable"; i.e., generate dependencies + on it (if any). This option is normally used in conjunction + with the --exclude-directory option. + +EOUSAGE + +$Status = 0; # just used for exit() status +$Verbose = 0; # 1 => verbose, 2 => very verbose +$Warnings = 1; # 1 => warn about duplicate interface files $Dashdashes_seen = 0; -$OrigCpp = '$(RAWCPP)'; -if ( $OrigCpp =~ /(\S+)\s+(.*)/ ) { - $cmd = $1; - $rest = $2; - if ( -x $cmd ) { # cool - $Cpp = $OrigCpp; - } else { # oops; try to guess - $GccV = `gcc -v 2>&1`; - if ( $GccV =~ /Reading specs from (.*)\/specs/ ) { - $Cpp = "$1/cpp $rest"; - } else { - die "hscpp: don't know how to run cpp: $OrigCpp\n"; - } - } -} else { - $Cpp = $OrigCpp; -} +$Cpp = ${RAWCPP}; +$Cpp_flag_set = 0; # 1 => run cpp over input files. if ( $ENV{'TMPDIR'} ) { # where to make tmp file names $Tmp_prefix = $ENV{'TMPDIR'} . "/mkdependHS$$"; } else { - $Tmp_prefix ="$(TMPDIR)/mkdependHS$$"; - $ENV{'TMPDIR'} = '$(TMPDIR)'; # set the env var as well + $Tmp_prefix ="${TMPDIR}/mkdependHS$$"; + $ENV{'TMPDIR'} = "${TMPDIR}"; # set the env var as well } -#------------------------------------------------------------------------ -# If you are adjusting paths by hand for a binary GHC distribution, -# de-commenting the line to set GLASGOW_HASKELL_ROOT should do. -# Or you can leave it as is, and set the environment variable externally. -#------------------------------------------------------------------------ -# $ENV{'GLASGOW_HASKELL_ROOT'} = '/some/absolute/path/name'; - -if (! $ENV{'GLASGOW_HASKELL_ROOT'}) { # good -- death to environment variables - $TopPwd = '$(TOP_PWD)'; - $InstLibDirGhc = '$(INSTLIBDIR_GHC)'; - $InstDataDirGhc = '$(INSTDATADIR_GHC)'; -} else { - $TopPwd = $ENV{'GLASGOW_HASKELL_ROOT'}; - - if ( '$(INSTLIBDIR_GHC)' =~ /\/local\/fp(\/.*)/ ) { - $InstLibDirGhc = $ENV{'GLASGOW_HASKELL_ROOT'} . $1; - } else { - print STDERR "GLASGOW_HASKELL_ROOT environment variable is set;\nBut can't untangle $(INSTLIBDIR_GHC).\n(Installation error)\n"; - exit(1); - } - - if ( '$(INSTDATADIR_GHC)' =~ /\/local\/fp(\/.*)/ ) { - $InstDataDirGhc = $ENV{'GLASGOW_HASKELL_ROOT'} . $1; - } else { - print STDERR "GLASGOW_HASKELL_ROOT environment variable is set;\nBut can't untangle $(INSTDATADIR_GHC).\n(Installation error)\n"; - exit(1); - } -} +$TopPwd = "${TOP_PWD}"; +$InstLibDirGhc = "${libdir}"; +$InstLibExecDirGhc = "${libexecdir}"; +$InstDataDirGhc = "${datadir}"; -$Unlit = ( $(INSTALLING) ) ? "$InstLibDirGhc/unlit" - : "$TopPwd/$(CURRENT_DIR)/$(GHC_UNLIT)"; +$Unlit = ($INSTALLING) ? "${InstLibExecDirGhc}/unlit" + : "${TopPwd}/ghc/utils/unlit/unlit"; $Begin_magic_str = "# DO NOT DELETE: Beginning of Haskell dependencies\n"; $End_magic_str = "# DO NOT DELETE: End of Haskell dependencies\n"; -$Obj_suffix = '.o'; -$ghc_version_info = $(PROJECTVERSION) * 100; -@Defines = ('-D__HASKELL1__=2', "-D__GLASGOW_HASKELL__=$ghc_version_info"); +@Obj_suffix = ("o"); +@File_suffix = (); $Import_dirs = '.'; %Syslibs = (); -%StableLibs = (); -%PreludeIfaces = ( 'Prelude', '1', - 'PreludeGlaST', '1', - 'PreludeGlaMisc', '1', - 'Concurrent', '1', - 'Parallel', '1'); -%GhcLibIfaces = ( 'Bag', '1', - 'BitSet', '1', - # CharSeq not supposed to be used by user (I think. WDP) - 'FiniteMap', '1', - 'ListSetOps', '1', - 'Maybes', '1', - 'PackedString', '1', - 'Regex', '1', - 'MatchPS', '1', - 'Readline', '1', - 'Socket', '1', - 'SocketPrim', '1', - 'BSD', '1', - 'Pretty', '1', - 'Set', '1', - 'Util', '1' ); -%HbcLibIfaces = ( 'Algebra', '1', - 'Hash', '1', - 'ListUtil', '1', - 'Miranda', '1', - 'NameSupply', '1', - 'Native', '1', - 'Number', '1', - 'Parse', '1', - 'Pretty', '1', - 'Printf', '1', - 'QSort', '1', - 'Random', '1', - 'SimpleLex', '1', - 'Time', '1', - 'Trace', '1', - 'Word', '1' ); -%IO13Ifaces = ( 'LibSystem', '1', - 'LibCPUTime', '1', - 'LibDirectory', '1', - 'LibPosix', '1', - 'LibTime', '1' ); - -$Haskell_1_3 = 0; # assume Haskell 1.2, still. Changed by -fhaskell-1.3 +%LibIfaces = (); # known prelude/syslib ifaces; read from a file +%IgnoreMe = (); +# directories to considered stable. +@Ignore_dirs = (); + $Include_dirs = '-I.'; -$Col_width = 78; # ignored $Makefile = ''; @Src_files = (); +$Include_prelude = 0; +@Defines = (); + +# Delete temp. file if script is halted. +sub quit_upon_signal { print STDERR "Deleting $Tmp_prefix.hs .. \n"; unlink "$Tmp_prefix.hs"; } +$SIG{'INT'} = 'quit_upon_signal'; +$SIG{'QUIT'} = 'quit_upon_signal'; &mangle_command_line_args(); +if ( $Status ) { + print stderr $Usage; + exit(1); +} + +@Import_dirs = split(/:/,$Import_dirs); +@Include_dirs = split(/\s+/,$Include_dirs); # still has -I's in it + +# set up array of ignored modules +local(@dirs) = ($INSTALLING) ? + ("$InstLibDirGhc/imports/std") + : ("$TopPwd/ghc/lib/std"); +if (!$Include_prelude) { + push(@Ignore_dirs, @dirs); +} else { + push(@Import_dirs, @dirs); +} + +foreach $lib ( @Syslibs ) { + local($dir); + + if ( $lib eq 'win32' && ! $INSTALLING ) { + $dir = "${TopPwd}/hslibs/${lib}/src"; + } else { + $dir = ($INSTALLING) ? "${InstLibDirGhc}/imports/${lib}" + : "${TopPwd}/ghc/lib/${lib}"; + } + if (!$Include_prelude) { + push(@Ignore_dirs,$dir); + } else { + push(@Import_dirs, $dir); + } +} + + +# NB: We keep the scalar-variable equivalents to use in error messages + if ( ! $Makefile && -f 'makefile' ) { $Makefile = 'makefile'; } elsif ( ! $Makefile && -f 'Makefile') { $Makefile = 'Makefile'; -} else { +} elsif ( ! $Makefile) { die "$Pgm: no makefile or Makefile found\n"; } -@Depend_lines = (); - print STDERR "CPP defines=@Defines\n" if $Verbose; -print STDERR "Import_dirs=$Import_dirs\n" if $Verbose; -print STDERR "Include_dirs=$Include_dirs\n" if $Verbose; +print STDERR "Import_dirs=@Import_dirs\n" if $Verbose; +print STDERR "Include_dirs=@Include_dirs\n" if $Verbose; + +&preprocess_import_dirs(); + +@Depend_lines = (); foreach $sf (@Src_files) { + # just like lit-inputter # except it puts each file through CPP and # a de-commenter (not implemented); # builds up @Depend_lines print STDERR "Here we go for source file: $sf\n" if $Verbose; - ($bf = $sf) =~ s/\.l?hs$//; - push(@Depend_lines, "$bf$Obj_suffix : $sf\n"); - foreach $suff (@File_suffix) { - push(@Depend_lines, "$bf$suff$Obj_suffix : $sf\n"); + ($bf = $sf) =~ s/\.l?(hs|y)$//; + + local($str)=""; + foreach $obj (@Obj_suffix) { + $str .= "$bf.$obj "; + foreach $suff (@File_suffix) { + $str .= "$bf.${suff}_$obj "; + } } - - # if it's a literate file, .lhs, then we de-literatize it: - if ( $sf !~ /\.lhs$/ ) { + push(@Depend_lines, "$str: $sf\n"); + # if it's a literate file, .lhs or .ly? (happy specs), then we de-literatize it: + if ( $sf !~ /\.l(hs|y)$/ ) { $file_to_read = $sf; } else { $file_to_read = "$Tmp_prefix.hs"; local($to_do) = "$Unlit $sf $file_to_read"; - &run_something($to_do, 'unlit'); + &run_something($to_do, $sf, 'unlit'); } &slurp_file_for_imports($file_to_read, $sf); - if ( $sf =~ /\.lhs$/ ) { + # Delete the temporary. + if ( $sf =~ /\.l(hs|y)$/ ) { unlink "$Tmp_prefix.hs"; } } -# OK, mangle the Makefile -unlink("$Makefile.bak"); -rename($Makefile,"$Makefile.bak"); + +# +# Create backup version of output file. +# +if ( ! -f $Makefile ) { + # truncate() may not be implemented, so we + # play it safe here. + local(*TRUNC); + open(TRUNC,"> $Makefile.bak") && close(TRUNC); +} else { + rename($Makefile,"$Makefile.bak"); +} # now copy Makefile.bak into Makefile, rm'ing old dependencies # and adding the new open(OMKF,"< $Makefile.bak") || die "$Pgm: can't open $Makefile.bak: $!\n"; @@ -187,15 +221,13 @@ while ($_ && $_ ne $End_magic_str) { # delete 'til End_magic_str $_ = ; } # insert dependencies -print $Begin_magic_str; -print @Depend_lines; -print $End_magic_str; +print "\n$Begin_magic_str", @Depend_lines, $End_magic_str || die "Failed to write out dependencies ($!)"; + while () { # copy the rest through - print $_; + print $_ || die "Failed to write out dependencies ($!)"; } close(NMKF) || exit(1); close(OMKF) || exit(1); -chmod 0444, 'Makefile'; exit 0; sub mangle_command_line_args { @@ -207,45 +239,69 @@ sub mangle_command_line_args { } elsif ( /^-D(.*)/ ) { # recognized wherever they occur push(@Defines, $_); + } elsif ( /^-cpp$/ ) { # recognized wherever they occur + $Cpp_flag_set =1; + } elsif ( /^-i$/ ) { + $Import_dirs = ''; # import path cleared! } elsif ( /^-i(.*)/ ) { - $Import_dirs .= ":$1"; + $Import_dirs = "$1:$Import_dirs"; } elsif ( /^-I/ ) { $Include_dirs .= " $_"; } elsif ( /^-syslib$/ ) { push(@Syslibs, &grab_arg_arg($_,'')); - } elsif ( /^-fhaskell-1\.3/ ) { - $Haskell_1_3 = 1; - } elsif ( /^-stable$/ ) { - # user-defined syslibs that she believes are stable. - push(@StableLibs, &grab_arg_arg($_,'')); - + } elsif ( /^-fglasgow-exts$/ ) { + push(@Syslibs, 'exts'); + } elsif ( /^-concurrent$/ ) { + push(@Syslibs, 'concurrent'); } elsif ($Dashdashes_seen != 1) { # not between -- ... -- if ( /^-v$/ ) { - $Verbose = '-v'; + $Verbose++; + } elsif ( /^-w$/ ) { + $Warnings = 0; } elsif ( /^-f(.*)/ ) { $Makefile = &grab_arg_arg('-f',$1); } elsif ( /^-o(.*)/ ) { - $Obj_suffix = &grab_arg_arg('-o',$1); + local($suff) = &grab_arg_arg('-o',$1); + # Weed out existing entry .. there must be a better way of doing this + # with arrays (non-assoc) ! -- sof + @Obj_suffix = grep(!/$suff/,@Obj_suffix); + push(@Obj_suffix, $suff); + # + # --exclude-module=mod => it's stable, trust me! + + } elsif ( /^-(x|-exclude-module=)(.*)/ ) { + local($thing) = &grab_arg_arg($1,$2); + $IgnoreMe{$thing} = 'Y'; + } elsif ( /^-(X|-exclude-directory=)(.*)/ ) { + foreach $d ( split(/:/,&grab_arg_arg($1, $2)) ) { + push(@Ignore_dirs,"$d"); + } + } elsif ( /^--include-module=(.*)/ ) { + local($thing) = &grab_arg_arg($1,$2); + $IgnoreMe{$thing} = 'n'; + } elsif ( /^--include-prelude$/ ) { + $Include_prelude = 1; } elsif ( /^-s(.*)/ ) { local($suff) = &grab_arg_arg('-s',$1); - $File_suffix{$suff} = $suff; - } elsif ( /^-bs(.*)/ ) { - $Begin_magic_str = &grab_arg_arg('-bs',$1) . "\n"; - } elsif ( /^-es(.*)/ ) { - $End_magic_str = &grab_arg_arg('-es',$1) . "\n"; - } elsif ( /^-w(.*)/ ) { - $Width = &grab_arg_arg('-w',$1); + push(@File_suffix, $suff); } elsif ( /^-/ ) { print STDERR "$Pgm: unknown option ignored: $_\n"; + $Status++; } else { push(@Src_files, $_); } - - } elsif ($Dashdashes_seen == 1) { # where we ignore unknown options - push(@Src_files,$_) if ! /^-/; - } + } + # Removed support for picking up plausible source file + # names inside the ghc options chunk of the command + # line. It failed to deal with `option-value' stuff present + # on some invocations of ghc (e.g., "-ohi foo.baz"). + # -- sof 12/97 + # + # } elsif ($Dashdashes_seen == 1) { + # push(@Src_files, $_) if ! /^-/; + # } } - @File_suffix = sort (keys %File_suffix); + @File_suffix = sort (@File_suffix); } sub grab_arg_arg { @@ -262,58 +318,184 @@ sub grab_arg_arg { } } +sub preprocess_import_dirs { + # it's probably cheaper to find out what's in all + # the @Import_dirs before we start processing. + local($d, $thing); + local($_); + %ModuleIn = (); + + foreach $d ( @Import_dirs ) { + # Check to see if it can be ignored + #print STDERR "Ignore imports from $d\n" if $Verbose && $Ignore_dirs{$d}; + #next if $Ignore_dirs{$d}; + + opendir(DIR, $d) || die "$Pgm: can't open directory $d\n"; + + for ($_ = readdir(DIR); $_; $_ = readdir(DIR)) { + next unless /(.*)\.hi$/; + $thing = $1; + if ($ModuleIn{$thing} && $ModuleIn{$thing} ne $d) { + print STDERR "$Pgm: warning: $thing.hi appears in both $ModuleIn{$thing} and $d!\n" if ($Warnings); + } else { + $ModuleIn{$thing} = $d; + } + } + closedir(DIR); # No, don't check the error code + } + + # Add all the modules + # to the IgnoreMe array before we start scanning for imports. + foreach $d (@Ignore_dirs) { + + opendir(DIR, $d) || die "$Pgm: can't open directory $d\n"; + + for ($_ = readdir(DIR); $_; $_ = readdir(DIR)) { + next unless /(.*)\.(hi|l?hs|l?y)$/; + #don't tag it twice or overwrite it with a diff. value + next if $IgnoreMe{$1}; + print STDERR "Module $d will be ignored\n" if $Verbose; + + $IgnoreMe{$1} = 'y'; + } + closedir(DIR); # No, don't check the error code + } +} + sub slurp_file_for_imports { local($file_to_read, $orig_src_file) = @_; - local($follow_file); + local($follow_file,$read_from_file); + local($cleanup)=0; local($last_seen_dir) = $orig_src_file; $last_seen_dir =~ s/\/[^\/]+$//; # strip to dir name $last_seen_dir = '.' if ($last_seen_dir eq $orig_src_file); + local($mod_name) = $orig_src_file; + + $mod_name =~ s/.*\/([^\/]+)$/$1/g; + $mod_name =~ s/^([^.]+)\.(.*)$/$1/; + + print STDERR "Warning: processing module $mod_name, which I was supposed to ignore.\n" + if ( $IgnoreMe{$mod_name} eq 'Y' && $Warnings ); + + &process_dependency('import',0,'Prelude') if ($Include_prelude); + # we mangle #include's so they will also leave something # behind to indicate the dependency on _them_ + + local ($open_cmd); + if ($Cpp_flag_set) { +# $open_cmd = "${SED} -e '/^# *include/{p;s/^# *include/!include/;};s/'\\''//g;s/\"//g' $file_to_read | $Cpp $Include_dirs -I$last_seen_dir @Defines |"; + &run_something("${SED} -e '/^# *include/{p;s/^# *include/!include/;};s/'\\''//g;s/\"//g' $file_to_read | $Cpp $Include_dirs -I$last_seen_dir @Defines 2>&1 > ${file_to_read}.i", $orig_src_file, 'cpp'); + $read_from_file="${file_to_read}.i"; + $cleanup=1; + } else { + $read_from_file="${file_to_read}"; + $open_cmd = $file_to_read; + } + print STDERR "$open_cmd\n" if $Verbose; - print STDERR "/usr/bin/sed -e '/^# *include/{p;s/^# *include/!include/;};s/'\\''//g;s/\"//g' $file_to_read | $Cpp $Include_dirs -I$last_seen_dir @Defines |\n" if $Verbose; - - open(SRCFILE, "/usr/bin/sed -e '/^# *include/{p;s/^# *include/!include/;};s/'\\''//g;s/\"//g' $file_to_read | $Cpp $Include_dirs -I$last_seen_dir @Defines |") - || die "$Pgm: Can't open $file_to_read: $!\n"; + open(SRCFILE, $read_from_file) || die "$Pgm: Can't open $file_to_read: $!\n"; while () { - if (/^>?\s*import\s+([A-Z][A-Za-z0-9_']*)/ || /^!include\s+"(\S+)"/) { - $modname = $1; - if (/^>?\s*import/) { - $follow_file = &find_in_Import_dirs($orig_src_file, $modname, $last_seen_dir); - } else { - $follow_file = &find_in_Include_dirs($orig_src_file, $modname, $last_seen_dir); + # + # import {-# SOURCE #-} Foo (bar) generates dependencies on the source file only, + # the compiler will deal with the absence of Foo.hi by consulting the + # source for Foo directly. (for dealing with recursive modules). + # + next unless (/^>?\s*(import)(\s+{-#\s*SOURCE\s*#-})?(\s+qualified)?\s+([A-Z][A-Za-z0-9_']*)/ || /^!(include)(\s+)"(\S+)"/); + $todo = $1; + $source = ( $2 ne '') ? 1 : 0; + $modname = $4; + + next if $modname eq ''; + &process_dependency($todo,$source,$modname); + } + close(SRCFILE) || exit(1); + # remove temporary file, if any. + if ($cleanup) { + # truncate() may not be implemented, so we + # play it safe here. + local(*TRUNC); + open(TRUNC,"> $read_from_file") && close(TRUNC); + } +} + +# +# Handle +sub process_dependency { + local($todo,$source,$modname) = @_; + + if ($todo eq 'import') { + if ( $IgnoreMe{$modname} eq 'Y' ) { + # user specifically asked for this module + # to be ignored. + $follow_file = '__ignore__'; + } elsif ( $ModuleIn{$modname} ) { + $follow_file = "$ModuleIn{$modname}/$modname.hi"; + } else { # hard way + $follow_file = + &find_in_Import_dirs($orig_src_file, $modname, $last_seen_dir, $source ); + } + } else { + $follow_file + = &find_in_Include_dirs($orig_src_file, $modname, $last_seen_dir); + } + + if (! $follow_file) { # it didnae find anything + die "$orig_src_file: Couldn't handle: $_\n"; + + } else { # it found something + if ($follow_file ne '__ignore__') { + local($int_file) = $follow_file; + + if ( $int_file !~ /\.(l?hs|hi|l?y)$/ ) { + local($str) = ""; + foreach $obj (@Obj_suffix) { + $str .= "$bf.$obj "; + foreach $suff (@File_suffix) { + $str .= "$bf.${suff}_$obj "; + } } + push(@Depend_lines, "$str: $int_file\n"); + } else { + $int_file =~ s/\.l?hs$//; + $int_file =~ s/\.l?y$//; + $int_file =~ s/\.hi$//; + local($source_dep); + + if ( $source ) { + $source_dep = "$int_file.hi-boot"; + } else { + local($str)=""; + foreach $obj (@Obj_suffix) { + $str .= "$bf.$obj "; + } + push(@Depend_lines, "$str: $int_file.hi\n"); + } - if ($follow_file) { # it found something - - if ($follow_file ne '__syslib__') { - local($int_file); - $int_file = $follow_file; - if ( $int_file !~ /\.(l?hs|hi)$/ ) { - push(@Depend_lines, "$bf$Obj_suffix : $int_file\n"); - foreach $suff (@File_suffix) { - push(@Depend_lines, "$bf$suff$Obj_suffix : $int_file\n"); - } - - } else { - $int_file =~ s/\.l?hs$//; - $int_file =~ s/\.hi$//; - - push(@Depend_lines, "$bf$Obj_suffix : $int_file.hi\n"); - foreach $suff (@File_suffix) { - push(@Depend_lines, "$bf$suff$Obj_suffix : $int_file$suff.hi\n"); - } - } - } + if ( ! $source ) { + foreach $suff (@File_suffix) { + local($str) = ""; + foreach $obj (@Obj_suffix) { + $str .= "$bf.${suff}_$obj "; + } + push(@Depend_lines, "$str: $int_file.${suff}_hi\n"); + } } else { - die "$orig_src_file: Couldn't handle: $_\n"; + local($str) = ""; + foreach $obj (@Obj_suffix) { + $str .= "$bf.$obj "; + foreach $suff (@File_suffix) { + $str .= "$bf.${suff}_$obj "; + } + } + push(@Depend_lines, "$str: $source_dep\n"); } } - } - close(SRCFILE) || exit(1); + } + } } # when we see something, we cache that fact ('y'). @@ -321,13 +503,13 @@ sub slurp_file_for_imports { %FileExists = (); sub find_in_Import_dirs { - local($orig_src_file, $modname, $last_seen_dir) = @_; + local($orig_src_file, $modname, $last_seen_dir, $source) = @_; local($import_dir); local($do_magical_check) = 0; local($name_to_check); - # hop along Import_dir list - foreach $import_dir (split(/:/,$Import_dirs)) { + # do it the old hard way: hop along Import_dir list + foreach $import_dir (@Import_dirs) { # handle . magically if ($import_dir eq '.') { # record that we should do a SPECIAL try for a file in last_seen_dir (LAST) @@ -336,7 +518,7 @@ sub find_in_Import_dirs { $name_to_check = "$import_dir/$modname.hi"; if ( $FileExists{$name_to_check} ne 'n' ) { # either 'y' or nothing - print STDERR "trying $name_to_check...\n" if $Verbose; + print STDERR "trying $name_to_check...\n" if $Verbose >= 2; # very verbose return($name_to_check) if $FileExists{$name_to_check} eq 'y'; if (-f $name_to_check) { $FileExists{$name_to_check} = 'y'; @@ -346,19 +528,23 @@ sub find_in_Import_dirs { } } - $name_to_check = "$import_dir/$modname.hs"; - print STDERR "trying... $name_to_check\n" if $Verbose; - return($name_to_check) if -f $name_to_check; - - $name_to_check = "$import_dir/$modname.lhs"; - print STDERR "trying... $name_to_check\n" if $Verbose; - return($name_to_check) if -f $name_to_check; + for $suff ('hs', 'lhs', 'ly', 'y') { + $name_to_check = "$import_dir/$modname.$suff"; + print STDERR "trying... $name_to_check\n" if $Verbose >= 2; # very verbose + return($name_to_check) if -f $name_to_check; + } + + if ( $source ) { + $name_to_check = "$import_dir/$modname.hi-boot"; + print STDERR "trying... $name_to_check\n" if $Verbose >= 2; # very verbose + return($name_to_check) if -f $name_to_check; + } } if ($do_magical_check == 1) { $name_to_check = "$last_seen_dir/$modname.hi"; if ( $FileExists{$name_to_check} ne 'n' ) { # either 'y' or nothing - print STDERR "trying $name_to_check...\n" if $Verbose; + print STDERR "trying $name_to_check...\n" if $Verbose >= 2; # very verbose return($name_to_check) if $FileExists{$name_to_check} eq 'y'; if (-f $name_to_check) { $FileExists{$name_to_check} = 'y'; @@ -368,39 +554,22 @@ sub find_in_Import_dirs { } } - $name_to_check = "$last_seen_dir/$modname.lhs"; - print STDERR "trying... $name_to_check\n" if $Verbose; - return($name_to_check) if -f $name_to_check; - - $name_to_check = "$last_seen_dir/$modname.hs"; - print STDERR "trying... $name_to_check\n" if $Verbose; - return($name_to_check) if -f $name_to_check; - } - # OK, maybe it's referring to something in a system library - foreach $lib ( @Syslibs ) { - if ( $lib eq 'ghc' ) { - return('__syslib__') if $GhcLibIfaces{$modname}; - } elsif ( $lib eq 'hbc' ) { - return('__syslib__') if $HbcLibIfaces{$modname}; - } else { - die "Unrecognised syslib: $lib\n"; - } - } - - # HACK HACK: Let the user define his own "stable" modules. - foreach $stableLib ( @StableLibs ) { - return('__syslib__') if ( $stableLib eq $modname ); + for $suff ('lhs', 'hs', 'ly', 'y') { + $name_to_check = "$last_seen_dir/$modname.$suff"; + print STDERR "trying... $name_to_check\n" if $Verbose >= 2; # very verbose + return($name_to_check) if -f $name_to_check; + } } - # Might be a Haskell 1.3 Module (but only if we've said -fhaskell-1.3) - if ( $Haskell_1_3 == 1 ) { - return('__syslib__') if $IO13Ifaces{$modname}; - } + # OK, maybe it's referring to something in a system library + #foreach $lib ( @Syslibs ) { + # return('__ignore__') if $LibIfaces{"$lib:$modname"}; + #} # Last hope: referring to a Prelude interface - return('__syslib__') if $PreludeIfaces{$modname}; + return('__ignore__') if ( $IgnoreMe{$modname} eq 'y' ); - die "No file `$modname.hi', `$modname.lhs' or `$modname.hs' (reqd from file `$orig_src_file')\namong import directories:\n\t$Import_dirs\n"; + die "No file `$modname.hi', `$modname.lhs', `$modname.hs' (reqd from file `$orig_src_file')\namong import directories:\n\t$Import_dirs\n"; } sub find_in_Include_dirs { @@ -411,7 +580,7 @@ sub find_in_Include_dirs { # no funny name guessing here # hop along Include_dir list - foreach $include_dir (split(/\s+/,$Include_dirs)) { + foreach $include_dir (@Include_dirs) { $include_dir =~ s/^-I//; # handle . magically @@ -419,13 +588,13 @@ sub find_in_Include_dirs { # record that we should do a SPECIAL try for a file in last_seen_dir (LAST) $do_magical_check = 1; } - print STDERR "trying $include_dir/$name...\n" if $Verbose; + print STDERR "trying $include_dir/$name...\n" if $Verbose >= 2; # very verbose if (-f "$include_dir/$name") { return("$include_dir/$name"); } } if ($do_magical_check == 1) { - print STDERR "trying $last_seen_dir/$name...\n" if $Verbose; + print STDERR "trying $last_seen_dir/$name...\n" if $Verbose >= 2; # very verbose if (-f "$last_seen_dir/$name") { return("$last_seen_dir/$name"); } @@ -435,7 +604,7 @@ sub find_in_Include_dirs { # out of the driver, actually sub run_something { - local($str_to_do, $tidy_name) = @_; + local($str_to_do, $file_to_read, $tidy_name) = @_; print STDERR "\n$tidy_name:\n\t" if $Verbose; print STDERR "$str_to_do\n" if $Verbose; @@ -443,8 +612,8 @@ sub run_something { local($return_val) = system($str_to_do) >> 8; if ($return_val != 0) { - local($die_msg) = "$Pgm: execution of the $tidy_name had trouble"; - $die_msg .= " (program not found)" if $return_val == 255; + local($die_msg) = "$Pgm: Running $tidy_name ( on $file_to_read ) failed"; + $die_msg .= " program not found: $str_to_do " if $return_val == 255; $die_msg .= " ($!)" if $Verbose && $! != 0; $die_msg .= "\n"; print STDERR $die_msg;