[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