[m-rev.] for review: fix command line quoting

Simon Taylor stayl at cs.mu.OZ.AU
Wed Aug 7 16:48:55 AEST 2002


On 06-Aug-2002, Fergus Henderson <fjh at cs.mu.OZ.AU> wrote:
> On 06-Aug-2002, Simon Taylor <stayl at cs.mu.OZ.AU> wrote:
> > 
> > Fix quoting of `--cflags', `--link-flags', etc.
> > The arguments are now quoted as if each `--cflags'
> > option gives a single word to be passed to the
> > gcc, ml, etc. This allows directory names containing
> > spaces to be passed.
 
> Did you consider defining alternative option names `--cflag',
> `--link-flag', etc., with the new semantics, and/or keeping
> the old option names with their existing semantics?

I've added `--cflag', etc options.
 
> > Index: compiler/compile_target_code.m
> > @@ -585,10 +590,10 @@
> >  	;
> >  		% XXX PathSeparator should be ";" on Windows
> >  		{ PathSeparator = ":" },
> > -		{ join_string_list(Java_Incl_Dirs, "", "",
> > +		{ join_quoted_string_list(Java_Incl_Dirs, "", "",
> >  			PathSeparator, ClassPath) },
> >  		{ InclOpt = string__append_list([
> > -			"-classpath ", ClassPath, " "]) }
> > +			"-classpath ", quote_arg(ClassPath), " "]) }
> 
> Won't that code incorrectly quote the Java_Incl_Dirs twice?

Fixed.

> > It's a little inconsistent to use double-quotes to quote empty
> arguments but single-quotes to quote arguments containing spaces, etc.

...

> Are you sure this handles arguments containing backslashes or
> double quotes correctly?
> 
> It looks like this code will convert e.g. the argument foo\bar"baz into
> 'foo\\bar\"baz' which the Bourne shell will convert into foo\\bar\"baz
> which is not the same as the original string.
> 
> Also, don't you also need to quote other shell meta-characters,
> such as "$", "<", ">", "=", etc.?
> 
> I think it also won't correctly handle arguments containing
> single quotes.

The code now double quotes arguments containing non-alphanumeric
characters, and puts backslashes before `/', `$', '`' and '"'.
 
> > Index: scripts/Mmake.vars.in
> > ===================================================================
> >  ALL_MCSFLAGS	= $(MCSFLAGS) $(EXTRA_MCSFLAGS) $(TARGET_MCFLAGS) \
> > -		  $(LIB_MCFLAGS) --cflags "$(ALL_CFLAGS)"
> > +		  $(LIB_MCFLAGS) $(patsubst %,--cflags %,$(ALL_CFLAGS))
> 
> Hmm.  I'm not sure this is really going to be an improvement.

I've undone this change.

Simon.


Estimated hours taken: 2
Branches: main

Fix quoting of arguments to commands invoked by mmc.

compiler/compile_target_code.m:
compiler/make.module_target.m:
	Quote arguments passed to commands.	

compiler/options_file.m:
	Pass each word in the value of CFLAGS (MLFLAGS, etc) as a
	separate `--cflag' option so it can be quoted correctly.

NEWS:
compiler/options.m:
doc/user_guide.texi:
	For each `--Xflags' option, add a `--Xflag' option which
	quotes its argument if necessary then adds it to
	the `--Xflags' option.

Index: NEWS
===================================================================
RCS file: /home/mercury1/repository/mercury/NEWS,v
retrieving revision 1.264
diff -u -u -r1.264 NEWS
--- NEWS	1 Aug 2002 11:52:13 -0000	1.264
+++ NEWS	7 Aug 2002 06:34:39 -0000
@@ -322,6 +322,10 @@
   only optimize using information from directly imported modules, use the
   option `--no-read-opt-files-transitively'.
 
+* For each `--Xflags' option there is now a `--Xflag' option which allows a
+  single quoted argument to be passed to the invoked program.  This is useful
+  where the argument is a directory name containing spaces.
+
 * The `--convert-to-goedel' option has been removed.
   It never really worked anyway.
 
Index: compiler/compile_target_code.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/compile_target_code.m,v
retrieving revision 1.18
diff -u -u -r1.18 compile_target_code.m
--- compiler/compile_target_code.m	30 Jul 2002 08:25:00 -0000	1.18
+++ compiler/compile_target_code.m	7 Aug 2002 06:37:23 -0000
@@ -588,7 +588,7 @@
 		{ join_string_list(Java_Incl_Dirs, "", "",
 			PathSeparator, ClassPath) },
 		{ InclOpt = string__append_list([
-			"-classpath ", ClassPath, " "]) }
+			"-classpath ", quote_arg(ClassPath), " "]) }
 	),
 	globals__io_lookup_bool_option(target_debug, Target_Debug),
 	{ Target_Debug = yes ->
@@ -821,14 +821,16 @@
 
 	globals__io_lookup_accumulating_option(init_file_directories,
 		InitFileDirsList),
-	{ join_string_list(InitFileDirsList, "-I ", "", " ", InitFileDirs) },
+	{ join_quoted_string_list(InitFileDirsList,
+		"-I ", "", " ", InitFileDirs) },
 
 	globals__io_lookup_accumulating_option(init_files, InitFileNamesList),
-	{ join_string_list(InitFileNamesList, "", "", " ", InitFileNames) },
+	{ join_quoted_string_list(InitFileNamesList,
+		"", "", " ", InitFileNames) },
 
 	globals__io_lookup_accumulating_option(trace_init_files,
 		TraceInitFileNamesList),
-	{ join_string_list(TraceInitFileNamesList, "--trace-init-file ",
+	{ join_quoted_string_list(TraceInitFileNamesList, "--trace-init-file ",
 		"", " ", TraceInitFileNames) },
 
 	{ TmpInitCFileName = InitCFileName ++ ".tmp" },
@@ -950,11 +952,11 @@
 		globals__io_lookup_accumulating_option(
 				link_library_directories,
 				LinkLibraryDirectoriesList),
-		{ join_string_list(LinkLibraryDirectoriesList, "-L", "",
+		{ join_quoted_string_list(LinkLibraryDirectoriesList, "-L", "",
 				" ", LinkLibraryDirectories) },
 		globals__io_lookup_accumulating_option(link_libraries,
 				LinkLibrariesList),
-		{ join_string_list(LinkLibrariesList, "-l", "", " ",
+		{ join_quoted_string_list(LinkLibrariesList, "-l", "", " ",
 				LinkLibraries) },
 
 		% Note that LDFlags may contain `-l' options
@@ -1028,6 +1030,16 @@
 		string__append_list([Prefix, String, Suffix, Separator,
 			Result0], Result)
 	).
+
+	% As above, but quote the strings first.
+	% Note that the strings in values of the *flags options are
+	% already quoted.
+:- pred join_quoted_string_list(list(string), string, string, string, string).
+:- mode join_quoted_string_list(in, in, in, in, out) is det.
+
+join_quoted_string_list(Strings, Prefix, Suffix, Separator, Result) :-
+	join_string_list(map(quote_arg, Strings),
+		Prefix, Suffix, Separator, Result).
 
 	% join_module_list(ModuleNames, Extension, Terminator, Result)
 	%
Index: compiler/make.module_target.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/make.module_target.m,v
retrieving revision 1.11
diff -u -u -r1.11 make.module_target.m
--- compiler/make.module_target.m	17 Jul 2002 07:09:21 -0000	1.11
+++ compiler/make.module_target.m	6 Aug 2002 01:38:57 -0000
@@ -245,7 +245,7 @@
 		{ AllArgs = list__append(AllOptionArgs, [ModuleArg]) },
 		io__write_string("Invoking command `mmc "),
 		% XXX Don't write the default options.
-		io__write_list(quote_args(AllArgs), " ",
+		io__write_list(list__map(quote_arg, AllArgs), " ",
 			io__write_string),
 		io__write_string("'"),
 		io__nl
@@ -369,7 +369,8 @@
 
 invoke_mmc(ErrorStream, Args, Succeeded) -->
 	{ CommandVerbosity = verbose }, % We've already written the command.
-	{ Command = string__join_list(" ", ["mmc" | quote_args(Args)]) },
+	{ Command = string__join_list(" ",
+			["mmc" | list__map(quote_arg, Args)]) },
 	invoke_shell_command(ErrorStream, CommandVerbosity,
 		Command, Succeeded).
 
Index: compiler/options.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/options.m,v
retrieving revision 1.378
diff -u -u -r1.378 options.m
--- compiler/options.m	29 Jul 2002 07:50:58 -0000	1.378
+++ compiler/options.m	7 Aug 2002 06:37:58 -0000
@@ -49,6 +49,9 @@
 :- func option_table_add_mercury_library_directory(option_table,
 		string) = option_table.
 
+	% Quote an argument to a shell command.
+:- func quote_arg(string) = string.
+
 :- type option	
 	% Warning options
 		--->	inhibit_warnings
@@ -480,6 +483,7 @@
 			% C
 		;	cc
 		;	cflags
+		;	quoted_cflag
 		;	c_include_directory
 		;	c_optimize
 		;	inline_alloc
@@ -496,28 +500,35 @@
 			% Java
 		;	java_compiler
 		;	java_flags
+		;	quoted_java_flag
 		;	java_classpath
 		;	java_object_file_extension
 
 			% IL
 		;	il_assembler
 		;	ilasm_flags
+		;	quoted_ilasm_flag
 		;	dotnet_library_version
 		;	support_ms_clr
 
 			% Managed C++
 		;	mcpp_compiler
 		;	mcpp_flags
+		;	quoted_mcpp_flag
 
 			% C#
 		;	csharp_compiler
 		;	csharp_flags
+		;	quoted_csharp_flag
 
 	% Link options
 		;	output_file_name
 		;	link_flags
+		;	quoted_link_flag
 		;	ld_flags
+		;	quoted_ld_flag
 		;	ld_libflags
+		;	quoted_ld_libflag
 		;	link_library_directories
 		;	link_libraries
 		;	link_objects
@@ -1008,6 +1019,7 @@
 	c_optimize		-	bool(no),
 	inline_alloc		-	bool(no),
 	cflags			-	accumulating([]),
+	quoted_cflag		-	string_special,
 
 					% the `mmc' script will override the
 					% following seven defaults with values
@@ -1023,12 +1035,14 @@
 % Java
 	java_compiler		-	string("javac"),
 	java_flags		-	accumulating([]),
+	quoted_java_flag	-	string_special,
 	java_classpath  	-	accumulating([]),
 	java_object_file_extension -	string(".class"),
 
 % IL
 	il_assembler		-	string("ilasm"),
 	ilasm_flags		-	accumulating([]),
+	quoted_ilasm_flag	-	string_special,
 		% We default to the version of the library that came
 		% with Beta2.
 	dotnet_library_version	-	string("1.0.3300.0"),
@@ -1037,10 +1051,12 @@
 % Managed C++
 	mcpp_compiler		-	string("cl"),
 	mcpp_flags		-	accumulating([]),
+	quoted_mcpp_flag	-	string_special,
 
 % C#
 	csharp_compiler		-	string("csc"),
-	csharp_flags		-	accumulating([])
+	csharp_flags		-	accumulating([]),
+	quoted_csharp_flag	-	string_special
 ]).
 option_defaults_2(link_option, [
 		% Link Options
@@ -1049,8 +1065,11 @@
 					% string, we use the name of the first
 					% module on the command line
 	link_flags		-	accumulating([]),
+	quoted_link_flag	-	string_special,
 	ld_flags		-	accumulating([]),
+	quoted_ld_flag		-	string_special,
 	ld_libflags		-	accumulating([]),
+	quoted_ld_libflag	-	string_special,
 	link_library_directories -	accumulating([]),
 	link_libraries		-	accumulating([]),
 	link_objects		-	accumulating([]),
@@ -1601,6 +1620,7 @@
 long_option("c-debug",			target_debug).
 long_option("c-include-directory",	c_include_directory).
 long_option("cflags",			cflags).
+long_option("cflag",			quoted_cflag).
 long_option("cflags-for-regs",		cflags_for_regs).
 long_option("cflags-for-gotos",		cflags_for_gotos).
 long_option("cflags-for-threads",	cflags_for_threads).
@@ -1612,6 +1632,7 @@
 long_option("java-compiler",		java_compiler).
 long_option("javac",			java_compiler).
 long_option("java-flags",		java_flags).
+long_option("java-flag",		quoted_java_flag).
 	% XXX we should consider the relationship between java_debug and
 	% target_debug more carefully.  Perhaps target_debug could imply
 	% Java debug if the target is Java.  However for the moment they are
@@ -1622,21 +1643,28 @@
 
 long_option("il-assembler",		il_assembler).
 long_option("ilasm-flags",		ilasm_flags).
+long_option("ilasm-flag",		quoted_ilasm_flag).
 long_option("dotnet-library-version",	dotnet_library_version).
 long_option("support-ms-clr",		support_ms_clr).
 
 long_option("mcpp-compiler",		mcpp_compiler).
 long_option("mcpp-flags",		mcpp_flags).
+long_option("mcpp-flag",		quoted_mcpp_flag).
 
 long_option("csharp-compiler",		csharp_compiler).
 long_option("csharp-flags",		csharp_flags).
+long_option("csharp-flag",		quoted_csharp_flag).
 
 % link options
 long_option("output-file",		output_file_name).
 long_option("link-flags",		link_flags).
+long_option("link-flag",		quoted_link_flag).
 long_option("ml-flags",			link_flags).
+long_option("ml-flag",			quoted_link_flag).
 long_option("ld-flags",			ld_flags).
+long_option("ld-flag",			quoted_ld_flag).
 long_option("ld-libflags",		ld_libflags).
+long_option("ld-libflag",		quoted_ld_libflag).
 long_option("library-directory",	link_library_directories).
 long_option("library",			link_libraries).
 long_option("link-object",		link_objects).
@@ -1815,6 +1843,32 @@
 		mercury_libraries - Lib,
 		init_files - (Lib ++ ".init")
 		], OptionTable0).
+special_handler(quoted_cflag, string(Flag),
+			OptionTable0, ok(OptionTable)) :-
+	handle_quoted_flag(cflags, Flag, OptionTable0, OptionTable).
+special_handler(quoted_java_flag, string(Flag),
+			OptionTable0, ok(OptionTable)) :-
+	handle_quoted_flag(java_flags, Flag, OptionTable0, OptionTable).
+special_handler(quoted_ilasm_flag, string(Flag),
+			OptionTable0, ok(OptionTable)) :-
+	handle_quoted_flag(ilasm_flags, Flag, OptionTable0, OptionTable).
+special_handler(quoted_mcpp_flag, string(Flag),
+			OptionTable0, ok(OptionTable)) :-
+	handle_quoted_flag(mcpp_flags, Flag, OptionTable0, OptionTable).
+special_handler(quoted_csharp_flag, string(Flag),
+			OptionTable0, ok(OptionTable)) :-
+	handle_quoted_flag(csharp_flags, Flag, OptionTable0, OptionTable).
+special_handler(quoted_link_flag, string(Flag),
+			OptionTable0, ok(OptionTable)) :-
+	handle_quoted_flag(link_flags, Flag, OptionTable0, OptionTable).
+special_handler(quoted_ld_flag, string(Flag),
+			OptionTable0, ok(OptionTable)) :-
+	handle_quoted_flag(ld_flags, Flag, OptionTable0, OptionTable).
+special_handler(quoted_ld_libflag, string(Flag),
+			OptionTable0, ok(OptionTable)) :-
+	handle_quoted_flag(ld_libflags, Flag, OptionTable0, OptionTable).
+
+%-----------------------------------------------------------------------------%
 
 option_table_add_mercury_library_directory(OptionTable0, Dir) =
 	% The link_library_directories for Mercury libraries are grade
@@ -2047,6 +2101,48 @@
 
 %-----------------------------------------------------------------------------%
 
+:- pred handle_quoted_flag(option::in, string::in, option_table::in,
+		option_table::out) is det.
+
+handle_quoted_flag(Option, Flag, Table,
+	append_to_accumulating_option(Option - quote_arg(Flag), Table)).
+
+quote_arg(Arg0) = Arg :-
+	ArgList = quote_arg_2(string__to_char_list(Arg0)),
+	(
+		ArgList = []
+	->
+		Arg = """"""
+	;
+		list__member(Char, ArgList),
+		\+ char__is_alnum_or_underscore(Char)
+	->
+		Arg = """" ++ string__from_char_list(ArgList) ++ """"
+	;
+		Arg = string__from_char_list(ArgList)
+	).
+
+:- func quote_arg_2(list(char)) = list(char).
+
+quote_arg_2([]) = [].
+quote_arg_2([Char | Chars0]) = Chars :-
+	Chars1 = quote_arg_2(Chars0),
+	( quote_char(Char) ->
+		Chars = [('\\'), Char | Chars1]
+	;
+		Chars = [Char | Chars1]	
+	).	
+
+
+:- pred quote_char(char::in) is semidet.
+
+quote_char('\\').
+quote_char('"').
+quote_char('`').
+quote_char('$').
+
+%-----------------------------------------------------------------------------%
+
 options_help -->
 	io__write_string("\t-?, -h, --help\n"),
 	io__write_string("\t\tPrint this usage message.\n"),
@@ -3304,8 +3400,10 @@
 		"\tThis option has no effect if `--gc conservative'",
 		"\tis not set or if the C compiler is not GNU C.",
 
-		"--cflags <options>",
+		"--cflags <options>, --cflag <option>",
 		"\tSpecify options to be passed to the C compiler.",
+		"\t`--cflag' should be used for single words which need",
+		"\tto be quoted when passed to the shell.",
 
 		% The --cflags-for-regs, --cflags-for-gotos,
 		% --cflags-for-threads, --cflags-for-pic options,
@@ -3318,8 +3416,10 @@
 		"--java-compiler",
 		"\tSpecify which Java compiler to use.  The default is javac.",
 		
-		"--java-flags <options>",
+		"--java-flags <options>, --java-flag <option>",
 		"\tSpecify options to be passed to the Java compiler.",
+		"\t`--java-flag' should be used for single words which need",
+		"\tto be quoted when passed to the shell.",
 
 		"--java-classpath <path>",
 		"\tSet the classpath for the Java compiler.",
@@ -3330,17 +3430,23 @@
 
 		"--il-assembler <ilasm>",
 		"\tThe Microsoft IL Assembler.",
-		"--ilasm-flags <options>",
+		"--ilasm-flags <options>, --ilasm-flag <options>",
 		"\tSpecify options to be passed to the IL assembler.",
+		"\t`--ilasm-flag' should be used for single words which need",
+		"\tto be quoted when passed to the shell.",
 		"--mcpp-compiler <cl>",
 		"\tSpecify the name of the Microsoft Managed C++ Compiler.",
-		"--mcpp-flags <options>",
-		"\tSpecify options to be passed to the Managed C++ Compiler.",
+		"--mcpp-flags <options>, --mcpp-flag <option>",
+		"\tSpecify options to be passed to the Managed C++ compiler.",
+		"\t`--mcpp-flag' should be used for single words which need",
+		"\tto be quoted when passed to the shell.",
 
 		"--csharp-compiler <csc>",
 		"\tSpecify the name of the Microsoft C# Compiler.",
-		"--csharp-flags <options>",
-		"\tSpecify options to be passed to the C# Compiler."
+		"--csharp-flags <options>, --csharp-flag <option>",
+		"\tSpecify options to be passed to the C# compiler.",
+		"\t`--csharp-flag' should be used for single words which need",
+		"\tto be quoted when passed to the shell."
 	]).
 
 :- pred options_help_link(io__state::di, io__state::uo) is det.
@@ -3354,17 +3460,24 @@
 		"\tof the first module on the command line.)",
 		"\tThis option is ignored by `mmc --make'.",
 		"--link-flags <options>, --ml-flags <options>",
+		"--link-flag <option>, --ml-flag <option>",
 		"\tSpecify options to be passed to ml, the Mercury linker.",
-		"--ld-flags <options>",
+		"\t`--ml-flag' should be used for single words which need",
+		"\tto be quoted when passed to the shell.",
+		"--ld-flags <options>, --ld-flags <option>",
 		"\tSpecify options to be passed to the linker command",
 		"\tinvoked by ml to link an executable.",
 		"\tUse `ml --print-link-command' to find out which",
 		"\tcommand is used.",
-		"--ld-libflags <options>",
+		"\t`--ld-flag' should be used for single words which need",
+		"\tto be quoted when passed to the shell.",
+		"--ld-libflags <options>, --ld-libflag <option>",
 		"\tSpecify options to be passed to the linker command",
 		"\tinvoked by ml to link a shared library.",
 		"\tUse `ml --print-shared-lib-link-command' to find out",
 		"\twhich command is used.",
+		"\t`--ld-libflags' should be used for single words which need",
+		"\tto be quoted when passed to the shell.",
 		"-L <directory>, --library-directory <directory>",
 		"\tAppend <directory> to the list of directories in which",
 		"\tto search for libraries.",
Index: compiler/options_file.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/options_file.m,v
retrieving revision 1.8
diff -u -u -r1.8 options_file.m
--- compiler/options_file.m	25 May 2002 13:25:09 -0000	1.8
+++ compiler/options_file.m	7 Aug 2002 03:22:52 -0000
@@ -40,9 +40,6 @@
 :- pred lookup_main_target(options_variables::in, maybe(list(string))::out,
 	io__state::di, io__state::uo) is det.
 
-	% Quote any strings containing whitespace.
-:- func quote_args(list(string)) = list(string).
-
 %-----------------------------------------------------------------------------%
 :- implementation.
 
@@ -820,52 +817,40 @@
 		MMCOptionType = mmc_flags,
 		OptionsStrings = VariableValue
 	;
-		MMCOptionType = option(not_split, OptionName),
-		OptionsStrings = [OptionName,
-					string__join_list(" ", VariableValue)]
-	;
-		MMCOptionType = option(split, OptionName),
-		OptionsStrings = list__condense(
+		MMCOptionType = option(InitialOptions, OptionName),
+		OptionsStrings = list__condense([InitialOptions |
 				list__map((func(Word) = [OptionName, Word]),
-					VariableValue))
+					VariableValue)])
 	).
 
 :- type mmc_option_type
 	--->	mmc_flags	% The options can be passed directly to mmc.
 
-	;	option(split_into_words, option_name :: string)
-				% The options need to be passed as an
-				% argument of an option to mmc.
-	.
-
-	% The split_into_words type specifies whether there should be
-	% one mmc option per word in a variable's value, or just a single
-	% mmc option.
-	% The value of CFLAGS is converted into a single `--cflags' option.
-	% The value of MLOBJS is converted into multiple `--link-object'
-	% options.
-:- type split_into_words
-	--->	split
-	;	not_split
+	;	option(initial_options :: list(string), option_name :: string)
+			% The options need to be passed as an
+			% argument of an option to mmc.
+			% The `initial_options' will be passed before
+			% the options generated by the variable.
+			% This is useful for clearing an accumulating option.
 	.
 
 :- func mmc_option_type(options_variable_type) = mmc_option_type.
 
 mmc_option_type(grade_flags) = mmc_flags.
 mmc_option_type(mmc_flags) = mmc_flags.
-mmc_option_type(c_flags) = option(not_split, "--cflags").
-mmc_option_type(java_flags) = option(not_split, "--java-flags").
-mmc_option_type(ilasm_flags) = option(not_split, "--ilasm-flags").
-mmc_option_type(mcpp_flags) = option(not_split, "--mcpp-flags").
-mmc_option_type(csharp_flags) = option(not_split, "--csharp-flags").
-mmc_option_type(ml_flags) = option(not_split, "--link-flags").
-mmc_option_type(ml_objs) = option(split, "--link-object").
+mmc_option_type(c_flags) = option([], "--cflag").
+mmc_option_type(java_flags) = option([], "--java-flag").
+mmc_option_type(ilasm_flags) = option([], "--ilasm-flag").
+mmc_option_type(mcpp_flags) = option([], "--mcpp-flag").
+mmc_option_type(csharp_flags) = option([], "--csharp-flag").
+mmc_option_type(ml_flags) = option([], "--link-flag").
+mmc_option_type(ml_objs) = option([], "--link-object").
 mmc_option_type(ml_libs) = mmc_flags.
-mmc_option_type(ld_flags) = option(not_split, "--ld-flags").
-mmc_option_type(ld_libflags) = option(not_split, "--ld-libflags").
-mmc_option_type(c2init_args) = option(split, "--init-file").
-mmc_option_type(libraries) = option(split, "--mercury-library").
-mmc_option_type(lib_dirs) = option(split, "--mercury-library-directory").
+mmc_option_type(ld_flags) = option([], "--ld-flag").
+mmc_option_type(ld_libflags) = option([], "--ld-libflag").
+mmc_option_type(c2init_args) = option([], "--init-file").
+mmc_option_type(libraries) = option([], "--mercury-library").
+mmc_option_type(lib_dirs) = option([], "--mercury-library-directory").
 
 %-----------------------------------------------------------------------------%
 
@@ -976,41 +961,6 @@
 			Undef = [Var | Undef0]
 		)
 	}.
-
-%-----------------------------------------------------------------------------%
-
-quote_args(Args) = list__map(quote_arg, Args).
-
-:- func quote_arg(string) = string.
-
-quote_arg(Arg0) = Arg :-
-	ArgList = quote_arg_2(string__to_char_list(Arg0)),
-	(
-		list__member(Char, ArgList),
-		( char__is_whitespace(Char)
-		; Char = ('\\')
-		; Char = '"'
-		)
-	->
-		Arg = "'" ++ string__from_char_list(ArgList) ++ "'"
-	;
-		Arg = string__from_char_list(ArgList)
-	).
-
-:- func quote_arg_2(list(char)) = list(char).
-
-quote_arg_2([]) = [].
-quote_arg_2([Char | Chars0]) = Chars :-
-	Chars1 = quote_arg_2(Chars0),
-	( Char = ('\\') ->
-		Chars = [Char, Char | Chars1]
-	; Char = '\n' ->
-		Chars = [('\\'), 'n' | Chars1]
-	; Char = '"' ->
-		Chars = [('\\'), '"' | Chars1]
-	;
-		Chars = [Char | Chars1]	
-	).	
 
 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
Index: doc/user_guide.texi
===================================================================
RCS file: /home/mercury1/repository/mercury/doc/user_guide.texi,v
retrieving revision 1.317
diff -u -u -r1.317 user_guide.texi
--- doc/user_guide.texi	5 Aug 2002 04:02:00 -0000	1.317
+++ doc/user_guide.texi	7 Aug 2002 06:40:26 -0000
@@ -5835,9 +5835,13 @@
 
 @sp 1
 @item --cflags @var{options}
+ at item --cflag @var{option}
 @findex --cflags
+ at findex --cflag
 @cindex C compiler options
 Specify options to be passed to the C compiler.
+ at samp{--cflag} should be used for single words which need
+to be quoted when passed to the shell.
 
 @sp 1
 @item --javac @var{compiler-name}
@@ -5849,9 +5853,13 @@
 
 @sp 1
 @item --java-flags @var{options}
+ at itemx --java-flag @var{option}
 @findex --java-flags
+ at findex --java-flag
 @cindex Java compiler options
 Specify options to be passed to the Java compiler.
+ at samp{--java-flag} should be used for single words which need
+to be quoted when passed to the shell.
 
 @sp 1
 @item --java-classpath @var{dir}
@@ -5885,29 +5893,41 @@
 This option is ignored by @samp{mmc --make}.
 
 @sp 1
- at item --link-flags @var{options}
- at itemx --ml-flags @var{options}
+ at item --ml-flags @var{options}
+ at itemx --link-flags @var{options}
+ at itemx --ml-flag @var{option}
 @findex --link-flags
 @findex --ml-flags
+ at findex --ml-flag
 @cindex Link options
 @cindex Linker options
 Specify options to be passed to @samp{ml}, the Mercury linker.
+ at samp{--ml-flag} should be used for single words which need
+to be quoted when passed to the shell.
 
 @sp 1
 @item --ld-flags @var{options}
+ at item --ld-flags @var{option}
 @findex --ld-flags
+ at findex --ld-flag
 Specify options to be passed to the command
 invoked by ml to link an executable.
 Use @code{ml --print-link-command} to find out
 which command is used.
+ at samp{--ld-flag} should be used for single words which need
+to be quoted when passed to the shell.
 
 @sp 1
 @item --ld-libflags @var{options}
+ at item --ld-libflag @var{option}
 @findex --ld-libflags
+ at findex --ld-libflag
 Specify options to be passed to the command
 invoked by ml to link a shared library.
 Use @code{ml --print-shared-lib-link-command}
 to find out which command is used.
+ at samp{--ld-libflag} should be used for single words which need
+to be quoted when passed to the shell.
 
 @sp 1
 @item -L @var{directory}
--------------------------------------------------------------------------
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