diff: mdb I/O streams
Fergus Henderson
fjh at cs.mu.OZ.AU
Fri Dec 18 00:29:17 AEDT 1998
This diff addresses Mark's review comments.
I'll commit this now.
--------------------
Estimated hours taken: 4
Add support to mdb for doing the debugger I/O in a different
window to the I/O of the program being debugged.
(TODO: I/O from the browser still goes to the standard I/O streams
rather than the debugger I/O streams. I'll commit that later,
as a separate change.)
runtime/mercury_wrapper.h:
runtime/mercury_wrapper.c:
Add new runtime options for specifying filenames
for the mdb I/O streams.
doc/user_guide.texi:
Document the new options.
trace/mercury_trace_internal.c:
Add three new variables holding the mdb I/O streams.
Initialise them based on the option settings.
Change the code so that all I/O goes through these streams.
trace/mercury_trace_tables.c:
trace/mercury_trace_tables.h:
Pass a `void *' parameter through MR_process_matching_procedures()
to the function it calls. This is needed by mercury_trace_internal.c
to pass `MR_mdb_in' down to MR_print_proc_id_for_debugger().
runtime/mercury_stack_trace.c:
runtime/mercury_stack_trace.h:
Add a `FILE *' parameter to MR_print_proc_id_for_debugger().
Index: doc/user_guide.texi
===================================================================
RCS file: /home/mercury1/repository/mercury/doc/user_guide.texi,v
retrieving revision 1.154
diff -u -r1.154 user_guide.texi
--- user_guide.texi 1998/12/06 23:48:17 1.154
+++ user_guide.texi 1998/12/16 23:44:20
@@ -3790,36 +3790,60 @@
@c Tells the Boehm collector not to perform any garbage collection.
@sp 1
- at item --heap-size=@var{size}
+ at item --heap-size @var{size}
Sets the size of the heap to @var{size} kilobytes.
@sp 1
- at item --detstack-size=@var{size}
+ at item --detstack-size @var{size}
Sets the size of the det stack to @var{size} kilobytes.
@sp 1
- at item --nondetstack-size=@var{size}
+ at item --nondetstack-size @var{size}
Sets the size of the nondet stack to @var{size} kilobytes.
@sp 1
- at item --trail-size=@var{size}
+ at item --trail-size @var{size}
Sets the size of the trail to @var{size} kilobytes.
@c @sp 1
- at c @item --heap-redzone-size=@var{size}
+ at c @item --heap-redzone-size @var{size}
@c Sets the size of the redzone on the heap to @var{size} kilobytes.
@c @sp 1
- at c @item --detstack-redzone-size=@var{size}
+ at c @item --detstack-redzone-size @var{size}
@c Sets the size of the redzone on the det stack to @var{size} kilobytes.
@c @sp 1
- at c @item --nondetstack-redzone-size=@var{size}
+ at c @item --nondetstack-redzone-size @var{size}
@c Sets the size of the redzone on the nondet stack to @var{size} kilobytes.
@c @sp 1
- at c @item --trail-redzone-size=@var{size}
+ at c @item --trail-redzone-size @var{size}
@c Sets the size of the redzone on the trail to @var{size} kilobytes.
+
+ at sp 1
+ at item -i @var{filename}
+ at itemx --mdb-in @var{filename}
+Read debugger input from the file or device specified by @var{filename},
+rather than from standard input.
+
+ at sp 1
+ at item -o @var{filename}
+ at item --mdb-out @var{filename}
+Print debugger output to the file or device specified by @var{filename},
+rather than to standard output.
+
+ at sp 1
+ at item -e @var{filename}
+ at itemx --mdb-err @var{filename}
+Print debugger error messages to the file or device specified by @var{filename},
+rather than to standard error.
+
+ at sp 1
+ at item -m @var{filename}
+ at itemx --mdb-tty @var{filename}
+Redirect all three debugger I/O streams -- input, output, and error messages --
+to the file or device specified by @var{filename}.
@end table
Index: runtime/mercury_stack_trace.c
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_stack_trace.c,v
retrieving revision 1.23
diff -u -r1.23 mercury_stack_trace.c
--- mercury_stack_trace.c 1998/12/09 12:26:29 1.23
+++ mercury_stack_trace.c 1998/12/17 00:08:06
@@ -365,9 +365,10 @@
}
void
-MR_print_proc_id_for_debugger(const MR_Stack_Layout_Entry *entry_layout)
+MR_print_proc_id_for_debugger(FILE *fp,
+ const MR_Stack_Layout_Entry *entry_layout)
{
- MR_print_proc_id(stdout, entry_layout, NULL, NULL, NULL);
+ MR_print_proc_id(fp, entry_layout, NULL, NULL, NULL);
}
void
Index: runtime/mercury_stack_trace.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_stack_trace.h,v
retrieving revision 1.13
diff -u -r1.13 mercury_stack_trace.h
--- mercury_stack_trace.h 1998/11/13 08:40:41 1.13
+++ mercury_stack_trace.h 1998/12/17 00:08:06
@@ -145,7 +145,7 @@
** call sequence number and call depth of the call.
*/
-extern void MR_print_proc_id_for_debugger(
+extern void MR_print_proc_id_for_debugger(FILE *fp,
const MR_Stack_Layout_Entry *entry);
extern void MR_print_proc_id(FILE *fp, const MR_Stack_Layout_Entry *entry,
const char *extra, Word *base_sp, Word *base_curfr);
Index: runtime/mercury_wrapper.c
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_wrapper.c,v
retrieving revision 1.28
diff -u -r1.28 mercury_wrapper.c
--- mercury_wrapper.c 1998/11/05 03:53:48 1.28
+++ mercury_wrapper.c 1998/12/16 21:16:45
@@ -74,6 +74,11 @@
/* primary cache size to optimize for, in bytes */
size_t pcache_size = 8192;
+/* file names for mdb's debugger I/O streams */
+const char *MR_mdb_in_filename = NULL;
+const char *MR_mdb_out_filename = NULL;
+const char *MR_mdb_err_filename = NULL;
+
/* other options */
bool check_space = FALSE;
@@ -510,7 +515,11 @@
MR_HEAP_REDZONE_SIZE,
MR_DETSTACK_REDZONE_SIZE,
MR_NONDETSTACK_REDZONE_SIZE,
- MR_TRAIL_REDZONE_SIZE
+ MR_TRAIL_REDZONE_SIZE,
+ MR_MDB_TTY,
+ MR_MDB_IN,
+ MR_MDB_OUT,
+ MR_MDB_ERR
};
struct MR_option MR_long_opts[] = {
@@ -522,6 +531,10 @@
{ "detstack-redzone-size", 1, 0, MR_DETSTACK_REDZONE_SIZE },
{ "nondetstack-redzone-size", 1, 0, MR_NONDETSTACK_REDZONE_SIZE },
{ "trail-redzone-size", 1, 0, MR_TRAIL_REDZONE_SIZE },
+ { "mdb-tty", 1, 0, MR_MDB_TTY },
+ { "mdb-in", 1, 0, MR_MDB_IN },
+ { "mdb-out", 1, 0, MR_MDB_OUT },
+ { "mdb-err", 1, 0, MR_MDB_ERR }
};
static void
@@ -531,7 +544,7 @@
int c;
int long_index;
- while ((c = MR_getopt_long(argc, argv, "acC:d:D:P:pr:tT:x",
+ while ((c = MR_getopt_long(argc, argv, "acC:d:e:D:i:m:o:P:pr:tT:x",
MR_long_opts, &long_index)) != EOF)
{
switch (c)
@@ -591,6 +604,28 @@
usage();
trail_zone_size = size;
+ break;
+
+ case 'i':
+ case MR_MDB_IN:
+ MR_mdb_in_filename = MR_optarg;
+ break;
+
+ case 'o':
+ case MR_MDB_OUT:
+ MR_mdb_out_filename = MR_optarg;
+ break;
+
+ case 'e':
+ case MR_MDB_ERR:
+ MR_mdb_err_filename = MR_optarg;
+ break;
+
+ case 'm':
+ case MR_MDB_TTY:
+ MR_mdb_in_filename = MR_optarg;
+ MR_mdb_out_filename = MR_optarg;
+ MR_mdb_err_filename = MR_optarg;
break;
case 'a':
Index: runtime/mercury_wrapper.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_wrapper.h,v
retrieving revision 1.15
diff -u -r1.15 mercury_wrapper.h
--- mercury_wrapper.h 1998/11/09 05:23:34 1.15
+++ mercury_wrapper.h 1998/12/16 21:15:36
@@ -135,6 +135,11 @@
extern size_t global_heap_zone_size;
extern size_t debug_heap_zone_size;
+/* file names for the mdb debugging streams */
+extern const char *MR_mdb_in_filename;
+extern const char *MR_mdb_out_filename;
+extern const char *MR_mdb_err_filename;
+
/* size of the primary cache */
extern size_t pcache_size;
Index: trace/mercury_trace_internal.c
===================================================================
RCS file: /home/mercury1/repository/mercury/trace/mercury_trace_internal.c,v
retrieving revision 1.18
diff -u -r1.18 mercury_trace_internal.c
--- mercury_trace_internal.c 1998/12/14 16:05:20 1.18
+++ mercury_trace_internal.c 1998/12/17 13:01:20
@@ -56,6 +56,19 @@
** should be thread local.
*/
+/*
+** Debugger I/O streams.
+** Replacements for stdin/stdout/stderr respectively.
+**
+** The distinction between MR_mdb_out and MR_mdb_err is analagous to
+** the distinction between stdout and stderr: ordinary output, including
+** information messages about conditions which are not errors, should
+** go to MR_mdb_out, but error messages should go to MR_mdb_err.
+*/
+static FILE *MR_mdb_in;
+static FILE *MR_mdb_out;
+static FILE *MR_mdb_err;
+
static MR_Trace_Print_Level MR_default_print_level = MR_PRINT_LEVEL_SOME;
/*
@@ -157,6 +170,9 @@
static void MR_print_spy_point(int i);
static void MR_trace_list_vars(const MR_Stack_Layout_Label *top_layout,
Word *saved_regs, int ancestor_level);
+static void MR_trace_set_level(const MR_Stack_Layout_Label *top_layout,
+ Word *saved_regs, int *ancestor_level,
+ int new_ancestor_level);
static const char *MR_trace_browse_check_level(const MR_Stack_Layout_Label
*top_layout, Word *saved_regs, int ancestor_level);
static void MR_trace_browse_one(const MR_Stack_Layout_Label *top_layout,
@@ -172,6 +188,7 @@
*layout, int *var_count_ptr);
static const char *MR_trace_find_var(const MR_Stack_Layout_Label *layout,
MR_Var_Spec var_spec, int *which_var_ptr);
+static void MR_trace_do_noop(void);
static const char *MR_trace_read_help_text(void);
static bool MR_trace_is_number(const char *word, int *value);
@@ -248,7 +265,7 @@
jumpaddr = NULL;
do {
- line = MR_trace_getline("mdb> ", stdin);
+ line = MR_trace_getline("mdb> ", MR_mdb_in);
res = MR_trace_debug_cmd(line, cmd, layout, saved_regs,
&event_details, port, seqno, depth, path,
&ancestor_level, max_mr_num, &jumpaddr);
@@ -272,6 +289,23 @@
mdb is free software, covered by the GNU General Public License.\n\
There is absolutely no warranty for mdb.\n";
+static FILE *
+MR_try_fopen(const char *filename, const char *mode, FILE *default_file)
+{
+ if (filename == NULL) {
+ return default_file;
+ } else {
+ FILE *f = fopen(filename, mode);
+ if (f == NULL) {
+ fprintf(stderr, "mdb: error opening `%s': %s\n",
+ filename, strerror(errno));
+ return default_file;
+ } else {
+ return f;
+ }
+ }
+}
+
static void
MR_trace_internal_ensure_init(void)
{
@@ -281,8 +315,12 @@
char *env;
int n;
+ MR_mdb_in = MR_try_fopen(MR_mdb_in_filename, "r", stdin);
+ MR_mdb_out = MR_try_fopen(MR_mdb_out_filename, "w", stdout);
+ MR_mdb_err = MR_try_fopen(MR_mdb_err_filename, "w", stderr);
+
if (getenv("MERCURY_SUPPRESS_MDB_BANNER") == NULL) {
- printf(MR_trace_banner, MR_VERSION);
+ fprintf(MR_mdb_out, MR_trace_banner, MR_VERSION);
}
env = getenv("LINES");
@@ -348,6 +386,27 @@
free(buf);
}
+static void
+MR_trace_do_noop(void)
+{
+ fprintf(MR_mdb_err,
+ "This command is a no-op from this port.\n");
+}
+
+/*
+** This function is just a wrapper for MR_print_proc_id_for_debugger,
+** with the first argument type being `void *' rather than `FILE *',
+** so that this function's address can be passed to
+** MR_process_matching_procedures().
+*/
+static void
+MR_mdb_print_proc_id(void *data, const MR_Stack_Layout_Entry *entry_layout)
+{
+ FILE *fp = data;
+ MR_print_proc_id_for_debugger(fp, entry_layout);
+}
+
+
static MR_Next
MR_trace_debug_cmd(char *line, MR_Trace_Cmd_Info *cmd,
const MR_Stack_Layout_Label *layout, Word *saved_regs,
@@ -386,13 +445,13 @@
}
if (MR_echo_commands) {
- fputs(line, stdout);
- putc('\n', stdout);
+ fputs(line, MR_mdb_out);
+ putc('\n', MR_mdb_out);
}
problem = MR_trace_parse_line(line, &words, &word_max, &word_count);
if (problem != NULL) {
- printf("%s.\n", problem);
+ fprintf(MR_mdb_err, "%s.\n", problem);
goto return_keep_interacting;
}
@@ -420,7 +479,7 @@
cmd->MR_trace_print_level = MR_default_print_level;
goto return_stop_interacting;
} else {
- printf("One of the first two words "
+ fprintf(MR_mdb_err, "One of the first two words "
"must be a command.\n");
}
} else if (streq(words[0], "step")) {
@@ -456,7 +515,8 @@
cmd->MR_trace_stop_event = n;
goto return_stop_interacting;
} else {
- printf("The debugger cannot go "
+ /* XXX this message is misleading */
+ fprintf(MR_mdb_err, "The debugger cannot go "
"to a past event.\n");
}
} else {
@@ -483,7 +543,7 @@
}
if (depth == stop_depth && MR_port_is_final(port)) {
- printf("This command is a no-op from this port.\n");
+ MR_trace_do_noop();
} else {
cmd->MR_trace_cmd = MR_CMD_FINISH;
cmd->MR_trace_stop_depth = stop_depth;
@@ -501,7 +561,7 @@
cmd->MR_trace_cmd = MR_CMD_RETURN;
goto return_stop_interacting;
} else {
- printf("This command is a no-op from this port.\n");
+ MR_trace_do_noop();
}
} else {
MR_trace_usage("forward", "return");
@@ -521,7 +581,7 @@
cmd->MR_trace_cmd = MR_CMD_RESUME_FORWARD;
goto return_stop_interacting;
} else {
- printf("This command is a no-op from this port.\n");
+ MR_trace_do_noop();
}
} else {
MR_trace_usage("forward", "forward");
@@ -611,7 +671,7 @@
cmd->MR_trace_print_level = MR_default_print_level;
goto return_stop_interacting;
} else if (stop_depth == depth && MR_port_is_entry(port)) {
- printf("This command is a no-op from this port.\n");
+ MR_trace_do_noop();
} else {
char *retry_cmd;
@@ -627,63 +687,28 @@
}
} else if (streq(words[0], "level")) {
if (word_count == 2 && MR_trace_is_number(words[1], &n)) {
- problem = MR_trace_browse_check_level(layout,
- saved_regs, n);
- if (problem == NULL) {
- *ancestor_level = n;
- printf("Ancestor level set to %d.\n",
- *ancestor_level);
- } else {
- printf("%s.\n", problem);
- }
+ MR_trace_set_level(layout, saved_regs, ancestor_level,
+ n);
} else {
MR_trace_usage("browsing", "level");
}
} else if (streq(words[0], "up")) {
if (word_count == 2 && MR_trace_is_number(words[1], &n)) {
- problem = MR_trace_browse_check_level(layout,
- saved_regs, *ancestor_level + n);
- if (problem == NULL) {
- *ancestor_level += n;
- printf("Ancestor level set to %d.\n",
- *ancestor_level);
- } else {
- printf("%s.\n", problem);
- }
+ MR_trace_set_level(layout, saved_regs, ancestor_level,
+ *ancestor_level + n);
} else if (word_count == 1) {
- problem = MR_trace_browse_check_level(layout,
- saved_regs, *ancestor_level + 1);
- if (problem == NULL) {
- *ancestor_level += 1;
- printf("Ancestor level set to %d.\n",
- *ancestor_level);
- } else {
- printf("%s.\n", problem);
- }
+ MR_trace_set_level(layout, saved_regs, ancestor_level,
+ *ancestor_level + 1);
} else {
MR_trace_usage("browsing", "up");
}
} else if (streq(words[0], "down")) {
if (word_count == 2 && MR_trace_is_number(words[1], &n)) {
- problem = MR_trace_browse_check_level(layout,
- saved_regs, *ancestor_level - n);
- if (problem == NULL) {
- *ancestor_level -= n;
- printf("Ancestor level set to %d.\n",
- *ancestor_level);
- } else {
- printf("%s.\n", problem);
- }
+ MR_trace_set_level(layout, saved_regs, ancestor_level,
+ *ancestor_level - n);
} else if (word_count == 1) {
- problem = MR_trace_browse_check_level(layout,
- saved_regs, *ancestor_level - 1);
- if (problem == NULL) {
- *ancestor_level -= 1;
- printf("Ancestor level set to %d.\n",
- *ancestor_level);
- } else {
- printf("%s.\n", problem);
- }
+ MR_trace_set_level(layout, saved_regs, ancestor_level,
+ *ancestor_level - 1);
} else {
MR_trace_usage("browsing", "down");
}
@@ -742,16 +767,15 @@
{
; /* the usage message has already been printed */
} else if (word_count == 1) {
- const char *result;
-
+ const char *msg;
do_init_modules();
- result = MR_dump_stack_from_layout(stdout,
+ msg = MR_dump_stack_from_layout(MR_mdb_out,
layout->MR_sll_entry,
MR_saved_sp(saved_regs),
MR_saved_curfr(saved_regs),
include_trace_data);
- if (result != NULL) {
- printf("%s.\n", result);
+ if (msg != NULL) {
+ fprintf(MR_mdb_err, "%s.\n", msg);
}
} else {
MR_trace_usage("browsing", "stack");
@@ -783,7 +807,7 @@
{
; /* the usage message has already been printed */
} else if (word_count == 2 && streq(words[1], "here")) {
- MR_register_all_modules_and_procs(stdout, TRUE);
+ MR_register_all_modules_and_procs(MR_mdb_out, TRUE);
MR_trace_internal_add_spy_point(MR_SPY_SPECIFIC,
action, layout->MR_sll_entry, layout);
} else if (word_count == 2 &&
@@ -792,7 +816,7 @@
const MR_Stack_Layout_Entry *spy_proc;
bool unique;
- MR_register_all_modules_and_procs(stdout, TRUE);
+ MR_register_all_modules_and_procs(MR_mdb_out, TRUE);
spy_proc = MR_search_for_matching_procedure(&spec,
&unique);
if (spy_proc != NULL) {
@@ -800,14 +824,17 @@
MR_trace_internal_add_spy_point(when,
action, spy_proc, NULL);
} else {
- printf("Ambiguous procedure "
+ fprintf(MR_mdb_err,
+ "Ambiguous procedure "
"specification. "
"The matches are:\n");
MR_process_matching_procedures(&spec,
- MR_print_proc_id_for_debugger);
+ MR_mdb_print_proc_id,
+ MR_mdb_err);
}
} else {
- printf("There is no such procedure.\n");
+ fprintf(MR_mdb_err,
+ "There is no such procedure.\n");
}
} else {
MR_trace_usage("breakpoint", "break");
@@ -818,7 +845,9 @@
MR_spy_points[n]->spy_enabled = TRUE;
MR_print_spy_point(n);
} else {
- printf("Break point #%d does not exist.\n", n);
+ fprintf(MR_mdb_err,
+ "Break point #%d does not exist.\n",
+ n);
}
} else if (word_count == 2 && streq(words[1], "*")) {
for (i = 0; i < MR_spy_point_next; i++) {
@@ -827,7 +856,8 @@
}
if (MR_spy_point_next == 0) {
- printf("There no break points yet.\n");
+ fprintf(MR_mdb_out,
+ "There no break points yet.\n");
}
} else {
MR_trace_usage("breakpoint", "enable");
@@ -838,7 +868,9 @@
MR_spy_points[n]->spy_enabled = FALSE;
MR_print_spy_point(n);
} else {
- printf("Break point #%d does not exist.\n", n);
+ fprintf(MR_mdb_err,
+ "Break point #%d does not exist.\n",
+ n);
}
} else if (word_count == 2 && streq(words[1], "*")) {
for (i = 0; i < MR_spy_point_next; i++) {
@@ -847,7 +879,8 @@
}
if (MR_spy_point_next == 0) {
- printf("There no break points yet.\n");
+ fprintf(MR_mdb_err,
+ "There no break points yet.\n");
}
} else {
MR_trace_usage("breakpoint", "disable");
@@ -860,21 +893,21 @@
{
; /* the usage message has already been printed */
} else if (word_count == 1) {
- MR_register_all_modules_and_procs(stdout, verbose);
+ MR_register_all_modules_and_procs(MR_mdb_out, verbose);
} else {
MR_trace_usage("breakpoint", "register");
}
} else if (streq(words[0], "modules")) {
if (word_count == 1) {
- MR_register_all_modules_and_procs(stdout, TRUE);
- MR_dump_module_list(stdout);
+ MR_register_all_modules_and_procs(MR_mdb_out, TRUE);
+ MR_dump_module_list(MR_mdb_out);
} else {
MR_trace_usage("breakpoint", "modules");
}
} else if (streq(words[0], "procedures")) {
if (word_count == 2) {
- MR_register_all_modules_and_procs(stdout, TRUE);
- MR_dump_module_procs(stdout, words[1]);
+ MR_register_all_modules_and_procs(MR_mdb_out, TRUE);
+ MR_dump_module_procs(MR_mdb_out, words[1]);
} else {
MR_trace_usage("breakpoint", "procedures");
}
@@ -883,19 +916,22 @@
if (streq(words[1], "none")) {
MR_default_print_level = MR_PRINT_LEVEL_NONE;
if (MR_trace_internal_interacting) {
- printf("Default print level set to "
+ fprintf(MR_mdb_out,
+ "Default print level set to "
"`none'.\n");
}
} else if (streq(words[1], "some")) {
MR_default_print_level = MR_PRINT_LEVEL_SOME;
if (MR_trace_internal_interacting) {
- printf("Default print level set to "
+ fprintf(MR_mdb_out,
+ "Default print level set to "
"`some'.\n");
}
} else if (streq(words[1], "all")) {
MR_default_print_level = MR_PRINT_LEVEL_ALL;
if (MR_trace_internal_interacting) {
- printf("Default print level set to "
+ fprintf(MR_mdb_out,
+ "Default print level set to "
"`all'.\n");
}
} else {
@@ -903,21 +939,21 @@
"printlevel");
}
} else if (word_count == 1) {
- printf("The default print level is ");
+ fprintf(MR_mdb_out, "The default print level is ");
switch (MR_default_print_level) {
case MR_PRINT_LEVEL_NONE:
- printf("`none'.\n");
+ fprintf(MR_mdb_out, "`none'.\n");
break;
case MR_PRINT_LEVEL_SOME:
- printf("`some'.\n");
+ fprintf(MR_mdb_out, "`some'.\n");
break;
case MR_PRINT_LEVEL_ALL:
- printf("`all'.\n");
+ fprintf(MR_mdb_out, "`all'.\n");
break;
default:
MR_default_print_level =
MR_PRINT_LEVEL_SOME;
- printf("invalid "
+ fprintf(MR_mdb_out, "invalid "
"(now set to `some').\n");
break;
}
@@ -929,30 +965,33 @@
if (streq(words[1], "off")) {
MR_scroll_control = FALSE;
if (MR_trace_internal_interacting) {
- printf("Scroll control disabled.\n");
+ fprintf(MR_mdb_out,
+ "Scroll control disabled.\n");
}
} else if (streq(words[1], "on")) {
MR_scroll_control = TRUE;
if (MR_trace_internal_interacting) {
- printf("Scroll control enabled.\n");
+ fprintf(MR_mdb_out,
+ "Scroll control enabled.\n");
}
} else if (MR_trace_is_number(words[1], &n)) {
MR_scroll_limit = n;
if (MR_trace_internal_interacting) {
- printf("Scroll window size set to "
+ fprintf(MR_mdb_out,
+ "Scroll window size set to "
"%d.\n", MR_scroll_limit);
}
} else {
MR_trace_usage("parameter", "scroll");
}
} else if (word_count == 1) {
- printf("Scroll control is ");
+ fprintf(MR_mdb_out, "Scroll control is ");
if (MR_scroll_control) {
- printf("on");
+ fprintf(MR_mdb_out, "on");
} else {
- printf("off");
+ fprintf(MR_mdb_out, "off");
}
- printf(", scroll window size is %d.\n",
+ fprintf(MR_mdb_out, ", scroll window size is %d.\n",
MR_scroll_limit);
} else {
MR_trace_usage("parameter", "scroll");
@@ -962,40 +1001,43 @@
if (streq(words[1], "off")) {
MR_echo_commands = FALSE;
if (MR_trace_internal_interacting) {
- printf("Command echo disabled.\n");
+ fprintf(MR_mdb_out,
+ "Command echo disabled.\n");
}
} else if (streq(words[1], "on")) {
MR_echo_commands = TRUE;
if (MR_trace_internal_interacting) {
- printf("Command echo enabled.\n");
+ fprintf(MR_mdb_out,
+ "Command echo enabled.\n");
}
} else {
MR_trace_usage("parameter", "echo");
}
} else if (word_count == 1) {
- printf("Command echo is ");
+ fprintf(MR_mdb_out, "Command echo is ");
if (MR_echo_commands) {
- printf("on.\n");
+ fprintf(MR_mdb_out, "on.\n");
} else {
- printf("off.\n");
+ fprintf(MR_mdb_out, "off.\n");
}
} else {
MR_trace_usage("parameter", "echo");
}
} else if (streq(words[0], "alias")) {
if (word_count == 1) {
- MR_trace_print_all_aliases(stdout);
+ MR_trace_print_all_aliases(MR_mdb_out);
} else if (word_count == 2) {
- MR_trace_print_alias(stdout, words[1]);
+ 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(stdout, words[1]);
+ MR_trace_print_alias(MR_mdb_out, words[1]);
}
} else {
- printf("%s is not a valid command.\n",
+ fprintf(MR_mdb_out,
+ "%s is not a valid command.\n",
words[2]);
}
}
@@ -1003,11 +1045,13 @@
if (word_count == 2) {
if (MR_trace_remove_alias(words[1])) {
if (MR_trace_internal_interacting) {
- printf("Alias `%s' removed.\n",
+ fprintf(MR_mdb_out,
+ "Alias `%s' removed.\n",
words[1]);
}
} else {
- printf("Alias `%s' cannot be removed, "
+ fprintf(MR_mdb_err,
+ "Alias `%s' cannot be removed, "
"since it does not exist.\n",
words[1]);
}
@@ -1027,7 +1071,8 @@
} else {
msg = MR_trace_add_cat(words[2], slot, help_text);
if (msg != NULL) {
- printf("Document category `%s' not added: "
+ fprintf(MR_mdb_err,
+ "Document category `%s' not added: "
"%s.\n", words[2], msg);
}
}
@@ -1045,7 +1090,8 @@
msg = MR_trace_add_item(words[1], words[3], slot,
help_text);
if (msg != NULL) {
- printf("Document item `%s' in category `%s' "
+ fprintf(MR_mdb_err,
+ "Document item `%s' in category `%s' "
"not added: %s.\n",
words[3], words[1], msg);
}
@@ -1117,14 +1163,15 @@
} else if (streq(words[0], "nondet_stack")) {
if (word_count == 1) {
do_init_modules();
- MR_dump_nondet_stack_from_layout(stdout,
+ MR_dump_nondet_stack_from_layout(MR_mdb_out,
MR_saved_maxfr(saved_regs));
} else {
MR_trace_usage("developer", "nondet_stack");
}
} else if (streq(words[0], "stack_regs")) {
if (word_count == 1) {
- printf("sp = %p, curfr = %p, maxfr = %p\n",
+ fprintf(MR_mdb_out,
+ "sp = %p, curfr = %p, maxfr = %p\n",
MR_saved_sp(saved_regs),
MR_saved_curfr(saved_regs),
MR_saved_maxfr(saved_regs));
@@ -1155,7 +1202,7 @@
line2 = MR_trace_getline(
"mdb: are you sure you want to quit? ",
- stdin);
+ MR_mdb_in);
if (line2 == NULL) {
/* This means the user input EOF. */
confirmed = TRUE;
@@ -1183,7 +1230,7 @@
MR_trace_usage("misc", "quit");
}
} else {
- printf("Unknown command `%s'. "
+ fprintf(MR_mdb_err, "Unknown command `%s'. "
"Give the command `help' for help.\n", words[0]);
}
@@ -1412,7 +1459,8 @@
/* cat is unused now, but could be used later */
{
- printf("mdb: %s: usage error -- type `help %s' for help.\n",
+ fprintf(MR_mdb_err,
+ "mdb: %s: usage error -- type `help %s' for help.\n",
item, item);
}
@@ -1435,7 +1483,8 @@
call_label = entry->MR_sle_call_label;
if (call_label->MR_sll_var_count < 0) {
- printf("Cannot perform retry because information about "
+ fprintf(MR_mdb_err,
+ "Cannot perform retry, because information about "
"the input arguments is not available.\n");
return;
}
@@ -1458,7 +1507,8 @@
input_args->MR_slvs_names[i], &succeeded);
if (! succeeded) {
- printf("Cannot perform retry because the values of "
+ fprintf(MR_mdb_err,
+ "Cannot perform retry because the values of "
"some input arguments are missing.\n");
return;
}
@@ -1584,12 +1634,12 @@
static void
MR_print_spy_point(int spy_point_num)
{
- printf("%2d: %1s %-5s %9s ",
+ fprintf(MR_mdb_out, "%2d: %1s %-5s %9s ",
spy_point_num,
MR_spy_points[spy_point_num]->spy_enabled ? "+" : "-",
MR_spy_action_string(MR_spy_points[spy_point_num]->spy_action),
MR_spy_when_string(MR_spy_points[spy_point_num]->spy_when));
- MR_print_proc_id(stdout, MR_spy_points[spy_point_num]->spy_proc,
+ MR_print_proc_id(MR_mdb_out, MR_spy_points[spy_point_num]->spy_proc,
NULL, NULL, NULL);
}
@@ -1612,19 +1662,37 @@
&base_sp, &base_curfr, &problem);
if (level_layout == NULL) {
- printf("%s\n", problem);
+ fprintf(MR_mdb_err, "%s\n", problem);
return;
}
problem = MR_trace_validate_var_count(level_layout, &var_count);
if (problem != NULL) {
- printf("mdb: %s.\n", problem);
+ fprintf(MR_mdb_err, "mdb: %s.\n", problem);
return;
}
vars = &level_layout->MR_sll_var_info;
for (i = 0; i < var_count; i++) {
- printf("%9d %s\n", i, MR_name_if_present(vars, i));
+ fprintf(MR_mdb_out, "%9d %s\n",
+ i, MR_name_if_present(vars, i));
+ }
+}
+
+static void
+MR_trace_set_level(const MR_Stack_Layout_Label *layout,
+ Word *saved_regs, int *ancestor_level, int new_ancestor_level)
+{
+ const char *problem;
+
+ problem = MR_trace_browse_check_level(layout, saved_regs,
+ new_ancestor_level);
+ if (problem == NULL) {
+ *ancestor_level = new_ancestor_level;
+ fprintf(MR_mdb_out, "Ancestor level set to %d.\n",
+ *ancestor_level);
+ } else {
+ fprintf(MR_mdb_err, "%s.\n", problem);
}
}
@@ -1647,8 +1715,8 @@
return problem;
} else {
entry = label_layout->MR_sll_entry;
- printf("%4d ", ancestor_level);
- MR_print_proc_id(stdout, entry, "", base_sp, base_curfr);
+ fprintf(MR_mdb_out, "%4d ", ancestor_level);
+ MR_print_proc_id(MR_mdb_out, entry, "", base_sp, base_curfr);
if (MR_ENTRY_LAYOUT_HAS_EXEC_TRACE(entry)) {
return NULL;
} else {
@@ -1677,13 +1745,13 @@
&base_sp, &base_curfr, &problem);
if (level_layout == NULL) {
- printf("mdb: %s.\n", problem);
+ fprintf(MR_mdb_err, "mdb: %s.\n", problem);
return;
}
problem = MR_trace_find_var(level_layout, var_spec, &which_var);
if (problem != NULL) {
- printf("mdb: %s.\n", problem);
+ fprintf(MR_mdb_err, "mdb: %s.\n", problem);
return;
}
@@ -1722,13 +1790,13 @@
&base_sp, &base_curfr, &problem);
if (level_layout == NULL) {
- printf("mdb: %s.\n", problem);
+ fprintf(MR_mdb_err, "mdb: %s.\n", problem);
return;
}
problem = MR_trace_validate_var_count(level_layout, &var_count);
if (problem != NULL) {
- printf("mdb: %s.\n", problem);
+ fprintf(MR_mdb_err, "mdb: %s.\n", problem);
return;
}
@@ -1775,12 +1843,13 @@
if (!browse) {
if (name != NULL) {
- printf("%7s%-21s\t", "", name);
+ fprintf(MR_mdb_out, "%7s%-21s\t", "", name);
} else {
- printf("%7s%-21s\t", "", "anonymous variable");
+ fprintf(MR_mdb_out, "%7s%-21s\t", "",
+ "anonymous variable");
}
- fflush(stdout);
+ fflush(MR_mdb_out);
}
@@ -1794,10 +1863,12 @@
base_sp, base_curfr, type_params, &type_info, &value);
if (print_value) {
if (browse) {
+ /* XXX should use MR_mdb_in and MR_mdb_out */
MR_trace_browse(type_info, value);
} else {
- printf("\t");
- fflush(stdout);
+ fprintf(MR_mdb_out, "\t");
+ fflush(MR_mdb_out);
+ /* XXX should use MR_mdb_out */
MR_trace_print(type_info, value);
}
}
@@ -1890,7 +1961,7 @@
int i;
next_char_slot = 0;
- while ((text = MR_trace_getline("cat> ", stdin)) != NULL) {
+ while ((text = MR_trace_getline("cat> ", MR_mdb_in)) != NULL) {
if (streq(text, "end")) {
free(text);
break;
@@ -2130,7 +2201,7 @@
fclose(fp);
return TRUE;
} else {
- printf("%s: %s.\n", filename, strerror(errno));
+ fprintf(MR_mdb_err, "%s: %s.\n", filename, strerror(errno));
return FALSE;
}
}
@@ -2166,8 +2237,8 @@
}
MR_trace_internal_interacting = TRUE;
- printf("%s", prompt);
- fflush(stdout);
+ fprintf(MR_mdb_out, "%s", prompt);
+ fflush(MR_mdb_out);
return MR_trace_getline_raw(fp);
}
@@ -2282,7 +2353,7 @@
/* We try to leave one line for the prompt itself. */
if (MR_scroll_control && MR_scroll_next >= MR_scroll_limit - 1) {
try_again:
- buf = MR_trace_getline("--more-- ", stdin);
+ buf = MR_trace_getline("--more-- ", MR_mdb_in);
if (buf != NULL) {
for (i = 0; buf[i] != '\0' && MR_isspace(buf[i]); i++)
;
@@ -2316,7 +2387,8 @@
max_mr_num);
default:
- printf("unknown command, "
+ fprintf(MR_mdb_err,
+ "unknown command, "
"try again\n");
free(buf);
goto try_again;
@@ -2339,65 +2411,68 @@
MR_trace_event_print_internal_report(const MR_Stack_Layout_Label *layout,
MR_Trace_Port port, int seqno, int depth, const char *path)
{
- printf("%8ld: %6ld %2ld ",
+ fprintf(MR_mdb_out, "%8ld: %6ld %2ld ",
(long) MR_trace_event_number, (long) seqno, (long) depth);
MR_trace_print_port(port);
- MR_print_proc_id(stdout, layout->MR_sll_entry, path, NULL, NULL);
+ MR_print_proc_id(MR_mdb_out, layout->MR_sll_entry, path, NULL, NULL);
}
static void
MR_trace_print_port(MR_Trace_Port port)
{
+ const char *port_name;
switch (port) {
case MR_PORT_CALL:
- printf("CALL ");
+ port_name = "CALL";
break;
case MR_PORT_EXIT:
- printf("EXIT ");
+ port_name = "EXIT";
break;
case MR_PORT_REDO:
- printf("REDO ");
+ port_name = "REDO";
break;
case MR_PORT_FAIL:
- printf("FAIL ");
+ port_name = "FAIL";
break;
case MR_PORT_THEN:
- printf("THEN ");
+ port_name = "THEN";
break;
case MR_PORT_ELSE:
- printf("ELSE ");
+ port_name = "ELSE";
break;
case MR_PORT_DISJ:
- printf("DISJ ");
+ port_name = "DISJ";
break;
case MR_PORT_SWITCH:
- printf("SWTC ");
+ port_name = "SWTC";
break;
case MR_PORT_PRAGMA_FIRST:
- printf("FRST ");
+ port_name = "FRST";
break;
case MR_PORT_PRAGMA_LATER:
- printf("LATR ");
+ port_name = "LATR";
break;
case MR_PORT_EXCEPTION:
- printf("EXCP ");
+ port_name = "EXCP";
break;
default:
+ port_name = "????";
fatal_error("MR_trace_event_internal called "
"with bad port");
}
+ fprintf(MR_mdb_out, "%s ", port_name);
}
typedef struct
Index: trace/mercury_trace_tables.c
===================================================================
RCS file: /home/mercury1/repository/mercury/trace/mercury_trace_tables.c,v
retrieving revision 1.3
diff -u -r1.3 mercury_trace_tables.c
--- mercury_trace_tables.c 1998/11/14 03:43:11 1.3
+++ mercury_trace_tables.c 1998/12/17 13:27:59
@@ -35,7 +35,8 @@
static void MR_process_matching_procedures_in_module(
MR_Module_Info *module, MR_Proc_Spec *spec,
- void f(const MR_Stack_Layout_Entry *));
+ void f(void *, const MR_Stack_Layout_Entry *),
+ void *);
void
MR_register_all_modules_and_procs(FILE *fp, bool verbose)
@@ -297,34 +298,41 @@
return TRUE;
}
-/* These two variables are for communication between */
-/* MR_register_match and MR_search_for_matching_procedure. */
-static const MR_Stack_Layout_Entry *matching_entry;
-static bool match_unique;
+/*
+** This struct is for communication between
+** MR_register_match and MR_search_for_matching_procedure.
+*/
+typedef struct {
+ const MR_Stack_Layout_Entry *matching_entry;
+ bool match_unique;
+} MR_match_info;
static void
-MR_register_match(const MR_Stack_Layout_Entry *entry)
+MR_register_match(void *data, const MR_Stack_Layout_Entry *entry)
{
- if (matching_entry == NULL) {
- matching_entry = entry;
+ MR_match_info *m = data;
+ if (m->matching_entry == NULL) {
+ m->matching_entry = entry;
} else {
- match_unique = FALSE;
+ m->match_unique = FALSE;
}
}
const MR_Stack_Layout_Entry *
MR_search_for_matching_procedure(MR_Proc_Spec *spec, bool *unique)
{
- matching_entry = NULL;
- match_unique = TRUE;
- MR_process_matching_procedures(spec, MR_register_match);
- *unique = match_unique;
- return matching_entry;
+ MR_match_info m;
+ m.matching_entry = NULL;
+ m.match_unique = TRUE;
+ MR_process_matching_procedures(spec, MR_register_match, &m);
+ *unique = m.match_unique;
+ return m.matching_entry;
}
void
MR_process_matching_procedures(MR_Proc_Spec *spec,
- void f(const MR_Stack_Layout_Entry *))
+ void f(void *, const MR_Stack_Layout_Entry *),
+ void *data)
{
if (spec->MR_proc_module != NULL) {
MR_Module_Info *module;
@@ -332,14 +340,14 @@
module = MR_search_module_info(spec->MR_proc_module);
if (module != NULL) {
MR_process_matching_procedures_in_module(
- module, spec, f);
+ module, spec, f, data);
}
} else {
int i;
for (i = 0; i < MR_module_info_next; i++) {
MR_process_matching_procedures_in_module(
- &MR_module_infos[i], spec, f);
+ &MR_module_infos[i], spec, f, data);
}
}
}
@@ -362,7 +370,8 @@
static void
MR_process_matching_procedures_in_module(MR_Module_Info *module,
- MR_Proc_Spec *spec, void f(const MR_Stack_Layout_Entry *))
+ MR_Proc_Spec *spec, void f(void *, const MR_Stack_Layout_Entry *),
+ void *data)
{
MR_Proc_Node *cur;
const MR_Stack_Layout_Entry *cur_entry;
@@ -375,7 +384,7 @@
match_mode(spec, cur_entry) &&
match_pf(spec, cur_entry))
{
- f(cur_entry);
+ f(data, cur_entry);
}
}
}
Index: trace/mercury_trace_tables.h
===================================================================
RCS file: /home/mercury1/repository/mercury/trace/mercury_trace_tables.h,v
retrieving revision 1.1
diff -u -r1.1 mercury_trace_tables.h
--- mercury_trace_tables.h 1998/10/16 06:20:22 1.1
+++ mercury_trace_tables.h 1998/12/17 13:26:52
@@ -110,11 +110,15 @@
MR_Proc_Spec *spec, bool *unique);
/*
-** Call f(entry) on the layout of every procedure that matches
-** the given specification.
+** MR_process_matching_procedures(spec, f, data):
+** For each procedure that matches the specification given by `spec',
+** call `f(data, entry)', where `entry' is the entry layout for that
+** procedure. The argument `data' is a `void *' which can be used
+** to pass any other information needed by the function `f'.
*/
extern void MR_process_matching_procedures(MR_Proc_Spec *spec,
- void f(const MR_Stack_Layout_Entry *));
+ void f(void *, const MR_Stack_Layout_Entry *),
+ void *data);
#endif /* not MERCURY_TRACE_TABLES_H */
Fergus Henderson <fjh at cs.mu.oz.au> | "Binaries may die
WWW: <http://www.cs.mu.oz.au/~fjh> | but source code lives forever"
PGP: finger fjh at 128.250.37.3 | -- leaked Microsoft memo.
More information about the developers
mailing list