[m-rev.] for review: fix module search bug
Simon Taylor
staylr at gmail.com
Mon May 14 16:19:27 AEST 2007
Estimated hours taken: 2
Branches: main
compiler/modules.m:
compiler/prog_io.m:
Fix a bug which caused the presence of a file named write.m
in the current directory to stop the compiler finding a module
bit_buffer.write in a library. The test case for this is
tests/hard_coded/bit_buffer_test.m.
`mmc --make' already handled this correctly.
Index: compiler/modules.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/modules.m,v
retrieving revision 1.422
diff -u -u -r1.422 modules.m
--- compiler/modules.m 7 May 2007 05:21:34 -0000 1.422
+++ compiler/modules.m 13 May 2007 11:05:12 -0000
@@ -3919,7 +3919,8 @@
!:OptDeps, !:TransOptDeps, !IO),
(
BuildOptFiles = yes,
- search_for_module_source(IntermodDirs, Dep, Result1, !IO),
+ search_for_module_source(IntermodDirs, IntermodDirs,
+ Dep, Result1, !IO),
(
Result1 = ok(_),
!:OptDeps = [Dep | !.OptDeps],
@@ -3973,7 +3974,8 @@
get_opt_deps(BuildOptFiles, Deps, IntermodDirs, Suffix, !:OptDeps, !IO),
(
BuildOptFiles = yes,
- search_for_module_source(IntermodDirs, Dep, Result1, !IO),
+ search_for_module_source(IntermodDirs, IntermodDirs,
+ Dep, Result1, !IO),
(
Result1 = ok(_),
!:OptDeps = [Dep | !.OptDeps],
@@ -6395,18 +6397,23 @@
maybe_write_string(VeryVerbose, "'... ", !IO),
maybe_flush_output(VeryVerbose, !IO),
+ globals.io_lookup_accumulating_option(search_directories,
+ InterfaceSearchDirs, !IO),
(
Search = yes,
- globals.io_lookup_accumulating_option(search_directories, SearchDirs,
- !IO)
+ SearchDirs = InterfaceSearchDirs
;
Search = no,
SearchDirs = [dir.this_directory]
),
( Extension = ".m" ->
% For `.m' files we need to deal with the case where
- % the module name does not match the file name.
- OpenFile = search_for_module_source(SearchDirs, ModuleName)
+ % the module name does not match the file name, or where
+ % a partial match occurs in the current directory but the
+ % full match occurs in a search directory.
+ %
+ OpenFile = search_for_module_source(SearchDirs,
+ InterfaceSearchDirs, ModuleName)
;
OpenFile = search_for_file(SearchDirs, FileName0)
),
Index: compiler/prog_io.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/prog_io.m,v
retrieving revision 1.281
diff -u -u -r1.281 prog_io.m
--- compiler/prog_io.m 19 Jan 2007 07:04:27 -0000 1.281
+++ compiler/prog_io.m 14 May 2007 00:07:16 -0000
@@ -145,14 +145,17 @@
:- pred search_for_file_returning_dir(list(dir_name)::in, file_name::in,
maybe_error(dir_name)::out, io::di, io::uo) is det.
- % search_for_module_source(Dirs, ModuleName, FoundSourceFileName, !IO):
+ % search_for_module_source(Dirs, InterfaceDirs, ModuleName,
+ % FoundSourceFileName, !IO):
%
% Look for the source for ModuleName in Dirs. This will also search for
- % files matching partially qualified versions of ModuleName. For example,
- % module foo.bar.baz can be found in foo.bar.m, bar.baz.m or bar.m.
+ % files matching partially qualified versions of ModuleName, but only if
+ % a more qualified `.m' or `.int' file doesn't exist in InterfaceDirs.
+ % in InterfaceDirs. For example, module foo.bar.baz can be found in
+ % foo.bar.m, bar.baz.m or bar.m.
%
-:- pred search_for_module_source(list(dir_name)::in, module_name::in,
- maybe_error(file_name)::out, io::di, io::uo) is det.
+:- pred search_for_module_source(list(dir_name)::in, list(dir_name)::in,
+ module_name::in, maybe_error(file_name)::out, io::di, io::uo) is det.
% Read the first item from the given file to find the module name.
%
@@ -432,14 +435,92 @@
search_for_file_returning_dir(Dirs, AllDirs, FileName, R, !IO)
).
-search_for_module_source(Dirs, ModuleName, MaybeFileName, !IO) :-
- search_for_module_source(Dirs, ModuleName, ModuleName, MaybeFileName, !IO).
+search_for_module_source(Dirs, InterfaceDirs,
+ ModuleName, MaybeFileName, !IO) :-
+ search_for_module_source_2(Dirs, ModuleName, ModuleName,
+ MaybeFileName0, !IO),
+ (
+ MaybeFileName0 = ok(SourceFileName),
+ (
+ string.remove_suffix(dir.basename(SourceFileName),
+ ".m", SourceFileBaseName),
+ file_name_to_module_name(SourceFileBaseName, SourceFileModuleName),
+ ModuleName \= SourceFileModuleName
+ ->
+ % The module name doesn't match the file name. Return an error
+ % if there is a more qualified matching `.m' or `.int' file in
+ % the interface search path. This avoids having a file `read.m'
+ % in the current directory prevent the compiler from finding
+ % `bit_buffer.read.int' in the standard library.
+ %
+ io.input_stream(SourceStream, !IO),
+ search_for_module_source_2(InterfaceDirs, ModuleName,
+ ModuleName, MaybeFileName2, !IO),
+ ( MaybeFileName2 = ok(_) ->
+ io.seen(!IO)
+ ;
+ true
+ ),
+ (
+ MaybeFileName2 = ok(SourceFileName2),
+ SourceFileName2 \= SourceFileName,
+ string.remove_suffix(dir.basename(SourceFileName2), ".m",
+ SourceFileBaseName2),
+ file_name_to_module_name(SourceFileBaseName2,
+ SourceFileModuleName2),
+ match_sym_name(SourceFileModuleName, SourceFileModuleName2)
+ ->
+ io.close_input(SourceStream, !IO),
+ MaybeFileName = error(find_source_error(ModuleName,
+ Dirs, yes(SourceFileName2)))
+ ;
+ module_name_to_file_name(ModuleName, ".int", no, IntFile, !IO),
+ search_for_file_returning_dir(InterfaceDirs, IntFile,
+ MaybeIntDir, !IO),
+ ( MaybeIntDir = ok(_) ->
+ io.seen(!IO)
+ ;
+ true
+ ),
+ (
+ MaybeIntDir = ok(IntDir),
+ IntDir \= dir.this_directory
+ ->
+ io.close_input(SourceStream, !IO),
+ MaybeFileName = error(find_source_error(ModuleName,
+ Dirs, yes(IntDir/IntFile)))
+ ;
+ io.set_input_stream(SourceStream, _, !IO),
+ MaybeFileName = MaybeFileName0
+ )
+ )
+ ;
+ MaybeFileName = MaybeFileName0
+ )
+ ;
+ MaybeFileName0 = error(_),
+ MaybeFileName = MaybeFileName0
+ ).
-:- pred search_for_module_source(list(dir_name)::in,
- module_name::in, module_name::in, maybe_error(file_name)::out,
- io::di, io::uo) is det.
+:- func find_source_error(module_name, list(dir_name),
+ maybe(file_name)) = string.
+
+find_source_error(ModuleName, Dirs, MaybeBetterMatch) = Msg :-
+ ModuleNameStr = sym_name_to_string(ModuleName),
+ Msg0 = "cannot find source for module `" ++ ModuleNameStr ++
+ "' in directories " ++ string.join_list(", ", Dirs),
+ (
+ MaybeBetterMatch = no, Msg = Msg0
+ ;
+ MaybeBetterMatch = yes(BetterMatchFile),
+ Msg = Msg0 ++ ", but found " ++ BetterMatchFile
+ ++ " in interface search path"
+ ).
+
+:- pred search_for_module_source_2(list(dir_name)::in, module_name::in,
+ module_name::in, maybe_error(file_name)::out, io::di, io::uo) is det.
-search_for_module_source(Dirs, ModuleName, PartialModuleName, Result, !IO) :-
+search_for_module_source_2(Dirs, ModuleName, PartialModuleName, Result, !IO) :-
module_name_to_file_name(PartialModuleName, ".m", no, FileName, !IO),
search_for_file(Dirs, FileName, Result0, !IO),
(
@@ -450,12 +531,10 @@
(
PartialModuleName1 = drop_one_qualifier(PartialModuleName)
->
- search_for_module_source(Dirs, ModuleName, PartialModuleName1,
+ search_for_module_source_2(Dirs, ModuleName, PartialModuleName1,
Result, !IO)
;
- ModuleNameStr = sym_name_to_string(ModuleName),
- Result = error("can't find source for module `" ++
- ModuleNameStr ++ "'")
+ Result = error(find_source_error(ModuleName, Dirs, no))
)
).
--------------------------------------------------------------------------
mercury-reviews mailing list
Post messages to: mercury-reviews at csse.unimelb.edu.au
Administrative Queries: owner-mercury-reviews at csse.unimelb.edu.au
Subscriptions: mercury-reviews-request at csse.unimelb.edu.au
--------------------------------------------------------------------------
More information about the reviews
mailing list