[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