[m-rev.] for review: move quote_arg/1 out of options.m

Julien Fischer jfischer at opturion.com
Mon Jul 25 20:42:52 AEST 2022


For review by anyone.

----------------------

Move quote_arg/1 out of options.m.

Move the function quote_arg/1, which is used to quote arguments to shell
commands, out of options.m and into its own module. It is called from
several other places other than options.m and its implementation details
have nothing to do with the other contents of options.m.

compiler/shell_util.m:
     New module for quote_arg/1 and its supporting predicates.

compiler/libs.m:
     Include the new module.

compiler/options.m:
compiler/compile_target_code.m:
compiler/file_util.m:
compiler/make.module_target.m:
compiler/make.program_target.m:
     Import the new module where necessary.

compiler/notes/compiler_design.m:
     Update this document.

Julien.

diff --git a/compiler/compile_target_code.m b/compiler/compile_target_code.m
index e8ff771..f023f99 100644
--- a/compiler/compile_target_code.m
+++ b/compiler/compile_target_code.m
@@ -236,6 +236,7 @@
  :- import_module libs.compute_grade.
  :- import_module libs.optimization_options.
  :- import_module libs.options.
+:- import_module libs.shell_util.
  :- import_module libs.trace_params.
  :- import_module parse_tree.error_util.
  :- import_module parse_tree.find_module.
diff --git a/compiler/file_util.m b/compiler/file_util.m
index 4291bb6..f3900f6 100644
--- a/compiler/file_util.m
+++ b/compiler/file_util.m
@@ -132,6 +132,7 @@

  :- import_module libs.compute_grade.
  :- import_module libs.options.
+:- import_module libs.shell_util.

  :- import_module benchmarking.
  :- import_module dir.
diff --git a/compiler/libs.m b/compiler/libs.m
index b07fbdf..65f5be7 100644
--- a/compiler/libs.m
+++ b/compiler/libs.m
@@ -44,6 +44,7 @@

  % OS interfaces not provided by the standard library.
  :- include_module process_util.
+:- include_module shell_util.
  :- include_module timestamp.

  % Constraint machinery for the termination analysers.
diff --git a/compiler/make.module_target.m b/compiler/make.module_target.m
index a027242..c7e3723 100644
--- a/compiler/make.module_target.m
+++ b/compiler/make.module_target.m
@@ -88,6 +88,7 @@
  :- import_module analysis.
  :- import_module libs.options.
  :- import_module libs.process_util.
+:- import_module libs.shell_util.
  :- import_module libs.timestamp.
  :- import_module make.build.
  :- import_module make.deps_set.
diff --git a/compiler/make.program_target.m b/compiler/make.program_target.m
index 98d3136..9585800 100644
--- a/compiler/make.program_target.m
+++ b/compiler/make.program_target.m
@@ -63,6 +63,7 @@
  :- import_module libs.handle_options.
  :- import_module libs.options.
  :- import_module libs.process_util.
+:- import_module libs.shell_util.
  :- import_module libs.timestamp.
  :- import_module make.build.
  :- import_module make.dependencies.
diff --git a/compiler/notes/compiler_design.html b/compiler/notes/compiler_design.html
index c8b5389..83ea894 100644
--- a/compiler/notes/compiler_design.html
+++ b/compiler/notes/compiler_design.html
@@ -2296,6 +2296,9 @@ process_util.m contains predicates
  that deal with process creation and signal handling.
  This module is mainly used by make.m and its submodules.
  <li>
+shell_util.m contains a utility function for quoting arguments to shell
+commands.
+<li>
  timestamp.m contains an ADT representing timestamps.
  It is used by smart recompilation and `mmc --make'.
  <li>
diff --git a/compiler/options.m b/compiler/options.m
index 99ebfc7..54b400b 100644
--- a/compiler/options.m
+++ b/compiler/options.m
@@ -128,10 +128,6 @@
  :- pred set_all_options_to(list(option)::in, option_data::in,
      option_table::in, option_table::out) is det.

-    % Quote an argument to a shell command.
-    %
-:- func quote_arg(string) = string.
-
  %---------------------------------------------------------------------------%

  :- pred options_help(io.text_output_stream::in, io::di, io::uo) is det.
@@ -1162,6 +1158,7 @@
  :- implementation.

  :- import_module libs.compute_grade.
+:- import_module libs.shell_util.

  :- import_module assoc_list.
  :- import_module bool.
@@ -4103,62 +4100,6 @@ set_all_options_to([Option | Options], Value, !OptionTable) :-
  handle_quoted_flag(Option, Flag, !OptionTable) :-
      append_to_accumulating_option(Option - quote_arg(Flag), !OptionTable).

-quote_arg(Arg0) = Arg :-
-    % XXX Instead of using dir.use_windows_paths, this should really
-    % test whether we are using a Unix or Windows shell.
-    ( if dir.use_windows_paths then
-        ( if
-            ( string.contains_match(char.is_whitespace, Arg0)
-            ; Arg0 = ""
-            )
-        then
-            Arg = """" ++ Arg0 ++ """"
-        else
-            Arg = Arg0
-        )
-    else
-        ArgList = quote_arg_unix(string.to_char_list(Arg0)),
-        (
-            ArgList = [],
-            Arg = """"""
-        ;
-            ArgList = [_ | _],
-            ( if
-                list.member(Char, ArgList),
-                not
-                    ( char.is_alnum_or_underscore(Char)
-                    ; Char = ('-')
-                    ; Char = ('/')
-                    ; Char = ('.')
-                    ; Char = (',')
-                    ; Char = (':')
-                    )
-            then
-                Arg = """" ++ string.from_char_list(ArgList) ++ """"
-            else
-                Arg = string.from_char_list(ArgList)
-            )
-        )
-    ).
-
-:- func quote_arg_unix(list(char)) = list(char).
-
-quote_arg_unix([]) = [].
-quote_arg_unix([Char | Chars0]) = Chars :-
-    Chars1 = quote_arg_unix(Chars0),
-    ( if quote_char_unix(Char) then
-        Chars = [('\\'), Char | Chars1]
-    else
-        Chars = [Char | Chars1]
-    ).
-
-:- pred quote_char_unix(char::in) is semidet.
-
-quote_char_unix('\\').
-quote_char_unix('"').
-quote_char_unix('`').
-quote_char_unix('$').
-
  %---------------------------------------------------------------------------%

  options_help(Stream, !IO) :-
diff --git a/compiler/shell_util.m b/compiler/shell_util.m
index e69de29..20f040c 100644
--- a/compiler/shell_util.m
+++ b/compiler/shell_util.m
@@ -0,0 +1,95 @@
+%-----------------------------------------------------------------------------%
+% vim: ft=mercury ts=4 sw=4 et
+%-----------------------------------------------------------------------------%
+% Copyright (C) 2002-2007, 2015, 2017 The University of Melbourne.
+% Copyright (C) 2022 The Mercury team.
+% This file may only be copied under the terms of the GNU General
+% Public License - see the file COPYING in the Mercury distribution.
+%-----------------------------------------------------------------------------%
+%
+% File: shell_util.m.
+% Main author: stayl.
+%
+% Utilities for interacting with the shell.
+%
+%-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
+
+:- module libs.shell_util.
+:- interface.
+
+    % Quote an argument to a shell command.
+    %
+:- func quote_arg(string) = string.
+
+%-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
+
+:- implementation.
+
+:- import_module char.
+:- import_module dir.
+:- import_module list.
+:- import_module string.
+
+%-----------------------------------------------------------------------------%
+
+quote_arg(Arg0) = Arg :-
+    % XXX Instead of using dir.use_windows_paths, this should really
+    % test whether we are using a Unix or Windows shell.
+    ( if dir.use_windows_paths then
+        ( if
+            ( string.contains_match(char.is_whitespace, Arg0)
+            ; Arg0 = ""
+            )
+        then
+            Arg = """" ++ Arg0 ++ """"
+        else
+            Arg = Arg0
+        )
+    else
+        ArgList = quote_arg_unix(string.to_char_list(Arg0)),
+        (
+            ArgList = [],
+            Arg = """"""
+        ;
+            ArgList = [_ | _],
+            ( if
+                list.member(Char, ArgList),
+                not
+                    ( char.is_alnum_or_underscore(Char)
+                    ; Char = ('-')
+                    ; Char = ('/')
+                    ; Char = ('.')
+                    ; Char = (',')
+                    ; Char = (':')
+                    )
+            then
+                Arg = """" ++ string.from_char_list(ArgList) ++ """"
+            else
+                Arg = string.from_char_list(ArgList)
+            )
+        )
+    ).
+
+:- func quote_arg_unix(list(char)) = list(char).
+
+quote_arg_unix([]) = [].
+quote_arg_unix([Char | Chars0]) = Chars :-
+    Chars1 = quote_arg_unix(Chars0),
+    ( if quote_char_unix(Char) then
+        Chars = [('\\'), Char | Chars1]
+    else
+        Chars = [Char | Chars1]
+    ).
+
+:- pred quote_char_unix(char::in) is semidet.
+
+quote_char_unix('\\').
+quote_char_unix('"').
+quote_char_unix('`').
+quote_char_unix('$').
+
+%-----------------------------------------------------------------------------%
+:- end_module libs.shell_util.
+%-----------------------------------------------------------------------------%


More information about the reviews mailing list