Files
mercury/trace/mercury_trace_cmd_parameter.c
Ralph Becket 0e110b8ea6 Fix an off-by-one bug that was causing the list_context_lines command
Branches: main
Estimated hours taken: 0.1

trace/mercury_trace_cmd_parameter.c:
	Fix an off-by-one bug that was causing the list_context_lines command
	to segfault.
2006-08-18 05:56:23 +00:00

1014 lines
31 KiB
C

/*
** vim: ts=4 sw=4 expandtab
*/
/*
** Copyright (C) 1998-2006 The University of Melbourne.
** This file may only be copied under the terms of the GNU Library General
** Public License - see the file COPYING.LIB in the Mercury distribution.
*/
/*
** This module implements the mdb commands in the "parameter" category.
**
** The structure of these files is:
**
** - all the #includes
** - local macros and declarations of local static functions
** - one function for each command in the category
** - any auxiliary functions
** - any command argument strings
** - option processing functions.
*/
#include "mercury_std.h"
#include "mercury_getopt.h"
#include "mercury_stack_trace.h" /* for MR_Context_Position */
#include "mercury_string.h"
#include "mercury_trace.h"
#include "mercury_trace_browse.h"
#include "mercury_trace_internal.h"
#include "mercury_trace_cmds.h"
#include "mercury_trace_cmd_parameter.h"
#include "mercury_trace_spy.h"
#include "mercury_trace_alias.h"
#include "mercury_trace_util.h"
#include "mdb.browser_info.mh" /* for ML_BROWSE_get_num_io_actions etc */
#include "mdb.listing.mh" /* for ML_LISTING_get_list_path etc */
/****************************************************************************/
char *MR_mmc_options = NULL;
MR_Trace_Print_Level MR_default_print_level = MR_PRINT_LEVEL_SOME;
MR_bool MR_scroll_control = MR_TRUE;
int MR_scroll_limit = 24;
int MR_scroll_next = 0;
int MR_stack_default_line_limit = 0;
MR_bool MR_echo_commands = MR_FALSE;
MR_bool MR_print_optionals = MR_FALSE;
char *MR_dice_pass_trace_counts_file = NULL;
char *MR_dice_fail_trace_counts_file = NULL;
MR_Context_Position MR_context_position = MR_CONTEXT_AFTER;
MR_bool MR_print_goal_paths = MR_TRUE;
MR_Word MR_listing_path;
int MR_num_context_lines = 2;
MR_Spy_When MR_default_breakpoint_scope = MR_SPY_INTERFACE;
/****************************************************************************/
static MR_bool MR_trace_options_cmd_format(MR_Word *print_set,
MR_Word *browse_set, MR_Word *print_all_set,
char ***words, int *word_count);
static MR_bool MR_trace_options_cmd_format_param(MR_Word *print_set,
MR_Word *browse_set, MR_Word *print_all_set,
MR_Word *flat_format, MR_Word *raw_pretty_format,
MR_Word *verbose_format, MR_Word *pretty_format,
char ***words, int *word_count);
/****************************************************************************/
MR_Next
MR_trace_cmd_mmc_options(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
MR_Event_Info *event_info, MR_Code **jumpaddr)
{
size_t len;
size_t i;
/* allocate the right amount of space */
len = 0;
for (i = 1; i < word_count; i++) {
len += strlen(words[i]) + 1;
}
len++;
MR_mmc_options = MR_realloc(MR_mmc_options, len);
/* copy the arguments to MR_mmc_options */
MR_mmc_options[0] = '\0';
for (i = 1; i < word_count; i++) {
strcat(MR_mmc_options, words[i]);
strcat(MR_mmc_options, " ");
}
MR_mmc_options[len - 1] = '\0';
return KEEP_INTERACTING;
}
MR_Next
MR_trace_cmd_printlevel(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
MR_Event_Info *event_info, MR_Code **jumpaddr)
{
if (word_count == 2) {
if (MR_streq(words[1], "none")) {
MR_default_print_level = MR_PRINT_LEVEL_NONE;
if (MR_trace_internal_interacting) {
fprintf(MR_mdb_out, "Default print level set to `none'.\n");
}
} else if (MR_streq(words[1], "some")) {
MR_default_print_level = MR_PRINT_LEVEL_SOME;
if (MR_trace_internal_interacting) {
fprintf(MR_mdb_out, "Default print level set to `some'.\n");
}
} else if (MR_streq(words[1], "all")) {
MR_default_print_level = MR_PRINT_LEVEL_ALL;
if (MR_trace_internal_interacting) {
fprintf(MR_mdb_out, "Default print level set to `all'.\n");
}
} else {
MR_trace_usage_cur_cmd();
}
} else if (word_count == 1) {
fprintf(MR_mdb_out, "The default print level is ");
switch (MR_default_print_level) {
case MR_PRINT_LEVEL_NONE:
fprintf(MR_mdb_out, "`none'.\n");
break;
case MR_PRINT_LEVEL_SOME:
fprintf(MR_mdb_out, "`some'.\n");
break;
case MR_PRINT_LEVEL_ALL:
fprintf(MR_mdb_out, "`all'.\n");
break;
default:
MR_default_print_level = MR_PRINT_LEVEL_SOME;
fprintf(MR_mdb_out, "invalid (now set to `some').\n");
break;
}
} else {
MR_trace_usage_cur_cmd();
}
return KEEP_INTERACTING;
}
MR_Next
MR_trace_cmd_scroll(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
MR_Event_Info *event_info, MR_Code **jumpaddr)
{
int n;
if (word_count == 2) {
if (MR_streq(words[1], "off")) {
MR_scroll_control = MR_FALSE;
if (MR_trace_internal_interacting) {
fprintf(MR_mdb_out, "Scroll control disabled.\n");
}
} else if (MR_streq(words[1], "on")) {
MR_scroll_control = MR_TRUE;
if (MR_trace_internal_interacting) {
fprintf(MR_mdb_out, "Scroll control enabled.\n");
}
} else if (MR_trace_is_natural_number(words[1], &n)) {
MR_scroll_limit = n;
if (MR_trace_internal_interacting) {
fprintf(MR_mdb_out,
"Scroll window size set to %d.\n", MR_scroll_limit);
}
} else {
MR_trace_usage_cur_cmd();
}
} else if (word_count == 1) {
fprintf(MR_mdb_out, "Scroll control is ");
if (MR_scroll_control) {
fprintf(MR_mdb_out, "on");
} else {
fprintf(MR_mdb_out, "off");
}
fprintf(MR_mdb_out, ", scroll window size is %d.\n", MR_scroll_limit);
} else {
MR_trace_usage_cur_cmd();
}
return KEEP_INTERACTING;
}
MR_Next
MR_trace_cmd_stack_default_limit(char **words, int word_count,
MR_Trace_Cmd_Info *cmd, MR_Event_Info *event_info, MR_Code **jumpaddr)
{
int n;
if (word_count == 2) {
if (MR_trace_is_natural_number(words[1], &n)) {
MR_stack_default_line_limit = n;
if (! MR_trace_internal_interacting) {
return KEEP_INTERACTING;
}
if (MR_stack_default_line_limit > 0) {
fprintf(MR_mdb_out,
"Default stack dump size limit set to %d.\n",
MR_stack_default_line_limit);
} else {
fprintf(MR_mdb_out,
"Default stack dump size limit set to none.\n");
}
} else {
MR_trace_usage_cur_cmd();
}
} else if (word_count == 1) {
if (MR_stack_default_line_limit > 0) {
fprintf(MR_mdb_out, "Default stack dump size limit is %d.\n",
MR_stack_default_line_limit);
} else {
fprintf(MR_mdb_out,
"There is no default stack dump size limit.\n");
}
} else {
MR_trace_usage_cur_cmd();
}
return KEEP_INTERACTING;
}
static const char *MR_context_set_msg[] = {
"Contexts will not be printed.",
"Contexts will be printed before, on the same line.",
"Contexts will be printed after, on the same line.",
"Contexts will be printed on the previous line.",
"Contexts will be printed on the next line.",
};
static const char *MR_context_report_msg[] = {
"Contexts are not printed.",
"Contexts are printed before, on the same line.",
"Contexts are printed after, on the same line.",
"Contexts are printed on the previous line.",
"Contexts are printed on the next line.",
};
MR_Next
MR_trace_cmd_context(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
MR_Event_Info *event_info, MR_Code **jumpaddr)
{
if (word_count == 2) {
if (MR_streq(words[1], "none")) {
MR_context_position = MR_CONTEXT_NOWHERE;
} else if (MR_streq(words[1], "before")) {
MR_context_position = MR_CONTEXT_BEFORE;
} else if (MR_streq(words[1], "after")) {
MR_context_position = MR_CONTEXT_AFTER;
} else if (MR_streq(words[1], "prevline")) {
MR_context_position = MR_CONTEXT_PREVLINE;
} else if (MR_streq(words[1], "nextline")) {
MR_context_position = MR_CONTEXT_NEXTLINE;
} else {
MR_trace_usage_cur_cmd();
return KEEP_INTERACTING;
}
if (MR_trace_internal_interacting) {
fprintf(MR_mdb_out, "%s\n",
MR_context_set_msg[MR_context_position]);
}
} else if (word_count == 1) {
switch (MR_context_position) {
case MR_CONTEXT_NOWHERE:
case MR_CONTEXT_BEFORE:
case MR_CONTEXT_AFTER:
case MR_CONTEXT_PREVLINE:
case MR_CONTEXT_NEXTLINE:
fprintf(MR_mdb_out, "%s\n",
MR_context_report_msg[MR_context_position]);
break;
default:
MR_fatal_error("invalid MR_context_position");
}
} else {
MR_trace_usage_cur_cmd();
}
return KEEP_INTERACTING;
}
MR_Next
MR_trace_cmd_goal_paths(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
MR_Event_Info *event_info, MR_Code **jumpaddr)
{
if (word_count == 2) {
if (MR_streq(words[1], "off")) {
MR_print_goal_paths = MR_FALSE;
fprintf(MR_mdb_out, "Goal path printing is now off.\n");
} else if (MR_streq(words[1], "on")) {
MR_print_goal_paths = MR_TRUE;
fprintf(MR_mdb_out, "Goal path printing is now on.\n");
} else {
MR_trace_usage_cur_cmd();
return KEEP_INTERACTING;
}
} else if (word_count == 1) {
if (MR_print_goal_paths) {
fprintf(MR_mdb_out, "Goal path printing is on.\n");
} else {
fprintf(MR_mdb_out, "Goal path printing is off.\n");
}
} else {
MR_trace_usage_cur_cmd();
}
return KEEP_INTERACTING;
}
static const char *MR_scope_set_msg[] = {
"The default scope of `break' commands is now all matching events.",
"The default scope of `break' commands is now all matching interface events.",
"The default scope of `break' commands is now all matching entry events.",
"MDB INTERNAL ERROR: scope set to MR_SPY_SPECIFIC",
"MDB INTERNAL ERROR: scope set to MR_SPY_LINENO",
};
static const char *MR_scope_report_msg[] = {
"The default scope of `break' commands is all matching events.",
"The default scope of `break' commands is all matching interface events.",
"The default scope of `break' commands is all matching entry events.",
"MDB INTERNAL ERROR: scope set to MR_SPY_SPECIFIC",
"MDB INTERNAL ERROR: scope set to MR_SPY_LINENO",
};
MR_Next
MR_trace_cmd_scope(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
MR_Event_Info *event_info, MR_Code **jumpaddr)
{
if (word_count == 2) {
if (MR_streq(words[1], "all")) {
MR_default_breakpoint_scope = MR_SPY_ALL;
} else if (MR_streq(words[1], "interface")) {
MR_default_breakpoint_scope = MR_SPY_INTERFACE;
} else if (MR_streq(words[1], "entry")) {
MR_default_breakpoint_scope = MR_SPY_ENTRY;
} else {
MR_trace_usage_cur_cmd();
return KEEP_INTERACTING;
}
if (MR_trace_internal_interacting) {
fprintf(MR_mdb_out, "%s\n",
MR_scope_set_msg[MR_default_breakpoint_scope]);
}
} else if (word_count == 1) {
switch (MR_default_breakpoint_scope) {
case MR_SPY_ALL:
case MR_SPY_INTERFACE:
case MR_SPY_ENTRY:
fprintf(MR_mdb_out, "%s\n",
MR_scope_report_msg[MR_default_breakpoint_scope]);
break;
default:
MR_fatal_error(
"invalid MR_default_breakpoint_scope");
}
} else {
MR_trace_usage_cur_cmd();
}
return KEEP_INTERACTING;
}
MR_Next
MR_trace_cmd_echo(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
MR_Event_Info *event_info, MR_Code **jumpaddr)
{
if (word_count == 2) {
if (MR_streq(words[1], "off")) {
MR_echo_commands = MR_FALSE;
if (MR_trace_internal_interacting) {
fprintf(MR_mdb_out, "Command echo disabled.\n");
}
} else if (MR_streq(words[1], "on")) {
if (!MR_echo_commands) {
/*
** Echo the `echo on' command. This is needed for historical
** reasons (compatibility with our existing test suite).
*/
fprintf(MR_mdb_out, "echo on\n");
MR_echo_commands = MR_TRUE;
}
if (MR_trace_internal_interacting) {
fprintf(MR_mdb_out, "Command echo enabled.\n");
}
} else {
MR_trace_usage_cur_cmd();
}
} else if (word_count == 1) {
fprintf(MR_mdb_out, "Command echo is ");
if (MR_echo_commands) {
fprintf(MR_mdb_out, "on.\n");
} else {
fprintf(MR_mdb_out, "off.\n");
}
} else {
MR_trace_usage_cur_cmd();
}
return KEEP_INTERACTING;
}
MR_Next
MR_trace_cmd_list_context_lines(char **words, int word_count,
MR_Trace_Cmd_Info *cmd, MR_Event_Info *event_info, MR_Code **jumpaddr)
{
int n;
if (word_count == 2 && MR_trace_is_natural_number(words[1], &n)) {
MR_num_context_lines = n;
} else if (word_count == 1) {
fprintf(MR_mdb_out,
"Printing %d lines around each context listing\n",
MR_num_context_lines);
} else {
MR_trace_usage_cur_cmd();
}
return KEEP_INTERACTING;
}
MR_Next
MR_trace_cmd_list_path(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
MR_Event_Info *event_info, MR_Code **jumpaddr)
{
if (word_count < 2) {
MR_Word list;
list = ML_LISTING_get_list_path(MR_listing_path);
if (MR_list_is_empty(list)) {
fprintf(MR_mdb_out, "Context search path is empty\n");
} else {
fprintf(MR_mdb_out, "Context search path:");
while (! MR_list_is_empty(list)) {
fprintf(MR_mdb_out, " %s", (const char *) MR_list_head(list));
list = MR_list_tail(list);
}
fprintf(MR_mdb_out, "\n");
}
} else {
int i;
MR_String aligned_word;
MR_TRACE_CALL_MERCURY(
ML_LISTING_clear_list_path(MR_listing_path, &MR_listing_path);
for(i = word_count - 1; i >= 1; i--) {
MR_TRACE_USE_HP(
MR_make_aligned_string(aligned_word, (MR_String) words[i]);
);
ML_LISTING_push_list_path(aligned_word,
MR_listing_path, &MR_listing_path);
}
);
MR_listing_path =
MR_make_permanent(MR_listing_path,
(MR_TypeInfo) ML_LISTING_listing_type());
}
return KEEP_INTERACTING;
}
MR_Next
MR_trace_cmd_push_list_dir(char **words, int word_count,
MR_Trace_Cmd_Info *cmd, MR_Event_Info *event_info, MR_Code **jumpaddr)
{
int i;
MR_String aligned_word;
if (word_count < 2) {
MR_trace_usage_cur_cmd();
return KEEP_INTERACTING;
}
MR_TRACE_CALL_MERCURY(
for(i = word_count - 1; i >= 1; i--) {
MR_TRACE_USE_HP(
MR_make_aligned_string(aligned_word, (MR_String) words[i]);
);
ML_LISTING_push_list_path(aligned_word,
MR_listing_path, &MR_listing_path);
}
);
MR_listing_path =
MR_make_permanent(MR_listing_path,
(MR_TypeInfo) ML_LISTING_listing_type());
return KEEP_INTERACTING;
}
MR_Next
MR_trace_cmd_pop_list_dir(char **words, int word_count,
MR_Trace_Cmd_Info *cmd, MR_Event_Info *event_info, MR_Code **jumpaddr)
{
if (word_count > 1) {
MR_trace_usage_cur_cmd();
return KEEP_INTERACTING;
}
MR_TRACE_CALL_MERCURY(
ML_LISTING_pop_list_path(MR_listing_path, &MR_listing_path);
);
MR_listing_path =
MR_make_permanent(MR_listing_path,
(MR_TypeInfo) ML_LISTING_listing_type());
return KEEP_INTERACTING;
}
MR_Next
MR_trace_cmd_fail_trace_counts(char **words, int word_count,
MR_Trace_Cmd_Info *cmd, MR_Event_Info *event_info, MR_Code **jumpaddr)
{
if (word_count == 2) {
if (MR_dice_fail_trace_counts_file != NULL) {
free(MR_dice_fail_trace_counts_file);
}
MR_dice_fail_trace_counts_file = MR_copy_string(words[1]);
} else if (word_count == 1) {
if (MR_dice_fail_trace_counts_file == NULL) {
fprintf(MR_mdb_out,
"The failing tests trace counts file has not been set.\n");
} else {
fprintf(MR_mdb_out,
"The failing tests trace counts file is %s\n",
MR_dice_fail_trace_counts_file);
}
} else {
MR_trace_usage_cur_cmd();
}
return KEEP_INTERACTING;
}
MR_Next
MR_trace_cmd_pass_trace_counts(char **words, int word_count,
MR_Trace_Cmd_Info *cmd, MR_Event_Info *event_info, MR_Code **jumpaddr)
{
if (word_count == 2) {
if (MR_dice_pass_trace_counts_file != NULL) {
free(MR_dice_pass_trace_counts_file);
}
MR_dice_pass_trace_counts_file = MR_copy_string(words[1]);
} else if (word_count == 1) {
if (MR_dice_pass_trace_counts_file == NULL) {
fprintf(MR_mdb_out,
"The passing tests trace counts file has not been set.\n");
} else {
fprintf(MR_mdb_out,
"The passing tests trace counts file is %s\n",
MR_dice_pass_trace_counts_file);
}
} else {
MR_trace_usage_cur_cmd();
}
return KEEP_INTERACTING;
}
MR_Next
MR_trace_cmd_max_io_actions(char **words, int word_count,
MR_Trace_Cmd_Info *cmd, MR_Event_Info *event_info, MR_Code **jumpaddr)
{
int num_io_actions;
if (word_count == 2 &&
MR_trace_is_natural_number(words[1], &num_io_actions)) {
MR_TRACE_CALL_MERCURY(
ML_BROWSE_set_num_io_actions(num_io_actions,
MR_trace_browser_persistent_state,
&MR_trace_browser_persistent_state);
);
} else if (word_count == 1) {
MR_Integer n;
MR_TRACE_CALL_MERCURY(
ML_BROWSE_get_num_io_actions(
MR_trace_browser_persistent_state, &n);
);
/*
** We do this to avoid warnings about MR_Integer and int
** having different sizes on 64-bit architectures.
*/
num_io_actions = (int) n;
fprintf(MR_mdb_out,
"The maximum number of I/O actions printed is %d\n",
num_io_actions);
} else {
MR_trace_usage_cur_cmd();
}
return KEEP_INTERACTING;
}
MR_Next
MR_trace_cmd_xml_browser_cmd(char **words, int word_count,
MR_Trace_Cmd_Info *cmd, MR_Event_Info *event_info, MR_Code **jumpaddr)
{
if (word_count == 2) {
char *copied_value;
char *aligned_value;
copied_value = (char *) MR_GC_malloc(strlen(words[1]) + 1);
strcpy(copied_value, words[1]);
MR_TRACE_USE_HP(
MR_make_aligned_string(aligned_value, copied_value);
);
MR_TRACE_CALL_MERCURY(
ML_BROWSE_set_xml_browser_cmd_from_mdb(aligned_value,
MR_trace_browser_persistent_state,
&MR_trace_browser_persistent_state);
);
} else if (word_count == 1) {
MR_String command;
MR_TRACE_CALL_MERCURY(
ML_BROWSE_get_xml_browser_cmd_from_mdb(
MR_trace_browser_persistent_state, &command);
);
if (command != NULL && strlen(command) > 0) {
fprintf(MR_mdb_out, "The XML browser command is %s\n", command);
} else {
fprintf(MR_mdb_out, "The XML browser command has not been set.\n");
}
} else {
MR_trace_usage_cur_cmd();
}
return KEEP_INTERACTING;
}
MR_Next
MR_trace_cmd_xml_tmp_filename(char **words, int word_count,
MR_Trace_Cmd_Info *cmd, MR_Event_Info *event_info, MR_Code **jumpaddr)
{
if (word_count == 2) {
char *copied_value;
char *aligned_value;
copied_value = (char *) MR_GC_malloc(strlen(words[1]) + 1);
strcpy(copied_value, words[1]);
MR_TRACE_USE_HP(
MR_make_aligned_string(aligned_value, copied_value);
);
MR_TRACE_CALL_MERCURY(
ML_BROWSE_set_xml_tmp_filename_from_mdb(aligned_value,
MR_trace_browser_persistent_state,
&MR_trace_browser_persistent_state);
);
} else if (word_count == 1) {
MR_String file;
MR_TRACE_CALL_MERCURY(
ML_BROWSE_get_xml_browser_cmd_from_mdb(
MR_trace_browser_persistent_state, &file);
);
if (file != NULL && strlen(file) > 0) {
fprintf(MR_mdb_out, "The XML tmp filename is %s\n", file);
} else {
fprintf(MR_mdb_out, "The XML tmp filename has not been set.\n");
}
} else {
MR_trace_usage_cur_cmd();
}
return KEEP_INTERACTING;
}
MR_Next
MR_trace_cmd_format(char **words, int word_count,
MR_Trace_Cmd_Info *cmd, MR_Event_Info *event_info, MR_Code **jumpaddr)
{
MR_Browse_Format new_format;
MR_Word print;
MR_Word browse;
MR_Word print_all;
if (! MR_trace_options_cmd_format(&print, &browse, &print_all,
&words, &word_count))
{
; /* the usage message has already been printed */
} else if (word_count == 2 &&
MR_trace_is_portray_format(words[1], &new_format))
{
MR_TRACE_CALL_MERCURY(
ML_BROWSE_set_format_from_mdb(print, browse, print_all, new_format,
MR_trace_browser_persistent_state,
&MR_trace_browser_persistent_state);
);
MR_trace_browser_persistent_state =
MR_make_permanent(MR_trace_browser_persistent_state,
MR_trace_browser_persistent_state_type);
} else {
MR_trace_usage_cur_cmd();
}
return KEEP_INTERACTING;
}
MR_Next
MR_trace_cmd_format_param(char **words, int word_count,
MR_Trace_Cmd_Info *cmd, MR_Event_Info *event_info, MR_Code **jumpaddr)
{
MR_Word print;
MR_Word browse;
MR_Word print_all;
MR_Word flat;
MR_Word raw_pretty;
MR_Word verbose;
MR_Word pretty;
int n;
if (! MR_trace_options_cmd_format_param(&print, &browse, &print_all,
&flat, &raw_pretty, &verbose, &pretty, &words, &word_count))
{
; /* the usage message has already been printed */
} else if (word_count != 3) {
MR_trace_usage_cur_cmd();
} else {
if (MR_streq(words[1], "depth") &&
MR_trace_is_natural_number(words[2], &n))
{
MR_TRACE_CALL_MERCURY(
ML_BROWSE_set_depth_from_mdb(print, browse, print_all,
flat, raw_pretty, verbose, pretty, n,
MR_trace_browser_persistent_state,
&MR_trace_browser_persistent_state);
);
} else if (MR_streq(words[1], "size") &&
MR_trace_is_natural_number(words[2], &n))
{
MR_TRACE_CALL_MERCURY(
ML_BROWSE_set_size_from_mdb(print, browse, print_all,
flat, raw_pretty, verbose, pretty, n,
MR_trace_browser_persistent_state,
&MR_trace_browser_persistent_state);
);
} else if (MR_streq(words[1], "width") &&
MR_trace_is_natural_number(words[2], &n))
{
MR_TRACE_CALL_MERCURY(
ML_BROWSE_set_width_from_mdb(print, browse, print_all,
flat, raw_pretty, verbose, pretty, n,
MR_trace_browser_persistent_state,
&MR_trace_browser_persistent_state);
);
} else if (MR_streq(words[1], "lines") &&
MR_trace_is_natural_number(words[2], &n))
{
MR_TRACE_CALL_MERCURY(
ML_BROWSE_set_lines_from_mdb(print, browse, print_all,
flat, raw_pretty, verbose, pretty, n,
MR_trace_browser_persistent_state,
&MR_trace_browser_persistent_state);
);
} else {
MR_trace_usage_cur_cmd();
return KEEP_INTERACTING;
}
MR_trace_browser_persistent_state =
MR_make_permanent(MR_trace_browser_persistent_state,
MR_trace_browser_persistent_state_type);
}
return KEEP_INTERACTING;
}
MR_Next
MR_trace_cmd_alias(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
MR_Event_Info *event_info, MR_Code **jumpaddr)
{
if (word_count == 1) {
MR_trace_print_all_aliases(MR_mdb_out, MR_FALSE);
} else if (word_count == 2) {
MR_trace_print_alias(MR_mdb_out, words[1]);
} else {
if (MR_trace_valid_command(words[2])) {
MR_trace_add_alias(words[1], words+2, word_count-2);
if (MR_trace_internal_interacting) {
MR_trace_print_alias(MR_mdb_out, words[1]);
}
} else {
fprintf(MR_mdb_out, "`%s' is not a valid command.\n", words[2]);
}
}
return KEEP_INTERACTING;
}
MR_Next
MR_trace_cmd_unalias(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
MR_Event_Info *event_info, MR_Code **jumpaddr)
{
if (word_count == 2) {
if (MR_trace_remove_alias(words[1])) {
if (MR_trace_internal_interacting) {
fprintf(MR_mdb_out, "Alias `%s' removed.\n", words[1]);
}
} else {
fflush(MR_mdb_out);
fprintf(MR_mdb_err,
"Alias `%s' cannot be removed, since it does not exist.\n",
words[1]);
}
} else {
MR_trace_usage_cur_cmd();
}
return KEEP_INTERACTING;
}
/****************************************************************************/
void
MR_trace_listing_path_ensure_init(void)
{
static MR_bool MR_trace_listing_path_initialized = MR_FALSE;
if (! MR_trace_listing_path_initialized) {
MR_TRACE_CALL_MERCURY(
MR_listing_path = ML_LISTING_new_list_path();
);
MR_trace_listing_path_initialized = MR_TRUE;
}
}
/****************************************************************************/
const char *const MR_trace_printlevel_cmd_args[] =
{ "none", "some", "all", NULL };
const char *const MR_trace_on_off_args[] =
{ "on", "off", NULL };
const char *const MR_trace_context_cmd_args[] =
{ "none", "before", "after", "prevline", "nextline", NULL };
const char *const MR_trace_scope_cmd_args[] =
{ "all", "interface", "entry", NULL };
const char *const MR_trace_format_cmd_args[] =
{ "-A", "-B", "-P",
"--print-all", "--print", "--browse",
"flat", "pretty", "verbose", NULL };
const char *const MR_trace_format_param_cmd_args[] =
{ "-A", "-B", "-P", "-f", "-p", "-v",
"--print-all", "--print", "--browse",
"--flat", "--pretty", "--verbose",
"depth", "size", "width", "lines",
"flat", "pretty", "verbose", NULL };
/****************************************************************************/
static struct MR_option MR_trace_param_cmd_format_opts[] =
{
{ "print", MR_no_argument, NULL, 'P' },
{ "browse", MR_no_argument, NULL, 'B' },
{ "print-all", MR_no_argument, NULL, 'A' },
{ NULL, MR_no_argument, NULL, 0 }
};
static MR_bool
MR_trace_options_cmd_format(MR_Word *print_set, MR_Word *browse_set,
MR_Word *print_all_set, char ***words, int *word_count)
{
int c;
MR_Word mercury_bool_yes;
MR_Word mercury_bool_no;
MR_TRACE_CALL_MERCURY(
mercury_bool_yes = ML_BROWSE_mercury_bool_yes();
mercury_bool_no = ML_BROWSE_mercury_bool_no();
);
*print_set = mercury_bool_no;
*browse_set = mercury_bool_no;
*print_all_set = mercury_bool_no;
MR_optind = 0;
while ((c = MR_getopt_long(*word_count, *words, "PBA",
MR_trace_param_cmd_format_opts, NULL)) != EOF)
{
switch (c) {
case 'P':
*print_set = mercury_bool_yes;
break;
case 'B':
*browse_set = mercury_bool_yes;
break;
case 'A':
*print_all_set = mercury_bool_yes;
break;
default:
MR_trace_usage_cur_cmd();
return MR_FALSE;
}
}
*words = *words + MR_optind - 1;
*word_count = *word_count - MR_optind + 1;
return MR_TRUE;
}
static struct MR_option MR_trace_param_cmd_format_param_opts[] =
{
{ "flat", MR_no_argument, NULL, 'f' },
{ "raw_pretty", MR_no_argument, NULL, 'r' },
{ "verbose", MR_no_argument, NULL, 'v' },
{ "pretty", MR_no_argument, NULL, 'p' },
{ "print", MR_no_argument, NULL, 'P' },
{ "browse", MR_no_argument, NULL, 'B' },
{ "print-all", MR_no_argument, NULL, 'A' },
{ NULL, MR_no_argument, NULL, 0 }
};
static MR_bool
MR_trace_options_cmd_format_param(MR_Word *print_set, MR_Word *browse_set,
MR_Word *print_all_set, MR_Word *flat_format,
MR_Word *raw_pretty_format, MR_Word *verbose_format,
MR_Word *pretty_format, char ***words, int *word_count)
{
int c;
MR_Word mercury_bool_yes;
MR_Word mercury_bool_no;
MR_TRACE_CALL_MERCURY(
mercury_bool_yes = ML_BROWSE_mercury_bool_yes();
mercury_bool_no = ML_BROWSE_mercury_bool_no();
);
*print_set = mercury_bool_no;
*browse_set = mercury_bool_no;
*print_all_set = mercury_bool_no;
*flat_format = mercury_bool_no;
*raw_pretty_format = mercury_bool_no;
*verbose_format = mercury_bool_no;
*pretty_format = mercury_bool_no;
MR_optind = 0;
while ((c = MR_getopt_long(*word_count, *words, "PBAfrvp",
MR_trace_param_cmd_format_param_opts, NULL)) != EOF)
{
switch (c) {
case 'f':
*flat_format = mercury_bool_yes;
break;
case 'r':
*raw_pretty_format = mercury_bool_yes;
break;
case 'v':
*verbose_format = mercury_bool_yes;
break;
case 'p':
*pretty_format = mercury_bool_yes;
break;
case 'P':
*print_set = mercury_bool_yes;
break;
case 'B':
*browse_set = mercury_bool_yes;
break;
case 'A':
*print_all_set = mercury_bool_yes;
break;
default:
MR_trace_usage_cur_cmd();
return MR_FALSE;
}
}
*words = *words + MR_optind - 1;
*word_count = *word_count - MR_optind + 1;
return MR_TRUE;
}