[m-rev.] for review: MERCURY_OPTIONS-progname

Zoltan Somogyi zs at csse.unimelb.edu.au
Tue May 20 17:11:06 AEST 2008


MERCURY_OPTIONS is a crude way to give options to Mercury programs, since it
applies to all Mercury programs, even though we often want to give options to
only one specific Mercury program. (For example, we may want to give it only
to a test program's executable, and not to the invocation of the compiler
that generates it.) This diff makes the runtime system, when executing a
program named "progname", look for and process the environment variable
whose name is "MERCURY_OPTIONS-progname". This allows options to be given
at runtime to only one specific program.

runtime/mercury_wrapper.c:
	Make the change described above.

runtime/mercury_wrapper.h:
	Fix some obsolete documentation, and add some up-to-date documentation.

doc/user_guide.texi:
	Document the change.

util/mkinit.c:
	Fix indentation.

Zoltan.

cvs diff: Diffing .
cvs diff: Diffing analysis
cvs diff: Diffing bindist
cvs diff: Diffing boehm_gc
cvs diff: Diffing boehm_gc/Mac_files
cvs diff: Diffing boehm_gc/cord
cvs diff: Diffing boehm_gc/cord/private
cvs diff: Diffing boehm_gc/doc
cvs diff: Diffing boehm_gc/include
cvs diff: Diffing boehm_gc/include/private
cvs diff: Diffing boehm_gc/libatomic_ops-1.2
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/doc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/gcc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/hpc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/ibmc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/icc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/msftc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/sunc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/tests
cvs diff: Diffing boehm_gc/tests
cvs diff: Diffing boehm_gc/windows-untested
cvs diff: Diffing boehm_gc/windows-untested/vc60
cvs diff: Diffing boehm_gc/windows-untested/vc70
cvs diff: Diffing boehm_gc/windows-untested/vc71
cvs diff: Diffing browser
cvs diff: Diffing bytecode
cvs diff: Diffing compiler
cvs diff: Diffing compiler/notes
cvs diff: Diffing debian
cvs diff: Diffing debian/patches
cvs diff: Diffing deep_profiler
cvs diff: Diffing deep_profiler/notes
cvs diff: Diffing doc
Index: doc/user_guide.texi
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/doc/user_guide.texi,v
retrieving revision 1.563
diff -u -b -r1.563 user_guide.texi
--- doc/user_guide.texi	16 May 2008 08:10:52 -0000	1.563
+++ doc/user_guide.texi	20 May 2008 07:09:49 -0000
@@ -9363,11 +9363,20 @@
 @sp 1
 @item MERCURY_OPTIONS
 @vindex MERCURY_OPTIONS
-A list of options for the Mercury runtime that gets
-linked into every Mercury program.  Options may also
-be set at compile time by passing @samp{--runtime-flags}
-options to @samp{ml} and @samp{c2init}.
-The Mercury runtime accepts the following options.
+A list of options for the Mercury runtime system,
+which gets linked into every Mercury program.
+The options given in this environment variable apply to every program;
+the options given in an environment variable
+whose name is of the form @samp{MERCURY_OPTIONS- at var{progname}}
+apply only to programs named @var{progname}.
+Options may also be set for a particular executable at compile time
+by passing @samp{--runtime-flags} options
+to the invocations of @samp{ml} and @samp{c2init} which create that executable.
+These options are processed first,
+followed by those in @samp{MERCURY_OPTIONS},
+with the options in @samp{MERCURY_OPTIONS- at var{progname}} being processed last.
+
+The Mercury runtime system accepts the following options.
 
 @sp 1
 @table @code
cvs diff: Diffing extras
cvs diff: Diffing extras/base64
cvs diff: Diffing extras/cgi
cvs diff: Diffing extras/complex_numbers
cvs diff: Diffing extras/complex_numbers/samples
cvs diff: Diffing extras/complex_numbers/tests
cvs diff: Diffing extras/concurrency
cvs diff: Diffing extras/curs
cvs diff: Diffing extras/curs/samples
cvs diff: Diffing extras/curses
cvs diff: Diffing extras/curses/sample
cvs diff: Diffing extras/dynamic_linking
cvs diff: Diffing extras/error
cvs diff: Diffing extras/fixed
cvs diff: Diffing extras/gator
cvs diff: Diffing extras/gator/generations
cvs diff: Diffing extras/gator/generations/1
cvs diff: Diffing extras/graphics
cvs diff: Diffing extras/graphics/easyx
cvs diff: Diffing extras/graphics/easyx/samples
cvs diff: Diffing extras/graphics/mercury_allegro
cvs diff: Diffing extras/graphics/mercury_allegro/examples
cvs diff: Diffing extras/graphics/mercury_allegro/samples
cvs diff: Diffing extras/graphics/mercury_allegro/samples/demo
cvs diff: Diffing extras/graphics/mercury_allegro/samples/mandel
cvs diff: Diffing extras/graphics/mercury_allegro/samples/pendulum2
cvs diff: Diffing extras/graphics/mercury_allegro/samples/speed
cvs diff: Diffing extras/graphics/mercury_glut
cvs diff: Diffing extras/graphics/mercury_opengl
cvs diff: Diffing extras/graphics/mercury_tcltk
cvs diff: Diffing extras/graphics/samples
cvs diff: Diffing extras/graphics/samples/calc
cvs diff: Diffing extras/graphics/samples/gears
cvs diff: Diffing extras/graphics/samples/maze
cvs diff: Diffing extras/graphics/samples/pent
cvs diff: Diffing extras/lazy_evaluation
cvs diff: Diffing extras/lex
cvs diff: Diffing extras/lex/samples
cvs diff: Diffing extras/lex/tests
cvs diff: Diffing extras/log4m
cvs diff: Diffing extras/logged_output
cvs diff: Diffing extras/moose
cvs diff: Diffing extras/moose/samples
cvs diff: Diffing extras/moose/tests
cvs diff: Diffing extras/mopenssl
cvs diff: Diffing extras/morphine
cvs diff: Diffing extras/morphine/non-regression-tests
cvs diff: Diffing extras/morphine/scripts
cvs diff: Diffing extras/morphine/source
cvs diff: Diffing extras/net
cvs diff: Diffing extras/odbc
cvs diff: Diffing extras/posix
cvs diff: Diffing extras/posix/samples
cvs diff: Diffing extras/quickcheck
cvs diff: Diffing extras/quickcheck/tutes
cvs diff: Diffing extras/references
cvs diff: Diffing extras/references/samples
cvs diff: Diffing extras/references/tests
cvs diff: Diffing extras/solver_types
cvs diff: Diffing extras/solver_types/library
cvs diff: Diffing extras/trailed_update
cvs diff: Diffing extras/trailed_update/samples
cvs diff: Diffing extras/trailed_update/tests
cvs diff: Diffing extras/windows_installer_generator
cvs diff: Diffing extras/windows_installer_generator/sample
cvs diff: Diffing extras/windows_installer_generator/sample/images
cvs diff: Diffing extras/xml
cvs diff: Diffing extras/xml/samples
cvs diff: Diffing extras/xml_stylesheets
cvs diff: Diffing java
cvs diff: Diffing java/runtime
cvs diff: Diffing library
cvs diff: Diffing mdbcomp
cvs diff: Diffing profiler
cvs diff: Diffing robdd
cvs diff: Diffing runtime
Index: runtime/mercury_wrapper.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_wrapper.c,v
retrieving revision 1.188
diff -u -b -r1.188 mercury_wrapper.c
--- runtime/mercury_wrapper.c	18 Mar 2008 03:09:43 -0000	1.188
+++ runtime/mercury_wrapper.c	20 May 2008 07:07:46 -0000
@@ -530,8 +530,8 @@
 #endif
 
     /*
-    ** Process the command line and the options in the environment
-    ** variable MERCURY_OPTIONS, and save results in global variables.
+    ** Process the command line and the options in the relevant environment
+    ** variables, and save results in global variables.
     */
 
     MR_process_args(argc, argv);
@@ -987,28 +987,67 @@
 }
 
 /*
-** MR_process_environment_options() is a function to parse the MERCURY_OPTIONS
-** environment variable.  
+** MR_process_environment_options() is a function to parse the options put
+** into MR_runtime_flags by mkinit, the MERCURY_OPTIONS environment variable,
+** and the MERCURY_OPTIONS-progname environment variable.
 */ 
 
+#define MERCURY_OPTIONS     "MERCURY_OPTIONS"
+
 static void
 MR_process_environment_options(void)
 {
-    char    *env_options;
+    char        *gen_env_options;
+    char        *prog_env_options;
+    char        *prog_env_option_name;
+    int         prog_env_option_name_len;
+    int         mercury_options_len;
+    const char  *progname;
+    const char  *s;
+
+    gen_env_options = getenv(MERCURY_OPTIONS);
+    if (gen_env_options == NULL) {
+        gen_env_options = (char *) "";
+    }
 
-    env_options = getenv("MERCURY_OPTIONS");
-    if (env_options == NULL) {
-        env_options = (char *) "";
+    /* Find out the program's name, stripping off any directory names. */
+    progname = MR_progname;
+    for (s = progname; *s != '\0'; s++) {
+        if (*s == '/') {
+            progname = s + 1;
     }
+    }
+
+    /* Build the program-specific option's name: MERCURY_OPTIONS-progname. */
+    mercury_options_len = strlen(MERCURY_OPTIONS);
+    prog_env_option_name_len = mercury_options_len + 1 + strlen(progname);
+    prog_env_option_name = MR_GC_NEW_ARRAY(char, prog_env_option_name_len);
+    strcpy(prog_env_option_name, MERCURY_OPTIONS);
+    prog_env_option_name[mercury_options_len] = '-';
+    strcpy(prog_env_option_name + mercury_options_len + 1, progname);
 
-    if (env_options[0] != '\0' || MR_runtime_flags[0] != '\0') {
-        const char  *cmd;
-        char        *arg_str, **argv;
+    prog_env_options = getenv(prog_env_option_name);
+    if (prog_env_options == NULL) {
+        prog_env_options = (char *) "";
+    }
+
+    MR_GC_free(prog_env_option_name);
+
+    if (gen_env_options[0] != '\0' || prog_env_options[0] != '\0'
+        || MR_runtime_flags[0] != '\0')
+    {
+        const char  *dummy_cmd;
+        int         dummy_cmd_len;
         char        *dummy_command_line;
-        const char  *error_msg;
-        int     argc;
-        int     cmd_len;
+        int         dummy_command_line_len;
+        char        *option_arg_str;
+        char        **option_argv;
+        int         option_argc;
         int     runtime_flags_len;
+        int         gen_env_options_len;
+        int         prog_env_options_len;
+        int         next_slot;
+        const char  *error_msg;
 
         /*
         ** getopt() expects the options to start in argv[1], not argv[0],
@@ -1016,28 +1055,92 @@
         ** at the start of the options before passing them to MR_make_argv()
         ** and then to getopt().
         */
-        cmd = "mercury_runtime ";
-        cmd_len = strlen(cmd);
+
+        dummy_cmd = "mercury_runtime";
+        dummy_cmd_len = strlen(dummy_cmd);
         runtime_flags_len = strlen(MR_runtime_flags);
-        dummy_command_line = MR_GC_NEW_ARRAY(char,
-            cmd_len + runtime_flags_len + 1 + strlen(env_options) + 1);
-        strcpy(dummy_command_line, cmd);
-        strcpy(dummy_command_line + cmd_len, MR_runtime_flags);
-        dummy_command_line[cmd_len + runtime_flags_len] = ' ';
-        strcpy(dummy_command_line + cmd_len + runtime_flags_len + 1,
-            env_options);
+        gen_env_options_len = strlen(gen_env_options);
+        prog_env_options_len = strlen(prog_env_options);
+        dummy_command_line_len =
+            dummy_cmd_len + 1 +
+            runtime_flags_len + 1 +
+            gen_env_options_len + 1 +
+            prog_env_options_len + 1;
+        dummy_command_line = MR_GC_NEW_ARRAY(char, dummy_command_line_len);
+
+        next_slot = 0;
+
+        strcpy(dummy_command_line + next_slot, dummy_cmd);
+        next_slot += dummy_cmd_len;
+        dummy_command_line[next_slot] = ' ';
+        next_slot += 1;
+        strcpy(dummy_command_line + next_slot, MR_runtime_flags);
+        next_slot += runtime_flags_len;
+        dummy_command_line[next_slot] = ' ';
+        next_slot += 1;
+        strcpy(dummy_command_line + next_slot, gen_env_options);
+        next_slot += gen_env_options_len;
+        dummy_command_line[next_slot] = ' ';
+        next_slot += 1;
+        strcpy(dummy_command_line + next_slot, prog_env_options);
+        next_slot += prog_env_options_len;
+        dummy_command_line[next_slot] = '\0';
+        next_slot += 1;
+
+        /* Sanity check. */
+        if (next_slot != dummy_command_line_len) {
+            MR_fatal_error("next_slot != dummy_command_line_len");
+        }
+
+#ifdef MR_DEBUG_ARGUMENT_HANDLING
+        /* Enable this is if you need to debug this code. */
+        printf("progname = <%s>\n", progname);
+        printf("MR_runtime_flags = <%s>\n", MR_runtime_flags);
+        printf("gen_env_options = <%s>\n", gen_env_options);
+        printf("prog_env_options = <%s>\n", prog_env_options);
+        printf("dummy_command_line = <%s>\n", dummy_command_line);
+#endif
         
-        error_msg = MR_make_argv(dummy_command_line, &arg_str, &argv, &argc);
+        error_msg = MR_make_argv(dummy_command_line, &option_arg_str,
+            &option_argv, &option_argc);
         if (error_msg != NULL) {
-            MR_fatal_error("error parsing the MERCURY_OPTIONS "
-                "environment variable:\n%s\n", error_msg);
+            char    *where_buf;
+            int     where_buf_next;
+
+            where_buf = MR_GC_NEW_ARRAY(char, 1000);
+            where_buf[0] = '\0';
+            where_buf_next = strlen(where_buf);
+
+            if (gen_env_options[0] != '\0') {
+                sprintf(where_buf + where_buf_next,
+                    "%sthe %s environment variable",
+                    where_buf_next == 0 ? "" : " and/or ",
+                    MERCURY_OPTIONS);
+                where_buf_next = strlen(where_buf);
         }
-        MR_GC_free(dummy_command_line);
 
-        MR_process_options(argc, argv);
+            if (prog_env_options[0] != '\0') {
+                sprintf(where_buf + where_buf_next,
+                    "%sthe %s environment variable",
+                    where_buf_next == 0 ? "" : " and/or ",
+                    prog_env_option_name);
+                where_buf_next = strlen(where_buf);
+            }
 
-        MR_GC_free(arg_str);
-        MR_GC_free(argv);
+            if (MR_runtime_flags[0] != '\0') {
+                sprintf(where_buf + where_buf_next,
+                    "%sthe runtime options built into the executable",
+                    where_buf_next == 0 ? "" : " and/or ");
+                where_buf_next = strlen(where_buf);
+            }
+
+            MR_fatal_error("error parsing %s:\n%s\n", where_buf, error_msg);
+        }
+
+        MR_GC_free(dummy_command_line);
+        MR_process_options(option_argc, option_argv);
+        MR_GC_free(option_arg_str);
+        MR_GC_free(option_argv);
     }
 }
 
Index: runtime/mercury_wrapper.h
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_wrapper.h,v
retrieving revision 1.80
diff -u -b -r1.80 mercury_wrapper.h
--- runtime/mercury_wrapper.h	12 Sep 2007 06:21:17 -0000	1.80
+++ runtime/mercury_wrapper.h	27 Mar 2008 12:54:16 -0000
@@ -75,6 +75,18 @@
 extern void MR_dummy_main(void);
 #endif
 
+/****************************************************************************/
+
+/*
+** The values of the variables in this section of mercury_wrapper.h
+** are defined by the program's _init.c file, which is generated by mkinit.
+*/
+
+/*
+** MR_runtime_flags holds program specific options, treated the same
+** as MERCURY_OPTIONS, that are burned into the program by mkinit.
+*/
+
 extern const char	*MR_runtime_flags;
 
 extern	void		(*MR_library_initializer)(void);
@@ -175,11 +187,7 @@
 
 extern	void		(*MR_register_module_layout)(const MR_ModuleLayout *);
 
-/*
-** These global variables have their values defined in the program's _init.c
-** file. MR_complexity_preds_size gives the number of elements in the
-** MR_complexity_preds array.
-*/
+/****************************************************************************/
 
 extern	void		MR_do_init_modules(void);
 extern	void		MR_do_init_modules_type_tables(void);
@@ -187,6 +195,10 @@
 #ifdef	MR_RECORD_TERM_SIZES
 extern	void		MR_do_init_modules_complexity(void);
 
+/*
+** MR_complexity_preds_size gives the number of elements in the
+** MR_complexity_preds array.
+*/
 extern	MR_ComplexityProc *MR_complexity_procs;
 extern  int             MR_num_complexity_procs;
 #endif
cvs diff: Diffing runtime/GETOPT
cvs diff: Diffing runtime/machdeps
cvs diff: Diffing samples
cvs diff: Diffing samples/c_interface
cvs diff: Diffing samples/c_interface/c_calls_mercury
cvs diff: Diffing samples/c_interface/cplusplus_calls_mercury
cvs diff: Diffing samples/c_interface/mercury_calls_c
cvs diff: Diffing samples/c_interface/mercury_calls_cplusplus
cvs diff: Diffing samples/c_interface/mercury_calls_fortran
cvs diff: Diffing samples/c_interface/simpler_c_calls_mercury
cvs diff: Diffing samples/c_interface/simpler_cplusplus_calls_mercury
cvs diff: Diffing samples/c_interface/standalone_c
cvs diff: Diffing samples/diff
cvs diff: Diffing samples/muz
cvs diff: Diffing samples/rot13
cvs diff: Diffing samples/solutions
cvs diff: Diffing samples/solver_types
cvs diff: Diffing samples/tests
cvs diff: Diffing samples/tests/c_interface
cvs diff: Diffing samples/tests/c_interface/c_calls_mercury
cvs diff: Diffing samples/tests/c_interface/cplusplus_calls_mercury
cvs diff: Diffing samples/tests/c_interface/mercury_calls_c
cvs diff: Diffing samples/tests/c_interface/mercury_calls_cplusplus
cvs diff: Diffing samples/tests/c_interface/mercury_calls_fortran
cvs diff: Diffing samples/tests/c_interface/simpler_c_calls_mercury
cvs diff: Diffing samples/tests/c_interface/simpler_cplusplus_calls_mercury
cvs diff: Diffing samples/tests/diff
cvs diff: Diffing samples/tests/muz
cvs diff: Diffing samples/tests/rot13
cvs diff: Diffing samples/tests/solutions
cvs diff: Diffing samples/tests/toplevel
cvs diff: Diffing scripts
cvs diff: Diffing slice
cvs diff: Diffing ssdb
cvs diff: Diffing tests
cvs diff: Diffing tests/benchmarks
cvs diff: Diffing tests/debugger
cvs diff: Diffing tests/debugger/declarative
cvs diff: Diffing tests/dppd
cvs diff: Diffing tests/general
cvs diff: Diffing tests/general/accumulator
cvs diff: Diffing tests/general/string_format
cvs diff: Diffing tests/general/structure_reuse
cvs diff: Diffing tests/grade_subdirs
cvs diff: Diffing tests/hard_coded
cvs diff: Diffing tests/hard_coded/exceptions
cvs diff: Diffing tests/hard_coded/purity
cvs diff: Diffing tests/hard_coded/sub-modules
cvs diff: Diffing tests/hard_coded/typeclasses
cvs diff: Diffing tests/invalid
cvs diff: Diffing tests/invalid/purity
cvs diff: Diffing tests/misc_tests
cvs diff: Diffing tests/mmc_make
cvs diff: Diffing tests/mmc_make/lib
cvs diff: Diffing tests/par_conj
cvs diff: Diffing tests/recompilation
cvs diff: Diffing tests/tabling
cvs diff: Diffing tests/term
cvs diff: Diffing tests/trailing
cvs diff: Diffing tests/valid
cvs diff: Diffing tests/warnings
cvs diff: Diffing tools
cvs diff: Diffing trace
cvs diff: Diffing util
Index: util/mkinit.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/util/mkinit.c,v
retrieving revision 1.119
diff -u -b -r1.119 mkinit.c
--- util/mkinit.c	12 Sep 2007 06:21:20 -0000	1.119
+++ util/mkinit.c	27 Mar 2008 12:51:20 -0000
@@ -284,16 +284,16 @@
 
 static int          num_experimental_complexity_procs = 0;
 
-    /* List of options to pass to the runtime */
+/* List of options to pass to the runtime */
 static String_List  *runtime_flags = NULL;
 
-    /* Pointer to tail of the runtime_flags list */
+/* Pointer to tail of the runtime_flags list */
 static String_List  **runtime_flags_tail = &runtime_flags;
 
-    /* List of functions to always execute at initialization */
+/* List of functions to always execute at initialization */
 static String_List  *always_exec_funcs = NULL;
 
-    /* Pointer to tail of the always_exec_funcs list */
+/* Pointer to tail of the always_exec_funcs list */
 static String_List  **always_exec_funcs_tail = &always_exec_funcs;
 
 /* --- code fragments to put in the output file --- */
cvs diff: Diffing vim
cvs diff: Diffing vim/after
cvs diff: Diffing vim/ftplugin
cvs diff: Diffing vim/syntax
--------------------------------------------------------------------------
mercury-reviews mailing list
Post messages to:       mercury-reviews at csse.unimelb.edu.au
Administrative Queries: owner-mercury-reviews at csse.unimelb.edu.au
Subscriptions:          mercury-reviews-request at csse.unimelb.edu.au
--------------------------------------------------------------------------



More information about the reviews mailing list