mirror of
https://github.com/Mercury-Language/mercury.git
synced 2026-04-15 09:23:44 +00:00
master
9 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
a14544b7e7 |
Rationalize the code expanding @file cmd line args.
compiler/mercury_compile_args.m:
Instead of writing out any error messages (and setting the exit status)
in different ways in different circumstances, return all error messages
to our caller, as error_specs, and the option_table needed to print
those error_specs out.
Simplify the code that actually does the expansion of @file arguments,
both by invoking higher level primitives than were available when
the original code was written, and by avoiding repeatedly putting
arguments info ok/1 wrappers and taking them out again.
Change the argument list of setup_all_args to delete the ErrorStream
argument and pass only ProgressStream, because its only caller always
passes the *same* stream as both arguments.
compiler/mercury_compile_main.m:
Print the error messages that mercury_compile_args.m now returns.
Standardize on printing "mmc:" before those messages to identify
the program reporting those errors. (The old code could print any
one of "mercury_compile:", "mmc:", the name of the executable,
or nothing.)
compiler/file_util.m:
Add two utility functions for the new code in mercury_compile_args.m.
compiler/handle_options.m:
Add an XXX.
tests/invalid/invalid_mllibs.err_exp:
tests/invalid_make_int/bad_color.int_err_exp:
tests/invalid_options_file/inf_incl_direct.err_exp:
tests/invalid_options_file/inf_incl_indirect.err_exp:
tests/invalid_options_file/no_assign.err_exp:
tests/invalid_options_file/no_var.err_exp:
tests/invalid_options_file/nonexistent_file.err_exp:
tests/invalid_options_file/undefined_var.err_exp:
tests/invalid_options_file/unterminated_string.err_exp:
tests/invalid_options_file/unterminated_var.err_exp:
Consistently expect the "mmc:" prefix before the error messages
now printed by mercury_compile_main.m.
|
||
|
|
e84eae190f |
Improve diagnostics about options files.
compiler/options_file.m:
Include the word "error" in two error messages.
tests/invalid_options_file/Mmakefile:
Document why enabling color in this test directory would not work.
tests/invalid_options_file/no_assign.err_exp:
tests/invalid_options_file/nonexistent_file.err_exp:
Expect updated diagnostics.
|
||
|
|
a98cca7fb3 |
Fix case error in an error message.
compiler/options_file.m:
As above. Also make the error message conform to our usual standard
scheme: expected X, got Y.
tests/invalid_options_file/no_assign.err_exp:
Update the expected error message.
|
||
|
|
c16f53c0a3 |
Fix some test failures on Windows.
tests/invalid_options_file/inf_incl_direct.err_exp2:
tests/invalid_options_file/inf_incl_indirect.err_exp2:
tests/invalid_options_file/nonexistent_file.err_exp2:
Handle the case where "\" is used as the directory separator.
tests/invalid_options_file/inf_incl_direct.m:
tests/invalid_options_file/inf_incl_indirect.m:
tests/invalid_options_file/nonexistent_file.m:
Document what each of the .err_exp files corresponds to.
|
||
|
|
adac4e462b | Fix (inconsequential) bad module name. | ||
|
|
297dab88f8 |
Construct error messages using more readable code.
compiler/file_util.m:
compiler/find_module.m:
As above.
Also, put quotes around directory names where that wasn't done before.
tests/invalid_options_file/nonexistent_file.err_exp:
Expect quotes around a directory name.
|
||
|
|
adf6c55847 |
Shut up mmake actions for check_namespace.
This reduces the size of the output of tools/bootcheck by 3700+ lines,
or about 25%.
Mmake.common.in:
Don't print the actions implementing namespace cleanliness checks.
To allow the attribution of any violations of the namespace rules,
print the name of the C module before any list of detected
nonallowed symbols.
To avoid mmake printing the actions for creating the .o files
that some of the check_namespace actions later check, rename
the affected object files .pseudo_o files, so that we can specify
a rule for them that is a copy of the rule for .o files, differing
only in not printing the compilation command.
Mark the files involved in check_namespace actions as dependencies
of .SECONDARY, which means that mmake does not automatically delete them
after building them as intermediate files. The reason for this is that
there is no way to tell make to delete intermediate files *silently*,
i.e. without writing out the rm command that deletes them.
To make up for this, tools/bootcheck now cleans up each directory
immediately after "mmake check_namespace" with "mmake clean_check",
which invokes mmake rules that do not print the rm commands.
This change does have the effect that these intermediate files *will*
hang around if the check_namespace target is every invoked manually.
However,
- we just about never run check_namespace in a directory manually, and
- when we do, a simple "mmake clean_check" will do the required cleanup.
scripts/Mmake.rules:
Move the vim tag line to its usual place at the top.
Replace old-school rules such as .m.err with their modern equivalents
(such as %.err: %.m).
scripts/Mmakefile:
Instead of printing the rules that make test_mdbrc, print only a
"making test_mdbrc" message.
runtime/Mmakefile:
Conform to the change of the name of a make variable in Mmake.common.in.
ssdb/Mmakefile:
Fix an old bug that something else in this diff tickled: make the
.depend target of each main module depend on SSDB_FLAGS, *not* just
the phony general "depend" target. This was a bug because tools/bootcheck
- copied across to stage 2 ONLY SSDB_FLAGS.in, and NOT SSDB_FLAGS,
- did NOT explicitly make SSDB_FLAGS from SSDB_FLAGS.in, even though
pretty much invocations of the Mercury compiler in this directory
have "--flags SSDB_FLAGS" as an implicit argument, and then
- built dependencies in the ssdb directory by invoking the top
Mmakefile's dep_ssdb target, which (indirectly) invokes
$(SSDB_LIB_NAME).depend.
Due to all the above, I don't actually know how tools/bootcheck
could ever build stage2/ssdb until now :-(
tools/bootcheck:
Invoke "mmake clean_check" after each "mmake check_namespace".
Change the code that explicitly builds the directory-specific
X_FLAGS file in each directory (which is invoked only when using
mmc --make) to actually build all such files, when previously
it built only a subset.
tests/invalid/Mmakefile:
tests/invalid_nodepend/Mmakefile:
tests/invalid_onlydepend/Mmakefile:
tests/invalid_options_file/Mmakefile:
tests/invalid_purity/Mmakefile:
tests/invalid_submodules/Mmakefile:
tests/stm/Mmakefile:
Fix an unintended consequence of replacing the .m.err rule in
scripts/Mmake.rules with %.err: %.m, which is that the %.err: %.m
rules in these mmakefiles became ineffective, because they appear
in the makefile we construct *after* the rule in scripts/Mmake.rules,
which specify a different action (the rules here return a nonzero
status in the *absence* of failure, which would be ridiculous
for the rule in scripts/Mmake.rules). Apparently, the %.err: %.m rules
overrode the rule in scripts/Mmake.rules while it had the old form,
but do not do so now it has the new form.
The fix is to make replace all the "%.err: %.m" rules in these Mmakefiles
with "$(PROGS:%=%.err): %.err: %.m" rules, which specify that they
override the generic rule for the .err files of the test cases
in each directory.
In invalid_purity/Mmakefile, fix a bug: -nodepend suffixes make sense
in only in the name of a *test*, not the name of a *program*, so
move such a suffix from a program name to a test name. Without this,
the program's .err file would be included in the list of .err files
to which the ".err: .m" rule applies under the wrong name.
In invalid_submodules/Mmakefile, fix the misleading names of some
make variables, and fix a misspelt directory name.
Standardize on "$(PROGS:%=%.err)" notation, replacing earlier instances
of "$(addsuffix .err,$(PROGS))". The reason for this is that when I tried
using "$addsuffix .int_err,$(PROGS))" in tests/invalid/invalid_make_int,
it did not work. (A google search on "gnu make addsuffix" did not yield
any clues as to why. Maybe you can only add suffixes that do not contain
underscores?)
|
||
|
|
1676d74e87 |
diff --git a/compiler/options_file.m b/compiler/options_file.m
index f3a6ee999..e9675c97d 100644
--- a/compiler/options_file.m
+++ b/compiler/options_file.m
@@ -130,12 +130,14 @@
:- import_module parse_tree.
:- import_module parse_tree.error_util.
+:- import_module assoc_list.
:- import_module bool.
:- import_module char.
:- import_module dir.
:- import_module int.
:- import_module one_or_more.
:- import_module map.
+:- import_module pair.
:- import_module require.
:- import_module std_util.
:- import_module string.
@@ -195,17 +197,15 @@ read_options_file_set_params(OptionSearchDirs, OptionsFile,
IsOptionsFileOptional = options_file_must_exist
),
SearchInfo = search_info(MaybeDirName, MaybeSearch),
- MaybeContext = no,
- read_options_file_params(SearchInfo, MaybeContext, IsOptionsFileOptional,
+ read_options_file_params(SearchInfo, pre_stack_base, IsOptionsFileOptional,
OptionsFile, !Variables, !IOSpecs, !ParseSpecs, !UndefSpecs, !IO).
%---------------------%
read_named_options_file(OptionsPathName, !Variables, Specs, UndefSpecs, !IO) :-
SearchInfo = search_info(no, no_search),
- MaybeContext = no,
- read_options_file_params(SearchInfo, MaybeContext, options_file_must_exist,
- OptionsPathName, !Variables,
+ read_options_file_params(SearchInfo, pre_stack_base,
+ options_file_must_exist, OptionsPathName, !Variables,
[], IOSpecs, [], ParseSpecs, [], UndefSpecs, !IO),
Specs = IOSpecs ++ ParseSpecs.
@@ -261,25 +261,63 @@ read_args_file(OptionsFile, MaybeMCFlags, Specs, UndefSpecs, !IO) :-
---> options_file_need_not_exist
; options_file_must_exist.
+ % The inclusion stack records, for the options file being processed,
+ % which other options files, if any, contained the include directives
+ % that lead to it being read. We use it to detect circular inclusions.
+:- type incl_stack
+ ---> incl_stack_base(
+ % The file named here is either read automatically by
+ % the compiler (e.g. Mercury.options) or its reading
+ % was requested by the user via an --options-file
+ % compiler option.
+ file_name
+ )
+ ; incl_stack_nested(
+ % We read the file named here in response to an "include"
+ % directive.
+ file_name,
+
+ % The context of that include directive.
+ term.context,
+
+ % The "provenance" of the file that contains that include
+ % directive.
+ incl_stack
+ ).
+
+ % The pre_incl_stack is a version of the incl_stack *before* file_util.m
+ % finds the full pathname of a possibly-searched-for options file for us.
+:- type pre_incl_stack
+ ---> pre_stack_base
+ ; pre_stack_nested(term.context, incl_stack).
+
:- pred read_options_file_params(search_info::in,
- maybe(term.context)::in, is_options_file_optional::in,
+ pre_incl_stack::in, is_options_file_optional::in,
string::in, options_variables::in, options_variables::out,
list(error_spec)::in, list(error_spec)::out,
list(error_spec)::in, list(error_spec)::out,
list(error_spec)::in, list(error_spec)::out, io::di, io::uo) is det.
-read_options_file_params(SearchInfo, MaybeContext, IsOptionsFileOptional,
+read_options_file_params(SearchInfo, PreStack0, IsOptionsFileOptional,
OptionsPathName, !Variables,
!IOSpecs, !ParseSpecs, !UndefSpecs, !IO) :-
( if OptionsPathName = "-" then
- % Read from standard input.
- trace [compiletime(flag("options_file_debug")), io(!TIO)] (
- io.write_string("Reading options file from stdin...", !TIO)
- ),
- SearchInfo = search_info(_MaybeDirName, Search),
- SubSearchInfo = search_info(yes(dir.this_directory), Search),
- read_options_lines(SubSearchInfo, io.stdin_stream, "stdin", 1,
- !Variables, !IOSpecs, !ParseSpecs, !UndefSpecs, !IO)
+ check_include_for_infinite_recursion(PreStack0, "-", CheckResult),
+ (
+ CheckResult = include_ok(InclStack0),
+ % Read from standard input.
+ trace [compiletime(flag("options_file_debug")), io(!TIO)] (
+ io.write_string("Reading options file from stdin...", !TIO)
+ ),
+ SearchInfo = search_info(_MaybeDirName, Search),
+ SubSearchInfo = search_info(yes(dir.this_directory), Search),
+ read_options_lines(SubSearchInfo, InclStack0,
+ io.stdin_stream, "stdin", 1, !Variables,
+ !IOSpecs, !ParseSpecs, !UndefSpecs, !IO)
+ ;
+ CheckResult = include_error(CheckSpec),
+ !:ParseSpecs = [CheckSpec | !.ParseSpecs]
+ )
else
trace [compiletime(flag("options_file_debug")), io(!TIO)] (
io.format("Searching for options file %s",
@@ -329,22 +367,31 @@ read_options_file_params(SearchInfo, MaybeContext, IsOptionsFileOptional,
(
MaybeDirAndStream =
ok(path_name_and_stream(FoundDir, FoundStream)),
- trace [compiletime(flag("options_file_debug")), io(!TIO)] (
- io.format("Reading options file %s",
- [s(FoundDir/FileToFind)], !TIO)
- ),
+ check_include_for_infinite_recursion(PreStack0,
+ FoundDir / FileToFind, CheckResult),
+ (
+ CheckResult = include_ok(InclStack0),
+ trace [compiletime(flag("options_file_debug")), io(!TIO)] (
+ io.format("Reading options file %s",
+ [s(FoundDir/FileToFind)], !TIO)
+ ),
- % XXX Instead of setting and unsetting the input stream,
- % we should simply pass FoundStream to read_options_lines.
- % However, when I (zs) tried that, I quickly found that
- % the call tree of read_options_lines includes many predicates
- % for which it is not at all clear whether they *intend*
- % to read from a current standard input that originates as
- % FoundStream, or they just *happen* to do so.
-
- SubSearchInfo = search_info(yes(FoundDir), Search),
- read_options_lines(SubSearchInfo, FoundStream, FileToFind, 1,
- !Variables, !IOSpecs, !ParseSpecs, !UndefSpecs, !IO),
+ % XXX Instead of setting and unsetting the input stream,
+ % we should simply pass FoundStream to read_options_lines.
+ % However, when I (zs) tried that, I quickly found that
+ % the call tree of read_options_lines includes many predicates
+ % for which it is not at all clear whether they *intend*
+ % to read from a current standard input that originates as
+ % FoundStream, or they just *happen* to do so.
+
+ SubSearchInfo = search_info(yes(FoundDir), Search),
+ read_options_lines(SubSearchInfo, InclStack0,
+ FoundStream, FileToFind, 1, !Variables,
+ !IOSpecs, !ParseSpecs, !UndefSpecs, !IO)
+ ;
+ CheckResult = include_error(CheckSpec),
+ !:ParseSpecs = [CheckSpec | !.ParseSpecs]
+ ),
io.close_input(FoundStream, !IO)
;
MaybeDirAndStream = error(Error),
@@ -359,6 +406,13 @@ read_options_file_params(SearchInfo, MaybeContext, IsOptionsFileOptional,
else
ErrorFile = FileToFind
),
+ (
+ PreStack0 = pre_stack_base,
+ MaybeContext = no
+ ;
+ PreStack0 = pre_stack_nested(Context, _),
+ MaybeContext = yes(Context)
+ ),
Spec = error_spec($pred, severity_error, phase_read_files,
[error_msg(MaybeContext, treat_as_first, 0,
[always([words("Cannot open options file"),
@@ -374,6 +428,99 @@ read_options_file_params(SearchInfo, MaybeContext, IsOptionsFileOptional,
io.write_string("done.\n", !TIO)
).
+%---------------------%
+
+:- type include_check_result
+ ---> include_ok(incl_stack)
+ ; include_error(error_spec).
+
+:- pred check_include_for_infinite_recursion(pre_incl_stack::in,
+ file_name::in, include_check_result::out) is det.
+
+check_include_for_infinite_recursion(PreStack0, PathName, Result) :-
+ (
+ PreStack0 = pre_stack_base,
+ InclStack = incl_stack_base(PathName),
+ Result = include_ok(InclStack)
+ ;
+ PreStack0 = pre_stack_nested(Context, InclStack0),
+ ( if
+ pathname_occurs_in_incl_stack(InclStack0, PathName, Context, Spec)
+ then
+ Result = include_error(Spec)
+ else
+ InclStack = incl_stack_nested(PathName, Context, InclStack0),
+ Result = include_ok(InclStack)
+ )
+ ).
+
+:- pred pathname_occurs_in_incl_stack(incl_stack::in, file_name::in,
+ term.context::in, error_spec::out) is semidet.
+
+pathname_occurs_in_incl_stack(InclStack0, PathName, Context, Spec) :-
+ (
+ InclStack0 = incl_stack_base(StackPathName0),
+ ( if PathName = StackPathName0 then
+ Pieces = [words("Error: options file"), quote(PathName),
+ words("includes itself."), nl],
+ Spec = simplest_spec($pred, severity_error, phase_read_files,
+ Context, Pieces)
+ else
+ fail
+ )
+ ;
+ InclStack0 = incl_stack_nested(StackPathName0, Context0, InclStack1),
+ ( if PathName = StackPathName0 then
+ Pieces = [words("Error: options file"), quote(PathName),
+ words("includes itself."), nl],
+ Spec = simplest_spec($pred, severity_error, phase_read_files,
+ Context, Pieces)
+ else
+ ( if
+ pathname_occurs_in_incl_stack_2(InclStack1, PathName,
+ [StackPathName0 - Context0], TopDownIncludes)
+ then
+ TopPathName - TopContext = list.det_head(TopDownIncludes),
+ MainPieces = [words("Error: options file"), quote(TopPathName),
+ words("indirectly includes itself through"),
+ words("the following chain of include directives."), nl],
+ MainMsg = simplest_msg(TopContext, MainPieces),
+ InclMsgs = list.map(include_context_msg, TopDownIncludes),
+ LastMsg = include_context_msg(PathName - Context),
+ Spec = error_spec($pred, severity_error, phase_read_files,
+ [MainMsg | InclMsgs] ++ [LastMsg])
+ else
+ fail
+ )
+ )
+ ).
+
+:- pred pathname_occurs_in_incl_stack_2(incl_stack::in, file_name::in,
+ assoc_list(file_name, term.context)::in,
+ assoc_list(file_name, term.context)::out) is semidet.
+
+pathname_occurs_in_incl_stack_2(InclStack0, PathName, !TopDownIncludes) :-
+ (
+ InclStack0 = incl_stack_base(StackPathName0),
+ PathName = StackPathName0
+ ;
+ InclStack0 = incl_stack_nested(StackPathName0, Context0, InclStack1),
+ !:TopDownIncludes = [StackPathName0 - Context0 | !.TopDownIncludes],
+ ( if PathName = StackPathName0 then
+ true
+ else
+ pathname_occurs_in_incl_stack_2(InclStack1, PathName,
+ !TopDownIncludes)
+ )
+ ).
+
+:- func include_context_msg(pair(file_name, term.context)) = error_msg.
+
+include_context_msg(FileName - Context) = Msg :-
+ Pieces = [words("The include directive for"), quote(FileName),
+ words("here."), nl],
+ Msg = simplest_msg(Context, Pieces).
+
%---------------------------------------------------------------------------%
:- type maybe_is_first
@@ -387,15 +534,15 @@ read_options_file_params(SearchInfo, MaybeContext, IsOptionsFileOptional,
%---------------------------------------------------------------------------%
-:- pred read_options_lines(search_info::in,
+:- pred read_options_lines(search_info::in, incl_stack::in,
io.text_input_stream::in, file_name::in, int::in,
options_variables::in, options_variables::out,
list(error_spec)::in, list(error_spec)::out,
list(error_spec)::in, list(error_spec)::out,
list(error_spec)::in, list(error_spec)::out, io::di, io::uo) is det.
-read_options_lines(SearchInfo, InStream, FileName, LineNumber0, !Variables,
- !IOSpecs, !ParseSpecs, !UndefSpecs, !IO) :-
+read_options_lines(SearchInfo, InclStack0, InStream, FileName, LineNumber0,
+ !Variables, !IOSpecs, !ParseSpecs, !UndefSpecs, !IO) :-
read_options_line(InStream, FileName, LineNumber0, LineNumber1,
LineResult, !IO),
(
@@ -425,9 +572,10 @@ read_options_lines(SearchInfo, InStream, FileName, LineNumber0, !Variables,
(
MaybeIncludedFileNames = ok(IncludedFileNames),
Context = term.context(FileName, LineNumber0),
+ PreStack1 = pre_stack_nested(Context, InclStack0),
list.foldl5(
read_options_file_params(SearchInfo,
- yes(Context), IsOptionsFileOptional),
+ PreStack1, IsOptionsFileOptional),
IncludedFileNames, !Variables,
!IOSpecs, !ParseSpecs, !UndefSpecs, !IO)
;
@@ -443,8 +591,9 @@ read_options_lines(SearchInfo, InStream, FileName, LineNumber0, !Variables,
)
),
LineNumber2 = LineNumber1 + 1,
- read_options_lines(SearchInfo, InStream, FileName, LineNumber2,
- !Variables, !IOSpecs, !ParseSpecs, !UndefSpecs, !IO)
+ read_options_lines(SearchInfo, InclStack0, InStream,
+ FileName, LineNumber2, !Variables,
+ !IOSpecs, !ParseSpecs, !UndefSpecs, !IO)
;
LineResult = pr_error(Spec),
!:IOSpecs = [Spec | !.IOSpecs]
diff --git a/tests/invalid_options_file/Mmakefile b/tests/invalid_options_file/Mmakefile
index 3642a03cc..b6965ae16 100644
--- a/tests/invalid_options_file/Mmakefile
+++ b/tests/invalid_options_file/Mmakefile
@@ -7,6 +7,8 @@ THIS_DIR = invalid_options_file
MAYBE_J1 =
PROGS = \
+ inf_incl_direct \
+ inf_incl_indirect \
no_assign \
no_var \
nonexistent_file \
diff --git a/tests/invalid_options_file/inf_incl_direct.err_exp b/tests/invalid_options_file/inf_incl_direct.err_exp
index e69de29bb..4466b9dee 100644
--- a/tests/invalid_options_file/inf_incl_direct.err_exp
+++ b/tests/invalid_options_file/inf_incl_direct.err_exp
@@ -0,0 +1,3 @@
+inf_incl_direct.options_file:002: Error: options file
+inf_incl_direct.options_file:002: `./inf_incl_direct.options_file' includes
+inf_incl_direct.options_file:002: itself.
diff --git a/tests/invalid_options_file/inf_incl_direct.m b/tests/invalid_options_file/inf_incl_direct.m
index e69de29bb..64ae69ad8 100644
--- a/tests/invalid_options_file/inf_incl_direct.m
+++ b/tests/invalid_options_file/inf_incl_direct.m
@@ -0,0 +1,16 @@
+%---------------------------------------------------------------------------%
+% vim: ts=4 sw=4 et ft=mercury
+%---------------------------------------------------------------------------%
+
+:- module infinite_include_direct.
+
+:- interface.
+
+:- import_module io.
+
+:- pred main(io::di, io::uo) is det.
+
+:- implementation.
+
+main(!IO) :-
+ io.write_string("Hello, world.\n", !IO).
diff --git a/tests/invalid_options_file/inf_incl_direct.options_file b/tests/invalid_options_file/inf_incl_direct.options_file
index e69de29bb..432f30bd1 100644
--- a/tests/invalid_options_file/inf_incl_direct.options_file
+++ b/tests/invalid_options_file/inf_incl_direct.options_file
@@ -0,0 +1,2 @@
+MCFLAGS += -V
+include inf_incl_direct.options_file
diff --git a/tests/invalid_options_file/inf_incl_indirect.err_exp b/tests/invalid_options_file/inf_incl_indirect.err_exp
index e69de29bb..88527df26 100644
--- a/tests/invalid_options_file/inf_incl_indirect.err_exp
+++ b/tests/invalid_options_file/inf_incl_indirect.err_exp
@@ -0,0 +1,23 @@
+inf_incl_indirect.options_file:002: Error: options file
+inf_incl_indirect.options_file:002: `./inf_incl_indirect.options_file_a'
+inf_incl_indirect.options_file:002: indirectly includes itself through the
+inf_incl_indirect.options_file:002: following chain of include directives.
+inf_incl_indirect.options_file:002: The include directive for
+inf_incl_indirect.options_file:002: `./inf_incl_indirect.options_file_a'
+inf_incl_indirect.options_file:002: here.
+inf_incl_indirect.options_file_a:002: The include directive for
+inf_incl_indirect.options_file_a:002: `./inf_incl_indirect.options_file_b'
+inf_incl_indirect.options_file_a:002: here.
+inf_incl_indirect.options_file_b:002: The include directive for
+inf_incl_indirect.options_file_b:002: `./inf_incl_indirect.options_file'
+inf_incl_indirect.options_file_b:002: here.
+inf_incl_indirect.options_file:003: Error: options file
+inf_incl_indirect.options_file:003: `./inf_incl_indirect.options_file_b'
+inf_incl_indirect.options_file:003: indirectly includes itself through the
+inf_incl_indirect.options_file:003: following chain of include directives.
+inf_incl_indirect.options_file:003: The include directive for
+inf_incl_indirect.options_file:003: `./inf_incl_indirect.options_file_b'
+inf_incl_indirect.options_file:003: here.
+inf_incl_indirect.options_file_b:002: The include directive for
+inf_incl_indirect.options_file_b:002: `./inf_incl_indirect.options_file'
+inf_incl_indirect.options_file_b:002: here.
diff --git a/tests/invalid_options_file/inf_incl_indirect.m b/tests/invalid_options_file/inf_incl_indirect.m
index e69de29bb..64ae69ad8 100644
--- a/tests/invalid_options_file/inf_incl_indirect.m
+++ b/tests/invalid_options_file/inf_incl_indirect.m
@@ -0,0 +1,16 @@
+%---------------------------------------------------------------------------%
+% vim: ts=4 sw=4 et ft=mercury
+%---------------------------------------------------------------------------%
+
+:- module infinite_include_direct.
+
+:- interface.
+
+:- import_module io.
+
+:- pred main(io::di, io::uo) is det.
+
+:- implementation.
+
+main(!IO) :-
+ io.write_string("Hello, world.\n", !IO).
diff --git a/tests/invalid_options_file/inf_incl_indirect.options_file b/tests/invalid_options_file/inf_incl_indirect.options_file
index e69de29bb..a3a3ec858 100644
--- a/tests/invalid_options_file/inf_incl_indirect.options_file
+++ b/tests/invalid_options_file/inf_incl_indirect.options_file
@@ -0,0 +1,3 @@
+MCFLAGS += -V
+include inf_incl_indirect.options_file_a
+include inf_incl_indirect.options_file_b
diff --git a/tests/invalid_options_file/inf_incl_indirect.options_file_a b/tests/invalid_options_file/inf_incl_indirect.options_file_a
index e69de29bb..bc0583dc9 100644
--- a/tests/invalid_options_file/inf_incl_indirect.options_file_a
+++ b/tests/invalid_options_file/inf_incl_indirect.options_file_a
@@ -0,0 +1,2 @@
+MCFLAGS += -A
+include inf_incl_indirect.options_file_b
diff --git a/tests/invalid_options_file/inf_incl_indirect.options_file_b b/tests/invalid_options_file/inf_incl_indirect.options_file_b
index e69de29bb..e7b843ab1 100644
--- a/tests/invalid_options_file/inf_incl_indirect.options_file_b
+++ b/tests/invalid_options_file/inf_incl_indirect.options_file_b
@@ -0,0 +1,2 @@
+MCFLAGS += -B
+include inf_incl_indirect.options_file
|
||
|
|
ac50b3cbd1 |
Do not use exceptions in options_file.m.
And add tests for how the compiler handles both valid and invalid
options files.
compiler/options_file.m:
This diff rewrites options_file.m in a straightforward, direct style that
returns indications of errors as error_specs rather than as exceptions.
A recent diff started on this task; this diff finishes it.
The new approach has several advantages.
- The control flow is much simpler, and therefore more understandable.
Correctness arguments for propositions such as "this code closes
all the file streams that it opens" are now much simpler to make.
- We now report errors using error_specs, which contain context
information, while previously, each error was described only
by a string, without context info.
- Once we detect and report one error, we can continue to read the
rest of the input. This allows a single compiler invocation to find
and report several errors, not just the first.
- Since we now return the gathered set of error_specs instead of printing
them, the predicates of this file don't have to take globals structures
as arguments, which allows our callers to avoid constructing those
structures.
- Deep profiling, which cannot handle exceptions, now works on
the code of this module.
Change over to using trace goals for debugging prints, since continuing
to use debug_make_msg would require a globals structure.
Add an XXX on a likely bug.
Add a mechanism for writing out a database of variable names and values.
compiler/mercury_compile_main.m:
Conform to the changes in options_file.m. Document where exactly
we could avoid constructing a globals just for options_file.m.
If the right option is given, get options_file to write out the database
of variable names and values it has just read in, to enable the
functionality of this module to be tested.
compiler/options.m:
doc/user_guide.texi:
Add a new developer option, --dump-options-file, to control the above.
compiler/make.build.m:
compiler/make.m:
compiler/make.program_target.m:
Conform to the changes in options_file.m.
compiler/file_util.m:
Fix an error message.
tests/Mmakefile:
tools/bootcheck:
List options_file and invalid_options_file as two new test directories.
Fix a command in bootcheck.
tests/options_file/Mmakefile:
Add a mechanism for testing whether options_file.m builds mapping
from make variable names to values that we expect.
tests/Mmake.common:
Provide a mechanism for comparing dumped options_files against
their expected contents, for use by tests/invalid_options_file/Mmakefile.
Fix a comment.
tests/options_file/basic_test.m:
tests/options_file/basic_test.optfile_exp:
tests/options_file/basic_test.options_file:
tests/options_file/basic_test.options_file.sub0:
tests/options_file/basic_test.options_file.sub1:
A simple test case for exercising all the usual options_file constructs.
tests/invalid_options_file/Mmakefile:
Add a mechanism for testing whether options_file.m generates
the error messages we expect for various kinds of errors in options files.
tests/invalid_options_file/no_assign.{m,options_file,err_exp}:
tests/invalid_options_file/no_var.{m,options_file,err_exp}:
tests/invalid_options_file/nonexistent_file.{m,options_file,err_exp}:
tests/invalid_options_file/undefined_var.{m,options_file,err_exp}:
tests/invalid_options_file/unterminated_string.{m,options_file,err_exp}:
tests/invalid_options_file/unterminated_var.{m,options_file,err_exp}:
Six test cases to test six different kinds of errors that can be
detected by options_file.m.
|