[m-rev.] for review: document `--use-grade-subdirs'
Simon Taylor
stayl at cs.mu.OZ.AU
Fri Nov 1 01:27:07 AEDT 2002
On 30-Oct-2002, Fergus Henderson <fjh at cs.mu.OZ.AU> wrote:
> On 30-Oct-2002, Simon Taylor <stayl at cs.mu.OZ.AU> wrote:
> > Index: NEWS
> > ===================================================================
> > +* There is a new `--use-grade-subdirs' option which is similar to
> > + `--use-subdirs', but allows multiple grades to be built in a
> > + directory at the same time. `--use-grade-subdirs' does not
> > + work with Mmake.
>
> It might be worth mentioning here that it does work with --make.
Done.
> > Index: compiler/compile_target_code.m
> > + % Link/copy the executable into the user's
> > + % directory. We don't do this for libraries
> > + % because in general they shouldn't be used
> > + % without being installed.
>
> I don't agree with the comment here.
> Often it does make sense to use a library before it is installed.
Fixed.
> > + make_symlink(OutputFileName, UserDirExeName,
> > + SymlinkSucceeded),
> > + ( { SymlinkSucceeded = yes } ->
> > + { Succeeded = yes }
> > + ;
> > + copy_file(OutputFileName, UserDirExeName,
> > + CopyRes),
>
> It would probably be worth abstracting the "make_symlink || copy_file"
> functionality out into a separate procedure.
Done.
> > +++ compiler/modules.m 29 Oct 2002 13:59:32 -0000
> ...
> > + % XXX This belongs in the library.
>
> s/library/standard library/g
Done.
> > + % make_symlink(LinkTarget, LinkName, Succeeded)
> > + %
> > + % Make a LinkName a symlink pointing to LinkTarget.
>
> s/a LinkName/LinkName/
Done.
> > +copy_file(Source, Destination, Res) -->
> > + io__open_input(Source, SourceRes),
>
> For copying files, you should use binary mode, not text mode.
Done.
> > Index: doc/user_guide.texi
> > ===================================================================
> > @@ -6188,6 +6188,17 @@
> > Create intermediate files in a @file{Mercury} subdirectory,
> > rather than in the current directory.
> >
> > + at item --use-grade-subdirs
> > + at findex --use-grade-subdirs
> > + at cindex File names
> > + at cindex Directories
> > + at cindex Subdirectories
> > + at cindex @file{Mercury} subdirectory
>
> I suggest also
>
> @cindex Grades
Done.
Simon.
Estimated hours taken: 2.5
Branches: main
Improve the handling of `--use-grade-subdirs' so that it can
be documented.
compiler/compile_target_code.m:
With `--use-grade-subdirs', link or copy executables
into the user's directory.
compiler/make.program_target.m:
compiler/modules.m:
Move code to create a symlink into modules.m, next to
the code to create directories (all of this should really
go in the standard library).
Add a predicate to copy a file (which should also go
in the standard library).
compiler/make.program_target.m:
Make the realclean target delete the symlinks or copies
of executables and libraries.
NEWS:
library/io.m:
Add io__binary_input_stream_foldl, etc. for use in copying files.
NEWS:
compiler/options.m:
doc/user_guide.texi:
Document `--use-grade-subdirs'.
diff -u NEWS NEWS
--- NEWS
+++ NEWS
@@ -149,6 +149,9 @@
* We've added predicates `io__input_stream_foldl', `io__input_stream_foldl_io'
and `io__input_stream_foldl2_io', which apply a predicate to each character
of an input stream in turn.
+* We've added predicates `io__binary_input_stream_foldl',
+ `io__binary_input_stream_foldl_io' and `io__binary_input_stream_foldl2_io',
+ which apply a predicate to each byte of a binary input stream in turn.
* We've added versions of `io__print', `io__write' and `io__write_univ'
that allow the caller to specify how they should treat values of noncanonical
types, e.g. types in which a single semantic value may have more than one
@@ -322,7 +325,7 @@
* There is a new `--use-grade-subdirs' option which is similar to
`--use-subdirs', but allows multiple grades to be built in a
directory at the same time. `--use-grade-subdirs' does not
- work with Mmake.
+ work with Mmake (it does work with `mmc --make').
* We've added a new compiler option `--warn-non-tail-recursion', which
causes the compiler to issue a warning about any directly recursive
diff -u compiler/compile_target_code.m compiler/compile_target_code.m
--- compiler/compile_target_code.m
+++ compiler/compile_target_code.m
globals__io_lookup_bool_option(use_grade_subdirs,
UseGradeSubdirs),
(
{ LinkSucceeded = yes },
- { LinkTargetType = executable },
{ UseGradeSubdirs = yes }
->
- % Link/copy the executable into the user's
- % directory. We don't do this for libraries
- % because in general they shouldn't be used
- % without being installed.
+ % Link/copy the executable into the user's directory.
+ globals__io_set_option(use_subdirs, bool(no)),
globals__io_set_option(use_grade_subdirs, bool(no)),
- module_name_to_file_name(ModuleName, "", no,
- UserDirExeName),
- globals__io_set_option(use_grade_subdirs,
- bool(UseGradeSubdirs)),
-
- make_symlink(OutputFileName, UserDirExeName,
- SymlinkSucceeded),
- ( { SymlinkSucceeded = yes } ->
- { Succeeded = yes }
- ;
- copy_file(OutputFileName, UserDirExeName,
- CopyRes),
- (
- { CopyRes = ok },
- { Succeeded = yes }
- ;
- { CopyRes = error(CopyError) },
- { Succeeded = no },
- io__progname_base("mercury_compile",
- ProgName),
- io__write_string(ErrorStream,
- ProgName),
- io__write_string(": can't copy "),
- io__write_string(OutputFileName),
- io__write_string(
- " into the current directory:"),
- io__write_string(
- io__error_message(CopyError))
- )
- )
+ module_name_to_file_name(ModuleName, "",
+ no, UserDirExeName),
+ globals__io_set_option(use_subdirs, bool(yes)),
+ globals__io_set_option(use_grade_subdirs, bool(yes)),
+
+ io__set_output_stream(ErrorStream, OutputStream),
+ make_symlink_or_copy_file(OutputFileName,
+ UserDirExeName, Succeeded),
+ io__set_output_stream(OutputStream, _)
;
{ Succeeded = LinkSucceeded }
)
diff -u compiler/make.program_target.m compiler/make.program_target.m
--- compiler/make.program_target.m
+++ compiler/make.program_target.m
@@ -855,8 +855,21 @@
linked_target_file_name(ModuleName, executable, ExeFileName),
linked_target_file_name(ModuleName, static_library, LibFileName),
linked_target_file_name(ModuleName, shared_library, SharedLibFileName),
+
+ % Remove the symlinks created for `--use-grade-subdirs'.
+ globals__io_lookup_bool_option(use_grade_subdirs, UseGradeSubdirs),
+ globals__io_set_option(use_grade_subdirs, bool(no)),
+ linked_target_file_name(ModuleName, executable, ThisDirExeFileName),
+ linked_target_file_name(ModuleName, static_library,
+ ThisDirLibFileName),
+ linked_target_file_name(ModuleName, shared_library,
+ ThisDirSharedLibFileName),
+ globals__io_set_option(use_grade_subdirs, bool(UseGradeSubdirs)),
+
list__foldl2(remove_file,
- [ExeFileName, LibFileName, SharedLibFileName],
+ [ExeFileName, LibFileName, SharedLibFileName,
+ ThisDirExeFileName, ThisDirLibFileName,
+ ThisDirSharedLibFileName],
Info0, Info1),
remove_file(ModuleName, ".init", Info1, Info2),
remove_init_files(ModuleName, Info2, Info).
diff -u compiler/modules.m compiler/modules.m
--- compiler/modules.m
+++ compiler/modules.m
@@ -681,7 +681,7 @@
% make_directory(Dir, Succeeded)
%
% Make the directory Dir and all its parents.
- % XXX This belongs in the library.
+ % XXX This belongs in the standard library.
:- pred make_directory(dir_name, bool, io__state, io__state).
:- mode make_directory(in, out, di, uo) is det.
@@ -690,17 +690,25 @@
% make_symlink(LinkTarget, LinkName, Succeeded)
%
- % Make a LinkName a symlink pointing to LinkTarget.
- % XXX This belongs in the library.
+ % Make LinkName a symlink pointing to LinkTarget.
+ % XXX This belongs in the standard library.
:- pred make_symlink(file_name, file_name, bool, io__state, io__state).
:- mode make_symlink(in, in, out, di, uo) is det.
% copy_file(Source, Destination, Succeeded).
%
- % XXX This belongs in the library.
+ % XXX This belongs in the standard library.
:- pred copy_file(file_name, file_name, io__res, io__state, io__state).
:- mode copy_file(in, in, out, di, uo) is det.
+ % make_symlink_or_copy_file(LinkTarget, LinkName, Succeeded).
+ %
+ % Attempt to make LinkName a symlink pointing to LinkTarget,
+ % copying LinkTarget to LinkName if that fails.
+:- pred make_symlink_or_copy_file(file_name, file_name,
+ bool, io__state, io__state).
+:- mode make_symlink_or_copy_file(in, in, out, di, uo) is det.
+
%-----------------------------------------------------------------------------%
% Check whether a particular `pragma' declaration is allowed
@@ -1077,21 +1085,21 @@
invoke_shell_command(ErrorStream, verbose, Command, Result).
copy_file(Source, Destination, Res) -->
- io__open_input(Source, SourceRes),
+ io__open_binary_input(Source, SourceRes),
(
{ SourceRes = ok(InputStream) },
- io__open_output(Destination, DestRes),
+ io__open_binary_output(Destination, DestRes),
(
{ DestRes = ok(OutputStream) },
% XXX Depending on file size it may be
% faster to call the system's cp command.
- io__input_stream_foldl_io(
+ io__binary_input_stream_foldl_io(
(pred(Char::in, di, uo) is det -->
- io__write_char(Char)
+ io__write_byte(Char)
),
Res),
- io__close_input(InputStream),
- io__close_output(OutputStream)
+ io__close_binary_input(InputStream),
+ io__close_binary_output(OutputStream)
;
{ DestRes = error(Error) },
{ Res = error(Error) }
@@ -1099,6 +1107,31 @@
;
{ SourceRes = error(Error) },
{ Res = error(Error) }
+ ).
+
+make_symlink_or_copy_file(SourceFileName, DestinationFileName, Succeeded) -->
+ make_symlink(SourceFileName, DestinationFileName, SymlinkSucceeded),
+ ( { SymlinkSucceeded = yes } ->
+ { Succeeded = yes }
+ ;
+ copy_file(SourceFileName, DestinationFileName,
+ CopyRes),
+ (
+ { CopyRes = ok },
+ { Succeeded = yes }
+ ;
+ { CopyRes = error(CopyError) },
+ { Succeeded = no },
+ io__progname_base("mercury_compile",
+ ProgName),
+ io__write_string(ProgName),
+ io__write_string(": error copying `"),
+ io__write_string(SourceFileName),
+ io__write_string("' to `"),
+ io__write_string(DestinationFileName),
+ io__write_string("': "),
+ io__write_string(io__error_message(CopyError))
+ )
).
:- pred make_file_name(dir_name, bool, bool, file_name, string,
diff -u compiler/options.m compiler/options.m
--- compiler/options.m
+++ compiler/options.m
@@ -3643,19 +3643,6 @@
"\tdirectories given by `--intermod-directory'.",
"--use-subdirs",
"\tGenerate intermediate files in a `Mercury' subdirectory,",
- "\trather than generating them in the current directory.",
- "--use-grade-subdirs",
- "\tGenerate intermediate files in a `Mercury' subdirectory,",
- "\tlaid out so that multiple grades can be built simultaneously.",
- "\tExecutables will be symlinked or copied into the current",
- "\tdirectory.",
- "\t`--use-grade-subdirs' does not work with Mmake."
- ]).
-
-:- pred options_help_misc(io__state::di, io__state::uo) is det.
- "\tdirectories given by `--intermod-directory'.",
- "--use-subdirs",
- "\tGenerate intermediate files in a `Mercury' subdirectory,",
"\trather than generating them in the current directory."
% `--use-grade-subdirs' is not documented because it
@@ -3664,6 +3651,20 @@
% Documenting it would require documenting (and setting
% in stone) the layout of the `Mercury' directory, which
% is probably a bad idea.
+ ]).
+
+:- pred options_help_misc(io__state::di, io__state::uo) is det.
+ "\tdirectories given by `--intermod-directory'.",
+ "--use-subdirs",
+ "\tGenerate intermediate files in a `Mercury' subdirectory,",
+ "\trather than generating them in the current directory.",
+ "--use-grade-subdirs",
+ "\tGenerate intermediate files in a `Mercury' subdirectory,",
+ "\tlaid out so that multiple grades can be built simultaneously.",
+ "\tExecutables and libraries will be symlinked or copied into",
+ "\tthe current directory.",
+ "\t`--use-grade-subdirs' does not work with Mmake (it does",
+ "\twork with `mmc --make')."
]).
:- pred options_help_misc(io__state::di, io__state::uo) is det.
diff -u doc/user_guide.texi doc/user_guide.texi
--- doc/user_guide.texi
+++ doc/user_guide.texi
@@ -6188,17 +6188,6 @@
Create intermediate files in a @file{Mercury} subdirectory,
rather than in the current directory.
- at item --use-grade-subdirs
- at findex --use-grade-subdirs
- at cindex File names
- at cindex Directories
- at cindex Subdirectories
- at cindex @file{Mercury} subdirectory
-Generate intermediate files in a @file{Mercury} subdirectory,
-laid out so that multiple grades can be built simultaneously.
-Executables will be symlinked or copied into the current
-directory.
- at samp{--use-grade-subdirs} does not work with Mmake.
@end table
@node Miscellaneous options
@@ -6225,6 +6214,19 @@
Create intermediate files in a @file{Mercury} subdirectory,
rather than in the current directory.
+ at item --use-grade-subdirs
+ at findex --use-grade-subdirs
+ at cindex File names
+ at cindex Directories
+ at cindex Subdirectories
+ at cindex @file{Mercury} subdirectory
+ at cindex Grades
+Generate intermediate files in a @file{Mercury} subdirectory,
+laid out so that multiple grades can be built simultaneously.
+Executables and libraries will be symlinked or copied into the
+current directory.
+ at samp{--use-grade-subdirs} does not work with Mmake (it does
+work with @samp{mmc --make}).
@end table
@node Miscellaneous options
only in patch2:
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ tests/grade_subdirs/hello.m 31 Oct 2002 02:17:57 -0000
@@ -0,0 +1,9 @@
+:- module hello.
+:- interface.
+:- import_module io.
+
+:- pred main(io__state::di, io__state::uo) is det.
+
+:- implementation.
+
+main --> io__write_string("Hello, world\n").
only in patch2:
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ tests/grade_subdirs/hello.exp 31 Oct 2002 02:27:02 -0000
@@ -0,0 +1 @@
+Hello, world
only in patch2:
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ tests/grade_subdirs/Mmakefile 31 Oct 2002 02:28:25 -0000
@@ -0,0 +1,31 @@
+#-----------------------------------------------------------------------------#
+# The tests in this directory are always run with `--use-grade-subdirs'.
+
+THIS_DIR = grade_subdirs
+
+ifndef WORKSPACE
+PROGS=\
+ hello
+else
+# We can only use a workspace if it was built with `--use-grade-subdirs',
+# which in general it won't be.
+PROGS=
+endif
+
+# `--use-grade-subdirs' doesn't work with Mmake.
+MMAKE_USE_MMC_MAKE=yes
+
+TESTS = $(PROGS)
+SUBDIRS =
+TESTS_DIR=..
+include $(TESTS_DIR)/Mmake.common
+
+# Module-specific options should go in Mercury.options so they
+# can be found by `mmc --make'.
+include Mercury.options
+
+MCFLAGS += --use-grade-subdirs
+
+%.runtest: %.res ;
+
+#-----------------------------------------------------------------------------#
only in patch2:
--- tests/Mmakefile 31 Oct 2002 07:03:48 -0000 1.8
+++ tests/Mmakefile 31 Oct 2002 14:00:08 -0000
@@ -5,6 +5,7 @@
benchmarks \
debugger \
general \
+ grade_subdirs \
hard_coded \
invalid \
misc_tests \
only in patch2:
--- library/io.m 25 Oct 2002 02:23:25 -0000 1.271
+++ library/io.m 30 Oct 2002 13:57:32 -0000
@@ -757,6 +757,67 @@
% Reads all the bytes from the given binary input stream until
% eof or error.
+:- pred io__binary_input_stream_foldl(pred(int, T, T),
+ T, io__maybe_partial_res(T), io__state, io__state).
+:- mode io__binary_input_stream_foldl((pred(in, in, out) is det),
+ in, out, di, uo) is det.
+:- mode io__binary_input_stream_foldl((pred(in, in, out) is cc_multi),
+ in, out, di, uo) is cc_multi.
+% Applies the given closure to each byte read from the
+% current binary input stream in turn, until eof or error.
+
+:- pred io__binary_input_stream_foldl_io(pred(int, io__state, io__state),
+ io__res, io__state, io__state).
+:- mode io__binary_input_stream_foldl_io((pred(in, di, uo) is det),
+ out, di, uo) is det.
+:- mode io__binary_input_stream_foldl_io((pred(in, di, uo) is cc_multi),
+ out, di, uo) is cc_multi.
+% Applies the given closure to each byte read from the
+% current binary input stream in turn, until eof or error.
+
+:- pred io__binary_input_stream_foldl2_io(
+ pred(int, T, T, io__state, io__state),
+ T, io__maybe_partial_res(T), io__state, io__state).
+:- mode io__binary_input_stream_foldl2_io((pred(in, in, out, di, uo) is det),
+ in, out, di, uo) is det.
+:- mode io__binary_input_stream_foldl2_io(
+ (pred(in, in, out, di, uo) is cc_multi),
+ in, out, di, uo) is cc_multi.
+% Applies the given closure to each byte read from the
+% current binary input stream in turn, until eof or error.
+
+:- pred io__binary_input_stream_foldl(io__binary_input_stream,
+ pred(int, T, T), T, io__maybe_partial_res(T),
+ io__state, io__state).
+:- mode io__binary_input_stream_foldl(in, (pred(in, in, out) is det),
+ in, out, di, uo) is det.
+:- mode io__binary_input_stream_foldl(in, (pred(in, in, out) is cc_multi),
+ in, out, di, uo) is cc_multi.
+% Applies the given closure to each byte read from the
+% given binary input stream in turn, until eof or error.
+
+:- pred io__binary_input_stream_foldl_io(io__binary_input_stream,
+ pred(int, io__state, io__state), io__res,
+ io__state, io__state).
+:- mode io__binary_input_stream_foldl_io(in, (pred(in, di, uo) is det),
+ out, di, uo) is det.
+:- mode io__binary_input_stream_foldl_io(in, (pred(in, di, uo) is cc_multi),
+ out, di, uo) is cc_multi.
+% Applies the given closure to each byte read from the
+% given binary input stream in turn, until eof or error.
+
+:- pred io__binary_input_stream_foldl2_io(io__binary_input_stream,
+ pred(int, T, T, io__state, io__state),
+ T, io__maybe_partial_res(T), io__state, io__state).
+:- mode io__binary_input_stream_foldl2_io(in,
+ (pred(in, in, out, di, uo) is det),
+ in, out, di, uo) is det.
+:- mode io__binary_input_stream_foldl2_io(in,
+ (pred(in, in, out, di, uo) is cc_multi),
+ in, out, di, uo) is cc_multi.
+% Applies the given closure to each byte read from the
+% given binary input stream in turn, until eof or error.
+
:- pred io__putback_byte(int, io__state, io__state).
:- mode io__putback_byte(in, di, uo) is det.
% Un-reads a byte from the current binary input stream.
@@ -2164,6 +2225,64 @@
{ Result0 = ok(Byte) },
io__read_binary_file_2(Stream, [Byte|Bytes0], Result)
).
+
+%-----------------------------------------------------------------------------%
+
+io__binary_input_stream_foldl(Pred, T0, Res) -->
+ io__binary_input_stream(Stream),
+ io__binary_input_stream_foldl(Stream, Pred, T0, Res).
+
+io__binary_input_stream_foldl(Stream, Pred, T0, Res) -->
+ io__read_byte(Stream, ByteResult),
+ (
+ { ByteResult = ok(Byte) },
+ { Pred(Byte, T0, T1) },
+ io__binary_input_stream_foldl(Stream, Pred, T1, Res)
+ ;
+ { ByteResult = eof },
+ { Res = ok(T0) }
+ ;
+ { ByteResult = error(Error) },
+ { Res = error(T0, Error) }
+ ).
+
+io__binary_input_stream_foldl_io(Pred, Res) -->
+ io__binary_input_stream(Stream),
+ io__binary_input_stream_foldl_io(Stream, Pred, Res).
+
+io__binary_input_stream_foldl_io(Stream, Pred, Res) -->
+ io__read_byte(Stream, ByteResult),
+ (
+ { ByteResult = ok(Byte) },
+ Pred(Byte),
+ io__binary_input_stream_foldl_io(Stream, Pred, Res)
+ ;
+ { ByteResult = eof },
+ { Res = ok }
+ ;
+ { ByteResult = error(Error) },
+ { Res = error(Error) }
+ ).
+
+io__binary_input_stream_foldl2_io(Pred, T0, Res) -->
+ io__binary_input_stream(Stream),
+ io__binary_input_stream_foldl2_io(Stream, Pred, T0, Res).
+
+io__binary_input_stream_foldl2_io(Stream, Pred, T0, Res) -->
+ io__read_byte(Stream, ByteResult),
+ (
+ { ByteResult = ok(Byte) },
+ Pred(Byte, T0, T1),
+ io__binary_input_stream_foldl2_io(Stream, Pred, T1, Res)
+ ;
+ { ByteResult = eof },
+ { Res = ok(T0) }
+ ;
+ { ByteResult = error(Error) },
+ { Res = error(T0, Error) }
+ ).
+
+%-----------------------------------------------------------------------------%
io__putback_char(Char) -->
io__input_stream(Stream),
--------------------------------------------------------------------------
mercury-reviews mailing list
post: mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------
More information about the reviews
mailing list