[m-rev.] for review: add 4 new mdb commands
Julien Fischer
juliensf at cs.mu.OZ.AU
Mon Mar 13 12:11:49 AEDT 2006
On Sun, 12 Mar 2006, Ian MacLarty wrote:
> 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
s/Occurances/Ocurrences/
> 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).
Is there any reason why this is limited to vim/emacs? Perhaps it ought
to look for the environment variable EDITOR first. Similarly there are
several variants of grep that I might want to use.
> 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.
s/occurances/occurrences/
> 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/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.
Rather than having separate vim and emacs commands can we not just have
a single edit command that looks up the value of an editor variable somewhere.
> + 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
s/Occurrances/Occurrences/
> +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/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
>
...
> 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);
Shouldn't you check that the call to system succeeds? e.g. that system
doesn't return -1. Furthermore I think the mdb should run system(NULL)
somewhere and check that a usable shell exists.
> + MR_free(command_string);
> +
> + return KEEP_INTERACTING;
> +}
...
> 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);
>
> +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;
> +
A lot of these could be of type size_t rather than int (and also above).
> + 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
s/occurances/occurrences/
> +** "$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
s/$n$/$n/ ?
> +** 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.
Why not?
Julien.
--------------------------------------------------------------------------
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