[m-rev.] for review: fix command line quoting
Simon Taylor
stayl at cs.mu.OZ.AU
Tue Aug 6 16:15:34 AEST 2002
Estimated hours taken: 1
Branches: main
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.
compiler/compile_target_code.m:
compiler/make.module_target.m:
Quote arguments passed to commands.
compiler/options_file.m:
scripts/Mmake.vars.in:
scripts/Mmake.rules:
Pass each word in the value of CFLAGS (MLFLAGS, etc) as a
separate `--cflags' option so it can be quoted correctly.
compiler/options.m:
compiler/user_guide.texi:
Document the change.
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 6 Aug 2002 06:09:02 -0000
@@ -141,6 +141,11 @@
list(module_name)) = string.
%-----------------------------------------------------------------------------%
+
+ % Quote an argument to a shell command.
+:- func quote_arg(string) = string.
+
+%-----------------------------------------------------------------------------%
:- implementation.
:- import_module libs__globals, libs__options, libs__handle_options.
@@ -172,7 +177,7 @@
maybe_write_string(Verbose, "':\n"),
globals__io_lookup_string_option(il_assembler, ILASM),
globals__io_lookup_accumulating_option(ilasm_flags, ILASMFlagsList),
- { join_string_list(ILASMFlagsList, "", "", " ", ILASMFlags) },
+ { join_quoted_string_list(ILASMFlagsList, "", "", " ", ILASMFlags) },
{ SignAssembly = yes ->
SignOpt = "/keyf=mercury.sn "
;
@@ -208,7 +213,7 @@
maybe_write_string(Verbose, "':\n"),
globals__io_lookup_string_option(mcpp_compiler, MCPP),
globals__io_lookup_accumulating_option(mcpp_flags, MCPPFlagsList),
- { join_string_list(MCPPFlagsList, "", "", " ", MCPPFlags) },
+ { join_quoted_string_list(MCPPFlagsList, "", "", " ", MCPPFlags) },
globals__io_lookup_bool_option(target_debug, Debug),
{ Debug = yes ->
DebugOpt = "" % XXX
@@ -243,7 +248,7 @@
maybe_write_string(Verbose, "':\n"),
globals__io_lookup_string_option(csharp_compiler, CSC),
globals__io_lookup_accumulating_option(csharp_flags, CSCFlagsList),
- { join_string_list(CSCFlagsList, "", "", " ", CSCFlags) },
+ { join_quoted_string_list(CSCFlagsList, "", "", " ", CSCFlags) },
globals__io_lookup_bool_option(target_debug, Debug),
{ Debug = yes ->
DebugOpt = "" % XXX
@@ -321,7 +326,7 @@
maybe_write_string(Verbose, "':\n"),
globals__io_lookup_string_option(cc, CC),
globals__io_lookup_accumulating_option(cflags, C_Flags_List),
- { join_string_list(C_Flags_List, "", "", " ", CFLAGS) },
+ { join_quoted_string_list(C_Flags_List, "", "", " ", CFLAGS) },
(
{ PIC = pic },
@@ -576,7 +581,7 @@
maybe_write_string(Verbose, "':\n"),
globals__io_lookup_string_option(java_compiler, JavaCompiler),
globals__io_lookup_accumulating_option(java_flags, JavaFlagsList),
- { join_string_list(JavaFlagsList, "", "", " ", JAVAFLAGS) },
+ { join_quoted_string_list(JavaFlagsList, "", "", " ", JAVAFLAGS) },
globals__io_lookup_accumulating_option(java_classpath,
Java_Incl_Dirs),
@@ -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), " "]) }
),
globals__io_lookup_bool_option(target_debug, Target_Debug),
{ Target_Debug = yes ->
@@ -628,7 +633,7 @@
globals__io_lookup_string_option(c_flag_to_name_object_file,
NameObjectFile),
globals__io_lookup_accumulating_option(cflags, C_Flags_List),
- { join_string_list(C_Flags_List, "", "", " ", CFLAGS) },
+ { join_quoted_string_list(C_Flags_List, "", "", " ", CFLAGS) },
% Be careful with the order here.
% Also be careful that each option is separated by spaces.
{ string__append_list([CC, " ", CFLAGS, " ", GCCFLAGS_FOR_PIC,
@@ -814,22 +819,24 @@
module_name_to_file_name(ThisModuleName, ".c", no,
CFileName)
), ModuleNames, CFileNameList),
- { join_string_list(CFileNameList, "", "", " ", CFileNames) },
+ { join_quoted_string_list(CFileNameList, "", "", " ", CFileNames) },
globals__io_lookup_accumulating_option(link_flags, LinkFlagsList),
- { join_string_list(LinkFlagsList, "", "", " ", LinkFlags) },
+ { join_quoted_string_list(LinkFlagsList, "", "", " ", LinkFlags) },
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 ",
- "", " ", TraceInitFileNames) },
+ { join_quoted_string_list(TraceInitFileNamesList,
+ "--trace-init-file ", "", " ", TraceInitFileNames) },
{ TmpInitCFileName = InitCFileName ++ ".tmp" },
{ MkInitCmd = string__append_list(
@@ -940,21 +947,22 @@
Target_Debug_Opt = ""
},
standard_library_directory_option(StdLibOpt),
- { join_string_list(ObjectsList, "", "", " ", Objects) },
+ { join_quoted_string_list(ObjectsList, "", "", " ", Objects) },
globals__io_lookup_accumulating_option(link_flags,
LinkFlagsList),
- { join_string_list(LinkFlagsList, "", "", " ", LinkFlags) },
+ { join_quoted_string_list(LinkFlagsList,
+ "", "", " ", LinkFlags) },
globals__io_lookup_accumulating_option(LDFlagsOpt,
LDFlagsList),
- { join_string_list(LDFlagsList, "", "", " ", LDFlags) },
+ { join_quoted_string_list(LDFlagsList, "", "", " ", LDFlags) },
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
@@ -979,11 +987,11 @@
globals__io_lookup_string_option(create_archive_command, ArCmd),
globals__io_lookup_accumulating_option(
create_archive_command_flags, ArFlagsList),
- { join_string_list(ArFlagsList, "", "", " ", ArFlags) },
+ { join_quoted_string_list(ArFlagsList, "", "", " ", ArFlags) },
globals__io_lookup_string_option(
create_archive_command_output_flag, ArOutputFlag),
globals__io_lookup_string_option(ranlib_command, RanLib),
- { join_string_list(ObjectList, "", "", " ", Objects) },
+ { join_quoted_string_list(ObjectList, "", "", " ", Objects) },
{ MakeLibCmd = string__append_list([
ArCmd, " ", ArFlags, " ", ArOutputFlag, " ",
LibFileName, " ", Objects,
@@ -1002,7 +1010,7 @@
{
MaybeStdLibDir = yes(StdLibDir),
Opt = "--mercury-standard-library-directory "
- ++ StdLibDir ++ " "
+ ++ quote_arg(StdLibDir) ++ " "
;
MaybeStdLibDir = no,
Opt = "--no-mercury-standard-library-directory "
@@ -1029,6 +1037,14 @@
Result0], Result)
).
+ % As above, but quote the strings first.
+:- 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)
%
% The list of strings `Result' is computed from the list of strings
@@ -1141,7 +1157,7 @@
(func(Module) = ModuleStr :-
prog_out__sym_name_to_string(Module, ".", ModuleStr)
), AllModules),
- join_string_list(AllModulesStrings,
+ join_quoted_string_list(AllModulesStrings,
"", "", " ", AllModulesStr),
Command = string__from_rev_char_list(substitute_user_command_2(
string__to_char_list(Command0),
@@ -1174,5 +1190,42 @@
substitute_user_command_2(Chars, RevMainModule,
RevAllModules, [Char | RevChars0])
).
+
+%-----------------------------------------------------------------------------%
+
+quote_arg(Arg0) = Arg :-
+ ArgList = quote_arg_2(string__to_char_list(Arg0)),
+ (
+ ArgList = []
+ ->
+ Arg = """"""
+ ;
+ 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),
+ ( EscapedChar = quote_char(Char) ->
+ Chars = [('\\'), EscapedChar | Chars1]
+ ;
+ Chars = [Char | Chars1]
+ ).
+
+
+:- func quote_char(char) = char is semidet.
+
+quote_char('\\') = ('\\').
+quote_char('"') = '"'.
%-----------------------------------------------------------------------------%
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 6 Aug 2002 03:06:36 -0000
@@ -3306,6 +3306,9 @@
"--cflags <options>",
"\tSpecify options to be passed to the C compiler.",
+ "\tUse one `--cflags' option per word",
+ "\t(e.g. `--cflags -Wall --cflags -O0', not",
+ "\t`--cflags ""-Wall -O0""').",
% The --cflags-for-regs, --cflags-for-gotos,
% --cflags-for-threads, --cflags-for-pic options,
@@ -3320,6 +3323,7 @@
"--java-flags <options>",
"\tSpecify options to be passed to the Java compiler.",
+ "\tUse one `--java-flags' option per word.",
"--java-classpath <path>",
"\tSet the classpath for the Java compiler.",
@@ -3332,15 +3336,18 @@
"\tThe Microsoft IL Assembler.",
"--ilasm-flags <options>",
"\tSpecify options to be passed to the IL assembler.",
+ "\tUse one `--ilasm-flags' option per word.",
"--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.",
+ "\tUse one `--mcpp-flags' option per word.",
"--csharp-compiler <csc>",
"\tSpecify the name of the Microsoft C# Compiler.",
"--csharp-flags <options>",
- "\tSpecify options to be passed to the C# Compiler."
+ "\tSpecify options to be passed to the C# Compiler.",
+ "\tUse one `--csharp-flags' option per word."
]).
:- pred options_help_link(io__state::di, io__state::uo) is det.
@@ -3355,14 +3362,17 @@
"\tThis option is ignored by `mmc --make'.",
"--link-flags <options>, --ml-flags <options>",
"\tSpecify options to be passed to ml, the Mercury linker.",
+ "\tUse one `--ml-flags' option per word.",
"--ld-flags <options>",
"\tSpecify options to be passed to the linker command",
"\tinvoked by ml to link an executable.",
+ "\tUse one `--ld-flags' option per word.",
"\tUse `ml --print-link-command' to find out which",
"\tcommand is used.",
"--ld-libflags <options>",
"\tSpecify options to be passed to the linker command",
"\tinvoked by ml to link a shared library.",
+ "\tUse one `--ld-libflags' option per word.",
"\tUse `ml --print-shared-lib-link-command' to find out",
"\twhich command is used.",
"-L <directory>, --library-directory <directory>",
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 6 Aug 2002 06:13:45 -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([], "--cflags").
+mmc_option_type(java_flags) = option([], "--java-flags").
+mmc_option_type(ilasm_flags) = option([], "--ilasm-flags").
+mmc_option_type(mcpp_flags) = option([], "--mcpp-flags").
+mmc_option_type(csharp_flags) = option([], "--csharp-flags").
+mmc_option_type(ml_flags) = option([], "--link-flags").
+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-flags").
+mmc_option_type(ld_libflags) = option([], "--ld-libflags").
+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 6 Aug 2002 03:07:09 -0000
@@ -5838,6 +5838,9 @@
@findex --cflags
@cindex C compiler options
Specify options to be passed to the C compiler.
+Use one @samp{--cflags} option per word
+(e.g.@:@samp{--cflags -Wall --cflags -O0}, not
+@:@samp{--cflags ``-Wall -O0''}).
@sp 1
@item --javac @var{compiler-name}
@@ -5852,6 +5855,7 @@
@findex --java-flags
@cindex Java compiler options
Specify options to be passed to the Java compiler.
+Use one @samp{--java-flags} option per word.
@sp 1
@item --java-classpath @var{dir}
@@ -5892,12 +5896,14 @@
@cindex Link options
@cindex Linker options
Specify options to be passed to @samp{ml}, the Mercury linker.
+Use one @samp{--ml-flags} option per word.
@sp 1
@item --ld-flags @var{options}
@findex --ld-flags
Specify options to be passed to the command
invoked by ml to link an executable.
+Use one @samp{--ld-flags} option per word.
Use @code{ml --print-link-command} to find out
which command is used.
@@ -5906,6 +5912,7 @@
@findex --ld-libflags
Specify options to be passed to the command
invoked by ml to link a shared library.
+Use one @samp{--ld-libflags} option per word.
Use @code{ml --print-shared-lib-link-command}
to find out which command is used.
Index: scripts/Mmake.rules
===================================================================
RCS file: /home/mercury1/repository/mercury/scripts/Mmake.rules,v
retrieving revision 1.129
diff -u -u -r1.129 Mmake.rules
--- scripts/Mmake.rules 26 Jun 2002 08:20:55 -0000 1.129
+++ scripts/Mmake.rules 6 Aug 2002 05:35:36 -0000
@@ -197,7 +197,8 @@
$(pic_s_dates_subdir)%.pic_s_date : %.m
$(MCG) $(ALL_GRADEFLAGS) --target-code-only $(ALL_MCGFLAGS) \
- --pic --cflags "$(GCCFLAGS_FOR_PIC)" $(*F) > $(*F).err 2>&1
+ --pic $(patsubst %,--cflags %,$(GCCFLAGS_FOR_PIC)) \
+ $(*F) > $(*F).err 2>&1
$(os_subdir)%.$O : $(ss_subdir)%.s
$(AS) $< $(OBJFILE_OPT)$@
Index: scripts/Mmake.vars.in
===================================================================
RCS file: /home/mercury1/repository/mercury/scripts/Mmake.vars.in,v
retrieving revision 1.76
diff -u -u -r1.76 Mmake.vars.in
--- scripts/Mmake.vars.in 29 Jul 2002 07:51:07 -0000 1.76
+++ scripts/Mmake.vars.in 6 Aug 2002 05:34:54 -0000
@@ -159,7 +159,7 @@
ALL_MCGFLAGS = $(MCGFLAGS) $(EXTRA_MCGFLAGS) $(TARGET_MCFLAGS) \
$(LIB_MCFLAGS)
ALL_MCSFLAGS = $(MCSFLAGS) $(EXTRA_MCSFLAGS) $(TARGET_MCFLAGS) \
- $(LIB_MCFLAGS) --cflags "$(ALL_CFLAGS)"
+ $(LIB_MCFLAGS) $(patsubst %,--cflags %,$(ALL_CFLAGS))
MCIFLAGS = $(MCFLAGS)
MCPIFLAGS = $(MCFLAGS)
--------------------------------------------------------------------------
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