Files
mercury/trace/mercury_trace_cmd_parameter.c
Julien Fischer 70ba4db53d Fix a problem introduced in my previous change to the trace directory
Estimated hours taken: 4
Branches: main

Fix a problem introduced in my previous change to the trace directory
which introduced a dependency between the runtime and the trace directory
which broke compilation of the former in high-level C grades.

Fix up conversion specifiers in the printf control strings in the
trace directory.

runtime/mercury_stack_trace.h:
	Define MR_FrameLimit, MR_SpecLineLimit and MR_AncestorLevel here rather
	than in the trace directory because the code in the runtime for
	stack tracing refers to them.  (Some code that was only enabled
	in high-level C grades and referred to the above types was
	added as part of my last change; this is what broke compilation
	in those grades.)

	Rename MR_AncestorLevel to (the more general) MR_Level in the
	process.

runtime/mercury_stack_trace.c:
	Use MR_FrameLimit and friends in place of ints here.

trace/mercury_trace.h:
	Delete the typedefs for MR_FrameLimit and friends.

trace/mercury_trace_cmd_backward.c:
trace/mercury_trace_external.c:
	Conform to the above change.

trace/*.c:
	Change the signedness of conversion specifiers to conform
	to recent type changes.
2007-10-02 17:04:38 +00:00

1081 lines
34 KiB
C

/*
** vim: ts=4 sw=4 expandtab
*/
/*
** Copyright (C) 1998-2007 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_ContextPosition */
#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_TracePrintLevel MR_default_print_level = MR_PRINT_LEVEL_SOME;
MR_bool MR_scroll_control = MR_TRUE;
MR_Unsigned MR_scroll_limit = 24;
MR_Unsigned 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_ContextPosition MR_context_position = MR_CONTEXT_AFTER;
MR_UserEventContext MR_user_event_context = MR_USER_EVENT_CONTEXT_FULL;
MR_bool MR_print_goal_paths = MR_TRUE;
MR_Word MR_listing_path;
MR_Unsigned MR_num_context_lines = 2;
MR_SpyWhen 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_TraceCmdInfo *cmd,
MR_EventInfo *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_TraceCmdInfo *cmd,
MR_EventInfo *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_TraceCmdInfo *cmd,
MR_EventInfo *event_info, MR_Code **jumpaddr)
{
MR_Unsigned 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 %" MR_INTEGER_LENGTH_MODIFIER
"u.\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 %" MR_INTEGER_LENGTH_MODIFIER "u.\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_TraceCmdInfo *cmd, MR_EventInfo *event_info, MR_Code **jumpaddr)
{
MR_Unsigned 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_TraceCmdInfo *cmd,
MR_EventInfo *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;
}
static const char *MR_user_event_context_set_msg[] = {
"User events will get no contexts printed.",
"User events will get only file contexts printed.",
"User events will get only procedure contexts printed.",
"User events will get full contexts printed.",
};
static const char *MR_user_event_context_report_msg[] = {
"User events get no contexts printed.",
"User events get only file contexts printed.",
"User events get only procedure contexts printed.",
"User events get full contexts printed.",
};
MR_Next
MR_trace_cmd_user_event_context(char **words, int word_count,
MR_TraceCmdInfo *cmd, MR_EventInfo *event_info, MR_Code **jumpaddr)
{
if (word_count == 2) {
if (MR_streq(words[1], "none")) {
MR_user_event_context = MR_USER_EVENT_CONTEXT_NONE;
} else if (MR_streq(words[1], "file")) {
MR_user_event_context = MR_USER_EVENT_CONTEXT_FILE;
} else if (MR_streq(words[1], "proc")) {
MR_user_event_context = MR_USER_EVENT_CONTEXT_PROC;
} else if (MR_streq(words[1], "full")) {
MR_user_event_context = MR_USER_EVENT_CONTEXT_FULL;
} else {
MR_trace_usage_cur_cmd();
return KEEP_INTERACTING;
}
if (MR_trace_internal_interacting) {
fprintf(MR_mdb_out, "%s\n",
MR_user_event_context_set_msg[MR_user_event_context]);
}
} else if (word_count == 1) {
switch (MR_user_event_context) {
case MR_USER_EVENT_CONTEXT_NONE:
case MR_USER_EVENT_CONTEXT_FILE:
case MR_USER_EVENT_CONTEXT_PROC:
case MR_USER_EVENT_CONTEXT_FULL:
fprintf(MR_mdb_out, "%s\n",
MR_user_event_context_report_msg[MR_user_event_context]);
break;
default:
MR_fatal_error("invalid MR_user_event_context");
}
} else {
MR_trace_usage_cur_cmd();
}
return KEEP_INTERACTING;
}
MR_Next
MR_trace_cmd_goal_paths(char **words, int word_count, MR_TraceCmdInfo *cmd,
MR_EventInfo *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_TraceCmdInfo *cmd,
MR_EventInfo *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_TraceCmdInfo *cmd,
MR_EventInfo *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_TraceCmdInfo *cmd, MR_EventInfo *event_info, MR_Code **jumpaddr)
{
MR_Unsigned 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 %" MR_INTEGER_LENGTH_MODIFIER
"u 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_TraceCmdInfo *cmd,
MR_EventInfo *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_TraceCmdInfo *cmd, MR_EventInfo *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_TraceCmdInfo *cmd, MR_EventInfo *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_TraceCmdInfo *cmd, MR_EventInfo *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_TraceCmdInfo *cmd, MR_EventInfo *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_TraceCmdInfo *cmd, MR_EventInfo *event_info, MR_Code **jumpaddr)
{
MR_Unsigned 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 %"
MR_INTEGER_LENGTH_MODIFIER "u\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_TraceCmdInfo *cmd, MR_EventInfo *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_TraceCmdInfo *cmd, MR_EventInfo *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_TraceCmdInfo *cmd, MR_EventInfo *event_info, MR_Code **jumpaddr)
{
MR_BrowseFormat 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_TraceCmdInfo *cmd, MR_EventInfo *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;
MR_Unsigned 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_TraceCmdInfo *cmd,
MR_EventInfo *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_TraceCmdInfo *cmd,
MR_EventInfo *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_user_event_context_cmd_args[] =
{ "none", "file", "proc", "full", 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;
}