[m-rev.] for review: add 4 new mdb commands

Ian MacLarty maclarty at cs.mu.OZ.AU
Sun Mar 12 11:24:14 AEDT 2006


Estimated hours taken: 5
Branches: main

Add a new mdb command, 'shell', that allows users to execute shell commands
from within the debugger.

Allow the user to give up to nine additional arguments to the 'source' command.
Occurances of the strings "$1" through "$9" in the sourced file are replaced by
the corresponding additional arguments, allowing for parameterised scripts.

Use the two new features mentioned above to add three more mdb commands: two
commands to open a term, goal or exception in vim or emacs and a third command
to perform a grep on a term, goal or exception (useful for seeing if a value
occurs in a big map, for example).

NEWS
	Mention the new commands.

doc/mdb_categories:
doc/user_guide.texi:
	Document the new commands.

scripts/Mmakefile:
scripts/mdb_emacs:
scripts/mdb_grep:
scripts/mdb_vim:
	Add scripts for the new emacs, grep and vim commands.

scripts/mdbrc.in:
	Add aliases for the new shell, emacs, grep and vim commands.

tests/debugger/Mmakefile:
tests/debugger/shell.exp:
tests/debugger/shell.inp:
tests/debugger/shell.m:
tests/debugger/shell_test_script:
	Test the shell and source commands.

trace/mercury_trace_internal.c:
	Implement the shell command and extend the source command
	to handle the optional extra arguments.

trace/mercury_trace_readline.c:
trace/mercury_trace_readline.h:
	Add a new function to read a line and replace all the 
	occurances of "$[1-9]" with the corresponding value from an array.

	Delete comments in the .c file that are duplicated in the .h file.

Index: NEWS
===================================================================
RCS file: /home/mercury1/repository/mercury/NEWS,v
retrieving revision 1.402
diff -u -r1.402 NEWS
--- NEWS	8 Mar 2006 02:25:26 -0000	1.402
+++ NEWS	12 Mar 2006 00:09:13 -0000
@@ -50,6 +50,12 @@
   left the goal at which the term was available as the value of a program
   variable.
 * Users can now see the set of places where two terms differ from each other.
+* Users can now execute system shell commands from within the debugger.
+* The source command now accepts optional additional arguments which
+  are substituted into the sourced file, allowing for parameterised
+  scripts.
+* Users can now open terms, goals or exceptions in vim or emacs, or
+  perform a grep on the term, goal or exception.
 * The declarative debugger now supports an `undo' command, and allows users to
   select the search algorithm.
 * The declarative debugger can now exploit information from the "code
Index: doc/mdb_categories
===================================================================
RCS file: /home/mercury1/repository/mercury/doc/mdb_categories,v
retrieving revision 1.30
diff -u -r1.30 mdb_categories
--- doc/mdb_categories	4 Feb 2006 14:30:02 -0000	1.30
+++ doc/mdb_categories	12 Mar 2006 00:00:10 -0000
@@ -27,8 +27,8 @@
 browsing   - Commands that let users explore the state of the computation.
              The browsing commands are `vars', `held_vars', `print', `browse',
              `stack', `up', `down', `level', `current', `view', `hold',
-             `diff', `save_to_file', `list', `push_list_dir' and
-             `pop_list_dir'.
+             `diff', `save_to_file', `vim', `emacs', `grep', `list', 
+             `push_list_dir' and `pop_list_dir'.
 
 end
 document_category 500 breakpoint
@@ -68,8 +68,8 @@
 end
 document_category 900 misc
 misc       - Commands that are of interest to most users but do not fit into
-             other categories. The misc commands are `source', `save' and 
-             `quit'.
+             other categories. The misc commands are `source', `save', `shell'
+             and `quit'.
 
 end
 document_category 1000 exp
Index: doc/user_guide.texi
===================================================================
RCS file: /home/mercury1/repository/mercury/doc/user_guide.texi,v
retrieving revision 1.470
diff -u -r1.470 user_guide.texi
--- doc/user_guide.texi	1 Mar 2006 22:58:44 -0000	1.470
+++ doc/user_guide.texi	11 Mar 2006 23:43:13 -0000
@@ -2866,6 +2866,33 @@
 with the given ordinal number or with the given name
 to the specified file. The option @samp{-x} (or @samp{--xml}) causes the
 output to be in XML.
+ at sp 1
+ at item vim @var{object}
+Save @var{object} to a temporary file and open the file with the vim
+editor.  
+ at var{object} may be a variable name or number, 
+the word @samp{goal} or
+the word @samp{exception},
+ at c or the word proc_body,
+the meanings of which are the same as for the @samp{safe_to_file} command.
+ at sp 1
+ at item emacs @var{object}
+Save @var{object} to a temporary file and open the file with the emacs
+editor.  
+ at var{object} may be a variable name or number, 
+the word @samp{goal} or
+the word @samp{exception},
+ at c or the word proc_body,
+the meanings of which are the same as for the @samp{safe_to_file} command.
+ at sp 1
+ at item grep @var{pattern} @var{object}
+Save the given object to a temporary file and perform a grep on the
+file using @var{pattern}.
+ at var{object} may be a variable name or number, 
+the word @samp{goal} or
+the word @samp{exception},
+ at c or the word proc_body,
+the meanings of which are the same as for the @samp{safe_to_file} command.
 @c @sp 1
 @c @item save_to_file [-x] proc_body @var{filename}
 @c Writes the representation of the body of the current procedure,
@@ -3737,9 +3764,18 @@
 In the case that the format itself is being set,
 these options are ignored.
 @sp 1
- at item source [-i] @var{filename}
+ at item shell @var{command}
+ at kindex shell (mdb command)
+Execute the given command in the system shell.
+ at samp{!} can be used as an alias for @samp{shell}.
+ at sp 1
+ at item source [-i] @var{filename} [@var{args}]
 @kindex source (mdb command)
 Executes the commands in the file named @var{filename}.
+Optionally a list of at most nine arguments can be given.
+Occurances of the strings "$1" to "$9" in the sourced file
+will be replaced by the corresponding arguments given in the source
+command before the commands in the sourced file are executed.
 @sp 1
 The option @samp{-i} or @samp{--ignore-errors} tells @samp{mdb}
 not to complain if the named file does not exist or is not readable.
Index: scripts/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/mercury/scripts/Mmakefile,v
retrieving revision 1.39
diff -u -r1.39 Mmakefile
--- scripts/Mmakefile	25 May 2005 05:19:50 -0000	1.39
+++ scripts/Mmakefile	11 Mar 2006 23:20:38 -0000
@@ -45,10 +45,15 @@
 	Mmake.vars \
 	parse_ml_options.sh-subr
 
-CONF_DEBUG_SCRIPTS = \
+CONF_DEBUG_SCRIPTS = 	\
 	mdbrc
 
-DEBUGGER_SCRIPTS = $(CONF_DEBUG_SCRIPTS) xul_tree.xsl
+DEBUGGER_SCRIPTS = $(CONF_DEBUG_SCRIPTS) 	\
+		xul_tree.xsl			\
+		mdb_vim				\
+		mdb_emacs			\
+		mdb_grep
+
 EMACS_SCRIPTS = gud.el
 
 #-----------------------------------------------------------------------------#
Index: scripts/mdb_emacs
===================================================================
RCS file: scripts/mdb_emacs
diff -N scripts/mdb_emacs
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ scripts/mdb_emacs	11 Mar 2006 20:56:23 -0000
@@ -0,0 +1,3 @@
+save_to_file $1 .mdb_emacs_tmp
+shell emacs .mdb_emacs_tmp
+shell rm .mdb_emacs_tmp
Index: scripts/mdb_grep
===================================================================
RCS file: scripts/mdb_grep
diff -N scripts/mdb_grep
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ scripts/mdb_grep	11 Mar 2006 21:02:37 -0000
@@ -0,0 +1,3 @@
+save_to_file $2 .mdb_grep_tmp
+shell grep $1 .mdb_grep_tmp
+shell rm .mdb_grep_tmp
Index: scripts/mdb_vim
===================================================================
RCS file: scripts/mdb_vim
diff -N scripts/mdb_vim
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ scripts/mdb_vim	11 Mar 2006 21:21:34 -0000
@@ -0,0 +1,3 @@
+save_to_file $1 .mdb_vim_tmp
+shell vim .mdb_vim_tmp
+shell rm .mdb_vim_tmp
Index: scripts/mdbrc.in
===================================================================
RCS file: /home/mercury1/repository/mercury/scripts/mdbrc.in,v
retrieving revision 1.5
diff -u -r1.5 mdbrc.in
--- scripts/mdbrc.in	11 Dec 2004 01:59:51 -0000	1.5
+++ scripts/mdbrc.in	11 Mar 2006 20:52:31 -0000
@@ -15,5 +15,9 @@
 alias	e	exception
 alias	EMPTY	step
 alias	NUMBER	step
+alias	!	shell
+alias	vim	source @DEFAULT_MERCURY_DEBUGGER_INIT_DIR@/mdb_vim
+alias	emacs	source @DEFAULT_MERCURY_DEBUGGER_INIT_DIR@/mdb_emacs
+alias	grep	source @DEFAULT_MERCURY_DEBUGGER_INIT_DIR@/mdb_grep
 set xml_browser_cmd '@DEFAULT_XML_BROWSER_CMD@'
 set xml_tmp_filename '@DEFAULT_XML_TMP_FILENAME@'
Index: tests/debugger/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/Mmakefile,v
retrieving revision 1.120
diff -u -r1.120 Mmakefile
--- tests/debugger/Mmakefile	1 Mar 2006 22:58:47 -0000	1.120
+++ tests/debugger/Mmakefile	11 Mar 2006 16:47:30 -0000
@@ -47,6 +47,7 @@
 	print_table			\
 	queens_rep			\
 	resume_typeinfos		\
+	shell				\
 	solver_test			\
 	type_desc_test			\
 	uci_index
@@ -477,6 +478,9 @@
 shallow.out: shallow shallow.inp
 	$(MDB) ./shallow < shallow.inp > shallow.out 2>&1
 
+shell.out: shell shell.inp
+	$(MDB_STD) ./shell < shell.inp > shell.out 2>&1
+
 solver_test.out: solver_test solver_test.inp
 	$(MDB_STD) ./solver_test < solver_test.inp > solver_test.out 2>&1
 
Index: tests/debugger/shell.exp
===================================================================
RCS file: tests/debugger/shell.exp
diff -N tests/debugger/shell.exp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/debugger/shell.exp	11 Mar 2006 16:44:38 -0000
@@ -0,0 +1,10 @@
+Melbourne Mercury Debugger, mdb version DEV.
+Copyright 1998-2006 The University of Melbourne, Australia.
+mdb is free software, covered by the GNU General Public License.
+There is absolutely no warranty for mdb.
+      E1:     C1 CALL pred shell.main/2-0 (det) shell.m:12
+mdb> echo on
+Command echo enabled.
+mdb> shell echo hello
+hello
+mdb> quit -y
Index: tests/debugger/shell.inp
===================================================================
RCS file: tests/debugger/shell.inp
diff -N tests/debugger/shell.inp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/debugger/shell.inp	11 Mar 2006 20:45:51 -0000
@@ -0,0 +1,6 @@
+echo on
+shell echo hello
+alias test source shell_test_script
+test value1 value2 3 'value 4' "a" '' 'b' file_name.ext 9
+test only_one_value
+quit -y
Index: tests/debugger/shell.m
===================================================================
RCS file: tests/debugger/shell.m
diff -N tests/debugger/shell.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/debugger/shell.m	11 Mar 2006 20:27:12 -0000
@@ -0,0 +1,12 @@
+:- module shell.
+
+:- interface.
+
+:- import_module io.
+
+:- pred main(io::di, io::uo) is det.
+
+:- implementation.
+
+main(!IO) :-
+	nl(!IO).
Index: tests/debugger/shell_test_script
===================================================================
RCS file: tests/debugger/shell_test_script
diff -N tests/debugger/shell_test_script
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/debugger/shell_test_script	11 Mar 2006 20:42:54 -0000
@@ -0,0 +1,3 @@
+shell echo $1 $2
+shell echo $2 $1
+shell echo $1 $2 $ \\$abc $3 $4 $5 $6 $7 $8 $9 \\$0 \\$b $
Index: trace/mercury_trace_internal.c
===================================================================
RCS file: /home/mercury1/repository/mercury/trace/mercury_trace_internal.c,v
retrieving revision 1.221
diff -u -r1.221 mercury_trace_internal.c
--- trace/mercury_trace_internal.c	1 Mar 2006 22:58:50 -0000	1.221
+++ trace/mercury_trace_internal.c	11 Mar 2006 21:45:44 -0000
@@ -542,6 +542,7 @@
 static  MR_TraceCmdFunc MR_trace_cmd_untrust;
 static  MR_TraceCmdFunc MR_trace_cmd_trusted;
 static  MR_TraceCmdFunc MR_trace_cmd_dice;
+static  MR_TraceCmdFunc MR_trace_cmd_shell;
 
 static  void        MR_maybe_print_spy_point(int slot, const char *problem);
 static  void        MR_print_unsigned_var(FILE *fp, const char *var,
@@ -749,8 +750,9 @@
 static  void        MR_trace_expand_aliases(char ***words,
                         int *word_max, int *word_count);
 static  MR_bool     MR_trace_source(const char *filename,
-                        MR_bool ignore_errors);
-static  void        MR_trace_source_from_open_file(FILE *fp);
+                        MR_bool ignore_errors, char **args, int num_args);
+static  void        MR_trace_source_from_open_file(FILE *fp, char **args,
+                        int num_args);
 static  char        *MR_trace_getline_queue(void);
 static  MR_bool     MR_trace_continue_line(char *ptr, MR_bool *single_quoted,
                         MR_bool *double_quoted);
@@ -1209,7 +1211,7 @@
 
     init = getenv("MERCURY_DEBUGGER_INIT");
     if (init != NULL) {
-        (void) MR_trace_source(init, MR_FALSE);
+        (void) MR_trace_source(init, MR_FALSE, NULL, 0);
         /* If the source failed, the error message has been printed. */
     }
 }
@@ -1222,7 +1224,7 @@
 
     init = MDBRC_FILENAME;
     if ((fp = fopen(init, "r")) != NULL) {
-        MR_trace_source_from_open_file(fp);
+        MR_trace_source_from_open_file(fp, NULL, 0);
         fclose(fp);
     }
 }
@@ -1246,7 +1248,7 @@
     (void) strcat(buf, "/");
     (void) strcat(buf, MDBRC_FILENAME);
     if ((fp = fopen(buf, "r")) != NULL) {
-        MR_trace_source_from_open_file(fp);
+        MR_trace_source_from_open_file(fp, NULL, 0);
         fclose(fp);
     }
 
@@ -5753,17 +5755,24 @@
     MR_Event_Info *event_info, MR_Code **jumpaddr)
 {
     MR_bool ignore_errors;
+    char    **args;
 
     ignore_errors = MR_FALSE;
     if (! MR_trace_options_ignore(&ignore_errors, &words, &word_count)) {
         ; /* the usage message has already been printed */
-    } else if (word_count == 2) {
+    } else if (word_count >= 2) {
         /*
         ** If the source fails, the error message
         ** will have already been printed by MR_trace_source
         ** (unless ignore_errors suppresses the message).
         */
-        (void) MR_trace_source(words[1], ignore_errors);
+        if (word_count == 2) {
+            args = NULL;
+        } else {
+            args = &words[2];
+        }
+        (void) MR_trace_source(words[1], ignore_errors, args,
+            word_count - 2);
     } else {
         MR_trace_usage_cur_cmd();
     }
@@ -6197,6 +6206,31 @@
     }
 }
 
+static MR_Next
+MR_trace_cmd_shell(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
+    MR_Event_Info *event_info, MR_Code **jumpaddr)
+{
+    char*       command_string;
+    int         command_string_length;
+    int         word_num;
+
+    command_string_length = 1;
+    for (word_num = 1; word_num < word_count; word_num++) {
+        command_string_length += strlen(words[word_num]) + 1;
+    }
+    command_string = (char*) MR_malloc(sizeof(char) * command_string_length);
+    command_string[0] = '\0';
+    for (word_num = 1; word_num < word_count; word_num++) {
+        strcat(command_string, words[word_num]);
+        strcat(command_string, " ");
+    }
+
+    system(command_string);
+    MR_free(command_string);
+
+    return KEEP_INTERACTING;
+}
+
 static void
 MR_maybe_print_spy_point(int slot, const char *problem)
 {
@@ -7889,12 +7923,13 @@
 }
 
 static MR_bool
-MR_trace_source(const char *filename, MR_bool ignore_errors)
+MR_trace_source(const char *filename, MR_bool ignore_errors,
+    char** args, int num_args)
 {
     FILE    *fp;
 
     if ((fp = fopen(filename, "r")) != NULL) {
-        MR_trace_source_from_open_file(fp);
+        MR_trace_source_from_open_file(fp, args, num_args);
         fclose(fp);
         return MR_TRUE;
     } else {
@@ -7905,7 +7940,7 @@
 }
 
 static void
-MR_trace_source_from_open_file(FILE *fp)
+MR_trace_source_from_open_file(FILE *fp, char **args, int num_args)
 {
     char    *contents;
     MR_Line *line;
@@ -7919,7 +7954,9 @@
     ** Insert the sourced commands at the front of the command queue,
     ** preserving their order in the sourced file.
     */
-    while ((contents = MR_trace_readline_raw(fp)) != NULL) {
+    while ((contents = MR_trace_readline_expand_args(fp, args, num_args))
+        != NULL)
+    {
         line = MR_NEW(MR_Line);
         line->MR_line_contents = MR_copy_string(contents);
 
@@ -8508,6 +8545,8 @@
         NULL, MR_trace_filename_completer },
     { "misc", "quit", MR_trace_cmd_quit,
         MR_trace_quit_cmd_args, MR_trace_null_completer },
+    { "misc", "shell", MR_trace_cmd_shell,
+        NULL, MR_trace_null_completer },
 
     { "exp", "histogram_all", MR_trace_cmd_histogram_all,
         NULL, MR_trace_filename_completer },
Index: trace/mercury_trace_readline.c
===================================================================
RCS file: /home/mercury1/repository/mercury/trace/mercury_trace_readline.c,v
retrieving revision 1.9
diff -u -r1.9 mercury_trace_readline.c
--- trace/mercury_trace_readline.c	6 Apr 2005 01:11:33 -0000	1.9
+++ trace/mercury_trace_readline.c	11 Mar 2006 23:58:42 -0000
@@ -50,13 +50,6 @@
 static	void	MR_dummy_prep_term_function(int ignored);
 static	void	MR_dummy_deprep_term_function(void);
 
-/*
-** Print the prompt to the `out' file, read a line from the `in' file,
-** and return it in a MR_malloc'd buffer holding the line (without the
-** final newline).
-** If EOF occurs on a nonempty line, treat the EOF as a newline; if EOF
-** occurs on an empty line, return NULL.
-*/
 char *
 MR_trace_readline(const char *prompt, FILE *in, FILE *out)
 {
@@ -147,12 +140,6 @@
 	return MR_trace_readline_raw(in);
 }
 
-/*
-** Read a line from a file, and return a pointer to a MR_malloc'd buffer
-** holding the line (without the final newline). If EOF occurs on a
-** nonempty line, treat the EOF as a newline; if EOF occurs on an empty
-** line, return NULL.
-*/
 char *
 MR_trace_readline_raw(FILE *fp)
 {
@@ -180,6 +167,65 @@
 	}
 }
 
+char *
+MR_trace_readline_expand_args(FILE *fp, char **args, int num_args)
+{
+	char	*line;
+	int	line_length;
+	int	line_index;
+	int	expanded_line_length;
+	char	*expanded_line;
+	int	expanded_line_index;
+	int	arg_num;
+	int	arg_length;
+	char	*arg;
+	
+	line = MR_trace_readline_raw(fp);
+	if (line == NULL) {
+		return NULL;
+	}
+	line_length = strlen(line);
+
+	expanded_line_length = line_length;
+	expanded_line = (char*) MR_malloc(line_length + 1);
+	expanded_line[0] = '\0';
+	expanded_line_index = 0;
+
+	for (line_index = 0; line_index < line_length; line_index++) {
+		if ((line[line_index] == '$') && 
+			(line_index < (line_length - 1)) &&
+			(line[line_index + 1] >= '1') &&
+			(line[line_index + 1] <= '9'))
+		{
+			arg_num = (int)(line[line_index + 1] - '1');
+			if (arg_num < num_args) {
+				arg = args[arg_num];
+				arg_length = strlen(arg);
+				/*
+				** Subtract 2 for the "$n" which will
+				** not occur in the expanded string.
+				*/
+				expanded_line_length += arg_length - 2;
+				expanded_line = MR_realloc(expanded_line, 
+					expanded_line_length + 1);
+				expanded_line[expanded_line_index] = '\0';
+				strcat(expanded_line, arg);
+				expanded_line_index += arg_length;
+			}
+			/* Skip the digit after the '$'. */
+			line_index++;
+		} else {
+			expanded_line[expanded_line_index] = line[line_index];
+			expanded_line_index++;
+		}
+	}
+
+	MR_free(line);
+	expanded_line[expanded_line_index] = '\0';
+	
+	return expanded_line;
+}
+
 static void
 MR_dummy_prep_term_function(int ignored)
 {
Index: trace/mercury_trace_readline.h
===================================================================
RCS file: /home/mercury1/repository/mercury/trace/mercury_trace_readline.h,v
retrieving revision 1.2
diff -u -r1.2 mercury_trace_readline.h
--- trace/mercury_trace_readline.h	18 Oct 1999 15:47:24 -0000	1.2
+++ trace/mercury_trace_readline.h	11 Mar 2006 23:55:05 -0000
@@ -28,3 +28,15 @@
 ** line, return NULL.  Don't use GNU readline.
 */
 char *	MR_trace_readline_raw(FILE *in);
+
+/*
+** Read a line from a file and replace occurances of the strings "$1" to
+** "$9" with the corresponding values in the args array.  If there is no
+** value in the args array, then the "$n$ string is replaced by the empty
+** string.
+** Return a pointer to a MR_malloc'd buffer holding the new string (without
+** the final newline).  If EOF occurs on a nonempty line, treat the EOF as a
+** newline; if EOF occurs on an empty line, return NULL.  
+** Don't use GNU readline.
+*/
+char * MR_trace_readline_expand_args(FILE *fp, char **args, int num_args);
--------------------------------------------------------------------------
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