[m-rev.] for review: Make mmc --make account for source files disappearing.

Peter Wang novalazy at gmail.com
Wed Apr 2 13:50:37 AEDT 2014


For the master branch.
---

mmc --make prints a grave error message when the source file of a module
can no longer be found:
    
** Module `foo' is imported or included by module `bar'.
** dependencies for `Mercury/int3s/foo.int3' do not exist: foo.m
** This indicates a bug in `mmc --make'.
    
compiler/make.module_dep_file.m:
    	Check that the source file of a local `.module_dep' file still
    	exists.  If it doesn't, delete the `.module_dep' file and ignore
    	the information it contains.

diff --git a/compiler/make.module_dep_file.m b/compiler/make.module_dep_file.m
index 8c2bb40..53f1b9f 100644
--- a/compiler/make.module_dep_file.m
+++ b/compiler/make.module_dep_file.m
@@ -456,7 +456,7 @@ read_module_dependencies_2(Globals, RebuildModuleDeps, SearchDirs, ModuleName,
         (
             TermResult = term(_, Term),
             read_module_dependencies_3(Globals, SearchDirs, ModuleName,
-                ModuleDir, Term, Result, !Info, !IO)
+                ModuleDir, ModuleDepFile, Term, Result, !Info, !IO)
         ;
             TermResult = eof,
             Result = error("unexpected eof")
@@ -479,11 +479,11 @@ read_module_dependencies_2(Globals, RebuildModuleDeps, SearchDirs, ModuleName,
     ).
 
 :- pred read_module_dependencies_3(globals::in, list(dir_name)::in,
-    module_name::in, dir_name::in, term::in, maybe_error::out,
+    module_name::in, dir_name::in, file_name::in, term::in, maybe_error::out,
     make_info::in, make_info::out, io::di, io::uo) is det.
 
 read_module_dependencies_3(Globals, SearchDirs, ModuleName, ModuleDir,
-        Term, Result, !Info, !IO) :-
+        ModuleDepFile, Term, Result, !Info, !IO) :-
     (
         atom_term(Term, "module", ModuleArgs),
         ModuleArgs = [
@@ -549,6 +549,21 @@ read_module_dependencies_3(Globals, SearchDirs, ModuleName, ModuleDir,
             ContainsForeignExport,
             Items, Specs, Errors, MaybeTimestamps, HasMain, ModuleDir),
 
+        % Discard the module dependencies if the module is a local module
+        % but the source file no longer exists.
+        ( ModuleDir = dir.this_directory ->
+            check_regular_file_exists(SourceFileName, SourceFileExists, !IO),
+            (
+                SourceFileExists = ok
+            ;
+                SourceFileExists = error(_),
+                io.remove_file(ModuleDepFile, _, !IO)
+            )
+        ;
+            SourceFileExists = ok
+        ),
+        (
+            SourceFileExists = ok,
             ModuleDepMap0 = !.Info ^ module_dependencies,
             % XXX Could this be map.det_insert?
             map.set(ModuleName, yes(Imports), ModuleDepMap0, ModuleDepMap),
@@ -569,6 +584,10 @@ read_module_dependencies_3(Globals, SearchDirs, ModuleName, ModuleDir,
                 Result = ok
             )
         ;
+            SourceFileExists = error(Error),
+            Result = error(Error)
+        )
+    ;
         Result = error("failed to parse term")
     ).
 
@@ -657,6 +676,37 @@ some_bad_module_dependency(Info, ModuleNames) :-
     list.member(ModuleName, ModuleNames),
     map.search(Info ^ module_dependencies, ModuleName, no).
 
+:- pred check_regular_file_exists(file_name::in, maybe_error::out,
+    io::di, io::uo) is det.
+
+check_regular_file_exists(FileName, FileExists, !IO) :-
+    FollowSymLinks = yes,
+    io.file_type(FollowSymLinks, FileName, ResFileType, !IO),
+    (
+        ResFileType = ok(FileType),
+        (
+            ( FileType = regular_file
+            ; FileType = unknown
+            ),
+            FileExists = ok
+        ;
+            ( FileType = directory
+            ; FileType = symbolic_link
+            ; FileType = named_pipe
+            ; FileType = socket
+            ; FileType = character_device
+            ; FileType = block_device
+            ; FileType = message_queue
+            ; FileType = semaphore
+            ; FileType = shared_memory
+            ),
+            FileExists = error(FileName ++ ": not a regular file")
+        )
+    ;
+        ResFileType = error(Error),
+        FileExists = error(FileName ++ ": " ++ io.error_message(Error))
+    ).
+
 %-----------------------------------------------------------------------------%
 
     % Something went wrong reading the dependencies, so just rebuild them.




More information about the reviews mailing list