[m-rev.] for post-commit review: regularize mdb commands for browser parameters
Zoltan Somogyi
zs at cs.mu.OZ.AU
Tue Apr 4 17:26:01 AEST 2006
For both branches.
browser/declarative_tree.m:
Fix references to predicates that have been moved to other modules
in the standard library.
Replace the "set" command of mdb with a bunch of commands: the `format',
`format_param', `list_context_lines', `list_path', `xml_browser_cmd',
`xml_tmp_filename', `fail_trace_counts', `pass_trace_counts' and
`max_io_actions' commands. Each of these set just one parameter
or one of set of closely related parameters.
Move all these commands, and some existing commands that set parameters
that were elsewhere, to the "parameter" command category.
Extend some of these commands so that if given no arguments, they report
the current values of the parameters they would otherwise set.
Replace the "set" commands of the mdb browser and of the declarative debugger
with a bunch of commands: "format", "depth", "size", "width", "lines",
"actions" and "params" (the last prints the current value of the parameters).
For each category of mdb commands, create files mercury_trace_cmd_<cat>.[ch],
and move the functions dealing with that category of commands there from
mercury_trace_internal.c. Give each of these new files a logical structure
that was sometimes missing from the relevant parts of mercury_trace_internal.c.
NEWS:
Mention these changes.
doc/mdb_categories:
Document these changes.
doc/user_guide.texi:
Document these changes.
Fix an old documentation bug: you couldn't set listing paramaters
from a declarative debugger command.
Fix an old documentation bug: the description of the goal_path step
for scopes was obsolete.
Fix some obsolete references to : as module qualifier.
browser/parse.m:
Update the browser command set along the lines at the top.
browser/declarative_user.m:
Update the declarative debugger command set along the lines at the top.
Move the declaration for the type representing declarative debugger
commands to near the top of the file.
browser/browser_info.m:
Provide some access predicates.
Update the predicate that generates mdb commands to save the persistent
state of the debugger to generate the new forms of parameter commands.
Move types and predicates for dealing with browser parameters from
browse.m to here, so that declarative_user.m can use them too.
browser/browse.m:
Delete the code moved to browser_info.m, and conform to the other
changes in the other modules.
browser/listing.m:
Provide a predicate to return the type of listing paths.
scripts/mdbrc.in:
Update the commands that set the XML parameters.
scripts/Mmakefile:
Get mmake to rebuild mdbrc from mdbrc.in when mdbrc.in changes.
trace/mercury_trace_internal.c:
trace/mercury_trace_cmds.h:
trace/mercury_trace_cmd_*.[ch]:
Implement the changes described at the top.
Fix an old bug: the commands that update the search path for the "list"
command don't make the search path term permanent, which is needed in
non-conservative-gc grades.
trace/mercury_trace_spy.c:
Fix some obsolete references to : as module qualifier.
trace/mercury_trace_browse.[ch]:
Delete the functionality now moved to mercury_trace_cmd_parameter.c.
tests/debugger/mdb_command_test.inp:
Update the set of commands being tested.
tests/debugger/save.{inp,exp}:
Update the parameter commands in this test case.
cvs diff: Diffing .
Index: NEWS
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/NEWS,v
retrieving revision 1.409
diff -u -b -r1.409 NEWS
--- NEWS 31 Mar 2006 05:12:07 -0000 1.409
+++ NEWS 1 Apr 2006 11:14:33 -0000
@@ -61,6 +61,10 @@
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.
+* The `set' command has been replaced by several other commands: the `format',
+ `format_param', `list_context_lines', `list_path', `xml_browser_cmd',
+ `xml_tmp_filename', `fail_trace_counts', `pass_trace_counts' and
+ `max_io_actions' commands.
* The `save_to_file' command has been renamed the `dump' command.
* The `save' command now saves the entire persistent state of the debugger
(with one small exception that cannot be reestablished by an mdb command from
cvs diff: Diffing analysis
cvs diff: Diffing bindist
cvs diff: Diffing boehm_gc
cvs diff: Diffing boehm_gc/Mac_files
cvs diff: Diffing boehm_gc/cord
cvs diff: Diffing boehm_gc/cord/private
cvs diff: Diffing boehm_gc/doc
cvs diff: Diffing boehm_gc/include
cvs diff: Diffing boehm_gc/include/private
cvs diff: Diffing boehm_gc/tests
cvs diff: Diffing browser
Index: browser/browse.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/browser/browse.m,v
retrieving revision 1.59
diff -u -b -r1.59 browse.m
--- browser/browse.m 31 Mar 2006 05:12:09 -0000 1.59
+++ browser/browse.m 2 Apr 2006 03:22:03 -0000
@@ -215,26 +215,6 @@
%---------------------------------------------------------------------------%
%
-% If the term browser is called from the internal debugger, input is
-% done via a call to the readline library (if available), using streams
-% MR_mdb_in and MR_mdb_out. If it is called from the external debugger,
-% Input/Output are done via MR_debugger_socket_in/MR_debugger_socket_out.
-% In the latter case we need to output terms; their type is
-% term_browser_response.
-
-:- type term_browser_response
- ---> browser_str(string)
- ; browser_int(int)
- ; browser_nl
- ; browser_end_command
- ; browser_quit.
-
-:- type debugger
- ---> internal
- ; external.
-
-%---------------------------------------------------------------------------%
-%
% Saving terms to files
%
@@ -614,18 +594,8 @@
help(Debugger, !IO),
Quit = no
;
- Command = set,
- show_settings(Debugger, !.Info, !IO),
- Quit = no
- ;
- Command = set(MaybeOptionTable, Setting),
- (
- MaybeOptionTable = ok(OptionTable),
- set_browse_param(OptionTable, Setting, !Info)
- ;
- MaybeOptionTable = error(Msg),
- write_string_debugger(Debugger, Msg, !IO)
- ),
+ Command = param_command(ParamCmd),
+ run_param_command(Debugger, ParamCmd, yes, !Info, !IO),
Quit = no
;
Command = cd,
@@ -770,27 +740,25 @@
bool_format_option_is_true(Format - bool(yes), Format).
-:- pred set_browse_param(option_table(setting_option)::in, setting::in,
- browser_info::in, browser_info::out) is det.
-
-set_browse_param(OptionTable, Setting, !Info) :-
- set_browser_param_from_option_table(yes, OptionTable, Setting,
- !.Info ^ state, NewState),
- !:Info = !.Info ^ state := NewState.
-
:- pred help(debugger::in, io::di, io::uo) is det.
-help(Debugger) -->
- { string.append_list([
+help(Debugger, !IO) :-
+ string.append_list([
"Commands are:\n",
"\t[print|p|ls] [format_options] [path]\n",
"\t -- print the specified subterm using the `browse' params\n",
"\tcd [path] -- cd to the specified subterm (default is root)\n",
"\tcdr n path -- repeatedly apply the cd command n times\n",
"\tpwd -- print the path to the current subterm\n",
-"\tset [setting_options] var value\n",
+"\tformat [format_options] <flat|raw-prety|verbose|pretty>\n",
+"\t -- set the format\n",
+"\tdepth [format_param_options] <n>\n",
+"\tsize [format_param_options] <n>\n",
+"\twidth [format_param_options] <n>\n",
+"\tlines [format_param_options] <n>\n",
+"\tnum_io_actions <n>\n",
"\t -- set a parameter value\n",
-"\tset -- show parameter values\n",
+"\tparams -- show format and parameter values\n",
"\tmark [path] -- mark the given subterm (default is current) and quit\n",
"\tmode [path] -- show the mode of a subterm (default is current)\n",
"\tquit -- quit browser\n",
@@ -802,14 +770,10 @@
"\t? -- help\n",
"\th -- help\n",
"\n",
-"-- Parameter variables with integer values:\n",
-"-- size <n>; depth <n>; path <n>; width <n>; lines <n>; num_io_actions <n>;\n",
-"-- Parameter variables with non-integer values:\n",
-"-- format <flat,raw_pretty,verbose,pretty>;\n",
"-- Paths can be Unix-style or SICStus-style: /2/3/1 or ^2^3^1\n",
"\n"],
- HelpMessage) },
- write_string_debugger(Debugger, HelpMessage).
+ HelpMessage),
+ write_string_debugger(Debugger, HelpMessage, !IO).
%---------------------------------------------------------------------------%
%
@@ -1336,60 +1300,6 @@
% Miscellaneous path handling
%
-:- pred write_path(debugger::in, list(dir)::in, io::di, io::uo) is det.
-
-write_path(Debugger, [], !IO) :-
- write_string_debugger(Debugger, "/", !IO).
-write_path(Debugger, [Dir], !IO) :-
- (
- Dir = parent,
- write_string_debugger(Debugger, "/", !IO)
- ;
- Dir = child_num(N),
- write_string_debugger(Debugger, "/", !IO),
- write_int_debugger(Debugger, N, !IO)
- ;
- Dir = child_name(Name),
- write_string_debugger(Debugger, "/", !IO),
- write_string_debugger(Debugger, Name, !IO)
- ).
-write_path(Debugger, [Dir, Dir2 | Dirs], !IO) :-
- write_path_2(Debugger, [Dir, Dir2 | Dirs], !IO).
-
-:- pred write_path_2(debugger::in, list(dir)::in, io::di, io::uo) is det.
-
-write_path_2(Debugger, [], !IO) :-
- write_string_debugger(Debugger, "/", !IO).
-write_path_2(Debugger, [Dir], !IO) :-
- (
- Dir = parent,
- write_string_debugger(Debugger, "/..", !IO)
- ;
- Dir = child_num(N),
- write_string_debugger(Debugger, "/", !IO),
- write_int_debugger(Debugger, N, !IO)
- ;
- Dir = child_name(Name),
- write_string_debugger(Debugger, "/", !IO),
- write_string_debugger(Debugger, Name, !IO)
- ).
-write_path_2(Debugger, [Dir, Dir2 | Dirs], !IO) :-
- (
- Dir = parent,
- write_string_debugger(Debugger, "/..", !IO),
- write_path_2(Debugger, [Dir2 | Dirs], !IO)
- ;
- Dir = child_num(N),
- write_string_debugger(Debugger, "/", !IO),
- write_int_debugger(Debugger, N, !IO),
- write_path_2(Debugger, [Dir2 | Dirs], !IO)
- ;
- Dir = child_name(Name),
- write_string_debugger(Debugger, "/", !IO),
- write_string_debugger(Debugger, Name, !IO),
- write_path_2(Debugger, [Dir2 | Dirs], !IO)
- ).
-
:- type deref_result(T)
---> deref_result(T)
; deref_error(list(dir), dir).
@@ -1574,8 +1484,8 @@
write_string_debugger(Debugger, pad_right("", ' ', row_name_len), !IO),
write_string_debugger(Debugger, pad_right("depth", ' ', depth_len), !IO),
write_string_debugger(Debugger, pad_right("size", ' ', size_len), !IO),
- write_string_debugger(Debugger, pad_right("x clip", ' ', x_len), !IO),
- write_string_debugger(Debugger, pad_right("y clip", ' ', y_len), !IO),
+ write_string_debugger(Debugger, pad_right("x clip", ' ', width_len), !IO),
+ write_string_debugger(Debugger, pad_right("y clip", ' ', lines_len), !IO),
nl_debugger(Debugger, !IO),
show_settings_caller_format(Debugger, Info, Caller, CallerName,
@@ -1605,24 +1515,24 @@
write_string_debugger(Debugger,
pad_right(int_to_string(Params ^ size), ' ', size_len), !IO),
write_string_debugger(Debugger,
- pad_right(int_to_string(Params ^ width), ' ', x_len), !IO),
+ pad_right(int_to_string(Params ^ width), ' ', width_len), !IO),
write_string_debugger(Debugger,
- pad_right(int_to_string(Params ^ lines), ' ', y_len), !IO),
+ pad_right(int_to_string(Params ^ lines), ' ', lines_len), !IO),
nl_debugger(Debugger, !IO).
:- func row_name_len = int.
:- func centering_len = int.
:- func depth_len = int.
:- func size_len = int.
-:- func x_len = int.
-:- func y_len = int.
+:- func width_len = int.
+:- func lines_len = int.
row_name_len = 30.
centering_len = 3.
depth_len = 10.
size_len = 10.
-x_len = 10.
-y_len = 10.
+width_len = 10.
+lines_len = 10.
:- pred string_to_path(string::in, path::out) is semidet.
@@ -1732,13 +1642,6 @@
%---------------------------------------------------------------------------%
-:- pred write_string_debugger(debugger::in, string::in, io::di, io::uo) is det.
-
-write_string_debugger(internal, String, !IO) :-
- io.write_string(String, !IO).
-write_string_debugger(external, String, !IO) :-
- send_term_to_socket(browser_str(String), !IO).
-
:- pred write_term_mode_debugger(debugger::in, maybe(browser_mode_func)::in,
list(dir)::in, io::di, io::uo) is det.
@@ -1760,47 +1663,6 @@
browser_mode_to_string(output) = "Output".
browser_mode_to_string(not_applicable) = "Not Applicable".
browser_mode_to_string(unbound) = "Unbound".
-
-:- pred nl_debugger(debugger::in, io::di, io::uo) is det.
-
-nl_debugger(internal, !IO) :-
- io.nl(!IO).
-nl_debugger(external, !IO) :-
- send_term_to_socket(browser_nl, !IO).
-
-:- pred write_int_debugger(debugger::in, int::in, io::di, io::uo) is det.
-
-write_int_debugger(internal, Int, !IO) :-
- io.write_int(Int, !IO).
-write_int_debugger(external, Int, !IO) :-
- send_term_to_socket(browser_int(Int), !IO).
-
-:- pred print_format_debugger(debugger::in, portray_format::in,
- io::di, io::uo) is det.
-
-print_format_debugger(internal, X, !IO) :-
- io.print(X, !IO).
-print_format_debugger(external, X, !IO) :-
- (
- X = flat,
- send_term_to_socket(browser_str("flat"), !IO)
- ;
- X = raw_pretty,
- send_term_to_socket(browser_str("raw_pretty"), !IO)
- ;
- X = verbose,
- send_term_to_socket(browser_str("verbose"), !IO)
- ;
- X = pretty,
- send_term_to_socket(browser_str("pretty"), !IO)
- ).
-
-:- pred send_term_to_socket(term_browser_response::in, io::di, io::uo) is det.
-
-send_term_to_socket(Term, !IO) :-
- write(Term, !IO),
- print(".\n", !IO),
- flush_output(!IO).
%---------------------------------------------------------------------------%
Index: browser/browser_info.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/browser/browser_info.m,v
retrieving revision 1.26
diff -u -b -r1.26 browser_info.m
--- browser/browser_info.m 31 Mar 2006 05:12:10 -0000 1.26
+++ browser/browser_info.m 2 Apr 2006 04:07:03 -0000
@@ -149,12 +149,9 @@
:- type setting
---> depth(int)
; size(int)
- ; format(portray_format)
; width(int)
; lines(int)
- ; num_io_actions(int)
- ; xml_browser_cmd(string)
- ; xml_tmp_filename(string).
+ ; format(portray_format).
% Initialise a new browser_info. The optional portray_format
% overrides the default format.
@@ -181,7 +178,7 @@
%---------------------------------------------------------------------------%
- % An data type that holds persistent browser settings.
+ % A data type that holds persistent browser settings.
% This state must be saved by the caller of the browse module
% between calls.
%
@@ -229,6 +226,74 @@
option_table(setting_option)::in, setting::in,
browser_persistent_state::in, browser_persistent_state::out) is det.
+:- pred info_set_browse_param(option_table(setting_option)::in,
+ setting::in, browser_info::in, browser_info::out) is det.
+
+:- pred info_set_num_io_actions(int::in,
+ browser_info::in, browser_info::out) is det.
+
+:- pred info_set_xml_browser_cmd(string::in,
+ browser_info::in, browser_info::out) is det.
+
+:- pred info_set_xml_tmp_filename(string::in,
+ browser_info::in, browser_info::out) is det.
+
+:- pred get_num_io_actions(browser_persistent_state::in, int::out) is det.
+:- pred set_num_io_actions(int::in,
+ browser_persistent_state::in, browser_persistent_state::out) is det.
+
+:- type param_cmd
+ ---> format(maybe_option_table(setting_option), setting)
+ ; format_param(maybe_option_table(setting_option), setting)
+ ; num_io_actions(int)
+ ; print_params.
+% We can't set the browser command from within the browser because we parse
+% user commands from the browser by breaking them up into words at whitespace,
+% which doesn't respect quotation marks. Since the browser command will usually
+% include spaces, this parsing method would need to be changed before we could
+% include xml_browser_cmd here. And until we handle xml_browser_cmd, there is
+% no point in handling xml_tmp_filename.
+%
+% ; xml_browser_cmd(string)
+% ; xml_tmp_filename(string)
+
+:- type debugger
+ ---> internal
+ ; external.
+%
+% If the term browser is called from the internal debugger, input is
+% done via a call to the readline library (if available), using streams
+% MR_mdb_in and MR_mdb_out. If it is called from the external debugger,
+% Input/Output are done via MR_debugger_socket_in/MR_debugger_socket_out.
+% In the latter case we need to output terms; their type is
+% term_browser_response.
+
+:- type term_browser_response
+ ---> browser_str(string)
+ ; browser_int(int)
+ ; browser_nl
+ ; browser_end_command
+ ; browser_quit.
+
+:- pred run_param_command(debugger::in, param_cmd::in, bool::in,
+ browser_info::in, browser_info::out, io::di, io::uo) is det.
+
+:- pred show_settings(debugger::in, bool::in, browser_info::in,
+ io::di, io::uo) is det.
+
+:- pred nl_debugger(debugger::in, io::di, io::uo) is det.
+
+:- pred write_string_debugger(debugger::in, string::in, io::di, io::uo) is det.
+
+:- pred write_int_debugger(debugger::in, int::in, io::di, io::uo) is det.
+
+:- pred print_format_debugger(debugger::in, portray_format::in,
+ io::di, io::uo) is det.
+
+:- pred write_path(debugger::in, list(dir)::in, io::di, io::uo) is det.
+
+:- pred send_term_to_socket(term_browser_response::in, io::di, io::uo) is det.
+
:- pred browser_params_to_string(browser_persistent_state::in, bool::in,
string::out) is det.
@@ -319,6 +384,27 @@
set_lines_from_mdb(P, B, A, F, Pr, V, NPr, Lines, !Browser) :-
set_browser_param(no, P, B, A, F, Pr, V, NPr, lines(Lines), !Browser).
+info_set_browse_param(OptionTable, Setting, !Info) :-
+ PersistentState0 = !.Info ^ state,
+ set_browser_param_from_option_table(yes, OptionTable, Setting,
+ PersistentState0, PersistentState),
+ !:Info = !.Info ^ state := PersistentState.
+
+info_set_num_io_actions(N, !Info) :-
+ PersistentState0 = !.Info ^ state,
+ set_num_io_actions(N, PersistentState0, PersistentState),
+ !:Info = !.Info ^ state := PersistentState.
+
+info_set_xml_browser_cmd(Cmd, !Info) :-
+ PersistentState0 = !.Info ^ state,
+ set_xml_browser_cmd_from_mdb(Cmd, PersistentState0, PersistentState),
+ !:Info = !.Info ^ state := PersistentState.
+
+info_set_xml_tmp_filename(FileName, !Info) :-
+ PersistentState0 = !.Info ^ state,
+ set_xml_tmp_filename_from_mdb(FileName, PersistentState0, PersistentState),
+ !:Info = !.Info ^ state := PersistentState.
+
:- pred set_format_from_mdb(bool::in, bool::in, bool::in, portray_format::in,
browser_persistent_state::in, browser_persistent_state::out) is det.
:- pragma export(set_format_from_mdb(in, in, in, in, in, out),
@@ -328,14 +414,32 @@
% Any format flags are ignored for this parameter.
set_browser_param(no, P, B, A, no, no, no, no, format(Format), !Browser).
-:- pred set_num_io_actions_from_mdb(int::in,
- browser_persistent_state::in, browser_persistent_state::out) is det.
-:- pragma export(set_num_io_actions_from_mdb(in, in, out),
- "ML_BROWSE_set_num_io_actions_from_mdb").
+:- pragma export(get_num_io_actions(in, out),
+ "ML_BROWSE_get_num_io_actions").
+
+get_num_io_actions(Browser, NumIOActions) :-
+ NumIOActions = Browser ^ num_printed_io_actions.
-set_num_io_actions_from_mdb(NumIOActions, !Browser) :-
+:- pragma export(set_num_io_actions(in, in, out),
+ "ML_BROWSE_set_num_io_actions").
+
+set_num_io_actions(NumIOActions, !Browser) :-
!:Browser = !.Browser ^ num_printed_io_actions := NumIOActions.
+:- pred get_xml_browser_cmd_from_mdb(browser_persistent_state::in,
+ string::out) is det.
+:- pragma export(get_xml_browser_cmd_from_mdb(in, out),
+ "ML_BROWSE_get_xml_browser_cmd_from_mdb").
+
+get_xml_browser_cmd_from_mdb(Browser, Command) :-
+ MaybeCommand = Browser ^ xml_browser_cmd,
+ (
+ MaybeCommand = no,
+ Command = ""
+ ;
+ MaybeCommand = yes(Command)
+ ).
+
:- pred set_xml_browser_cmd_from_mdb(string::in,
browser_persistent_state::in, browser_persistent_state::out) is det.
:- pragma export(set_xml_browser_cmd_from_mdb(in, in, out),
@@ -348,6 +452,20 @@
!:Browser = !.Browser ^ xml_browser_cmd := yes(Command)
).
+:- pred get_xml_tmp_filename_from_mdb(browser_persistent_state::in,
+ string::out) is det.
+:- pragma export(get_xml_tmp_filename_from_mdb(in, out),
+ "ML_BROWSE_get_xml_tmp_filename_from_mdb").
+
+get_xml_tmp_filename_from_mdb(Browser, FileName) :-
+ MaybeFileName = Browser ^ xml_tmp_filename,
+ (
+ MaybeFileName = no,
+ FileName = ""
+ ;
+ MaybeFileName = yes(FileName)
+ ).
+
:- pred set_xml_tmp_filename_from_mdb(string::in,
browser_persistent_state::in, browser_persistent_state::out) is det.
:- pragma export(set_xml_tmp_filename_from_mdb(in, in, out),
@@ -491,13 +609,6 @@
set_browser_param(FromBrowser, P0, B0, A0, F0, Pr0, V0, NPr0, Setting,
!State) :-
- ( Setting = num_io_actions(NumIoActions) ->
- !:State = !.State ^ num_printed_io_actions := NumIoActions
- ; Setting = xml_browser_cmd(CommandStr) ->
- !:State = !.State ^ xml_browser_cmd := yes(CommandStr)
- ; Setting = xml_tmp_filename(CommandStr) ->
- !:State = !.State ^ xml_tmp_filename := yes(CommandStr)
- ;
(
FromBrowser = no,
default_all_yes(P0, B0, A0, P, B, A)
@@ -524,8 +635,7 @@
maybe_set_param(A, F, Pr, V, NPr, Setting, AParams0, AParams),
!:State = browser_persistent_state(PParams, BParams, AParams,
!.State ^ num_printed_io_actions,
- !.State ^ xml_browser_cmd, !.State ^ xml_tmp_filename)
- ).
+ !.State ^ xml_browser_cmd, !.State ^ xml_tmp_filename).
set_browser_param_maybe_caller_type(FromBrowser, MaybeCallerType,
F0, Pr0, V0, NPr0, Setting, !State) :-
@@ -536,13 +646,13 @@
set_browser_param_from_option_table(FromBrowser, OptionTable, Setting,
!State) :-
set_browser_param(FromBrowser,
- lookup_bool_option(OptionTable, print):bool,
- lookup_bool_option(OptionTable, browse):bool,
- lookup_bool_option(OptionTable, print_all):bool,
- lookup_bool_option(OptionTable, flat):bool,
- lookup_bool_option(OptionTable, raw_pretty):bool,
- lookup_bool_option(OptionTable, verbose):bool,
- lookup_bool_option(OptionTable, pretty):bool,
+ lookup_bool_option(OptionTable, set_print):bool,
+ lookup_bool_option(OptionTable, set_browse):bool,
+ lookup_bool_option(OptionTable, set_print_all):bool,
+ lookup_bool_option(OptionTable, set_flat):bool,
+ lookup_bool_option(OptionTable, set_raw_pretty):bool,
+ lookup_bool_option(OptionTable, set_verbose):bool,
+ lookup_bool_option(OptionTable, set_pretty):bool,
Setting, !State).
:- pred affected_caller_types(bool::in, maybe(browse_caller_type)::in,
@@ -635,12 +745,6 @@
error("maybe_set_param_2: cannot set format here").
maybe_set_param_2(yes, width(W), Params, Params ^ width := W).
maybe_set_param_2(yes, lines(L), Params, Params ^ lines := L).
-maybe_set_param_2(yes, num_io_actions(_), _, _) :-
- error("maybe_set_param_2: num_io_actions").
-maybe_set_param_2(yes, xml_browser_cmd(_), _, _) :-
- error("maybe_set_param_2: xml_browser_cmd").
-maybe_set_param_2(yes, xml_tmp_filename(_), _, _) :-
- error("maybe_set_param_2: xml_tmp_filename").
:- pred get_caller_params(browser_persistent_state::in, browse_caller_type::in,
caller_params::out) is det.
@@ -662,6 +766,218 @@
%---------------------------------------------------------------------------%
+run_param_command(Debugger, ParamCmd, ShowPath, !PersistentState, !IO) :-
+ (
+ ParamCmd = format(MaybeOptionTable, Setting),
+ (
+ MaybeOptionTable = ok(OptionTable),
+ info_set_browse_param(OptionTable, Setting, !PersistentState)
+ ;
+ MaybeOptionTable = error(Msg),
+ write_string_debugger(Debugger, Msg, !IO)
+ )
+ ;
+ ParamCmd = format_param(MaybeOptionTable, Setting),
+ (
+ MaybeOptionTable = ok(OptionTable),
+ info_set_browse_param(OptionTable, Setting, !PersistentState)
+ ;
+ MaybeOptionTable = error(Msg),
+ write_string_debugger(Debugger, Msg, !IO)
+ )
+ ;
+ ParamCmd = num_io_actions(N),
+ info_set_num_io_actions(N, !PersistentState)
+ ;
+ ParamCmd = print_params,
+ show_settings(Debugger, ShowPath, !.PersistentState, !IO)
+% ;
+% ParamCmd = xml_browser_cmd(Cmd),
+% set_xml_browser_cmd(Cmd, !PersistentState)
+% ;
+% ParamCmd = xml_tmp_filename(FileName),
+% set_xml_tmp_filename(FileName, !PersistentState)
+ ).
+
+%---------------------------------------------------------------------------%
+%
+% Display predicates.
+%
+
+show_settings(Debugger, ShowPath, Info, !IO) :-
+ show_settings_caller(Debugger, Info, browse, "Browser", !IO),
+ show_settings_caller(Debugger, Info, print, "Print", !IO),
+ show_settings_caller(Debugger, Info, print_all, "Printall", !IO),
+
+ write_string_debugger(Debugger,
+ "Number of I/O actions printed is: ", !IO),
+ write_int_debugger(Debugger,
+ get_num_printed_io_actions(Info ^ state), !IO),
+ nl_debugger(Debugger, !IO),
+
+ (
+ ShowPath = yes,
+ write_string_debugger(Debugger, "Current path is: ", !IO),
+ write_path(Debugger, Info ^ dirs, !IO),
+ nl_debugger(Debugger, !IO)
+ ;
+ ShowPath = no
+ ).
+
+:- pred show_settings_caller(debugger::in, browser_info::in,
+ browse_caller_type::in, string::in, io::di, io::uo) is det.
+
+show_settings_caller(Debugger, Info, Caller, CallerName, !IO) :-
+ browser_info.get_format(Info, Caller, no, Format),
+ write_string_debugger(Debugger, CallerName ++ " default format: ", !IO),
+ print_format_debugger(Debugger, Format, !IO),
+ nl_debugger(Debugger, !IO),
+
+ write_string_debugger(Debugger, pad_right("", ' ', row_name_len), !IO),
+ write_string_debugger(Debugger, pad_right(" ", ' ', centering_len), !IO),
+ write_string_debugger(Debugger, pad_right("depth", ' ', depth_len), !IO),
+ write_string_debugger(Debugger, pad_right("size", ' ', size_len), !IO),
+ write_string_debugger(Debugger, pad_right("width", ' ', width_len), !IO),
+ write_string_debugger(Debugger, pad_right("lines", ' ', lines_len), !IO),
+ nl_debugger(Debugger, !IO),
+
+ show_settings_caller_format(Debugger, Info, Caller, CallerName,
+ flat, "flat", !IO),
+ show_settings_caller_format(Debugger, Info, Caller, CallerName,
+ verbose, "verbose", !IO),
+ show_settings_caller_format(Debugger, Info, Caller, CallerName,
+ pretty, "pretty", !IO),
+ show_settings_caller_format(Debugger, Info, Caller, CallerName,
+ raw_pretty, "raw_pretty", !IO),
+ nl_debugger(Debugger, !IO).
+
+:- pred show_settings_caller_format(debugger::in, browser_info::in,
+ browse_caller_type::in, string::in, portray_format::in, string::in,
+ io::di, io::uo) is det.
+
+show_settings_caller_format(Debugger, Info, Caller, CallerName,
+ Format, FormatName, !IO) :-
+ browser_info.get_format_params(Info, Caller, Format, Params),
+ write_string_debugger(Debugger,
+ pad_right(CallerName ++ " " ++ FormatName ++ ":", ' ', row_name_len),
+ !IO),
+ write_string_debugger(Debugger,
+ pad_right(" ", ' ', centering_len), !IO),
+ write_string_debugger(Debugger,
+ pad_right(int_to_string(Params ^ depth), ' ', depth_len), !IO),
+ write_string_debugger(Debugger,
+ pad_right(int_to_string(Params ^ size), ' ', size_len), !IO),
+ write_string_debugger(Debugger,
+ pad_right(int_to_string(Params ^ width), ' ', width_len), !IO),
+ write_string_debugger(Debugger,
+ pad_right(int_to_string(Params ^ lines), ' ', lines_len), !IO),
+ nl_debugger(Debugger, !IO).
+
+:- func row_name_len = int.
+:- func centering_len = int.
+:- func depth_len = int.
+:- func size_len = int.
+:- func width_len = int.
+:- func lines_len = int.
+
+row_name_len = 30.
+centering_len = 3.
+depth_len = 10.
+size_len = 10.
+width_len = 10.
+lines_len = 10.
+
+nl_debugger(internal, !IO) :-
+ io.nl(!IO).
+nl_debugger(external, !IO) :-
+ send_term_to_socket(browser_nl, !IO).
+
+write_string_debugger(internal, String, !IO) :-
+ io.write_string(String, !IO).
+write_string_debugger(external, String, !IO) :-
+ send_term_to_socket(browser_str(String), !IO).
+
+write_int_debugger(internal, Int, !IO) :-
+ io.write_int(Int, !IO).
+write_int_debugger(external, Int, !IO) :-
+ send_term_to_socket(browser_int(Int), !IO).
+
+print_format_debugger(internal, X, !IO) :-
+ io.print(X, !IO).
+print_format_debugger(external, X, !IO) :-
+ (
+ X = flat,
+ send_term_to_socket(browser_str("flat"), !IO)
+ ;
+ X = raw_pretty,
+ send_term_to_socket(browser_str("raw_pretty"), !IO)
+ ;
+ X = verbose,
+ send_term_to_socket(browser_str("verbose"), !IO)
+ ;
+ X = pretty,
+ send_term_to_socket(browser_str("pretty"), !IO)
+ ).
+
+write_path(Debugger, [], !IO) :-
+ write_string_debugger(Debugger, "/", !IO).
+write_path(Debugger, [Dir], !IO) :-
+ (
+ Dir = parent,
+ write_string_debugger(Debugger, "/", !IO)
+ ;
+ Dir = child_num(N),
+ write_string_debugger(Debugger, "/", !IO),
+ write_int_debugger(Debugger, N, !IO)
+ ;
+ Dir = child_name(Name),
+ write_string_debugger(Debugger, "/", !IO),
+ write_string_debugger(Debugger, Name, !IO)
+ ).
+write_path(Debugger, [Dir, Dir2 | Dirs], !IO) :-
+ write_path_2(Debugger, [Dir, Dir2 | Dirs], !IO).
+
+:- pred write_path_2(debugger::in, list(dir)::in, io::di, io::uo) is det.
+
+write_path_2(Debugger, [], !IO) :-
+ write_string_debugger(Debugger, "/", !IO).
+write_path_2(Debugger, [Dir], !IO) :-
+ (
+ Dir = parent,
+ write_string_debugger(Debugger, "/..", !IO)
+ ;
+ Dir = child_num(N),
+ write_string_debugger(Debugger, "/", !IO),
+ write_int_debugger(Debugger, N, !IO)
+ ;
+ Dir = child_name(Name),
+ write_string_debugger(Debugger, "/", !IO),
+ write_string_debugger(Debugger, Name, !IO)
+ ).
+write_path_2(Debugger, [Dir, Dir2 | Dirs], !IO) :-
+ (
+ Dir = parent,
+ write_string_debugger(Debugger, "/..", !IO),
+ write_path_2(Debugger, [Dir2 | Dirs], !IO)
+ ;
+ Dir = child_num(N),
+ write_string_debugger(Debugger, "/", !IO),
+ write_int_debugger(Debugger, N, !IO),
+ write_path_2(Debugger, [Dir2 | Dirs], !IO)
+ ;
+ Dir = child_name(Name),
+ write_string_debugger(Debugger, "/", !IO),
+ write_string_debugger(Debugger, Name, !IO),
+ write_path_2(Debugger, [Dir2 | Dirs], !IO)
+ ).
+
+send_term_to_socket(Term, !IO) :-
+ write(Term, !IO),
+ print(".\n", !IO),
+ flush_output(!IO).
+
+%---------------------------------------------------------------------------%
+
:- pragma export(browser_params_to_string(in, in, out),
"ML_BROWSE_browser_params_to_string").
@@ -671,11 +987,11 @@
(
MDBCommandFormat = yes,
ParamCmds =
- caller_params_to_mdb_command("-P", PrintParams) ++
- caller_params_to_mdb_command("-B", BrowseParams) ++
- caller_params_to_mdb_command("-A", PrintAllParams),
+ caller_params_to_mdb_command("-P ", PrintParams) ++
+ caller_params_to_mdb_command("-B ", BrowseParams) ++
+ caller_params_to_mdb_command("-A ", PrintAllParams),
NumIOActionCmd =
- "set max_io_actions " ++ int_to_string(NumIOActions) ++ "\n",
+ "max_io_actions " ++ int_to_string(NumIOActions) ++ "\n",
(
MaybeXMLBrowserCmd = yes(XMLBrowserCmd),
% XMLBrowserCmd shouldn't be "" if MaybeXMLBrowserCmd is yes,
@@ -683,7 +999,7 @@
XMLBrowserCmd \= ""
->
XMLBrowserCmdCmd =
- "set xml_browser_cmd " ++ XMLBrowserCmd ++ "\n"
+ "xml_browser_cmd " ++ XMLBrowserCmd ++ "\n"
;
XMLBrowserCmdCmd = ""
),
@@ -694,7 +1010,7 @@
XMLTmpFileName \= ""
->
XMLTmpFileNameCmd =
- "set xml_tmp_filename " ++ XMLTmpFileName ++ "\n"
+ "xml_tmp_filename " ++ XMLTmpFileName ++ "\n"
;
XMLTmpFileNameCmd = ""
),
@@ -735,15 +1051,15 @@
:- func caller_params_to_mdb_command(string, caller_params) = string.
caller_params_to_mdb_command(CallerOpt, CallerParams) = Cmds :-
- CmdCallerOpt = "set " ++ CallerOpt ++ " ",
CallerParams = caller_params(Format, FlatParams, RawPrettyParams,
VerboseParams, PrettyParams),
- FormatCmd = CmdCallerOpt ++ "format " ++ format_to_string(Format) ++ "\n",
+ FormatCmd = "format " ++ CallerOpt ++ format_to_string(Format) ++ "\n",
+ CmdPrefix = "format_param " ++ CallerOpt,
FormatParamCmds =
- format_params_to_mdb_command(CmdCallerOpt ++ "-f ", FlatParams) ++
- format_params_to_mdb_command(CmdCallerOpt ++ "-r ", RawPrettyParams) ++
- format_params_to_mdb_command(CmdCallerOpt ++ "-v ", VerboseParams) ++
- format_params_to_mdb_command(CmdCallerOpt ++ "-p ", PrettyParams),
+ format_params_to_mdb_command(CmdPrefix ++ "-f ", FlatParams) ++
+ format_params_to_mdb_command(CmdPrefix ++ "-r ", RawPrettyParams) ++
+ format_params_to_mdb_command(CmdPrefix ++ "-v ", VerboseParams) ++
+ format_params_to_mdb_command(CmdPrefix ++ "-p ", PrettyParams),
Cmds = FormatCmd ++ FormatParamCmds.
:- func caller_params_to_desc(caller_params) = string.
Index: browser/declarative_user.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/browser/declarative_user.m,v
retrieving revision 1.59
diff -u -b -r1.59 declarative_user.m
--- browser/declarative_user.m 31 Mar 2006 05:12:10 -0000 1.59
+++ browser/declarative_user.m 4 Apr 2006 01:12:48 -0000
@@ -125,6 +125,72 @@
%-----------------------------------------------------------------------------%
+:- type user_command
+ ---> yes
+ % The node is correct.
+
+ ; no
+ % The node is erroneous.
+
+ ; inadmissible
+ % The node is inadmissible.
+
+ ; skip
+ % The user has no answer.
+
+ ; browse_arg(maybe(int))
+ % Browse the nth argument before answering. Or browse
+ % the whole predicate/function if the maybe is no.
+
+ ; browse_xml_arg(maybe(int))
+ % Browse the argument using an XML browser.
+
+ ; browse_io(int)
+ % Browse the nth IO action before answering.
+
+ ; print_arg(int, int)
+ % Print the nth to the mth arguments before answering.
+
+ ; print_io(int, int)
+ % Print the nth to the mth IO actions before answering.
+
+ ; pd
+ % Commence procedural debugging from this point.
+
+ ; param_command(param_cmd)
+
+ ; trust_predicate
+ % Trust the predicate being asked about.
+
+ ; trust_module
+ % Trust the module being asked about.
+
+ ; info
+ % Print some information about the current question.
+
+ ; undo
+ % Undo the user's last answer.
+
+ ; ask
+ % The user wants the current question re-asked.
+
+ ; change_search(user_search_mode)
+ % Change the current search strategy.
+
+ ; quit
+ % Abort this diagnosis session.
+
+ ; help(maybe(string))
+ % Request help before answering. If the maybe argument
+ % is no then a general help message is displayed,
+ % otherwise help on the given command is displayed.
+
+ ; empty_command
+ % User just pressed return.
+
+ ; illegal_command.
+ % None of the above.
+
:- type user_state
---> user(
instr :: io.input_stream,
@@ -264,17 +330,14 @@
print_atom_arguments(TraceAtom, From, To, !.User, !IO),
query_user(UserQuestion, Response, !User, !IO).
-handle_command(set(MaybeOptionTable, Setting), UserQuestion, Response, !User,
- !IO) :-
- (
- MaybeOptionTable = ok(OptionTable),
- set_browser_param_from_option_table(no, OptionTable, Setting,
- !.User ^ browser, Browser),
- !:User = !.User ^ browser := Browser
- ;
- MaybeOptionTable = error(Msg),
- io.write_string(Msg++"\n", !IO)
- ),
+handle_command(param_command(ParamCommand), UserQuestion, Response,
+ !User, !IO) :-
+ Browser0 = !.User ^ browser,
+ DummyTerm = synthetic_term("", [], no),
+ Info0 = browser_info(DummyTerm, [], browse, no, Browser0, no_track, no),
+ run_param_command(internal, ParamCommand, no, Info0, Info, !IO),
+ Info = browser_info(_, _, _, _, Browser, _, _),
+ !:User = !.User ^ browser := Browser,
query_user(UserQuestion, Response, !User, !IO).
handle_command(trust_predicate, UserQuestion, trust_predicate(Question),
@@ -770,73 +833,6 @@
%-----------------------------------------------------------------------------%
-:- type user_command
- ---> yes
- % The node is correct.
-
- ; no
- % The node is erroneous.
-
- ; inadmissible
- % The node is inadmissible.
-
- ; skip
- % The user has no answer.
-
- ; browse_arg(maybe(int))
- % Browse the nth argument before answering. Or browse
- % the whole predicate/function if the maybe is no.
-
- ; browse_xml_arg(maybe(int))
- % Browse the argument using an XML browser.
-
- ; browse_io(int)
- % Browse the nth IO action before answering.
-
- ; print_arg(int, int)
- % Print the nth to the mth arguments before answering.
-
- ; print_io(int, int)
- % Print the nth to the mth IO actions before answering.
-
- ; pd
- % Commence procedural debugging from this point.
-
- ; set(maybe_option_table(setting_option), setting)
- % Set a browser option.
-
- ; trust_predicate
- % Trust the predicate being asked about.
-
- ; trust_module
- % Trust the module being asked about.
-
- ; info
- % Print some information about the current question.
-
- ; undo
- % Undo the user's last answer.
-
- ; ask
- % The user wants the current question re-asked.
-
- ; change_search(user_search_mode)
- % Change the current search strategy.
-
- ; quit
- % Abort this diagnosis session.
-
- ; help(maybe(string))
- % Request help before answering. If the maybe argument
- % is no then a general help message is displayed,
- % otherwise help on the given command is displayed.
-
- ; empty_command
- % User just pressed return.
-
- ; illegal_command.
- % None of the above.
-
:- pred user_confirm_bug_help(user_state::in, io::di, io::uo) is det.
user_confirm_bug_help(User, !IO) :-
@@ -909,7 +905,14 @@
cmd_handler("browse", browse_arg_cmd).
cmd_handler("p", print_arg_cmd).
cmd_handler("print", print_arg_cmd).
-cmd_handler("set", set_arg_cmd).
+cmd_handler("format", format_arg_cmd).
+cmd_handler("depth", format_param_arg_cmd("depth")).
+cmd_handler("size", format_param_arg_cmd("size")).
+cmd_handler("width", format_param_arg_cmd("width")).
+cmd_handler("lines", format_param_arg_cmd("lines")).
+cmd_handler("num_io_actions", num_io_actions_cmd).
+% cmd_handler("xml_browser_cmd", set_xml_browser_cmd_cmd).
+% cmd_handler("xml_tmp_filename", set_xml_tmp_filename_cmd).
cmd_handler("t", trust_arg_cmd).
cmd_handler("trust", trust_arg_cmd).
cmd_handler("mode", search_mode_cmd).
@@ -946,13 +949,36 @@
print_arg_cmd(["io", Arg]) = print_io(From, To) :-
string_to_range(Arg, From, To).
-:- pred string_to_range(string::in, int::out, int::out) is semidet.
+:- func format_arg_cmd(list(string)::in) = (user_command::out) is semidet.
+
+format_arg_cmd(ArgWords) = param_command(format(MaybeOptionTable, Setting)) :-
+ ArgWords \= [],
+ parse.parse(["format" | ArgWords],
+ param_command(format(MaybeOptionTable, Setting))).
-:- func set_arg_cmd(list(string)::in) = (user_command::out) is semidet.
+:- func format_param_arg_cmd(string::in, list(string)::in)
+ = (user_command::out) is semidet.
-set_arg_cmd(ArgWords) = set(MaybeOptionTable, Setting) :-
+format_param_arg_cmd(Cmd, ArgWords)
+ = param_command(format_param(MaybeOptionTable, Setting)) :-
ArgWords \= [],
- parse.parse(["set" | ArgWords], set(MaybeOptionTable, Setting)).
+ parse.parse([Cmd | ArgWords],
+ param_command(format_param(MaybeOptionTable, Setting))).
+
+:- func num_io_actions_cmd(list(string)::in) = (user_command::out) is semidet.
+
+num_io_actions_cmd([Arg]) = param_command(num_io_actions(N)) :-
+ string.to_int(Arg, N).
+
+% :- func set_xml_browser_cmd_cmd(list(string)::in) = (user_command::out)
+% is semidet.
+%
+% set_xml_browser_cmd_cmd([Arg]) = param_command(xml_browser_cmd(Arg)).
+%
+% :- func set_xml_tmp_filename_cmd(list(string)::in) = (user_command::out)
+% is semidet.
+%
+% set_xml_tmp_filename_cmd([Arg]) = param_command(xml_tmp_filename(Arg)).
:- func trust_arg_cmd(list(string)::in) = (user_command::out) is semidet.
@@ -980,6 +1006,8 @@
help_cmd([]) = help(no).
help_cmd([Cmd]) = help(yes(Cmd)).
+
+:- pred string_to_range(string::in, int::out, int::out) is semidet.
string_to_range(Arg, From, To) :-
( string.to_int(Arg, Num) ->
Index: browser/listing.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/browser/listing.m,v
retrieving revision 1.4
diff -u -b -r1.4 listing.m
--- browser/listing.m 31 Mar 2006 05:12:10 -0000 1.4
+++ browser/listing.m 1 Apr 2006 06:59:40 -0000
@@ -89,6 +89,7 @@
:- import_module int.
:- import_module map.
:- import_module maybe.
+:- import_module type_desc.
%-----------------------------------------------------------------------------%
@@ -112,6 +113,12 @@
"ML_LISTING_pop_list_path").
:- pragma export(list_file(in, in, in, in, in, in, in, di, uo),
"ML_LISTING_list_file").
+
+:- pred listing_type(type_desc::out) is det.
+:- pragma export(listing_type(out), "ML_LISTING_listing_type").
+
+listing_type(type_of(Path)) :-
+ clear_list_path(Path @ [], _).
%-----------------------------------------------------------------------------%
Index: browser/parse.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/browser/parse.m,v
retrieving revision 1.28
diff -u -b -r1.28 parse.m
--- browser/parse.m 29 Mar 2006 08:06:32 -0000 1.28
+++ browser/parse.m 2 Apr 2006 17:21:38 -0000
@@ -35,7 +35,13 @@
% "p" [formatoptions] [path] // short for print
% "display"
% "write"
-% "set" [[setoptions] varvalue]
+% "format" [formatcmdoptions] fmt
+% "depth" [formatparamcmdoptions] value
+% "size" [formatparamcmdoptions] value
+% "width" [formatparamcmdoptions] value
+% "lines" [formatparamcmdoptions] value
+% "num_io_actions" int
+% "params"
% "track" [--accurate] [path]
% "t" [--accurate] [path]
% "mark" [--accurate] [path]
@@ -57,11 +63,23 @@
% --verbose
% --pretty
%
-% setoptions:
+% formatcmdoptions:
% /* empty */
-% setoption setoptions
+% formatcmdoption formatcmdoptions
%
-% setoption:
+% formatcmdoption:
+% -P
+% -B
+% -A
+% --print
+% --browse
+% --print-all
+%
+% formatparamcmdoptions:
+% /* empty */
+% formatparamcmdoption formatparamcmdoptions
+%
+% formatparamcmdoption:
% -P
% -B
% -A
@@ -77,18 +95,6 @@
% --verbose
% --pretty
%
-% varvalue:
-% "depth" num
-% "size" num
-% "clipx" num
-% "clipy" num
-% "format" fmt
-% "num_io_actions" num
-%
-% numlist:
-% num
-% num numlist
-%
% fmt:
% "flat"
% "raw_pretty"
@@ -129,14 +135,19 @@
; mode_query
; pwd
; help
- ; set(maybe_option_table(setting_option), setting)
- ; set
+ ; param_command(param_cmd)
; quit
; display
; write
; empty
; unknown.
+:- type format_param_cmd
+ ---> param_depth
+ ; param_size
+ ; param_width
+ ; param_lines.
+
:- type path
---> root_rel(list(dir))
; dot_rel(list(dir)).
@@ -148,13 +159,13 @@
; pretty.
:- type setting_option
- ---> print
- ; browse
- ; print_all
- ; flat
- ; raw_pretty
- ; verbose
- ; pretty.
+ ---> set_print
+ ; set_browse
+ ; set_print_all
+ ; set_flat
+ ; set_raw_pretty
+ ; set_verbose
+ ; set_pretty.
% If the term browser is called from the external debugger, the term
% browser commands are send through the socket via terms of type
@@ -178,10 +189,13 @@
:- import_module mdb.util.
+:- import_module assoc_list.
:- import_module bool.
:- import_module char.
:- import_module int.
:- import_module list.
+:- import_module map.
+:- import_module pair.
:- type token
---> (.)
@@ -442,23 +456,63 @@
Command = mode_query(Path)
)
;
- CmdToken = name("set")
+ CmdToken = name("format")
+ ->
+ (
+ ArgTokens = [],
+ Command = param_command(print_params)
+ ;
+ ArgTokens = [_ | _],
+ MaybeArgWords = yes(ArgWords),
+ OptionOps = option_ops_multi(short_format_cmd_option,
+ long_format_cmd_option, format_cmd_option_defaults),
+ getopt.process_options(OptionOps, ArgWords,
+ RemainingWords, MaybeOptionTable),
+ lexer_words(RemainingWords, RemainingTokens),
+ parse_format(RemainingTokens, Setting),
+ Command = param_command(format(MaybeOptionTable, Setting))
+ )
+ ;
+ (
+ CmdToken = name("depth"),
+ ParamCmd = param_depth
+ ;
+ CmdToken = name("size"),
+ ParamCmd = param_size
+ ;
+ CmdToken = name("width"),
+ ParamCmd = param_width
+ ;
+ CmdToken = name("lines"),
+ ParamCmd = param_lines
+ )
->
(
ArgTokens = [],
- Command = set
+ Command = param_command(print_params)
;
ArgTokens = [_ | _],
MaybeArgWords = yes(ArgWords),
- OptionOps = option_ops_multi(short_setting_option,
- long_setting_option, setting_option_defaults),
+ OptionOps = option_ops_multi(short_format_param_cmd_option,
+ long_format_param_cmd_option,
+ format_param_cmd_option_defaults),
getopt.process_options(OptionOps, ArgWords,
RemainingWords, MaybeOptionTable),
lexer_words(RemainingWords, RemainingTokens),
- parse_setting(RemainingTokens, Setting),
- Command = set(MaybeOptionTable, Setting)
+ RemainingTokens = [num(N)],
+ param_cmd_to_setting(ParamCmd, N, Setting),
+ Command = param_command(format_param(MaybeOptionTable, Setting))
)
;
+ CmdToken = name("params")
+ ->
+ Command = param_command(print_params)
+ ;
+ CmdToken = name("num_io_actions")
+ ->
+ ArgTokens = [num(N)],
+ Command = param_command(num_io_actions(N))
+ ;
CmdToken = name("quit")
->
ArgTokens = [],
@@ -509,15 +563,22 @@
CmdToken = (<)
->
ArgTokens = [num(Depth)],
- % compute the default MaybeOptionTable
- OptionOps = option_ops_multi(short_setting_option,
- long_setting_option, setting_option_defaults),
+ OptionOps = option_ops_multi(short_format_param_cmd_option,
+ long_format_param_cmd_option, format_param_cmd_option_defaults),
getopt.process_options(OptionOps, [], _, MaybeOptionTable),
- Command = set(MaybeOptionTable, depth(Depth))
+ Command = param_command(format_param(MaybeOptionTable, depth(Depth)))
;
fail
).
+:- pred param_cmd_to_setting(format_param_cmd::in, int::in, setting::out)
+ is det.
+
+param_cmd_to_setting(param_depth, N, depth(N)).
+param_cmd_to_setting(param_size, N, size(N)).
+param_cmd_to_setting(param_width, N, width(N)).
+param_cmd_to_setting(param_lines, N, lines(N)).
+
:- pred parse_path(list(token)::in, path::out) is semidet.
% SICStus is forgiving in the syntax of paths, hence so are we.
@@ -558,9 +619,24 @@
parse_dirs(Tokens, Dirs)
).
-:- pred parse_setting(list(token)::in, setting::out) is semidet.
+:- pred parse_format(list(token)::in, setting::out) is semidet.
-parse_setting([Token | Tokens], Setting) :-
+parse_format([Fmt], Setting) :-
+ ( Fmt = name("flat") ->
+ Setting = format(flat)
+ ; Fmt = name("raw_pretty") ->
+ Setting = format(raw_pretty)
+ ; Fmt = name("verbose") ->
+ Setting = format(verbose)
+ ; Fmt = name("pretty") ->
+ Setting = format(pretty)
+ ;
+ fail
+ ).
+
+:- pred parse_format_param(list(token)::in, setting::out) is semidet.
+
+parse_format_param([Token | Tokens], Setting) :-
( Token = name("depth") ->
Tokens = [num(Depth)],
Setting = depth(Depth)
@@ -573,21 +649,6 @@
; Token = name("lines") ->
Tokens = [num(Y)],
Setting = lines(Y)
- ; Token = name("num_io_actions") ->
- Tokens = [num(Y)],
- Setting = num_io_actions(Y)
- ; Token = name("format") ->
- Tokens = [Fmt],
- ( Fmt = name("flat") ->
- Setting = format(flat)
- ; Fmt = name("raw_pretty") ->
- Setting = format(raw_pretty)
- ; Fmt = name("verbose") ->
- Setting = format(verbose)
- ;
- Fmt = name("pretty"),
- Setting = format(pretty)
- )
;
fail
).
@@ -617,36 +678,63 @@
%---------------------------------------------------------------------------%
-:- pred short_setting_option(char::in, setting_option::out) is semidet.
+:- pred short_format_cmd_option(char::in, setting_option::out) is semidet.
+
+short_format_cmd_option('P', set_print).
+short_format_cmd_option('B', set_browse).
+short_format_cmd_option('A', set_print_all).
-short_setting_option('P', print).
-short_setting_option('B', browse).
-short_setting_option('A', print_all).
-short_setting_option('f', flat).
-short_setting_option('r', raw_pretty).
-short_setting_option('v', verbose).
-short_setting_option('p', pretty).
-
-:- pred long_setting_option(string::in, setting_option::out) is semidet.
-
-long_setting_option("print", print).
-long_setting_option("browse", browse).
-long_setting_option("print-all", print_all).
-long_setting_option("flat", flat).
-long_setting_option("raw-pretty", raw_pretty).
-long_setting_option("verbose", verbose).
-long_setting_option("pretty", pretty).
+:- pred long_format_cmd_option(string::in, setting_option::out) is semidet.
-:- pred setting_option_defaults(setting_option::out, option_data::out)
+long_format_cmd_option("print", set_print).
+long_format_cmd_option("browse", set_browse).
+long_format_cmd_option("print-all", set_print_all).
+
+:- pred format_cmd_option_defaults(setting_option::out, option_data::out)
is multi.
-setting_option_defaults(print, bool(no)).
-setting_option_defaults(browse, bool(no)).
-setting_option_defaults(print_all, bool(no)).
-setting_option_defaults(flat, bool(no)).
-setting_option_defaults(raw_pretty, bool(no)).
-setting_option_defaults(verbose, bool(no)).
-setting_option_defaults(pretty, bool(no)).
+format_cmd_option_defaults(set_print, bool(no)).
+format_cmd_option_defaults(set_browse, bool(no)).
+format_cmd_option_defaults(set_print_all, bool(no)).
+format_cmd_option_defaults(set_flat, bool(no)).
+format_cmd_option_defaults(set_raw_pretty, bool(no)).
+format_cmd_option_defaults(set_verbose, bool(no)).
+format_cmd_option_defaults(set_pretty, bool(no)).
+
+%---------------------------------------------------------------------------%
+
+:- pred short_format_param_cmd_option(char::in, setting_option::out)
+ is semidet.
+
+short_format_param_cmd_option('P', set_print).
+short_format_param_cmd_option('B', set_browse).
+short_format_param_cmd_option('A', set_print_all).
+short_format_param_cmd_option('f', set_flat).
+short_format_param_cmd_option('r', set_raw_pretty).
+short_format_param_cmd_option('v', set_verbose).
+short_format_param_cmd_option('p', set_pretty).
+
+:- pred long_format_param_cmd_option(string::in, setting_option::out)
+ is semidet.
+
+long_format_param_cmd_option("print", set_print).
+long_format_param_cmd_option("browse", set_browse).
+long_format_param_cmd_option("print-all", set_print_all).
+long_format_param_cmd_option("flat", set_flat).
+long_format_param_cmd_option("raw-pretty", set_raw_pretty).
+long_format_param_cmd_option("verbose", set_verbose).
+long_format_param_cmd_option("pretty", set_pretty).
+
+:- pred format_param_cmd_option_defaults(setting_option::out,
+ option_data::out) is multi.
+
+format_param_cmd_option_defaults(set_print, bool(no)).
+format_param_cmd_option_defaults(set_browse, bool(no)).
+format_param_cmd_option_defaults(set_print_all, bool(no)).
+format_param_cmd_option_defaults(set_flat, bool(no)).
+format_param_cmd_option_defaults(set_raw_pretty, bool(no)).
+format_param_cmd_option_defaults(set_verbose, bool(no)).
+format_param_cmd_option_defaults(set_pretty, bool(no)).
%---------------------------------------------------------------------------%
@@ -676,12 +764,6 @@
% io.write_string("pwd\n").
% show_command(help) -->
% io.write_string("help\n").
-% show_command(set(Setting)) -->
-% io.write_string("set "),
-% show_setting(Setting),
-% io.nl.
-% show_command(set) -->
-% io.write_string("set\n").
% show_command(quit) -->
% io.write_string("quit\n").
% show_command(print) -->
cvs diff: Diffing bytecode
cvs diff: Diffing compiler
cvs diff: Diffing compiler/notes
cvs diff: Diffing debian
cvs diff: Diffing debian/patches
cvs diff: Diffing deep_profiler
cvs diff: Diffing deep_profiler/notes
cvs diff: Diffing doc
Index: doc/mdb_categories
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/doc/mdb_categories,v
retrieving revision 1.31
diff -u -b -r1.31 mdb_categories
--- doc/mdb_categories 31 Mar 2006 05:12:12 -0000 1.31
+++ doc/mdb_categories 1 Apr 2006 08:33:47 -0000
@@ -27,7 +27,7 @@
browsing - Commands that let users explore the state of the computation.
The browsing commands are `vars', `held_vars', `print', `browse',
`stack', `up', `down', `level', `current', `view', `hold',
- `diff', `dump', `list', `push_list_dir' and `pop_list_dir'.
+ `diff', `dump', and `list'.
end
document_category 500 breakpoint
@@ -43,9 +43,12 @@
end
document_category 700 parameter
parameter - Commands that let users access debugger parameters.
- The parameter commands are `set', `printlevel', `echo', `context',
- `goal_paths' `scroll', `mmc_options', `scope', `alias',
- `unalias', and `stack_default_limit'.
+ The parameter commands are `mmc_options', `printlevel', `scroll',
+ `stack_default_limit', `goal_paths' `scope', `echo',
+ `context', `list_context_lines', `list_path', `push_list_dir',
+ `pop_list_dir', `fail_trace_counts', `pass_trace_counts',
+ `max_io_actions', `xml_browser_cmd', `xml_tmp_filename',
+ `format', `format_param', `alias' and `unalias'.
end
document_category 800 help
Index: doc/user_guide.texi
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/doc/user_guide.texi,v
retrieving revision 1.472
diff -u -b -r1.472 user_guide.texi
--- doc/user_guide.texi 31 Mar 2006 05:12:12 -0000 1.472
+++ doc/user_guide.texi 2 Apr 2006 06:46:38 -0000
@@ -1571,8 +1571,12 @@
The else part of an if-then-else.
@item ~
The goal inside a negation.
+ at item q!
+The goal inside an existential quantification or other scope
+that changes the determinism of the goal.
@item q
-The goal inside an existential quantification.
+The goal inside an existential quantification or other scope
+that doesn't change the determinism of the goal.
@end table
A path describes the position of a goal
@@ -2073,9 +2077,9 @@
that specifies whether the procedure belongs
to a unify, compare, index or init predicate.
@item
-An optional prefix of the form @samp{@var{module}:}, @samp{@var{module}.}
-or @samp{@var{module}__} that specifies the name of the module that defines
-the predicate or function to which the procedure belongs.
+An optional prefix of the form @samp{@var{module}.} or @samp{@var{module}__}
+that specifies the name of the module that defines the predicate or function
+to which the procedure belongs.
@item
The name of the type constructor.
@item
@@ -2878,16 +2882,6 @@
Lists the source code text for the current environment, including
@var{num} preceding and following lines. If @var{num} is not provided then
the default of two is used.
- at sp 1
- at item push_list_dir @var{dir1} @var{dir2} ...
- at kindex push_list_dir (mdb command)
-The @samp{list} command searches a list of directories when looking for a
-source code file. The @samp{push_list_dir} pushes one or more such
-directories on to this list.
- at sp 1
- at item pop_list_dir
- at kindex pop_list_dir (mdb command)
-Pops the most recent @samp{push_list_dir}' directory from the search list.
@end table
@sp 1
@@ -3158,12 +3152,14 @@
@kindex procedures (mdb command)
Lists all the procedures in the debuggable module @var{module}.
@sp 1
- at item register
+ at item register [-q]
@kindex register (mdb command)
Registers all debuggable modules with the debugger.
Has no effect if this registration has already been done.
The debugger will perform this registration when creating breakpoints
and when listing debuggable modules and/or procedures.
+The command will print a message to this effect
+unless the @samp{-q} or @samp{--quiet} option is given.
@end table
@sp 1
@@ -3219,16 +3215,6 @@
@item printlevel
Reports the current default print level.
@sp 1
- at item echo on
- at kindex echo (mdb command)
-Turns on the echoing of commands.
- at sp 1
- at item echo off
-Turns off the echoing of commands.
- at sp 1
- at item echo
-Reports whether commands are being echoed or not.
- at sp 1
@item scroll on
@kindex scroll (mdb command)
Turns on user control over the scrolling of sequences of event reports.
@@ -3263,6 +3249,45 @@
the @samp{stack} and @samp{nondet_stack} commands to @var{size}.
If @var{size} is zero, the limit is disabled.
@sp 1
+ at item goal_paths on
+ at kindex goal_path (mdb command)
+Turns on printing of goal paths at events.
+ at sp 1
+ at item goal_paths off
+Turns off printing of goal paths at events.
+ at sp 1
+ at item goal_paths
+Reports whether goal paths are printed at events.
+ at sp 1
+ at item scope all
+ at kindex scope (mdb command)
+Sets the default scope of new breakpoints to ``all'',
+i.e.@: by default, new breakpoints on procedures
+will stop at all events in the procedure.
+ at sp 1
+ at item scope interface
+Sets the default scope of new breakpoints to ``interface'',
+i.e.@: by default, new breakpoints on procedures
+will stop at all interface events in the procedure.
+ at sp 1
+ at item scope entry
+Sets the default scope of new breakpoints to ``entry'',
+i.e.@: by default, new breakpoints on procedures
+will stop only at events representing calls to the procedure.
+ at sp 1
+ at item scope
+Reports the current default scope of new breakpoints.
+ at sp 1
+ at item echo on
+ at kindex echo (mdb command)
+Turns on the echoing of commands.
+ at sp 1
+ at item echo off
+Turns off the echoing of commands.
+ at sp 1
+ at item echo
+Reports whether commands are being echoed or not.
+ at sp 1
@item context none
@kindex context (mdb command)
@cindex line numbers
@@ -3299,33 +3324,175 @@
@item context
Reports where contexts are being printed.
@sp 1
- at item goal_paths on
- at kindex goal_path (mdb command)
-Turns on printing of goal paths at events.
+ at item list_context_lines @var{num}
+ at kindex list_context_lines (mdb command)
+Sets the number of lines to be printed by the @samp{list} command
+printed before and after the target context.
@sp 1
- at item goal_paths off
-Turns off printing of goal paths at events.
+ at item list_context_lines
+Prints the number of lines to be printed by the @samp{list} command
+printed before and after the target context.
@sp 1
- at item goal_paths
-Reports whether goal paths are printed at events.
+ at item list_path @var{dir1} @var{dir2} ...
+ at kindex list_path (mdb command)
+The @samp{list} command searches a list of directories
+when looking for a source code file.
+The @samp{list_path} command sets the search path
+to the given list of directories.
+ at sp 1
+ at item list_path
+When invoked without arguments, the @samp{list_path} command
+prints the search path consulted by the @samp{list} command.
@sp 1
- at item scope all
-Sets the default scope of new breakpoints to ``all'',
-i.e.@: by default, new breakpoints on procedures
-will stop at all events in the procedure.
+ at item push_list_dir @var{dir1} @var{dir2} ...
+ at kindex push_list_dir (mdb command)
+Pushes the given directories
+on to the search path consulted by the @samp{list} command.
@sp 1
- at item scope interface
-Sets the default scope of new breakpoints to ``interface'',
-i.e.@: by default, new breakpoints on procedures
-will stop at all interface events in the procedure.
+ at item pop_list_dir
+ at kindex pop_list_dir (mdb command)
+Pops the leftmost (most recently pushed) directory
+from the search path consulted by the @samp{list} command.
@sp 1
- at item scope entry
-Sets the default scope of new breakpoints to ``entry'',
-i.e.@: by default, new breakpoints on procedures
-will stop only at events representing calls to the procedure.
+ at item fail_trace_counts @var{filename}
+ at kindex fail_trace_counts (mdb command)
+The declarative debugger can exploit information
+about the failing and passing test cases to ask better questions.
+This command tells the @samp{dice} command
+that @var{filename} contains execution trace counts from failing test cases.
+The @samp{dice} command will use this file
+unless this is overridden with its @samp{--fail-trace-counts} option.
+ at sp 1
+ at item fail_trace_counts
+Prints the name of the file containing
+execution trace counts from failing test cases,
+if this has already been set.
@sp 1
- at item scope
-Reports the current default scope of new breakpoints.
+ at item pass_trace_counts @var{filename}
+ at kindex pass_trace_counts (mdb command)
+The declarative debugger can exploit information
+about the failing and passing test cases to ask better questions.
+This command tells the @samp{dice} command
+that @var{filename} contains execution trace counts from passing test cases.
+The @samp{dice} command will use this file
+unless this is overridden with its @samp{--pass-trace-counts} option.
+ at sp 1
+ at item pass_trace_counts
+Prints the name of the file containing
+execution trace counts from passing test cases,
+if this has already been set.
+ at sp 1
+ at item max_io_actions @var{num}
+ at kindex max_io_actions (mdb command)
+Set the maximum number of I/O actions to print
+in questions from the declarative debugger to @var{num}.
+ at sp 1
+ at item max_io_actions
+Prints the maximum number of I/O actions to print
+in questions from the declarative debugger.
+ at sp 1
+ at item xml_browser_cmd @var{command}
+ at kindex xml_browser_cmd (mdb command)
+Set the shell command used to launch an XML browser to @var{command}.
+If you want a stylesheet to be applied to the XML
+before the browser is invoked,
+then you should do that in this command using the appropriate program
+(such as xsltproc, which comes with libxslt
+and is available from http://xmlsoft.org/XSLT/).
+By default if xsltproc and mozilla (or firefox) are available,
+xsltproc is invoked to apply the xul_tree.xsl stylesheet in
+extras/xml_stylesheets, then mozilla is invoked on the resulting XUL file.
+ at sp 1
+You can use the apostrophe character (') to quote the command string,
+for example "xml_browser_cmd 'firefox file:///tmp/mdbtmp.xml'".
+ at sp 1
+ at item xml_browser_cmd
+Prints the shell command used to launch an XML browser,
+if this has been set.
+ at sp 1
+ at item xml_tmp_filename @var{filename}
+ at kindex xml_tmp_filename (mdb command)
+Tells the debugger to dump XML into the named file
+before invoking the XML browser.
+The command named as the argument of @samp{xml_browser_cmd}
+will usually refer to this file.
+ at sp 1
+ at item xml_tmp_filename
+Prints the temporary filename used for XML browsing,
+if this has been set.
+ at sp 1
+ at item format [-APB] @var{format}
+ at kindex format (mdb command)
+Sets the default format of the browser to @var{format},
+which should be one of @samp{flat}, @samp{pretty} and @samp{verbose}.
+ at sp 1
+The browser maintains separate configuration parameters
+for the three commands @samp{print *}, @samp{print @var{var}},
+and @samp{browse @var{var}}.
+A @samp{format} command applies to all three,
+unless it specifies one or more of the options
+ at samp{-A} or @samp{--print-all},
+ at samp{-P} or @samp{--print},
+and @samp{-B} or @samp{--browse},
+in which case it will set only the selected command's default format.
+ at sp 1
+ at item format_param [-APBfpv] @var{param} @var{value}
+ at kindex format_param (mdb command)
+ at kindex depth (mdb command)
+ at kindex size (mdb command)
+ at kindex width (mdb command)
+ at kindex lines (mdb command)
+Sets one of the parameters of the browser to the given value.
+The parameter @var{param} must be one of
+ at samp{depth}, @samp{size}, @samp{width} and @samp{lines}.
+ at sp 1
+ at itemize @bullet
+ at item
+ at samp{depth} is the maximum depth to which subterms will be displayed.
+Subterms at the depth limit may be abbreviated as functor/arity,
+or (in lists) may be replaced by an ellipsis (@samp{...}).
+The principal functor of any term has depth zero.
+For subterms which are not lists,
+the depth of any argument of the functor is one greater than the
+depth of the functor.
+For subterms which are lists,
+the depth of each element of the list
+is one greater than the depth of the list.
+ at sp 1
+ at item
+ at samp{size} is the suggested maximum number of functors to display.
+Beyond this limit, subterms may be abbreviated as functor/arity,
+or (in lists) may be replaced by an ellipsis (@samp{...}).
+For the purposes of this parameter,
+the size of a list is one greater than
+the sum of the sizes of the elements in the list.
+ at sp 1
+ at item
+ at samp{width} is the width of the screen in characters.
+ at sp 1
+ at item
+ at samp{lines} is the preferred maximum number of lines of one term to display.
+ at sp 1
+ at end itemize
+ at sp 1
+The browser maintains separate configuration parameters
+for the three commands @samp{print *}, @samp{print @var{var}},
+and @samp{browse @var{var}}.
+A @samp{format_param} command applies to all three,
+unless it specifies one or more of the options
+ at samp{-A} or @samp{--print-all},
+ at samp{-P} or @samp{--print},
+and @samp{-B} or @samp{--browse},
+in which case it will set only the selected command's parameters.
+ at sp 1
+The browser also maintains separate configuration parameters
+for the different output formats: flat, pretty and verbose.
+A @samp{format_param} command applies to all of these,
+unless it specifies one or more of the options
+ at samp{-f} or @samp{--flat},
+ at samp{-p} or @samp{--pretty},
+and @samp{-v} or @samp{--verbose},
+in which case it will set only the selected format's parameter.
@sp 1
@item alias @var{name} @var{command} [@var{command-parameter} ...]
@kindex alias (mdb command)
@@ -3339,7 +3506,6 @@
the debugger will substitute the given command and parameters
whenever the user types in an empty command line.
@sp 1
- at sp 1
If @var{name} is the upper-case word @samp{NUMBER},
the debugger will insert the given command and parameters
before the command line
@@ -3586,7 +3752,7 @@
@end itemize
@sp 1
The name of the file containing the failing slice can be specified with the
- at samp{-f} or @samp{--fail-trace-count} option or with a separate
+ at samp{-f} or @samp{--fail-trace-counts} option or with a separate
@samp{set fail_trace_count @var{filename}} command.
@sp 1
The name of a file containing a list of the files containing the passing
@@ -3633,110 +3799,6 @@
@sp 1
@table @code
- at item set [-APBfpv] @var{param} @var{value}
- at kindex set (mdb command)
- at kindex format (mdb command)
- at kindex depth (mdb command)
- at kindex size (mdb command)
- at kindex width (mdb command)
- at kindex lines (mdb command)
- at kindex xml_browser_cmd (mdb command)
- at kindex xml_tmp_filename (mdb command)
- at kindex fail_trace_counts (mdb command)
- at kindex pass_trace_counts (mdb command)
- at kindex list_path (mdb command)
- at kindex list_context_lines (mdb command)
-Updates the given configuration parameter.
-The parameters that can be configured are
- at samp{format}, @samp{depth}, @samp{size}, @samp{width}, @samp{lines},
- at samp{xml_browser_cmd}, @samp{xml_tmp_filename}, @samp{fail_trace_counts},
- at samp{pass_trace_counts}.
- at sp 1
- at itemize @bullet
- at item
- at samp{format} can be set to @samp{flat}, @samp{pretty} or @samp{verbose}
-to change the output style of the browser.
- at sp 1
- at item
- at samp{depth} is the maximum depth to which subterms will be displayed.
-Subterms at the depth limit may be abbreviated as functor/arity,
-or (in lists) may be replaced by an ellipsis (@samp{...}).
-The principal functor of any term has depth zero.
-For subterms which are not lists,
-the depth of any argument of the functor is one greater than the
-depth of the functor.
-For subterms which are lists,
-the depth of each element of the list
-is one greater than the depth of the list.
- at sp 1
- at item
- at samp{size} is the suggested maximum number of functors to display.
-Beyond this limit, subterms may be abbreviated as functor/arity,
-or (in lists) may be replaced by an ellipsis (@samp{...}).
-For the purposes of this parameter,
-the size of a list is one greater than
-the sum of the sizes of the elements in the list.
- at sp 1
- at item
- at samp{width} is the width of the screen in characters.
- at sp 1
- at item
- at samp{lines} is the maximum number of lines of one term to display.
- at sp 1
- at item
- at samp{xml_tmp_filename} is the name of the file to dump XML to before
-invoking your XML browser.
- at sp 1
- at item
- at samp{xml_browser_cmd} is the shell command(s) used to invoke your XML browser.
-If you want a stylesheet to be applied to the XML before the browser is invoked
-then you should do that in this command using the appropriate program
-(such as xsltproc, which comes with libxslt and is available from
-http://xmlsoft.org/XSLT/).
-By default if xsltproc and mozilla (or firefox) are available,
-xsltproc is invoked to apply the xul_tree.xsl stylesheet in
-extras/xml_stylesheets, then mozilla is invoked on the resulting XUL file.
- at sp 1
-You can use the apostrophe character (') to quote the command string when using
-the @samp{set} command, for example "set xml_browser_cmd 'firefox
-file:///tmp/mdbtmp.xml'".
- at item
- at samp{fail_trace_count} is the name of a file that contains the slice of a
-failing test case run. This configuration parameter is used by the
- at samp{dice} command if no @samp{--fail-trace-count} option is given for that
-command. See @ref{Experimental commands} for more information on the
- at samp{dice} command.
- at sp 1
- at item
- at samp{pass_trace_counts} is the name of a file that contains a list of file
-names which contain the slices of passing test case runs. This configuration
-parameter is used by the @samp{dice} command if no @samp{--pass-trace-counts}
-option is given for that command. See @ref{Experimental commands} for more
-information on the @samp{dice} command.
- at end itemize
- at sp 1
-The browser maintains separate configuration parameters
-for the three commands @samp{print *}, @samp{print @var{var}},
-and @samp{browse @var{var}}.
-A single @samp{set} command can modify the parameters
-for more than one of these;
-the options @samp{-A} or @samp{--print-all}, @samp{-P} or @samp{--print},
-and @samp{-B} or @samp{--browse}
-select which commands will be affected by the change.
-If none of these options is given,
-the default is to affect all commands.
- at sp 1
-The browser also maintains separate configuration parameters
-for the three different output formats.
-This applies to all parameters except for the format itself.
-The options @samp{-f} or @samp{--flat}, @samp{-p} or @samp{--pretty},
-and @samp{-v} or @samp{--verbose}
-select which formats will be affected by the change.
-If none of these options is given,
-the default is to affect all formats.
-In the case that the format itself is being set,
-these options are ignored.
- at sp 1
@item source [-i] @var{filename}
@kindex source (mdb command)
Executes the commands in the file named @var{filename}.
@@ -4254,11 +4316,28 @@
@item print io @var{n}- at var{m}
Print the @var{n}th to @var{m}th IO actions (inclusive).
@sp 1
- at item set @var{param} @var{value}
-Update the given configuration parameter.
-The parameters that can be configured are
- at samp{list_path}, @samp{list_context_lines}, @samp{format}, @samp{depth},
- at samp{size}, @samp{width} and @samp{lines}.
+ at item format @var{format}
+Set the default format to @var{format},
+which should be one of @samp{flat}, @samp{verbose} and @samp{pretty}.
+ at sp 1
+ at item depth @var{num}
+Set the maximum depth to which terms are printed to @var{num}.
+ at sp 1
+ at item size @var{num}
+Set the maximum number of function symbols
+to be printed in terms to @var{num}.
+ at sp 1
+ at item width @var{num}
+Set the number of columnds in which terms are to be printed to @var{num}.
+ at sp 1
+ at item lines @var{num}
+Set the maximum number of lines in terms to be printed to @var{num}.
+ at sp 1
+ at item actions @var{num}
+Set the maximum number of I/O actions to be printed in questions to @var{num}.
+ at sp 1
+ at item params
+Print the current values of browser parameters.
@sp 1
@item track [-a] [@var{term-path}]
The @samp{track} command can only be given from within the interactive
cvs diff: Diffing extras
cvs diff: Diffing extras/cgi
cvs diff: Diffing extras/complex_numbers
cvs diff: Diffing extras/complex_numbers/samples
cvs diff: Diffing extras/complex_numbers/tests
cvs diff: Diffing extras/concurrency
cvs diff: Diffing extras/curs
cvs diff: Diffing extras/curs/samples
cvs diff: Diffing extras/curses
cvs diff: Diffing extras/curses/sample
cvs diff: Diffing extras/dynamic_linking
cvs diff: Diffing extras/error
cvs diff: Diffing extras/gator
cvs diff: Diffing extras/gator/generations
cvs diff: Diffing extras/gator/generations/1
cvs diff: Diffing extras/graphics
cvs diff: Diffing extras/graphics/easyx
cvs diff: Diffing extras/graphics/easyx/samples
cvs diff: Diffing extras/graphics/mercury_glut
cvs diff: Diffing extras/graphics/mercury_opengl
cvs diff: Diffing extras/graphics/mercury_tcltk
cvs diff: Diffing extras/graphics/samples
cvs diff: Diffing extras/graphics/samples/calc
cvs diff: Diffing extras/graphics/samples/gears
cvs diff: Diffing extras/graphics/samples/maze
cvs diff: Diffing extras/graphics/samples/pent
cvs diff: Diffing extras/lazy_evaluation
cvs diff: Diffing extras/lex
cvs diff: Diffing extras/lex/samples
cvs diff: Diffing extras/lex/tests
cvs diff: Diffing extras/logged_output
cvs diff: Diffing extras/moose
cvs diff: Diffing extras/moose/samples
cvs diff: Diffing extras/moose/tests
cvs diff: Diffing extras/morphine
cvs diff: Diffing extras/morphine/non-regression-tests
cvs diff: Diffing extras/morphine/scripts
cvs diff: Diffing extras/morphine/source
cvs diff: Diffing extras/odbc
cvs diff: Diffing extras/posix
cvs diff: Diffing extras/quickcheck
cvs diff: Diffing extras/quickcheck/tutes
cvs diff: Diffing extras/references
cvs diff: Diffing extras/references/samples
cvs diff: Diffing extras/references/tests
cvs diff: Diffing extras/solver_types
cvs diff: Diffing extras/solver_types/library
cvs diff: Diffing extras/stream
cvs diff: Diffing extras/trailed_update
cvs diff: Diffing extras/trailed_update/samples
cvs diff: Diffing extras/trailed_update/tests
cvs diff: Diffing extras/windows_installer_generator
cvs diff: Diffing extras/windows_installer_generator/sample
cvs diff: Diffing extras/windows_installer_generator/sample/images
cvs diff: Diffing extras/xml
cvs diff: Diffing extras/xml/samples
cvs diff: Diffing extras/xml_stylesheets
cvs diff: Diffing java
cvs diff: Diffing java/runtime
cvs diff: Diffing library
cvs diff: Diffing mdbcomp
cvs diff: Diffing profiler
cvs diff: Diffing robdd
cvs diff: Diffing runtime
cvs diff: Diffing runtime/GETOPT
cvs diff: Diffing runtime/machdeps
cvs diff: Diffing samples
cvs diff: Diffing samples/c_interface
cvs diff: Diffing samples/c_interface/c_calls_mercury
cvs diff: Diffing samples/c_interface/cplusplus_calls_mercury
cvs diff: Diffing samples/c_interface/mercury_calls_c
cvs diff: Diffing samples/c_interface/mercury_calls_cplusplus
cvs diff: Diffing samples/c_interface/mercury_calls_fortran
cvs diff: Diffing samples/c_interface/simpler_c_calls_mercury
cvs diff: Diffing samples/c_interface/simpler_cplusplus_calls_mercury
cvs diff: Diffing samples/diff
cvs diff: Diffing samples/muz
cvs diff: Diffing samples/rot13
cvs diff: Diffing samples/solutions
cvs diff: Diffing samples/tests
cvs diff: Diffing samples/tests/c_interface
cvs diff: Diffing samples/tests/c_interface/c_calls_mercury
cvs diff: Diffing samples/tests/c_interface/cplusplus_calls_mercury
cvs diff: Diffing samples/tests/c_interface/mercury_calls_c
cvs diff: Diffing samples/tests/c_interface/mercury_calls_cplusplus
cvs diff: Diffing samples/tests/c_interface/mercury_calls_fortran
cvs diff: Diffing samples/tests/c_interface/simpler_c_calls_mercury
cvs diff: Diffing samples/tests/c_interface/simpler_cplusplus_calls_mercury
cvs diff: Diffing samples/tests/diff
cvs diff: Diffing samples/tests/muz
cvs diff: Diffing samples/tests/rot13
cvs diff: Diffing samples/tests/solutions
cvs diff: Diffing samples/tests/toplevel
cvs diff: Diffing scripts
Index: scripts/Mmakefile
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/scripts/Mmakefile,v
retrieving revision 1.39
diff -u -b -r1.39 Mmakefile
--- scripts/Mmakefile 25 May 2005 05:19:50 -0000 1.39
+++ scripts/Mmakefile 3 Apr 2006 16:10:13 -0000
@@ -69,7 +69,7 @@
chmod a+x $* ; \
fi \
done
- @for file in $(CONF_FILES) ; do \
+ @for file in $(CONF_FILES) $(CONF_DEBUG_SCRIPTS) ; do \
if test "$*" = "$$file" ; then \
$(MERCURY_DIR)/config.status --file=$* ; \
if grep -n '[^$$]@' $@; then false; else true; fi \
Index: scripts/mdbrc.in
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/scripts/mdbrc.in,v
retrieving revision 1.5
diff -u -b -r1.5 mdbrc.in
--- scripts/mdbrc.in 11 Dec 2004 01:59:51 -0000 1.5
+++ scripts/mdbrc.in 1 Apr 2006 11:20:31 -0000
@@ -15,5 +15,5 @@
alias e exception
alias EMPTY step
alias NUMBER step
-set xml_browser_cmd '@DEFAULT_XML_BROWSER_CMD@'
-set xml_tmp_filename '@DEFAULT_XML_TMP_FILENAME@'
+xml_browser_cmd '@DEFAULT_XML_BROWSER_CMD@'
+xml_tmp_filename '@DEFAULT_XML_TMP_FILENAME@'
cvs diff: Diffing slice
cvs diff: Diffing tests
cvs diff: Diffing tests/benchmarks
cvs diff: Diffing tests/debugger
Index: tests/debugger/breakpoints.exp
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/debugger/breakpoints.exp,v
retrieving revision 1.14
diff -u -b -r1.14 breakpoints.exp
--- tests/debugger/breakpoints.exp 29 Mar 2006 00:57:42 -0000 1.14
+++ tests/debugger/breakpoints.exp 1 Apr 2006 13:43:25 -0000
@@ -106,8 +106,8 @@
mdb> break_print 1 none
1: + stop interface pred breakpoints.qperm/2-0 (nondet)
-mdb> set -p depth 10
-mdb> set -p size 20
+mdb> format_param -p depth 10
+mdb> format_param -p size 20
mdb> break_print -p -n 1 HeadVar__1 HeadVar__2
1: + stop interface pred breakpoints.qperm/2-0 (nondet)
HeadVar__1 (pretty, nowarn), HeadVar__2 (pretty, nowarn)
Index: tests/debugger/breakpoints.exp2
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/debugger/breakpoints.exp2,v
retrieving revision 1.10
diff -u -b -r1.10 breakpoints.exp2
--- tests/debugger/breakpoints.exp2 30 Mar 2006 00:42:00 -0000 1.10
+++ tests/debugger/breakpoints.exp2 1 Apr 2006 13:43:29 -0000
@@ -114,8 +114,8 @@
mdb> break_print 1 none
1: + stop interface pred breakpoints.qperm/2-0 (nondet)
-mdb> set -p depth 10
-mdb> set -p size 20
+mdb> format_param -p depth 10
+mdb> format_param -p size 20
mdb> break_print -p -n 1 HeadVar__1 HeadVar__2
1: + stop interface pred breakpoints.qperm/2-0 (nondet)
HeadVar__1 (pretty, nowarn), HeadVar__2 (pretty, nowarn)
Index: tests/debugger/breakpoints.inp
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/debugger/breakpoints.inp,v
retrieving revision 1.8
diff -u -b -r1.8 breakpoints.inp
--- tests/debugger/breakpoints.inp 27 Jan 2005 06:17:37 -0000 1.8
+++ tests/debugger/breakpoints.inp 1 Apr 2006 13:43:07 -0000
@@ -30,8 +30,8 @@
break_print -v -n 1 HeadVar__1 HeadVar__2
continue
break_print 1 none
-set -p depth 10
-set -p size 20
+format_param -p depth 10
+format_param -p size 20
break_print -p -n 1 HeadVar__1 HeadVar__2
continue
finish -N
Index: tests/debugger/browse_pretty.exp
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/debugger/browse_pretty.exp,v
retrieving revision 1.13
diff -u -b -r1.13 browse_pretty.exp
--- tests/debugger/browse_pretty.exp 5 Nov 2004 06:30:20 -0000 1.13
+++ tests/debugger/browse_pretty.exp 2 Apr 2006 17:01:31 -0000
@@ -6,17 +6,17 @@
mdb> print *
Data (arg 1) big(big(big(small, [|]/2, small), [1, ...], small), [1, 2, 3], big(big/3, [|]/2, small))
mdb> browse 1
-browser> set format pretty
-browser> set depth 10
+browser> format pretty
+browser> depth 10
browser> ls
big(big(big(small, [1], small), [1, 2], small), [1, 2, 3],
big(big(small, [1, 2, 3, 4], big(small, [1, 2, 3, 4, 5], small)),
[1, 2, 3, 4, 5, 6], small))
-browser> set width 131
+browser> width 131
browser> ls
big(big(big(small, [1], small), [1, 2], small), [1, 2, 3],
big(big(small, [1, 2, 3, 4], big(small, [1, 2, 3, 4, 5], small)), [1, 2, 3, 4, 5, 6], small))
-browser> set width 30
+browser> width 30
browser> ls
big(
big(
@@ -29,7 +29,7 @@
[1, 2, 3, 4, 5],
small)),
[1, 2, 3, 4, 5, 6], small))
-browser> set width 10
+browser> width 10
browser> ls
big(
big(
@@ -64,26 +64,26 @@
4,
5, 6],
small))
-browser> set width 79
-browser> set depth 3
+browser> width 79
+browser> depth 3
browser> ls
big(big(big(...), ...), [1, ...], ...)
-browser> set format raw_pretty
-browser> set lines 4
-browser> set width 40
+browser> format raw_pretty
+browser> lines 4
+browser> width 40
browser> ls
big(
big(big/3, [|]/2, small),
[|](1, [|](2, [|](3, []))),
big(big/3, [|]/2, small))
-browser> set width 80
+browser> width 80
browser> ls
big(
big(big(small, [|](1, []), small), [|](1, [|](2, [])), small),
[|](1, [|](2, [|](3, []))),
big(big(small, [|]/2, big/3), [|](1, [|](2, [|](3, [|]/2))), small))
-browser> set lines 12
-browser> set width 40
+browser> lines 12
+browser> width 40
browser> ls
big(
big(
@@ -96,8 +96,8 @@
[|](1, [|](2, [|](3, [|]/2))),
small))
browser> cd 3
-browser> set lines 4
-browser> set width 30
+browser> lines 4
+browser> width 30
browser> ls
big(
big(small, [|]/2, big/3),
Index: tests/debugger/browse_pretty.inp
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/debugger/browse_pretty.inp,v
retrieving revision 1.5
diff -u -b -r1.5 browse_pretty.inp
--- tests/debugger/browse_pretty.inp 5 Nov 2004 06:30:20 -0000 1.5
+++ tests/debugger/browse_pretty.inp 2 Apr 2006 17:01:55 -0000
@@ -2,30 +2,30 @@
goto 3
print *
browse 1
-set format pretty
-set depth 10
+format pretty
+depth 10
ls
-set width 131
+width 131
ls
-set width 30
+width 30
ls
-set width 10
+width 10
ls
-set width 79
-set depth 3
+width 79
+depth 3
ls
-set format raw_pretty
-set lines 4
-set width 40
+format raw_pretty
+lines 4
+width 40
ls
-set width 80
+width 80
ls
-set lines 12
-set width 40
+lines 12
+width 40
ls
cd 3
-set lines 4
-set width 30
+lines 4
+width 30
ls
quit
print goal
Index: tests/debugger/browser_test.exp
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/debugger/browser_test.exp,v
retrieving revision 1.25
diff -u -b -r1.25 browser_test.exp
--- tests/debugger/browser_test.exp 31 Mar 2006 05:12:15 -0000 1.25
+++ tests/debugger/browser_test.exp 1 Apr 2006 13:52:50 -0000
@@ -11,11 +11,11 @@
mdb> delete *
0: E stop interface pred browser_test.big_data/1-0 (det)
mdb> dump 1 browser_test.save.1
-mdb> set format raw_pretty
+mdb> format raw_pretty
mdb> print *
Data (arg 1)
big(big(big(small, 1, small), 2, small), 3, big(big(small, 4, big/3), 6, small))
-mdb> set -A format verbose
+mdb> format -A verbose
mdb> print *
Data (arg 1)
big
@@ -29,7 +29,7 @@
big(big(small, 1, small), 2, small),
3,
big(big(small, 4, big(small, 5, small)), 6, small))
-mdb> set -AP format flat
+mdb> format -AP flat
mdb> print -f 1
Data (arg 1) big(big(big(small, 1, small), 2, small), 3, big(big(small, 4, big/3), 6, small))
mdb> print -p 1
@@ -106,8 +106,8 @@
3,
big(big(small, 4, big(small, 5, small)), 6, small))
browser> quit
-mdb> set xml_tmp_filename './browser_test.xml.out'
-mdb> set xml_browser_cmd 'cat ./browser_test.xml.out'
+mdb> xml_tmp_filename './browser_test.xml.out'
+mdb> xml_browser_cmd 'cat ./browser_test.xml.out'
mdb> browse --xml 1
Saving term to XML file...
Launching XML browser (this may take some time) ...
@@ -166,12 +166,12 @@
<small functor="small" type="browser_test.big" arity="0" />
</big>
</big>
-mdb> set -A -f depth 1
+mdb> format_param -A -f depth 1
mdb> print *
Data (arg 1) big(big/3, 3, big/3)
mdb> print Data/1
Data (arg 1) big(big(small, 1, small), 2, small)
-mdb> set -f depth 3
+mdb> format_param -f depth 3
mdb> print 1
Data (arg 1) big(big(big(small, 1, small), 2, small), 3, big(big(small, 4, big/3), 6, small))
mdb> print Data/1/2
Index: tests/debugger/browser_test.exp2
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/debugger/browser_test.exp2,v
retrieving revision 1.16
diff -u -b -r1.16 browser_test.exp2
--- tests/debugger/browser_test.exp2 30 Jan 2003 05:59:26 -0000 1.16
+++ tests/debugger/browser_test.exp2 1 Apr 2006 13:53:14 -0000
@@ -3,11 +3,11 @@
Command echo enabled.
mdb> goto 3
E2: C2 2 EXIT pred browser_test.big_data/1-0 (det) browser_test.m:18 (browser_test.m:12)
-mdb> set format pretty
+mdb> format pretty
mdb> print *
Data (arg 1)
big(big(big(small, 1, small), 2, small), 3, big(big(small, 4, big/3), 6, small))
-mdb> set -A format verbose
+mdb> format -A verbose
mdb> print *
Data (arg 1)
big
@@ -21,7 +21,7 @@
big(big(small, 1, small), 2, small),
3,
big(big(small, 4, big(small, 5, small)), 6, small))
-mdb> set -AP format flat
+mdb> format -AP flat
mdb> print -f 1
Data (arg 1) big(big(big(small, 1, small), 2, small), 3, big(big(small, 4, big/3), 6, small))
mdb> print -r 1
@@ -84,12 +84,12 @@
3,
big(big(small, 4, big(small, 5, small)), 6, small))
browser> quit
-mdb> set -A -f depth 1
+mdb> format_param -A -f depth 1
mdb> print *
Data (arg 1) big(big/3, 3, big/3)
mdb> print Data/1
Data (arg 1) big(big(small, 1, small), 2, small)
-mdb> set -f depth 3
+mdb> format_param -f depth 3
mdb> print 1
Data (arg 1) big(big(big(small, 1, small), 2, small), 3, big(big(small, 4, big/3), 6, small))
mdb> print Data/1/2
Index: tests/debugger/browser_test.inp
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/debugger/browser_test.inp,v
retrieving revision 1.15
diff -u -b -r1.15 browser_test.inp
--- tests/debugger/browser_test.inp 31 Mar 2006 05:12:15 -0000 1.15
+++ tests/debugger/browser_test.inp 1 Apr 2006 13:52:20 -0000
@@ -5,12 +5,12 @@
finish
delete *
dump 1 browser_test.save.1
-set format raw_pretty
+format raw_pretty
print *
-set -A format verbose
+format -A verbose
print *
browse 1; ls; quit
-set -AP format flat
+format -AP flat
print -f 1
print -p 1
print -v 1
@@ -36,14 +36,14 @@
cdr 3 ../1/..
ls
quit
-set xml_tmp_filename './browser_test.xml.out'
-set xml_browser_cmd 'cat ./browser_test.xml.out'
+xml_tmp_filename './browser_test.xml.out'
+xml_browser_cmd 'cat ./browser_test.xml.out'
browse --xml 1
browse -x Data
-set -A -f depth 1
+format_param -A -f depth 1
print *
print Data/1
-set -f depth 3
+format_param -f depth 3
print 1
print Data/1/2
print 1^1^2^3
Index: tests/debugger/completion.exp
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/debugger/completion.exp,v
retrieving revision 1.31
diff -u -b -r1.31 completion.exp
--- tests/debugger/completion.exp 25 Oct 2005 04:00:53 -0000 1.31
+++ tests/debugger/completion.exp 4 Apr 2006 04:28:33 -0000
@@ -3,41 +3,43 @@
Command echo enabled.
mdb> register --quiet
mdb>
-? exception query
-P excp quit
-alias f r
-all_class_decls finish register
-all_procedures flag retry
-all_regs forward return
-all_type_ctors g s
-ambiguity gen_stack save
-b goal_paths save_to_file
-break goto scope
-break_print h scroll
-browse held_vars set
-c help source
-cc_query histogram_all stack
-class_decl histogram_exp stack_default_limit
-clear_histogram hold stack_regs
-condition ignore stats
-consumer io_query step
-context level subgoal
-continue list table
-current maxdepth table_io
-cut_stack mindepth term_size
-d mm_stacks trust
-dd mmc_options trusted
-debug_vars modules type_ctor
-delete next unalias
-dice nondet_stack unhide_events
-diff p untrust
-disable pneg_stack up
-document pop_list_dir v
-document_category print var_details
-down print_optionals vars
-e printlevel view
-echo procedures
-enable push_list_dir
+? excp print_optionals
+P f printlevel
+alias fail_trace_counts procedures
+all_class_decls finish push_list_dir
+all_procedures flag query
+all_regs format quit
+all_type_ctors format_param r
+ambiguity forward register
+b g retry
+break gen_stack return
+break_print goal_paths s
+browse goto save
+c h scope
+cc_query held_vars scroll
+class_decl help source
+clear_histogram histogram_all stack
+condition histogram_exp stack_default_limit
+consumer hold stack_regs
+context ignore stats
+continue io_query step
+current level subgoal
+cut_stack list table
+d list_context_lines table_io
+dd list_path term_size
+debug_vars max_io_actions trust
+delete maxdepth trusted
+dice mindepth type_ctor
+diff mm_stacks unalias
+disable mmc_options unhide_events
+document modules untrust
+document_category next up
+down nondet_stack v
+dump p var_details
+e pass_trace_counts vars
+echo pneg_stack view
+enable pop_list_dir xml_browser_cmd
+exception print xml_tmp_filename
h help histogram_exp
held_vars histogram_all hold
var_details vars view
@@ -63,7 +65,9 @@
List of procedures in module `completion.sub1'
pred completion.sub1.zp/1-0 (det)
func completion.sub1.z1/0-0 (det)
-mdb> set --flat format pretty
+mdb>
+format format_param
+format_param --flat lines 10
mdb> unalias excp
Alias `excp' removed.
mdb> b zabc3
@@ -91,7 +95,7 @@
mdb>
2d 2dice 2document_category
2dd 2diff 2down
-2debug_vars 2disable
+2debug_vars 2disable 2dump
2delete 2document
2debug_vars 2delete
2delete
Index: tests/debugger/completion.inp
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/debugger/completion.inp,v
retrieving revision 1.11
diff -u -b -r1.11 completion.inp
--- tests/debugger/completion.inp 1 Aug 2005 02:40:11 -0000 1.11
+++ tests/debugger/completion.inp 4 Apr 2006 01:04:40 -0000
@@ -4,7 +4,7 @@
p --f@@D@
stac@ @
proc at complet@. at 1
-set --f at fo@p@
+form at _par@ --f@ lines 10
una at ex@
b za@
b func*complet at z@
Index: tests/debugger/dice.exp
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/debugger/dice.exp,v
retrieving revision 1.3
diff -u -b -r1.3 dice.exp
--- tests/debugger/dice.exp 29 Mar 2006 00:57:42 -0000 1.3
+++ tests/debugger/dice.exp 1 Apr 2006 13:44:17 -0000
@@ -26,8 +26,8 @@
pred dice.msort_n/4-0 <e;t;> dice.m:50 11 (3) 4 0.27
pred dice.msort_n/4-0 <e;t;s2;> dice.m:47 11 (3) 4 0.27
pred dice.msort_n/4-0 <e;e;> dice.m:55 8 (3) 3 0.27
-mdb> set fail_trace_count dice.fail
-mdb> set pass_trace_counts dice.passes
+mdb> fail_trace_counts dice.fail
+mdb> pass_trace_counts dice.passes
mdb> dice -sS -m dice
Procedure Path/Port File:Line Pass (3) Fail Suspicion
pred dice.merge/3-0 <s2;c2;s2;c4;e;> dice.m:74 0 (0) 1 1.00
Index: tests/debugger/dice.exp2
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/debugger/dice.exp2,v
retrieving revision 1.1
diff -u -b -r1.1 dice.exp2
--- tests/debugger/dice.exp2 10 Feb 2005 04:10:31 -0000 1.1
+++ tests/debugger/dice.exp2 1 Apr 2006 13:44:22 -0000
@@ -54,8 +54,8 @@
func int.+/2-0 EXIT int.m:82 44 (3) 13 0.23
func int.-/2-0 CALL int.m:96 34 (3) 11 0.24
func int.-/2-0 EXIT int.m:96 34 (3) 11 0.24
-mdb> set fail_trace_count dice.fail
-mdb> set pass_trace_counts dice.passes
+mdb> fail_trace_counts dice.fail
+mdb> pass_trace_counts dice.passes
mdb> dice -sS
Procedure Path/Port File:Line Pass (3) Fail Suspicion
pred dice.merge/3-0 <s2;c2;s2;c4;e;> dice.m:74 0 (0) 1 1.00
Index: tests/debugger/dice.inp
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/debugger/dice.inp,v
retrieving revision 1.2
diff -u -b -r1.2 dice.inp
--- tests/debugger/dice.inp 18 Feb 2005 04:05:35 -0000 1.2
+++ tests/debugger/dice.inp 1 Apr 2006 13:44:28 -0000
@@ -2,8 +2,8 @@
context none
echo on
dice -f dice.fail -p dice.passes -m dice
-set fail_trace_count dice.fail
-set pass_trace_counts dice.passes
+fail_trace_counts dice.fail
+pass_trace_counts dice.passes
dice -sS -m dice
dice -sSF -m dice
dice -n 3 -s P -m dice
Index: tests/debugger/exception_value.exp
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/debugger/exception_value.exp,v
retrieving revision 1.9
diff -u -b -r1.9 exception_value.exp
--- tests/debugger/exception_value.exp 16 Nov 2004 00:16:38 -0000 1.9
+++ tests/debugger/exception_value.exp 2 Apr 2006 17:03:14 -0000
@@ -21,8 +21,8 @@
mdb> finish
E5: C3 EXCP pred exception_value.q/1-0 (det)
mdb> browse exception
-browser> set depth 9
-browser> set size 99
+browser> depth 9
+browser> size 99
browser> ls
"q oops" - [1, 2, 3]
browser> quit
Index: tests/debugger/exception_value.exp2
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/debugger/exception_value.exp2,v
retrieving revision 1.9
diff -u -b -r1.9 exception_value.exp2
--- tests/debugger/exception_value.exp2 16 Nov 2004 00:16:38 -0000 1.9
+++ tests/debugger/exception_value.exp2 2 Apr 2006 17:03:25 -0000
@@ -18,8 +18,8 @@
mdb> finish
E5: C3 EXCP pred exception_value.q/1-0 (det)
mdb> browse exception
-browser> set depth 9
-browser> set size 99
+browser> depth 9
+browser> size 99
browser> ls
"q oops" - [1, 2, 3]
browser> quit
Index: tests/debugger/exception_value.exp3
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/debugger/exception_value.exp3,v
retrieving revision 1.2
diff -u -b -r1.2 exception_value.exp3
--- tests/debugger/exception_value.exp3 10 Nov 2004 02:21:40 -0000 1.2
+++ tests/debugger/exception_value.exp3 2 Apr 2006 17:04:06 -0000
@@ -18,8 +18,8 @@
mdb> finish
E5: C3 8 EXCP pred exception_value.q/1-0 (det)
mdb> browse exception
-browser> set depth 9
-browser> set size 99
+browser> depth 9
+browser> size 99
browser> ls
"q oops" - [1, 2, 3]
browser> quit
Index: tests/debugger/exception_value.inp
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/debugger/exception_value.inp,v
retrieving revision 1.1
diff -u -b -r1.1 exception_value.inp
--- tests/debugger/exception_value.inp 19 Jun 2000 07:59:20 -0000 1.1
+++ tests/debugger/exception_value.inp 2 Apr 2006 17:03:06 -0000
@@ -8,8 +8,8 @@
continue
finish
browse exception
-set depth 9
-set size 99
+depth 9
+size 99
ls
quit
continue
Index: tests/debugger/higher_order.exp
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/debugger/higher_order.exp,v
retrieving revision 1.7
diff -u -b -r1.7 higher_order.exp
--- tests/debugger/higher_order.exp 26 May 2005 00:17:04 -0000 1.7
+++ tests/debugger/higher_order.exp 1 Apr 2006 13:45:19 -0000
@@ -3,9 +3,9 @@
Command echo enabled.
mdb> context none
Contexts will not be printed.
-mdb> set size 100
-mdb> set depth 100
-mdb> set format flat
+mdb> format_param size 100
+mdb> format_param depth 100
+mdb> format flat
mdb> step
E2: C2 CALL pred higher_order.domap/3-0 (det)
mdb> print *
Index: tests/debugger/higher_order.exp2
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/debugger/higher_order.exp2,v
retrieving revision 1.2
diff -u -b -r1.2 higher_order.exp2
--- tests/debugger/higher_order.exp2 17 Jan 2003 05:56:53 -0000 1.2
+++ tests/debugger/higher_order.exp2 1 Apr 2006 13:45:30 -0000
@@ -3,9 +3,9 @@
Command echo enabled.
mdb> context none
Contexts will not be printed.
-mdb> set size 100
-mdb> set depth 100
-mdb> set format flat
+mdb> format_param size 100
+mdb> format_param depth 100
+mdb> format flat
mdb> step
2: 2 2 CALL pred higher_order.domap/3-0 (det)
mdb> print *
Index: tests/debugger/higher_order.inp
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/debugger/higher_order.inp,v
retrieving revision 1.1
diff -u -b -r1.1 higher_order.inp
--- tests/debugger/higher_order.inp 24 Feb 2002 11:53:39 -0000 1.1
+++ tests/debugger/higher_order.inp 1 Apr 2006 13:46:02 -0000
@@ -1,8 +1,8 @@
echo on
context none
-set size 100
-set depth 100
-set format flat
+format_param size 100
+format_param depth 100
+format flat
step
print *
finish
Index: tests/debugger/loopcheck.exp3
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/debugger/loopcheck.exp3,v
retrieving revision 1.4
diff -u -b -r1.4 loopcheck.exp3
--- tests/debugger/loopcheck.exp3 7 Dec 2005 16:07:13 -0000 1.4
+++ tests/debugger/loopcheck.exp3 2 Apr 2006 17:05:36 -0000
@@ -10,9 +10,9 @@
1: + stop interface pred loopcheck.loop/1-0 (det)
mdb> finish
2: 2 2 CALL pred loopcheck.loop/1-0 (det)
- loopcheck.m:21 (from loopcheck.m:14)
+ loopcheck.m:20 (from loopcheck.m:14)
3: 3 3 CALL pred loopcheck.loop/1-0 (det)
- loopcheck.m:21 (from loopcheck.m:21)
+ loopcheck.m:20 (from loopcheck.m:21)
12: 3 3 EXCP pred loopcheck.loop/1-0 (det)
loopcheck.m:21 (from loopcheck.m:21)
13: 2 2 EXCP pred loopcheck.loop/1-0 (det)
Index: tests/debugger/mdb_command_test.inp
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/debugger/mdb_command_test.inp,v
retrieving revision 1.49
diff -u -b -r1.49 mdb_command_test.inp
--- tests/debugger/mdb_command_test.inp 31 Mar 2006 05:12:15 -0000 1.49
+++ tests/debugger/mdb_command_test.inp 4 Apr 2006 04:21:46 -0000
@@ -7,7 +7,13 @@
mode xyzzy xyzzy xyzzy xyzzy xyzzy
browse xyzzy xyzzy xyzzy xyzzy xyzzy
print xyzzy xyzzy xyzzy xyzzy xyzzy
-set xyzzy xyzzy xyzzy xyzzy xyzzy
+format xyzzy xyzzy xyzzy xyzzy xyzzy
+depth xyzzy xyzzy xyzzy xyzzy xyzzy
+size xyzzy xyzzy xyzzy xyzzy xyzzy
+width xyzzy xyzzy xyzzy xyzzy xyzzy
+lines xyzzy xyzzy xyzzy xyzzy xyzzy
+actions xyzzy xyzzy xyzzy xyzzy xyzzy
+params xyzzy xyzzy xyzzy xyzzy xyzzy
track xyzzy xyzzy xyzzy xyzzy xyzzy
mark xyzzy xyzzy xyzzy xyzzy xyzzy
pd xyzzy xyzzy xyzzy xyzzy xyzzy
@@ -41,8 +47,6 @@
diff xyzzy xyzzy xyzzy xyzzy xyzzy
dump xyzzy xyzzy xyzzy xyzzy xyzzy
list xyzzy xyzzy xyzzy xyzzy xyzzy
-push_list_dir xyzzy xyzzy xyzzy xyzzy xyzzy
-pop_list_dir xyzzy xyzzy xyzzy xyzzy xyzzy
break xyzzy xyzzy xyzzy xyzzy xyzzy
condition xyzzy xyzzy xyzzy xyzzy xyzzy
ignore xyzzy xyzzy xyzzy xyzzy xyzzy
@@ -56,18 +60,28 @@
table_io xyzzy xyzzy xyzzy xyzzy xyzzy
mmc_options xyzzy xyzzy xyzzy xyzzy xyzzy
printlevel xyzzy xyzzy xyzzy xyzzy xyzzy
-echo xyzzy xyzzy xyzzy xyzzy xyzzy
scroll xyzzy xyzzy xyzzy xyzzy xyzzy
stack_default_limit xyzzy xyzzy xyzzy xyzzy xyzzy
-context xyzzy xyzzy xyzzy xyzzy xyzzy
goal_paths xyzzy xyzzy xyzzy xyzzy xyzzy
scope xyzzy xyzzy xyzzy xyzzy xyzzy
+echo xyzzy xyzzy xyzzy xyzzy xyzzy
+context xyzzy xyzzy xyzzy xyzzy xyzzy
+list_context_lines xyzzy xyzzy xyzzy xyzzy xyzzy
+list_path xyzzy xyzzy xyzzy xyzzy xyzzy
+push_list_dir xyzzy xyzzy xyzzy xyzzy xyzzy
+pop_list_dir xyzzy xyzzy xyzzy xyzzy xyzzy
+fail_trace_counts xyzzy xyzzy xyzzy xyzzy xyzzy
+pass_trace_counts xyzzy xyzzy xyzzy xyzzy xyzzy
+max_io_actions xyzzy xyzzy xyzzy xyzzy xyzzy
+xml_browser_cmd xyzzy xyzzy xyzzy xyzzy xyzzy
+xml_tmp_filename xyzzy xyzzy xyzzy xyzzy xyzzy
+format xyzzy xyzzy xyzzy xyzzy xyzzy
+format_param xyzzy xyzzy xyzzy xyzzy xyzzy
unalias xyzzy xyzzy xyzzy xyzzy xyzzy
dd xyzzy xyzzy xyzzy xyzzy xyzzy
trust xyzzy xyzzy xyzzy xyzzy xyzzy
trusted xyzzy xyzzy xyzzy xyzzy xyzzy
untrust xyzzy xyzzy xyzzy xyzzy xyzzy
-set xyzzy xyzzy xyzzy xyzzy xyzzy
source xyzzy xyzzy xyzzy xyzzy xyzzy
save xyzzy xyzzy xyzzy xyzzy xyzzy
quit xyzzy xyzzy xyzzy xyzzy xyzzy
Index: tests/debugger/polymorphic_output.exp
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/debugger/polymorphic_output.exp,v
retrieving revision 1.16
diff -u -b -r1.16 polymorphic_output.exp
--- tests/debugger/polymorphic_output.exp 23 Mar 2006 02:11:57 -0000 1.16
+++ tests/debugger/polymorphic_output.exp 1 Apr 2006 13:46:21 -0000
@@ -12,8 +12,8 @@
0: E stop interface func polymorphic_output.functor_names/1-0 (det)
mdb> p goal
functor_names(two("three", 3, three("four", 4, "one", 1, empty, empty, empty), two("two", 2, empty, empty))) = _
-mdb> set format verbose
-mdb> set lines 100
+mdb> format verbose
+mdb> format_param lines 100
mdb> p goal
functor_names
1-two
@@ -34,7 +34,7 @@
| 4-empty
2-_
-mdb> set format flat
+mdb> format flat
mdb> browse goal
browser> ^1
browser> p
Index: tests/debugger/polymorphic_output.exp2
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/debugger/polymorphic_output.exp2,v
retrieving revision 1.19
diff -u -b -r1.19 polymorphic_output.exp2
--- tests/debugger/polymorphic_output.exp2 22 Mar 2006 02:56:26 -0000 1.19
+++ tests/debugger/polymorphic_output.exp2 1 Apr 2006 13:46:32 -0000
@@ -12,8 +12,8 @@
0: E stop interface func polymorphic_output.functor_names/1-0 (det)
mdb> p goal
functor_names(two("three", 3, three("four", 4, "one", 1, empty, empty, empty), two("two", 2, empty, empty))) = _
-mdb> set format verbose
-mdb> set lines 100
+mdb> format verbose
+mdb> format_param lines 100
mdb> p goal
functor_names
1-two
@@ -34,7 +34,7 @@
| 4-empty
2-_
-mdb> set format flat
+mdb> format flat
mdb> browse goal
browser> ^1
browser> p
Index: tests/debugger/polymorphic_output.exp3
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/debugger/polymorphic_output.exp3,v
retrieving revision 1.11
diff -u -b -r1.11 polymorphic_output.exp3
--- tests/debugger/polymorphic_output.exp3 8 Feb 2006 21:48:34 -0000 1.11
+++ tests/debugger/polymorphic_output.exp3 1 Apr 2006 13:46:42 -0000
@@ -12,8 +12,8 @@
0: E stop interface func polymorphic_output.functor_names/1-0 (det)
mdb> p goal
functor_names(two("three", 3, three("four", 4, "one", 1, empty, empty, empty), two("two", 2, empty, empty))) = _
-mdb> set format verbose
-mdb> set lines 100
+mdb> format verbose
+mdb> format_param lines 100
mdb> p goal
functor_names
1-two
@@ -34,7 +34,7 @@
| 4-empty
2-_
-mdb> set format flat
+mdb> format flat
mdb> browse goal
browser> ^1
browser> p
Index: tests/debugger/polymorphic_output.inp
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/debugger/polymorphic_output.inp,v
retrieving revision 1.4
diff -u -b -r1.4 polymorphic_output.inp
--- tests/debugger/polymorphic_output.inp 22 Mar 2006 02:56:26 -0000 1.4
+++ tests/debugger/polymorphic_output.inp 1 Apr 2006 13:46:52 -0000
@@ -5,10 +5,10 @@
c
delete 0
p goal
-set format verbose
-set lines 100
+format verbose
+format_param lines 100
p goal
-set format flat
+format flat
browse goal
^1
p
Index: tests/debugger/save.exp
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/debugger/save.exp,v
retrieving revision 1.1
diff -u -b -r1.1 save.exp
--- tests/debugger/save.exp 31 Mar 2006 05:12:15 -0000 1.1
+++ tests/debugger/save.exp 1 Apr 2006 11:19:02 -0000
@@ -49,58 +49,58 @@
break pred*save.nodiag/3-0
condition B = 5
scope interface
-set -P format flat
-set -P -f depth 3
-set -P -f size 10
-set -P -f width 80
-set -P -f lines 25
-set -P -r depth 3
-set -P -r size 10
-set -P -r width 80
-set -P -r lines 25
-set -P -v depth 3
-set -P -v size 10
-set -P -v width 80
-set -P -v lines 25
-set -P -p depth 3
-set -P -p size 10
-set -P -p width 80
-set -P -p lines 25
-set -B format flat
-set -B -f depth 10
-set -B -f size 30
-set -B -f width 80
-set -B -f lines 25
-set -B -r depth 10
-set -B -r size 30
-set -B -r width 80
-set -B -r lines 25
-set -B -v depth 10
-set -B -v size 30
-set -B -v width 80
-set -B -v lines 25
-set -B -p depth 10
-set -B -p size 30
-set -B -p width 80
-set -B -p lines 25
-set -A format flat
-set -A -f depth 3
-set -A -f size 10
-set -A -f width 80
-set -A -f lines 2
-set -A -r depth 3
-set -A -r size 10
-set -A -r width 80
-set -A -r lines 2
-set -A -v depth 3
-set -A -v size 10
-set -A -v width 80
-set -A -v lines 5
-set -A -p depth 3
-set -A -p size 10
-set -A -p width 80
-set -A -p lines 2
-set max_io_actions 20
+format -P flat
+format_param -P -f depth 3
+format_param -P -f size 10
+format_param -P -f width 80
+format_param -P -f lines 25
+format_param -P -r depth 3
+format_param -P -r size 10
+format_param -P -r width 80
+format_param -P -r lines 25
+format_param -P -v depth 3
+format_param -P -v size 10
+format_param -P -v width 80
+format_param -P -v lines 25
+format_param -P -p depth 3
+format_param -P -p size 10
+format_param -P -p width 80
+format_param -P -p lines 25
+format -B flat
+format_param -B -f depth 10
+format_param -B -f size 30
+format_param -B -f width 80
+format_param -B -f lines 25
+format_param -B -r depth 10
+format_param -B -r size 30
+format_param -B -r width 80
+format_param -B -r lines 25
+format_param -B -v depth 10
+format_param -B -v size 30
+format_param -B -v width 80
+format_param -B -v lines 25
+format_param -B -p depth 10
+format_param -B -p size 30
+format_param -B -p width 80
+format_param -B -p lines 25
+format -A flat
+format_param -A -f depth 3
+format_param -A -f size 10
+format_param -A -f width 80
+format_param -A -f lines 2
+format_param -A -r depth 3
+format_param -A -r size 10
+format_param -A -r width 80
+format_param -A -r lines 2
+format_param -A -v depth 3
+format_param -A -v size 10
+format_param -A -v width 80
+format_param -A -v lines 5
+format_param -A -p depth 3
+format_param -A -p size 10
+format_param -A -p width 80
+format_param -A -p lines 2
+max_io_actions 20
trust save
trust std lib
-set list_context_lines 2
+list_context_lines 2
cvs diff: Diffing tests/debugger/declarative
Index: tests/debugger/declarative/browse_arg.exp
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/debugger/declarative/browse_arg.exp,v
retrieving revision 1.9
diff -u -b -r1.9 browse_arg.exp
--- tests/debugger/declarative/browse_arg.exp 29 Mar 2006 08:07:55 -0000 1.9
+++ tests/debugger/declarative/browse_arg.exp 1 Apr 2006 14:13:11 -0000
@@ -8,9 +8,9 @@
2: 2 2 CALL pred browse_arg.p/2-0 (det) browse_arg.m:19 (browse_arg.m:8)
mdb> finish
3: 2 2 EXIT pred browse_arg.p/2-0 (det) browse_arg.m:19 (browse_arg.m:8)
-mdb> set depth 10
-mdb> set xml_browser_cmd 'cat ./browse_arg.xml.out'
-mdb> set xml_tmp_filename './browse_arg.xml.out'
+mdb> format_param depth 10
+mdb> xml_browser_cmd 'cat ./browse_arg.xml.out'
+mdb> xml_tmp_filename './browse_arg.xml.out'
mdb> dd -d 3 -n 7
p(1, baz(1, bar))
Valid? browse 2
Index: tests/debugger/declarative/browse_arg.inp
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/debugger/declarative/browse_arg.inp,v
retrieving revision 1.6
diff -u -b -r1.6 browse_arg.inp
--- tests/debugger/declarative/browse_arg.inp 20 May 2005 05:40:21 -0000 1.6
+++ tests/debugger/declarative/browse_arg.inp 3 Apr 2006 16:12:48 -0000
@@ -3,18 +3,18 @@
break p
continue
finish
-set depth 10
-set xml_browser_cmd 'cat ./browse_arg.xml.out'
-set xml_tmp_filename './browse_arg.xml.out'
+format_param depth 10
+xml_browser_cmd 'cat ./browse_arg.xml.out'
+xml_tmp_filename './browse_arg.xml.out'
dd -d 3 -n 7
browse 2
ls
quit
-set format verbose
+format verbose
print
-set -B format pretty
+format -B pretty
p
-set -P format pretty
+format -P pretty
p
b -x 2
b --xml
Index: tests/debugger/declarative/change_search.exp
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/debugger/declarative/change_search.exp,v
retrieving revision 1.2
diff -u -b -r1.2 change_search.exp
--- tests/debugger/declarative/change_search.exp 24 Aug 2005 09:07:12 -0000 1.2
+++ tests/debugger/declarative/change_search.exp 3 Apr 2006 18:39:52 -0000
@@ -8,8 +8,8 @@
E2: C2 CALL pred change_search.mylast/2-0 (det)
mdb> finish -n
E3: C2 EXIT pred change_search.mylast/2-0 (det)
-mdb> set format pretty
-mdb> set depth 10
+mdb> format pretty
+mdb> format_param depth 10
mdb> dd
mylast([1, 2, 3, 4, 5, 6, 7, 8, ...], no)
Valid? info
Index: tests/debugger/declarative/change_search.inp
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/debugger/declarative/change_search.inp,v
retrieving revision 1.1
diff -u -b -r1.1 change_search.inp
--- tests/debugger/declarative/change_search.inp 19 Aug 2005 16:08:31 -0000 1.1
+++ tests/debugger/declarative/change_search.inp 3 Apr 2006 16:13:53 -0000
@@ -4,8 +4,8 @@
break mylast
continue
finish -n
-set format pretty
-set depth 10
+format pretty
+format_param depth 10
dd
info
no
Index: tests/debugger/declarative/dependency.exp
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/debugger/declarative/dependency.exp,v
retrieving revision 1.11
diff -u -b -r1.11 dependency.exp
--- tests/debugger/declarative/dependency.exp 20 May 2005 05:40:22 -0000 1.11
+++ tests/debugger/declarative/dependency.exp 3 Apr 2006 18:40:02 -0000
@@ -15,9 +15,9 @@
4: 3 2 CALL pred dependency.test/1-0 (cc_multi) dependency.m:19 (dependency.m:13)
mdb> finish
18: 3 2 EXIT pred dependency.test/1-0 (cc_multi) dependency.m:19 (dependency.m:13)
-mdb> set depth 20
-mdb> set size 201
-mdb> set format raw_pretty
+mdb> format_param depth 20
+mdb> format_param size 201
+mdb> format raw_pretty
mdb> p proc_body
proc_rep(
Index: tests/debugger/declarative/dependency.inp
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/debugger/declarative/dependency.inp,v
retrieving revision 1.5
diff -u -b -r1.5 dependency.inp
--- tests/debugger/declarative/dependency.inp 20 May 2005 05:40:22 -0000 1.5
+++ tests/debugger/declarative/dependency.inp 3 Apr 2006 16:14:25 -0000
@@ -6,9 +6,9 @@
quit
step
finish
-set depth 20
-set size 201
-set format raw_pretty
+format_param depth 20
+format_param size 201
+format raw_pretty
p proc_body
dd -d 3 -n 7
browse 1
Index: tests/debugger/declarative/dice.exp
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/debugger/declarative/dice.exp,v
retrieving revision 1.1
diff -u -b -r1.1 dice.exp
--- tests/debugger/declarative/dice.exp 24 Aug 2005 09:07:12 -0000 1.1
+++ tests/debugger/declarative/dice.exp 3 Apr 2006 18:40:19 -0000
@@ -12,8 +12,8 @@
0: E stop interface pred dice.merge_sort/2-0 (det)
mdb> finish
E3: C2 EXIT pred dice.merge_sort/2-0 (det)
-mdb> set format pretty
-mdb> set depth 10
+mdb> format pretty
+mdb> format_param depth 10
mdb> dd -s sdq -f dice.fail -p dice.pass
merge_sort([4, 1, 2, 3], [1, 1, 2, 3])
Valid? n
Index: tests/debugger/declarative/dice.inp
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/debugger/declarative/dice.inp,v
retrieving revision 1.1
diff -u -b -r1.1 dice.inp
--- tests/debugger/declarative/dice.inp 24 Aug 2005 09:07:12 -0000 1.1
+++ tests/debugger/declarative/dice.inp 3 Apr 2006 16:14:47 -0000
@@ -6,8 +6,8 @@
continue
delete *
finish
-set format pretty
-set depth 10
+format pretty
+format_param depth 10
dd -s sdq -f dice.fail -p dice.pass
n
n
Index: tests/debugger/declarative/divide_and_query1.exp
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/debugger/declarative/divide_and_query1.exp,v
retrieving revision 1.3
diff -u -b -r1.3 divide_and_query1.exp
--- tests/debugger/declarative/divide_and_query1.exp 20 May 2005 05:40:22 -0000 1.3
+++ tests/debugger/declarative/divide_and_query1.exp 3 Apr 2006 18:40:29 -0000
@@ -2,8 +2,8 @@
mdb> mdb> Contexts will not be printed.
mdb> echo on
Command echo enabled.
-mdb> set format flat
-mdb> set size 100
+mdb> format flat
+mdb> format_param size 100
mdb> break to_b
0: + stop interface pred divide_and_query1.to_b/2-0 (det)
mdb> c -n
Index: tests/debugger/declarative/divide_and_query1.inp
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/debugger/declarative/divide_and_query1.inp,v
retrieving revision 1.2
diff -u -b -r1.2 divide_and_query1.inp
--- tests/debugger/declarative/divide_and_query1.inp 20 May 2005 05:40:23 -0000 1.2
+++ tests/debugger/declarative/divide_and_query1.inp 3 Apr 2006 16:16:01 -0000
@@ -1,8 +1,8 @@
register --quiet
context none
echo on
-set format flat
-set size 100
+format flat
+format_param size 100
break to_b
c -n
f -n
Index: tests/debugger/declarative/find_origin.inp
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/debugger/declarative/find_origin.inp,v
retrieving revision 1.2
diff -u -b -r1.2 find_origin.inp
--- tests/debugger/declarative/find_origin.inp 20 May 2005 05:40:24 -0000 1.2
+++ tests/debugger/declarative/find_origin.inp 3 Apr 2006 16:13:04 -0000
@@ -19,7 +19,7 @@
b 2
mark
browse
-set format pretty
+format pretty
p
quit
no
Index: tests/debugger/declarative/sort.exp
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/debugger/declarative/sort.exp,v
retrieving revision 1.1
diff -u -b -r1.1 sort.exp
--- tests/debugger/declarative/sort.exp 20 May 2005 07:14:35 -0000 1.1
+++ tests/debugger/declarative/sort.exp 4 Apr 2006 01:16:31 -0000
@@ -10,8 +10,8 @@
ian
ian
E2: C1 EXIT pred sort.main/2-0 (det) sort.m:27
-mdb> set format pretty
-mdb> set depth 1
+mdb> format pretty
+mdb> format_param depth 1
mdb> dd
main(...)
16 tabled IO actions:
@@ -31,10 +31,10 @@
write_string(...)
write_string(...)
write_string(...)
-Valid? set depth 10
+Valid? depth 10
dd> print io 9
read_line_as_string_2(<<foreign>>, yes, -1, "")
-dd> set depth 1
+dd> depth 1
dd> no
open_stream(...)
3 tabled IO actions:
Index: tests/debugger/declarative/sort.inp
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/debugger/declarative/sort.inp,v
retrieving revision 1.1
diff -u -b -r1.1 sort.inp
--- tests/debugger/declarative/sort.inp 20 May 2005 07:14:36 -0000 1.1
+++ tests/debugger/declarative/sort.inp 3 Apr 2006 16:19:45 -0000
@@ -2,12 +2,12 @@
register --quiet
table_io start
finish
-set format pretty
-set depth 1
+format pretty
+format_param depth 1
dd
-set depth 10
+depth 10
print io 9
-set depth 1
+depth 1
no
yes
quit
Index: tests/debugger/declarative/tabled_read_decl.exp
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/debugger/declarative/tabled_read_decl.exp,v
retrieving revision 1.15
diff -u -b -r1.15 tabled_read_decl.exp
--- tests/debugger/declarative/tabled_read_decl.exp 20 May 2005 05:40:30 -0000 1.15
+++ tests/debugger/declarative/tabled_read_decl.exp 3 Apr 2006 18:44:20 -0000
@@ -34,10 +34,10 @@
dd> browse io 4
browser> print
read_char_code('<<c_pointer>>', 10)
-browser> set num_io_actions 3
+browser> num_io_actions 3
browser> quit
dd> browse 1
-browser> set num_io_actions 10
+browser> num_io_actions 10
browser> quit
dd> no
test_2('<<c_pointer>>', 1, 1123, _, _)
Index: tests/debugger/declarative/tabled_read_decl.inp
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/debugger/declarative/tabled_read_decl.inp,v
retrieving revision 1.6
diff -u -b -r1.6 tabled_read_decl.inp
--- tests/debugger/declarative/tabled_read_decl.inp 20 May 2005 05:40:30 -0000 1.6
+++ tests/debugger/declarative/tabled_read_decl.inp 3 Apr 2006 16:17:15 -0000
@@ -13,10 +13,10 @@
print io 2-1
browse io 4
print
-set num_io_actions 3
+num_io_actions 3
quit
browse 1
-set num_io_actions 10
+num_io_actions 10
quit
no
yes
Index: tests/debugger/declarative/tabled_read_decl_goto.exp
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/debugger/declarative/tabled_read_decl_goto.exp,v
retrieving revision 1.1
diff -u -b -r1.1 tabled_read_decl_goto.exp
--- tests/debugger/declarative/tabled_read_decl_goto.exp 16 Sep 2005 05:42:58 -0000 1.1
+++ tests/debugger/declarative/tabled_read_decl_goto.exp 3 Apr 2006 18:44:27 -0000
@@ -34,10 +34,10 @@
dd> browse io 4
browser> print
read_char_code('<<c_pointer>>', 10)
-browser> set num_io_actions 3
+browser> num_io_actions 3
browser> quit
dd> browse 1
-browser> set num_io_actions 10
+browser> num_io_actions 10
browser> quit
dd> no
test_2('<<c_pointer>>', 1, 1123, _, _)
Index: tests/debugger/declarative/tabled_read_decl_goto.inp
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/debugger/declarative/tabled_read_decl_goto.inp,v
retrieving revision 1.1
diff -u -b -r1.1 tabled_read_decl_goto.inp
--- tests/debugger/declarative/tabled_read_decl_goto.inp 16 Sep 2005 05:42:58 -0000 1.1
+++ tests/debugger/declarative/tabled_read_decl_goto.inp 3 Apr 2006 16:17:47 -0000
@@ -13,10 +13,10 @@
print io 2-1
browse io 4
print
-set num_io_actions 3
+num_io_actions 3
quit
browse 1
-set num_io_actions 10
+num_io_actions 10
quit
no
yes
Index: tests/debugger/declarative/track_through_catch.exp
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/debugger/declarative/track_through_catch.exp,v
retrieving revision 1.4
diff -u -b -r1.4 track_through_catch.exp
--- tests/debugger/declarative/track_through_catch.exp 30 Mar 2006 04:44:59 -0000 1.4
+++ tests/debugger/declarative/track_through_catch.exp 3 Apr 2006 18:45:27 -0000
@@ -35,13 +35,14 @@
Valid? b 2
browser> cd 1
browser> track
-cc_multi_equal(succeeded(2), succeeded(2))
+succeeded(2)
+p(2)
Valid? info
-Context of current question : builtin.m:1061 (exception.m:488)
+Context of current question : track_through_catch.m:21 (track_through_catch.m:14)
Search mode : top down
The current question was chosen because the marked subterm was bound by
-the foreign procedure call inside the predicate builtin.cc_multi_equal/2
-(builtin.m:1055). The path to the subterm in the atom is 2/1.
+the unification inside the predicate track_through_catch.p/1
+(track_through_catch.m:21). The path to the subterm in the atom is 1.
dd> quit
Diagnosis aborted.
E5: C2 EXIT pred exception.try/2-0 (cc_multi) exception.m:480 (track_through_catch.m:15)
cvs diff: Diffing tests/dppd
cvs diff: Diffing tests/general
cvs diff: Diffing tests/general/accumulator
cvs diff: Diffing tests/general/string_format
cvs diff: Diffing tests/general/structure_reuse
cvs diff: Diffing tests/grade_subdirs
cvs diff: Diffing tests/hard_coded
cvs diff: Diffing tests/hard_coded/exceptions
cvs diff: Diffing tests/hard_coded/purity
cvs diff: Diffing tests/hard_coded/sub-modules
cvs diff: Diffing tests/hard_coded/typeclasses
cvs diff: Diffing tests/invalid
cvs diff: Diffing tests/invalid/purity
cvs diff: Diffing tests/misc_tests
cvs diff: Diffing tests/mmc_make
cvs diff: Diffing tests/mmc_make/lib
cvs diff: Diffing tests/recompilation
cvs diff: Diffing tests/tabling
cvs diff: Diffing tests/term
cvs diff: Diffing tests/trailing
cvs diff: Diffing tests/valid
cvs diff: Diffing tests/warnings
cvs diff: Diffing tools
cvs diff: Diffing trace
Index: trace/Mmakefile
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/trace/Mmakefile,v
retrieving revision 1.44
diff -u -b -r1.44 Mmakefile
--- trace/Mmakefile 11 Jul 2005 07:30:30 -0000 1.44
+++ trace/Mmakefile 3 Apr 2006 12:39:22 -0000
@@ -13,6 +13,18 @@
HDRS = \
mercury_trace_alias.h \
mercury_trace_browse.h \
+ mercury_trace_cmd_backward.h \
+ mercury_trace_cmd_breakpoint.h \
+ mercury_trace_cmd_browsing.h \
+ mercury_trace_cmd_dd.h \
+ mercury_trace_cmd_developer.h \
+ mercury_trace_cmd_exp.h \
+ mercury_trace_cmd_help.h \
+ mercury_trace_cmd_misc.h \
+ mercury_trace_cmd_parameter.h \
+ mercury_trace_cmd_queries.h \
+ mercury_trace_cmds.h \
+ mercury_trace_cmd_table_io.h \
mercury_trace_completion.h \
mercury_trace_declarative.h \
mercury_trace_external.h \
@@ -32,6 +44,18 @@
mercury_trace_alias.c \
mercury_trace_browse.c \
mercury_trace.c \
+ mercury_trace_cmd_backward.c \
+ mercury_trace_cmd_breakpoint.c \
+ mercury_trace_cmd_browsing.c \
+ mercury_trace_cmd_dd.c \
+ mercury_trace_cmd_developer.c \
+ mercury_trace_cmd_exp.c \
+ mercury_trace_cmd_forward.c \
+ mercury_trace_cmd_help.c \
+ mercury_trace_cmd_misc.c \
+ mercury_trace_cmd_parameter.c \
+ mercury_trace_cmd_queries.c \
+ mercury_trace_cmd_table_io.c \
mercury_trace_completion.c \
mercury_trace_declarative.c \
mercury_trace_external.c \
Index: trace/mercury_trace_alias.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/trace/mercury_trace_alias.c,v
retrieving revision 1.9
diff -u -b -r1.9 mercury_trace_alias.c
--- trace/mercury_trace_alias.c 31 Mar 2006 05:12:18 -0000 1.9
+++ trace/mercury_trace_alias.c 3 Apr 2006 12:24:32 -0000
@@ -18,11 +18,15 @@
#include "mercury_array_macros.h"
#include "mercury_trace_alias.h"
+#include "mercury_trace_util.h"
static MR_Alias *MR_alias_records = NULL;
static int MR_alias_record_max = 0;
static int MR_alias_record_next = 0;
+/* The initial size of arrays of words. */
+#define MR_INIT_WORD_COUNT 20
+
/* The initial size of the alias table. */
#define INIT_ALIAS_COUNT 32
@@ -179,4 +183,43 @@
MR_trace_filter_alias_completions(const char *word, MR_Completer_Data *data)
{
return (MR_strdiff(word, "EMPTY") && MR_strdiff(word, "NUMBER"));
+}
+
+void
+MR_trace_expand_aliases(char ***words, int *word_max, int *word_count)
+{
+ const char *alias_key;
+ char **alias_words;
+ int alias_word_count;
+ int alias_copy_start;
+ int i;
+ int n;
+
+ if (*word_count == 0) {
+ alias_key = "EMPTY";
+ alias_copy_start = 0;
+ } else if (MR_trace_is_natural_number(*words[0], &n)) {
+ alias_key = "NUMBER";
+ alias_copy_start = 0;
+ } else {
+ alias_key = *words[0];
+ alias_copy_start = 1;
+ }
+
+ if (MR_trace_lookup_alias(alias_key, &alias_words, &alias_word_count)) {
+ MR_ensure_big_enough(*word_count + alias_word_count, *word, char *,
+ MR_INIT_WORD_COUNT);
+
+ /* Move the original words (except the alias key) up. */
+ for (i = *word_count - 1; i >= alias_copy_start; i--) {
+ (*words)[i + alias_word_count - alias_copy_start] = (*words)[i];
+ }
+
+ /* Move the alias body to the words array. */
+ for (i = 0; i < alias_word_count; i++) {
+ (*words)[i] = alias_words[i];
+ }
+
+ *word_count += alias_word_count - alias_copy_start;
+ }
}
Index: trace/mercury_trace_alias.h
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/trace/mercury_trace_alias.h,v
retrieving revision 1.6
diff -u -b -r1.6 mercury_trace_alias.h
--- trace/mercury_trace_alias.h 31 Mar 2006 05:12:18 -0000 1.6
+++ trace/mercury_trace_alias.h 3 Apr 2006 08:15:22 -0000
@@ -73,9 +73,19 @@
extern void MR_trace_print_all_aliases(FILE *fp,
MR_bool mdb_command_format);
+/*
+** If the main command in *words[0] MR_trace_expand_aliases is an alias, then
+** expand the alias. Words, word_max and word_count should form a resizeable
+** array of words, in the sense of mercury_array_macros.h.
+*/
+
+extern void MR_trace_expand_aliases(char ***words, int *word_max,
+ int *word_count);
+
/* A Readline completer for aliases. */
extern MR_Completer_List
*MR_trace_alias_completer(const char *word,
size_t word_length);
+
#endif /* MERCURY_TRACE_ALIAS_H */
Index: trace/mercury_trace_browse.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/trace/mercury_trace_browse.c,v
retrieving revision 1.38
diff -u -b -r1.38 mercury_trace_browse.c
--- trace/mercury_trace_browse.c 31 Mar 2006 05:12:18 -0000 1.38
+++ trace/mercury_trace_browse.c 3 Apr 2006 08:59:46 -0000
@@ -45,9 +45,6 @@
MR_Word MR_trace_browser_persistent_state;
-static MR_bool MR_trace_is_portray_format(const char *str,
- MR_Browse_Format *format);
-
MR_Word
MR_type_value_to_browser_term(MR_TypeInfo type_info, MR_Word value)
{
@@ -132,6 +129,28 @@
);
}
+MR_bool
+MR_trace_is_portray_format(const char *str, MR_Browse_Format *format)
+{
+ *format = MR_BROWSE_DEFAULT_FORMAT;
+
+ if (MR_streq(str, "flat")) {
+ *format = MR_BROWSE_FORMAT_FLAT;
+ return MR_TRUE;
+ } else if (MR_streq(str, "raw_pretty")) {
+ *format = MR_BROWSE_FORMAT_RAW_PRETTY;
+ return MR_TRUE;
+ } else if (MR_streq(str, "verbose")) {
+ *format = MR_BROWSE_FORMAT_VERBOSE;
+ return MR_TRUE;
+ } else if (MR_streq(str, "pretty")) {
+ *format = MR_BROWSE_FORMAT_PRETTY;
+ return MR_TRUE;
+ }
+
+ return MR_FALSE;
+}
+
void
MR_trace_browse(MR_Word type_info, MR_Word value, MR_Browse_Format format)
{
@@ -283,119 +302,6 @@
(MR_Word) caller, MR_trace_browser_persistent_state);
);
}
-}
-
-MR_bool
-MR_trace_set_browser_param(MR_Word print, MR_Word browse, MR_Word print_all,
- MR_Word flat, MR_Word raw_pretty, MR_Word verbose,
- MR_Word pretty, const char *param, const char *value)
-{
- int depth;
- int size;
- int width;
- int lines;
- MR_Browse_Format new_format;
- MR_String aligned_value;
- char *copied_value;
-
- MR_trace_browse_ensure_init();
-
- if (MR_streq(param, "format") &&
- MR_trace_is_portray_format(value, &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);
- );
- } else if (MR_streq(param, "depth") &&
- MR_trace_is_natural_number(value, &depth))
- {
- MR_TRACE_CALL_MERCURY(
- ML_BROWSE_set_depth_from_mdb(print, browse, print_all,
- flat, raw_pretty, verbose, pretty, depth,
- MR_trace_browser_persistent_state,
- &MR_trace_browser_persistent_state);
- );
- } else if (MR_streq(param, "size") &&
- MR_trace_is_natural_number(value, &size))
- {
- MR_TRACE_CALL_MERCURY(
- ML_BROWSE_set_size_from_mdb(print, browse, print_all,
- flat, raw_pretty, verbose, pretty, size,
- MR_trace_browser_persistent_state,
- &MR_trace_browser_persistent_state);
- );
- } else if (MR_streq(param, "width") &&
- MR_trace_is_natural_number(value, &width))
- {
- MR_TRACE_CALL_MERCURY(
- ML_BROWSE_set_width_from_mdb(print, browse, print_all,
- flat, raw_pretty, verbose, pretty, width,
- MR_trace_browser_persistent_state,
- &MR_trace_browser_persistent_state);
- );
- } else if (MR_streq(param, "lines") &&
- MR_trace_is_natural_number(value, &lines))
- {
- MR_TRACE_CALL_MERCURY(
- ML_BROWSE_set_lines_from_mdb(print, browse, print_all,
- flat, raw_pretty, verbose, pretty, lines,
- MR_trace_browser_persistent_state,
- &MR_trace_browser_persistent_state);
- );
- } else if (MR_streq(param, "xml_browser_cmd")) {
- copied_value = (char *) MR_GC_malloc(strlen(value) + 1);
- strcpy(copied_value, value);
- 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 (MR_streq(param, "xml_tmp_filename")) {
- copied_value = (char *) MR_GC_malloc(strlen(value) + 1);
- strcpy(copied_value, value);
- 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 {
- return MR_FALSE;
- }
-
- MR_trace_browser_persistent_state =
- MR_make_permanent(MR_trace_browser_persistent_state,
- MR_trace_browser_persistent_state_type);
- return MR_TRUE;
-}
-
-static MR_bool
-MR_trace_is_portray_format(const char *str, MR_Browse_Format *format)
-{
- *format = MR_BROWSE_DEFAULT_FORMAT;
-
- if (MR_streq(str, "flat")) {
- *format = MR_BROWSE_FORMAT_FLAT;
- return MR_TRUE;
- } else if (MR_streq(str, "raw_pretty")) {
- *format = MR_BROWSE_FORMAT_RAW_PRETTY;
- return MR_TRUE;
- } else if (MR_streq(str, "verbose")) {
- *format = MR_BROWSE_FORMAT_VERBOSE;
- return MR_TRUE;
- } else if (MR_streq(str, "pretty")) {
- *format = MR_BROWSE_FORMAT_PRETTY;
- return MR_TRUE;
- }
- return MR_FALSE;
}
void
Index: trace/mercury_trace_browse.h
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/trace/mercury_trace_browse.h,v
retrieving revision 1.23
diff -u -b -r1.23 mercury_trace_browse.h
--- trace/mercury_trace_browse.h 31 Mar 2006 14:50:40 -0000 1.23
+++ trace/mercury_trace_browse.h 3 Apr 2006 09:02:51 -0000
@@ -1,4 +1,7 @@
/*
+** vim: ts=4 sw=4 expandtab
+*/
+/*
** Copyright (C) 1998-2002, 2004-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.
@@ -19,7 +22,7 @@
#include "mercury_std.h" /* for MR_bool */
#include "mercury_tags.h" /* for MR_DEFINE_MERCURY_ENUM_CONST */
-#include <stdio.h> /* For FILE */
+#include <stdio.h> /* for FILE */
/*
** Convert a term (expressed either as a typeinfo/value pair or as a univ)
@@ -36,7 +39,8 @@
** Save the given browser term to the named file.
*/
-extern void MR_trace_save_term(const char *filename, MR_Word browser_term);
+extern void MR_trace_save_term(const char *filename,
+ MR_Word browser_term);
extern void MR_trace_save_term_xml(const char *filename,
MR_Word browser_term);
@@ -63,9 +67,18 @@
/*
** This value must be different from any of the MR_BROWSE_FORMAT_* values.
*/
+
#define MR_BROWSE_DEFAULT_FORMAT -1
/*
+** If *str represents a value of type MR_Browse_Format, set *format to that
+** value.
+*/
+
+extern MR_bool MR_trace_is_portray_format(const char *str,
+ MR_Browse_Format *format);
+
+/*
** Interactively browse a term.
*/
@@ -94,14 +107,6 @@
MR_Word is_func, MR_Browse_Caller_Type caller,
MR_Browse_Format format);
-/*
-** Set browser parameters.
-*/
-
-extern MR_bool MR_trace_set_browser_param(MR_Word print, MR_Word browse,
- MR_Word print_all, MR_Word flat, MR_Word raw_pretty,
- MR_Word verbose, MR_Word pretty, const char *param,
- const char *value);
/*
** Print all the browser parameters. If mdb_command_format is true, print them
@@ -122,6 +127,7 @@
** that it is possible to cast to/from MR_Word in order to interface with
** Mercury code.
*/
+
typedef enum {
MR_DEFINE_MERCURY_ENUM_CONST(MR_NORMAL_QUERY),
MR_DEFINE_MERCURY_ENUM_CONST(MR_CC_QUERY),
@@ -132,21 +138,23 @@
int num_imports, /* const */ char *imports[]);
#ifdef MR_USE_EXTERNAL_DEBUGGER
-extern void MR_trace_query_external(MR_Query_Type type, MR_String options,
- int num_imports, MR_Word imports_list);
+extern void MR_trace_query_external(MR_Query_Type type,
+ MR_String options, int num_imports,
+ MR_Word imports_list);
#endif
/*
** Points to the state of the interactive term browser that should persist
** between browsing sessions, like the format settings.
*/
+
extern MR_Word MR_trace_browser_persistent_state;
/*
** Initializes the interactive term browser persistent state or does nothing
** if it's already been initialized.
*/
-extern void MR_trace_browse_ensure_init(void);
+extern void MR_trace_browse_ensure_init(void);
#endif /* MERCURY_TRACE_BROWSE_H */
Index: trace/mercury_trace_cmd_backward.c
===================================================================
RCS file: trace/mercury_trace_cmd_backward.c
diff -N trace/mercury_trace_cmd_backward.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ trace/mercury_trace_cmd_backward.c 3 Apr 2006 12:48:17 -0000
@@ -0,0 +1,185 @@
+/*
+** 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 "backward" 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_trace.h"
+#include "mercury_trace_internal.h"
+#include "mercury_trace_cmds.h"
+#include "mercury_trace_cmd_backward.h"
+#include "mercury_trace_cmd_parameter.h"
+#include "mercury_trace_util.h"
+
+/****************************************************************************/
+
+/*
+** The message to print for retries through un-io-tabled areas, when
+** the MR_RETRY_IO_INTERACTIVE option is given.
+*/
+
+#define MR_UNTABLED_IO_RETRY_MESSAGE \
+ "Retry across I/O operations is not always safe.\n" \
+ "Are you sure you want to do it? "
+
+static MR_bool MR_trace_options_retry(MR_Retry_Across_Io *across_io,
+ MR_bool *assume_all_io_is_tabled,
+ char ***words, int *word_count);
+
+/****************************************************************************/
+
+MR_Next
+MR_trace_cmd_retry(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
+ MR_Event_Info *event_info, MR_Code **jumpaddr)
+{
+ int n;
+ int ancestor_level;
+ MR_Retry_Across_Io across_io;
+ const char *problem;
+ MR_Retry_Result result;
+ MR_bool assume_all_io_is_tabled;
+ MR_bool unsafe_retry;
+
+ ancestor_level = 0;
+ across_io = MR_RETRY_IO_INTERACTIVE;
+ assume_all_io_is_tabled = MR_FALSE;
+ if (! MR_trace_options_retry(&across_io, &assume_all_io_is_tabled,
+ &words, &word_count))
+ {
+ ; /* the usage message has already been printed */
+ } else if (word_count == 2 && MR_trace_is_natural_number(words[1], &n)) {
+ ancestor_level = n;
+ } else if (word_count == 1) {
+ ancestor_level = 0;
+ } else {
+ MR_trace_usage_cur_cmd();
+ return KEEP_INTERACTING;
+ }
+
+ if (ancestor_level == 0 && MR_port_is_entry(event_info->MR_trace_port)) {
+ MR_trace_do_noop();
+ return KEEP_INTERACTING;
+ }
+
+ result = MR_trace_retry(event_info, ancestor_level,
+ across_io, assume_all_io_is_tabled, MR_UNTABLED_IO_RETRY_MESSAGE,
+ &unsafe_retry, &problem, MR_mdb_in, MR_mdb_out,
+ jumpaddr);
+ switch (result) {
+
+ case MR_RETRY_OK_DIRECT:
+ cmd->MR_trace_cmd = MR_CMD_GOTO;
+ cmd->MR_trace_stop_event = MR_trace_event_number + 1;
+ cmd->MR_trace_strict = MR_FALSE;
+ cmd->MR_trace_print_level = MR_default_print_level;
+ return STOP_INTERACTING;
+
+ case MR_RETRY_OK_FINISH_FIRST:
+ cmd->MR_trace_cmd = MR_CMD_FINISH;
+ cmd->MR_trace_stop_depth = event_info->MR_call_depth - ancestor_level;
+ cmd->MR_trace_strict = MR_TRUE;
+ cmd->MR_trace_print_level = MR_PRINT_LEVEL_NONE;
+
+ /* Arrange to retry the call once it is finished. */
+ /* XXX we should use the same options as the original retry */
+ MR_insert_line_at_head("retry -o");
+ return STOP_INTERACTING;
+
+ case MR_RETRY_OK_FAIL_FIRST:
+ cmd->MR_trace_cmd = MR_CMD_FAIL;
+ cmd->MR_trace_stop_depth = event_info->MR_call_depth - ancestor_level;
+ cmd->MR_trace_strict = MR_TRUE;
+ cmd->MR_trace_print_level = MR_PRINT_LEVEL_NONE;
+
+ /* Arrange to retry the call once it is finished. */
+ /* XXX we should use the same options as the original retry */
+ MR_insert_line_at_head("retry -o");
+ return STOP_INTERACTING;
+
+ case MR_RETRY_ERROR:
+ fflush(MR_mdb_out);
+ fprintf(MR_mdb_err, "%s\n", problem);
+ return KEEP_INTERACTING;
+ }
+
+ MR_fatal_error("unrecognized retry result");
+}
+
+/****************************************************************************/
+
+/*
+** "retry --assume-all-io-is-tabled" is deliberately not documented as
+** it is for developers only.
+*/
+
+const char *const MR_trace_retry_cmd_args[] =
+ { "--force", "--interactive", "--only-if-safe", NULL };
+
+/****************************************************************************/
+
+static struct MR_option MR_trace_retry_opts[] =
+{
+ { "assume-all-io-is-tabled", MR_no_argument, NULL, 'a' },
+ { "force", MR_no_argument, NULL, 'f' },
+ { "interactive", MR_no_argument, NULL, 'i' },
+ { "only-if-safe", MR_no_argument, NULL, 'o' },
+ { NULL, MR_no_argument, NULL, 0 }
+};
+
+static MR_bool
+MR_trace_options_retry(MR_Retry_Across_Io *across_io,
+ MR_bool *assume_all_io_is_tabled, char ***words, int *word_count)
+{
+ int c;
+
+ MR_optind = 0;
+ while ((c = MR_getopt_long(*word_count, *words, "afio",
+ MR_trace_retry_opts, NULL)) != EOF)
+ {
+ switch (c) {
+
+ case 'a':
+ *assume_all_io_is_tabled = MR_TRUE;
+ break;
+
+ case 'f':
+ *across_io = MR_RETRY_IO_FORCE;
+ break;
+
+ case 'i':
+ *across_io = MR_RETRY_IO_INTERACTIVE;
+ break;
+
+ case 'o':
+ *across_io = MR_RETRY_IO_ONLY_IF_SAFE;
+ 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;
+}
Index: trace/mercury_trace_cmd_backward.h
===================================================================
RCS file: trace/mercury_trace_cmd_backward.h
diff -N trace/mercury_trace_cmd_backward.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ trace/mercury_trace_cmd_backward.h 3 Apr 2006 10:36:53 -0000
@@ -0,0 +1,16 @@
+/*
+** 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.
+*/
+
+#include "mercury_imp.h"
+
+#include "mercury_trace_cmds.h"
+
+extern MR_TraceCmdFunc MR_trace_cmd_retry;
+
+extern const char *const MR_trace_retry_cmd_args[];
Index: trace/mercury_trace_cmd_breakpoint.c
===================================================================
RCS file: trace/mercury_trace_cmd_breakpoint.c
diff -N trace/mercury_trace_cmd_breakpoint.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ trace/mercury_trace_cmd_breakpoint.c 3 Apr 2006 12:50:17 -0000
@@ -0,0 +1,1043 @@
+/*
+** 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 "breakpoint" 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_trace_internal.h"
+#include "mercury_trace_cmds.h"
+#include "mercury_trace_cmd_breakpoint.h"
+#include "mercury_trace_cmd_parameter.h"
+#include "mercury_trace_spy.h"
+#include "mercury_trace_tables.h"
+#include "mercury_trace_util.h"
+
+/****************************************************************************/
+
+typedef enum {
+ MR_MULTIMATCH_ASK, MR_MULTIMATCH_ALL, MR_MULTIMATCH_ONE
+} MR_MultiMatch;
+
+static MR_Spy_Print_List
+ MR_add_to_print_list_end(MR_Browse_Format format,
+ char *word, MR_bool warn,
+ MR_Spy_Print_List print_list);
+static void MR_maybe_print_spy_point(int slot, const char *problem);
+static MR_bool MR_parse_source_locn(char *word, const char **file,
+ int *line);
+
+static MR_bool MR_trace_options_when_action_multi_ignore(MR_Spy_When *when,
+ MR_Spy_Action *action, MR_MultiMatch *multi_match,
+ MR_Spy_Ignore_When *ignore_when, int *ignore_count,
+ MR_Spy_Print_List *print_list,
+ char ***words, int *word_count);
+static MR_bool MR_trace_options_condition(int *break_num,
+ MR_bool *require_var, MR_bool *require_path,
+ char ***words, int *word_count);
+static MR_bool MR_trace_options_ignore_count(
+ MR_Spy_Ignore_When *ignore_when,
+ int *ignore_count, char ***words, int *word_count);
+static MR_bool MR_trace_options_break_print(MR_Browse_Format *format,
+ MR_bool *at_start, MR_bool *warn, char ***words,
+ int *word_count);
+static MR_bool MR_trace_options_register(MR_bool *verbose, char ***words,
+ int *word_count);
+
+/****************************************************************************/
+
+MR_Next
+MR_trace_cmd_break(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
+ MR_Event_Info *event_info, MR_Code **jumpaddr)
+{
+ const MR_Label_Layout *layout;
+ MR_Proc_Spec spec;
+ MR_Spy_When when;
+ MR_Spy_Action action;
+ MR_MultiMatch multi_match;
+ MR_Spy_Ignore_When ignore_when;
+ int ignore_count;
+ MR_Spy_Print_List print_list;
+ const char *file;
+ int line;
+ int breakline;
+ const char *problem;
+
+ layout = event_info->MR_event_sll;
+
+ if (word_count == 2 && MR_streq(words[1], "info")) {
+ int i;
+ int count;
+
+ count = 0;
+ for (i = 0; i < MR_spy_point_next; i++) {
+ if (MR_spy_points[i]->spy_exists) {
+ MR_print_spy_point(MR_mdb_out, i, MR_TRUE);
+ count++;
+ }
+ }
+
+ if (count == 0) {
+ fprintf(MR_mdb_out, "There are no break points.\n");
+ }
+
+ return KEEP_INTERACTING;
+ }
+
+ when = MR_default_breakpoint_scope;
+ action = MR_SPY_STOP;
+ multi_match = MR_MULTIMATCH_ASK;
+ /*
+ ** The value of ignore_when doesn't matter
+ ** while ignore_count contains zero.
+ */
+ ignore_when = MR_SPY_DONT_IGNORE;
+ ignore_count = 0;
+ print_list = NULL;
+ if (! MR_trace_options_when_action_multi_ignore(&when, &action,
+ &multi_match, &ignore_when, &ignore_count, &print_list,
+ &words, &word_count))
+ {
+ ; /* the usage message has already been printed */
+ } else if (word_count == 2 && MR_streq(words[1], "here")) {
+ int slot;
+ MR_Trace_Port port;
+
+ port = event_info->MR_trace_port;
+ if (ignore_count > 0 && ignore_when == MR_SPY_IGNORE_ENTRY &&
+ ! MR_port_is_entry(port))
+ {
+ fprintf(MR_mdb_out, "That breakpoint "
+ "would never become enabled.\n");
+ return KEEP_INTERACTING;
+ } else if (ignore_count > 0 &&
+ ignore_when == MR_SPY_IGNORE_INTERFACE &&
+ ! MR_port_is_interface(port))
+ {
+ fprintf(MR_mdb_out, "That breakpoint "
+ "would never become enabled.\n");
+ return KEEP_INTERACTING;
+ }
+
+ MR_register_all_modules_and_procs(MR_mdb_out, MR_TRUE);
+ slot = MR_add_proc_spy_point(MR_SPY_SPECIFIC, action, ignore_when,
+ ignore_count, layout->MR_sll_entry, layout, print_list, &problem);
+ MR_maybe_print_spy_point(slot, problem);
+ } else if (word_count == 2 && MR_parse_proc_spec(words[1], &spec)) {
+ MR_Matches_Info matches;
+ int slot;
+
+ MR_register_all_modules_and_procs(MR_mdb_out, MR_TRUE);
+ matches = MR_search_for_matching_procedures(&spec);
+ if (matches.match_proc_next == 0) {
+ fflush(MR_mdb_out);
+ fprintf(MR_mdb_err, "mdb: there is no such procedure.\n");
+ } else if (matches.match_proc_next == 1) {
+ slot = MR_add_proc_spy_point(when, action, ignore_when,
+ ignore_count, matches.match_procs[0], NULL, print_list,
+ &problem);
+ MR_maybe_print_spy_point(slot, problem);
+ } else if (multi_match == MR_MULTIMATCH_ALL) {
+ int i;
+
+ for (i = 0; i < matches.match_proc_next; i++) {
+ slot = MR_add_proc_spy_point(when, action, ignore_when,
+ ignore_count, matches.match_procs[i], NULL, print_list,
+ &problem);
+ MR_maybe_print_spy_point(slot, problem);
+ }
+ } else {
+ char buf[80];
+ int i;
+ char *line2;
+
+ fflush(MR_mdb_out);
+ fprintf(MR_mdb_err,
+ "Ambiguous procedure specification. The matches are:\n");
+
+ for (i = 0; i < matches.match_proc_next; i++) {
+ fprintf(MR_mdb_out, "%d: ", i);
+ MR_print_proc_id_and_nl(MR_mdb_out, matches.match_procs[i]);
+ }
+
+ if (multi_match == MR_MULTIMATCH_ONE) {
+ return KEEP_INTERACTING;
+ }
+
+ sprintf(buf, "\nWhich do you want to put "
+ "a breakpoint on (0-%d or *)? ",
+ matches.match_proc_next - 1);
+ line2 = MR_trace_getline(buf, MR_mdb_in, MR_mdb_out);
+ if (line2 == NULL) {
+ /* This means the user input EOF. */
+ fprintf(MR_mdb_out, "none of them\n");
+ } else if (MR_streq(line2, "*")) {
+ for (i = 0; i < matches.match_proc_next; i++) {
+ slot = MR_add_proc_spy_point(when, action, ignore_when,
+ ignore_count, matches.match_procs[i], NULL, print_list,
+ &problem);
+ MR_maybe_print_spy_point(slot, problem);
+ }
+
+ MR_free(line2);
+ } else if (MR_trace_is_natural_number(line2, &i)) {
+ if (0 <= i && i < matches.match_proc_next) {
+ slot = MR_add_proc_spy_point(when, action, ignore_when,
+ ignore_count, matches.match_procs[i], NULL, print_list,
+ &problem);
+ MR_maybe_print_spy_point(slot, problem);
+ } else {
+ fprintf(MR_mdb_out, "no such match\n");
+ }
+ MR_free(line2);
+ } else {
+ fprintf(MR_mdb_out, "none of them\n");
+ MR_free(line2);
+ }
+ }
+ } else if (word_count == 2 &&
+ MR_parse_source_locn(words[1], &file, &line))
+ {
+ int slot;
+
+ slot = MR_add_line_spy_point(action, ignore_when, ignore_count, file,
+ line, print_list, &problem);
+ MR_maybe_print_spy_point(slot, problem);
+ } else if (word_count == 2 &&
+ MR_trace_is_natural_number(words[1], &breakline))
+ {
+ int slot;
+
+ if (MR_find_context(layout, &file, &line)) {
+ slot = MR_add_line_spy_point(action, ignore_when, ignore_count,
+ file, breakline, print_list, &problem);
+ MR_maybe_print_spy_point(slot, problem);
+ } else {
+ MR_fatal_error("cannot find current filename");
+ }
+ } else {
+ MR_trace_usage_cur_cmd();
+ }
+
+ return KEEP_INTERACTING;
+}
+
+MR_Next
+MR_trace_cmd_condition(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
+ MR_Event_Info *event_info, MR_Code **jumpaddr)
+{
+ int break_num;
+ MR_bool require_var;
+ MR_bool require_path;
+ int i;
+ const char *problem;
+ MR_CTerm term;
+ MR_Spy_Test test;
+ char *what_str;
+ char *term_str;
+ int len;
+ char *rest;
+ MR_Spy_Cond *cond;
+ MR_Var_Spec var_spec;
+ char *path;
+
+ break_num = MR_most_recent_spy_point;
+ require_var = MR_TRUE;
+ require_path = MR_TRUE;
+ if (! MR_trace_options_condition(&break_num, &require_var, &require_path,
+ &words, &word_count))
+ {
+ /* the usage message has already been printed */
+ return KEEP_INTERACTING;
+ } else if (word_count < 4) {
+ MR_trace_usage_cur_cmd();
+ return KEEP_INTERACTING;
+ }
+
+ if (break_num < 0) {
+ fprintf(MR_mdb_err, "There is no breakpoint.\n");
+ return KEEP_INTERACTING;
+ }
+
+ if (! (0 <= break_num && break_num < MR_spy_point_next)) {
+ fprintf(MR_mdb_err, "There is no breakpoint %d.\n", break_num);
+ return KEEP_INTERACTING;
+ }
+
+ if (! MR_spy_points[break_num]->spy_exists) {
+ fprintf(MR_mdb_err, "Breakpoint %d has been deleted.\n", break_num);
+ return KEEP_INTERACTING;
+ }
+
+ cond = MR_malloc(sizeof(MR_Spy_Cond));
+
+ what_str = MR_malloc(strlen(words[1]) + 1);
+ strcpy(what_str, words[1]);
+
+ problem = MR_trace_parse_var_path(what_str, &var_spec, &path);
+ if (problem != NULL) {
+ fprintf(MR_mdb_err, "mdb: %s: %s.\n", what_str, problem);
+ return KEEP_INTERACTING;
+ }
+
+ if (MR_streq(words[2], "=") || MR_streq(words[2], "==")) {
+ test = MR_SPY_TEST_EQUAL;
+ } else if (MR_streq(words[2], "!=") || MR_streq(words[2], "\\=")) {
+ test = MR_SPY_TEST_NOT_EQUAL;
+ } else {
+ fprintf(MR_mdb_err, "invalid condition: should be = or !=\n");
+ return KEEP_INTERACTING;
+ }
+
+ len = 0;
+ for (i = 3; i < word_count; i++) {
+ len += strlen(words[i]);
+ }
+
+ term_str = MR_malloc(len + 1);
+ len = 0;
+ for (i = 3; i < word_count; i++) {
+ strcpy(term_str + len, words[i]);
+ len += strlen(words[i]);
+ }
+
+ term = MR_create_cterm(term_str, &rest);
+ if (term == NULL) {
+ fprintf(MR_mdb_out, "syntax error in term\n");
+ return KEEP_INTERACTING;
+ }
+
+ if (*rest != '\0') {
+ fprintf(MR_mdb_out, "syntax error after term\n");
+ return KEEP_INTERACTING;
+ }
+
+ if (MR_spy_points[break_num]->spy_cond != NULL) {
+ MR_delete_cterm(MR_spy_points[break_num]->spy_cond->cond_term);
+ MR_free(MR_spy_points[break_num]->spy_cond->cond_what_string);
+ MR_free(MR_spy_points[break_num]->spy_cond->cond_term_string);
+ MR_free(MR_spy_points[break_num]->spy_cond);
+ }
+
+ cond->cond_var_spec = var_spec;
+ cond->cond_path = path;
+ cond->cond_test = test;
+ cond->cond_term = term;
+ cond->cond_term_string = term_str;
+ cond->cond_what_string = what_str;
+ cond->cond_require_var = require_var;
+ cond->cond_require_path = require_path;
+
+ MR_spy_points[break_num]->spy_cond = cond;
+
+ MR_print_spy_point(MR_mdb_out, break_num, MR_TRUE);
+ return KEEP_INTERACTING;
+}
+
+MR_Next
+MR_trace_cmd_ignore(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
+ MR_Event_Info *event_info, MR_Code **jumpaddr)
+{
+ int n;
+ MR_Spy_Ignore_When ignore_when;
+ int ignore_count;
+ const char *problem;
+
+ ignore_when = MR_SPY_IGNORE_ENTRY;
+ ignore_count = 1;
+ if (! MR_trace_options_ignore_count(&ignore_when, &ignore_count,
+ &words, &word_count))
+ {
+ ; /* the usage message has already been printed */
+ } else if (word_count == 2 && MR_trace_is_natural_number(words[1], &n)) {
+ if (0 <= n && n < MR_spy_point_next && MR_spy_points[n]->spy_exists) {
+ problem = MR_ignore_spy_point(n, ignore_when, ignore_count);
+ MR_maybe_print_spy_point(n, problem);
+ } else {
+ fflush(MR_mdb_out);
+ fprintf(MR_mdb_err, "mdb: break point #%d does not exist.\n", n);
+ }
+ } else if (word_count == 2 && MR_streq(words[1], "*")) {
+ int i;
+ int count;
+
+ count = 0;
+ for (i = 0; i < MR_spy_point_next; i++) {
+ if (MR_spy_points[i]->spy_exists) {
+ problem = MR_ignore_spy_point(n, ignore_when, ignore_count);
+ MR_maybe_print_spy_point(n, problem);
+ count++;
+ }
+ }
+
+ if (count == 0) {
+ fprintf(MR_mdb_err, "There are no break points.\n");
+ }
+ } else if (word_count == 1) {
+ if (0 <= MR_most_recent_spy_point
+ && MR_most_recent_spy_point < MR_spy_point_next
+ && MR_spy_points[MR_most_recent_spy_point]->spy_exists)
+ {
+ n = MR_most_recent_spy_point;
+ problem = MR_ignore_spy_point(n, ignore_when, ignore_count);
+ MR_maybe_print_spy_point(n, problem);
+ } else {
+ fflush(MR_mdb_out);
+ fprintf(MR_mdb_err, "mdb: there is no most recent break point.\n");
+ }
+ } else {
+ MR_trace_usage_cur_cmd();
+ }
+
+ return KEEP_INTERACTING;
+}
+
+MR_Next
+MR_trace_cmd_break_print(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
+ MR_Event_Info *event_info, MR_Code **jumpaddr)
+{
+ int n;
+ int i;
+ MR_Browse_Format format;
+ MR_bool at_start;
+ MR_bool warn;
+ MR_Spy_Print_List print_list;
+
+ if (! MR_trace_options_break_print(&format, &at_start, &warn,
+ &words, &word_count))
+ {
+ ; /* the usage message has already been printed */
+ } else if (word_count > 2 && MR_trace_is_natural_number(words[1], &n)) {
+ if (word_count == 3 && MR_streq(words[2], "none")) {
+ MR_clear_spy_point_print_list(n);
+ MR_print_spy_point(MR_mdb_out, n, MR_TRUE);
+ } else if (0 <= n && n < MR_spy_point_next
+ && MR_spy_points[n]->spy_exists)
+ {
+ print_list = NULL;
+ for (i = 2; i < word_count; i++) {
+ print_list = MR_add_to_print_list_end(format, words[i], warn,
+ print_list);
+ }
+
+ if (at_start) {
+ MR_add_spy_point_print_list_start(n, print_list);
+ } else {
+ MR_add_spy_point_print_list_end(n, print_list);
+ }
+
+ MR_print_spy_point(MR_mdb_out, n, MR_TRUE);
+ } else {
+ fflush(MR_mdb_out);
+ fprintf(MR_mdb_err, "mdb: break point #%d does not exist.\n", n);
+ }
+ } else {
+ MR_trace_usage_cur_cmd();
+ }
+
+ return KEEP_INTERACTING;
+}
+
+MR_Next
+MR_trace_cmd_enable(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)) {
+ if (0 <= n && n < MR_spy_point_next && MR_spy_points[n]->spy_exists) {
+ MR_spy_points[n]->spy_enabled = MR_TRUE;
+ MR_print_spy_point(MR_mdb_out, n, MR_FALSE);
+ } else {
+ fflush(MR_mdb_out);
+ fprintf(MR_mdb_err, "mdb: break point #%d does not exist.\n", n);
+ }
+ } else if (word_count == 2 && MR_streq(words[1], "*")) {
+ int i;
+ int count;
+
+ count = 0;
+ for (i = 0; i < MR_spy_point_next; i++) {
+ if (MR_spy_points[i]->spy_exists) {
+ MR_spy_points[i]->spy_enabled = MR_TRUE;
+ MR_print_spy_point(MR_mdb_out, i, MR_FALSE);
+ count++;
+ }
+ }
+
+ if (count == 0) {
+ fprintf(MR_mdb_err, "There are no break points.\n");
+ }
+ } else if (word_count == 1) {
+ if (0 <= MR_most_recent_spy_point
+ && MR_most_recent_spy_point < MR_spy_point_next
+ && MR_spy_points[MR_most_recent_spy_point]->spy_exists)
+ {
+ MR_spy_points[MR_most_recent_spy_point]->spy_enabled = MR_TRUE;
+ MR_print_spy_point(MR_mdb_out, MR_most_recent_spy_point, MR_FALSE);
+ } else {
+ fflush(MR_mdb_out);
+ fprintf(MR_mdb_err, "mdb: there is no most recent break point.\n");
+ }
+ } else {
+ MR_trace_usage_cur_cmd();
+ }
+
+ return KEEP_INTERACTING;
+}
+
+MR_Next
+MR_trace_cmd_disable(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)) {
+ if (0 <= n && n < MR_spy_point_next && MR_spy_points[n]->spy_exists) {
+ MR_spy_points[n]->spy_enabled = MR_FALSE;
+ MR_print_spy_point(MR_mdb_out, n, MR_FALSE);
+ } else {
+ fflush(MR_mdb_out);
+ fprintf(MR_mdb_err, "mdb: break point #%d does not exist.\n", n);
+ }
+ } else if (word_count == 2 && MR_streq(words[1], "*")) {
+ int i;
+ int count;
+
+ count = 0;
+ for (i = 0; i < MR_spy_point_next; i++) {
+ if (MR_spy_points[i]->spy_exists) {
+ MR_spy_points[i]->spy_enabled = MR_FALSE;
+ MR_print_spy_point(MR_mdb_out, i, MR_FALSE);
+ count++;
+ }
+ }
+
+ if (count == 0) {
+ fflush(MR_mdb_out);
+ fprintf(MR_mdb_err, "There are no break points.\n");
+ }
+ } else if (word_count == 1) {
+ if (0 <= MR_most_recent_spy_point
+ && MR_most_recent_spy_point < MR_spy_point_next
+ && MR_spy_points[MR_most_recent_spy_point]->spy_exists)
+ {
+ MR_spy_points[MR_most_recent_spy_point]->spy_enabled = MR_FALSE;
+ MR_print_spy_point(MR_mdb_out, MR_most_recent_spy_point, MR_FALSE);
+ } else {
+ fflush(MR_mdb_out);
+ fprintf(MR_mdb_err, "There is no most recent break point.\n");
+ }
+ } else {
+ MR_trace_usage_cur_cmd();
+ }
+
+ return KEEP_INTERACTING;
+}
+
+MR_Next
+MR_trace_cmd_delete(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)) {
+ if (0 <= n && n < MR_spy_point_next && MR_spy_points[n]->spy_exists) {
+ MR_spy_points[n]->spy_exists = MR_FALSE;
+ MR_print_spy_point(MR_mdb_out, n, MR_FALSE);
+ MR_spy_points[n]->spy_exists = MR_TRUE;
+ MR_delete_spy_point(n);
+ } else {
+ fflush(MR_mdb_out);
+ fprintf(MR_mdb_err, "mdb: break point #%d does not exist.\n", n);
+ }
+ } else if (word_count == 2 && MR_streq(words[1], "*")) {
+ int i;
+ int count;
+
+ count = 0;
+ for (i = 0; i < MR_spy_point_next; i++) {
+ if (MR_spy_points[i]->spy_exists) {
+ MR_spy_points[i]->spy_exists = MR_FALSE;
+ MR_print_spy_point(MR_mdb_out, i, MR_FALSE);
+ MR_spy_points[i]->spy_exists = MR_TRUE;
+ MR_delete_spy_point(i);
+ count++;
+ }
+ }
+
+ if (count == 0) {
+ fflush(MR_mdb_out);
+ fprintf(MR_mdb_err, "There are no break points.\n");
+ }
+ } else if (word_count == 1) {
+ if (0 <= MR_most_recent_spy_point
+ && MR_most_recent_spy_point < MR_spy_point_next
+ && MR_spy_points[MR_most_recent_spy_point]->spy_exists)
+ {
+ int slot;
+
+ slot = MR_most_recent_spy_point;
+ MR_spy_points[slot]->spy_exists = MR_FALSE;
+ MR_print_spy_point(MR_mdb_out, slot, MR_FALSE);
+ MR_spy_points[slot]->spy_exists = MR_TRUE;
+ MR_delete_spy_point(slot);
+ } else {
+ fflush(MR_mdb_out);
+ fprintf(MR_mdb_err, "mdb: there is no most recent break point.\n");
+ }
+ } else {
+ MR_trace_usage_cur_cmd();
+ }
+
+ return KEEP_INTERACTING;
+}
+
+MR_Next
+MR_trace_cmd_register(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
+ MR_Event_Info *event_info, MR_Code **jumpaddr)
+{
+ MR_bool verbose;
+
+ verbose = MR_TRUE;
+
+ if (! MR_trace_options_register(&verbose, &words, &word_count)) {
+ ; /* the usage message has already been printed */
+ } else if (word_count == 1) {
+ MR_register_all_modules_and_procs(MR_mdb_out, verbose);
+ } else {
+ MR_trace_usage_cur_cmd();
+ }
+
+ return KEEP_INTERACTING;
+}
+
+MR_Next
+MR_trace_cmd_modules(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
+ MR_Event_Info *event_info, MR_Code **jumpaddr)
+{
+ if (word_count == 1) {
+ MR_register_all_modules_and_procs(MR_mdb_out, MR_TRUE);
+ MR_dump_module_list(MR_mdb_out);
+ } else {
+ MR_trace_usage_cur_cmd();
+ }
+
+ return KEEP_INTERACTING;
+}
+
+MR_Next
+MR_trace_cmd_procedures(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
+ MR_Event_Info *event_info, MR_Code **jumpaddr)
+{
+ if (word_count == 2) {
+ MR_register_all_modules_and_procs(MR_mdb_out, MR_TRUE);
+ MR_dump_module_procs(MR_mdb_out, words[1]);
+ } else {
+ MR_trace_usage_cur_cmd();
+ }
+
+ return KEEP_INTERACTING;
+}
+
+/****************************************************************************/
+
+static MR_Spy_Print_List
+MR_add_to_print_list_end(MR_Browse_Format format, char *word, MR_bool warn,
+ MR_Spy_Print_List print_list)
+{
+ MR_Spy_Print_List list;
+ MR_Spy_Print_List new_list;
+ MR_Spy_Print new_node;
+
+ new_node = MR_malloc(sizeof(struct MR_Spy_Print_Struct));
+ new_node->p_format = format;
+ new_node->p_warn = warn;
+ if (MR_streq(word, "*")) {
+ new_node->p_what = MR_SPY_PRINT_ALL;
+ new_node->p_name = NULL;
+ } else if (MR_streq(word, "goal")) {
+ new_node->p_what = MR_SPY_PRINT_GOAL;
+ new_node->p_name = NULL;
+ } else {
+ new_node->p_what = MR_SPY_PRINT_ONE;
+ new_node->p_name = MR_copy_string(word);
+ }
+
+ new_list = MR_malloc(sizeof(struct MR_Spy_Print_List_Struct));
+ new_list->pl_cur = new_node;
+ new_list->pl_next = NULL;
+
+ list = print_list;
+ if (list == NULL) {
+ return new_list;
+ }
+
+ while (list->pl_next != NULL) {
+ list = list->pl_next;
+ }
+
+ list->pl_next = new_list;
+ return print_list;
+}
+
+static void
+MR_maybe_print_spy_point(int slot, const char *problem)
+{
+ if (slot < 0) {
+ fflush(MR_mdb_out);
+ fprintf(MR_mdb_err, "mdb: %s.\n", problem);
+ } else {
+ MR_print_spy_point(MR_mdb_out, slot, MR_TRUE);
+ }
+}
+
+static MR_bool
+MR_parse_source_locn(char *word, const char **file, int *line)
+{
+ char *s;
+ const char *t;
+
+ if ((s = strrchr(word, ':')) != NULL) {
+ for (t = s+1; *t != '\0'; t++) {
+ if (! MR_isdigit(*t)) {
+ return MR_FALSE;
+ }
+ }
+
+ *s = '\0';
+ *file = word;
+ *line = atoi(s+1);
+ return MR_TRUE;
+ }
+
+ return MR_FALSE;
+}
+
+/****************************************************************************/
+
+const char *const MR_trace_break_cmd_args[] =
+ { "-A", "-E", "-I", "-O", "-P", "-S", "-a", "-e", "-i",
+ "--all", "--entry", "--ignore-entry", "--ignore-interface",
+ "--interface", "--print", "--select-all", "--select-one",
+ "--stop", "here", "info", NULL };
+
+const char *const MR_trace_ignore_cmd_args[] =
+ { "-E", "-I", "--ignore-entry", "--ignore-interface", NULL };
+
+/****************************************************************************/
+
+static struct MR_option MR_trace_when_action_multi_ignore_opts[] =
+{
+ { "all", MR_no_argument, NULL, 'a' },
+ { "entry", MR_no_argument, NULL, 'e' },
+ { "interface", MR_no_argument, NULL, 'i' },
+ { "ignore-entry", MR_required_argument, NULL, 'E' },
+ { "ignore-interface", MR_required_argument, NULL, 'I' },
+ { "print-list", MR_required_argument, NULL, 'p' },
+ { "no-warn", MR_no_argument, NULL, 'n' },
+ { "print", MR_no_argument, NULL, 'P' },
+ { "stop", MR_no_argument, NULL, 'S' },
+ { "select-all", MR_no_argument, NULL, 'A' },
+ { "select-one", MR_no_argument, NULL, 'O' },
+ { NULL, MR_no_argument, NULL, 0 }
+};
+
+static MR_bool
+MR_trace_options_when_action_multi_ignore(MR_Spy_When *when,
+ MR_Spy_Action *action, MR_MultiMatch *multi_match,
+ MR_Spy_Ignore_When*ignore_when, int *ignore_count,
+ MR_Spy_Print_List *print_list,
+ char ***words, int *word_count)
+{
+ int c;
+ MR_Spy_Print node;
+ MR_Spy_Print_List list;
+ MR_bool warn;
+
+ warn = MR_TRUE;
+ MR_optind = 0;
+ while ((c = MR_getopt_long(*word_count, *words, "AE:I:OPSaeinp:",
+ MR_trace_when_action_multi_ignore_opts, NULL)) != EOF)
+ {
+ switch (c) {
+
+ case 'a':
+ *when = MR_SPY_ALL;
+ break;
+
+ case 'e':
+ *when = MR_SPY_ENTRY;
+ break;
+
+ case 'i':
+ *when = MR_SPY_INTERFACE;
+ break;
+
+ case 'n':
+ warn = MR_FALSE;
+ break;
+
+ case 'p':
+ *print_list = MR_add_to_print_list_end(MR_BROWSE_FORMAT_FLAT,
+ MR_optarg, warn, *print_list);
+ break;
+
+ case 'E':
+ if (! MR_trace_is_natural_number(MR_optarg, ignore_count)) {
+ MR_trace_usage_cur_cmd();
+ return MR_FALSE;
+ }
+ *ignore_when = MR_SPY_IGNORE_ENTRY;
+ break;
+
+ case 'I':
+ if (! MR_trace_is_natural_number(MR_optarg, ignore_count)) {
+ MR_trace_usage_cur_cmd();
+ return MR_FALSE;
+ }
+ *ignore_when = MR_SPY_IGNORE_INTERFACE;
+ break;
+
+ case 'A':
+ *multi_match = MR_MULTIMATCH_ALL;
+ break;
+
+ case 'O':
+ *multi_match = MR_MULTIMATCH_ONE;
+ break;
+
+ case 'P':
+ *action = MR_SPY_PRINT;
+ break;
+
+ case 'S':
+ *action = MR_SPY_STOP;
+ 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_condition_opts[] =
+{
+ { "break-num", MR_required_argument, NULL, 'n' },
+ { "dont-require-var", MR_no_argument, NULL, 'v' },
+ { "dont-require-path", MR_no_argument, NULL, 'p' },
+ { NULL, MR_no_argument, NULL, 0 }
+};
+
+static MR_bool
+MR_trace_options_condition(int *break_num, MR_bool *require_var,
+ MR_bool *require_path, char ***words, int *word_count)
+{
+ int c;
+ int n;
+
+ MR_optind = 0;
+ while ((c = MR_getopt_long(*word_count, *words, "n:vp",
+ MR_trace_condition_opts, NULL)) != EOF)
+ {
+ switch (c) {
+
+ case 'n':
+ if (! MR_trace_is_natural_number(MR_optarg, &n)) {
+ MR_trace_usage_cur_cmd();
+ return MR_FALSE;
+ }
+ *break_num = n;
+ break;
+
+ case 'p':
+ *require_path = MR_FALSE;
+ break;
+
+ case 'v':
+ /*
+ ** If a variable is missing, then the path inside
+ ** is missing as well.
+ */
+
+ *require_path = MR_FALSE;
+ *require_var = MR_FALSE;
+ 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_ignore_count_opts[] =
+{
+ { "ignore-entry", MR_required_argument, NULL, 'E' },
+ { "ignore-interface", MR_required_argument, NULL, 'I' },
+ { NULL, MR_no_argument, NULL, 0 }
+};
+
+static MR_bool
+MR_trace_options_ignore_count(MR_Spy_Ignore_When *ignore_when,
+ int *ignore_count, char ***words, int *word_count)
+{
+ int c;
+
+ MR_optind = 0;
+ while ((c = MR_getopt_long(*word_count, *words, "E:I:",
+ MR_trace_ignore_count_opts, NULL)) != EOF)
+ {
+ switch (c) {
+
+ case 'E':
+ if (! MR_trace_is_natural_number(MR_optarg, ignore_count)) {
+ MR_trace_usage_cur_cmd();
+ return MR_FALSE;
+ }
+ *ignore_when = MR_SPY_IGNORE_ENTRY;
+ break;
+
+ case 'I':
+ if (! MR_trace_is_natural_number(MR_optarg, ignore_count)) {
+ MR_trace_usage_cur_cmd();
+ return MR_FALSE;
+ }
+ *ignore_when = MR_SPY_IGNORE_INTERFACE;
+ 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_break_print_opts[] =
+{
+ { "end", MR_no_argument, NULL, 'e' },
+ { "no-warn", MR_no_argument, NULL, 'n' },
+ { "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' },
+ { NULL, MR_no_argument, NULL, 0 }
+};
+
+static MR_bool
+MR_trace_options_break_print(MR_Browse_Format *format, MR_bool *at_start,
+ MR_bool *warn, char ***words, int *word_count)
+{
+ int c;
+
+ *format = MR_BROWSE_FORMAT_FLAT;
+ *at_start = MR_TRUE;
+ *warn = MR_TRUE;
+ MR_optind = 0;
+ while ((c = MR_getopt_long(*word_count, *words, "enfrvp",
+ MR_trace_break_print_opts, NULL)) != EOF)
+ {
+ switch (c) {
+
+ case 'e':
+ *at_start = MR_FALSE;
+ break;
+
+ case 'n':
+ *warn = MR_FALSE;
+ break;
+
+ case 'f':
+ *format = MR_BROWSE_FORMAT_FLAT;
+ break;
+
+ case 'r':
+ *format = MR_BROWSE_FORMAT_RAW_PRETTY;
+ break;
+
+ case 'v':
+ *format = MR_BROWSE_FORMAT_VERBOSE;
+ break;
+
+ case 'p':
+ *format = MR_BROWSE_FORMAT_PRETTY;
+ 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_register_opts[] =
+{
+ { "quiet", MR_no_argument, NULL, 'q' },
+ { "verbose", MR_no_argument, NULL, 'v' },
+ { NULL, MR_no_argument, NULL, 0 }
+};
+
+static MR_bool
+MR_trace_options_register(MR_bool *verbose, char ***words, int *word_count)
+{
+ int c;
+
+ MR_optind = 0;
+ while ((c = MR_getopt_long(*word_count, *words, "qv",
+ MR_trace_register_opts, NULL)) != EOF)
+ {
+ switch (c) {
+
+ case 'q':
+ *verbose = MR_FALSE;
+ break;
+
+ case 'v':
+ *verbose = MR_TRUE;
+ 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;
+}
Index: trace/mercury_trace_cmd_breakpoint.h
===================================================================
RCS file: trace/mercury_trace_cmd_breakpoint.h
diff -N trace/mercury_trace_cmd_breakpoint.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ trace/mercury_trace_cmd_breakpoint.h 3 Apr 2006 11:46:21 -0000
@@ -0,0 +1,26 @@
+/*
+** 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.
+*/
+
+#include "mercury_imp.h"
+
+#include "mercury_trace_cmds.h"
+
+extern MR_TraceCmdFunc MR_trace_cmd_break;
+extern MR_TraceCmdFunc MR_trace_cmd_condition;
+extern MR_TraceCmdFunc MR_trace_cmd_ignore;
+extern MR_TraceCmdFunc MR_trace_cmd_break_print;
+extern MR_TraceCmdFunc MR_trace_cmd_enable;
+extern MR_TraceCmdFunc MR_trace_cmd_disable;
+extern MR_TraceCmdFunc MR_trace_cmd_delete;
+extern MR_TraceCmdFunc MR_trace_cmd_register;
+extern MR_TraceCmdFunc MR_trace_cmd_modules;
+extern MR_TraceCmdFunc MR_trace_cmd_procedures;
+
+extern const char *const MR_trace_break_cmd_args[];
+extern const char *const MR_trace_ignore_cmd_args[];
Index: trace/mercury_trace_cmd_browsing.c
===================================================================
RCS file: trace/mercury_trace_cmd_browsing.c
diff -N trace/mercury_trace_cmd_browsing.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ trace/mercury_trace_cmd_browsing.c 3 Apr 2006 12:50:24 -0000
@@ -0,0 +1,1278 @@
+/*
+** 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 "browsing" 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_trace_internal.h"
+#include "mercury_trace_cmds.h"
+#include "mercury_trace_cmd_browsing.h"
+#include "mercury_trace_cmd_parameter.h"
+#include "mercury_trace_vars.h"
+#include "mercury_trace_hold_vars.h"
+#include "mercury_trace_browse.h"
+#include "mercury_trace_util.h"
+
+#include "mdb.listing.mh"
+#include "mdb.diff.mh"
+#include "mdb.declarative_execution.mh"
+#include "mdbcomp.program_representation.mh"
+
+/****************************************************************************/
+
+static void MR_trace_set_level_and_report(int ancestor_level,
+ MR_bool detailed, MR_bool print_optionals);
+static const char *MR_trace_browse_exception(MR_Event_Info *event_info,
+ MR_Browser browser, MR_Browse_Caller_Type caller,
+ MR_Browse_Format format);
+static const char *MR_trace_browse_proc_body(MR_Event_Info *event_info,
+ MR_Browser browser, MR_Browse_Caller_Type caller,
+ MR_Browse_Format format);
+
+/* Functions to invoke the user's XML browser on terms or goals */
+static void MR_trace_browse_xml(MR_Word type_info, MR_Word value,
+ MR_Browse_Caller_Type caller, MR_Browse_Format format);
+static void MR_trace_browse_goal_xml(MR_ConstString name,
+ MR_Word arg_list, MR_Word is_func,
+ MR_Browse_Caller_Type caller, MR_Browse_Format format);
+
+static void MR_trace_cmd_stack_2(MR_Event_Info *event_info,
+ MR_bool detailed, int frame_limit, int line_limit);
+
+static const char *MR_trace_new_source_window(const char *window_cmd,
+ const char *server_cmd, const char *server_name,
+ int timeout, MR_bool force, MR_bool verbose,
+ MR_bool split);
+
+static MR_bool MR_trace_options_detailed(MR_bool *detailed, char ***words,
+ int *word_count);
+static MR_bool MR_trace_options_stack_trace(MR_bool *detailed,
+ int *frame_limit, char ***words, int *word_count);
+static MR_bool MR_trace_options_format(MR_Browse_Format *format,
+ MR_bool *xml, char ***words, int *word_count);
+static MR_bool MR_trace_options_view(const char **window_cmd,
+ const char **server_cmd, const char **server_name,
+ int *timeout, MR_bool *force, MR_bool *verbose,
+ MR_bool *split, MR_bool *close_window, char ***words,
+ int *word_count);
+static MR_bool MR_trace_options_diff(int *start, int *max,
+ char ***words, int *word_count);
+static MR_bool MR_trace_options_dump(MR_bool *xml,
+ char ***words, int *word_count);
+
+/****************************************************************************/
+
+MR_Next
+MR_trace_cmd_level(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
+ MR_Event_Info *event_info, MR_Code **jumpaddr)
+{
+ int n;
+ MR_bool detailed;
+
+ detailed = MR_FALSE;
+ if (! MR_trace_options_detailed(&detailed, &words, &word_count)) {
+ ; /* the usage message has already been printed */
+ } else if (word_count == 2 && MR_trace_is_natural_number(words[1], &n)) {
+ MR_trace_set_level_and_report(n, detailed, MR_print_optionals);
+ } else {
+ MR_trace_usage_cur_cmd();
+ }
+
+ return KEEP_INTERACTING;
+}
+
+MR_Next
+MR_trace_cmd_up(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
+ MR_Event_Info *event_info, MR_Code **jumpaddr)
+{
+ int n;
+ MR_bool detailed;
+
+ detailed = MR_FALSE;
+ if (! MR_trace_options_detailed(&detailed, &words, &word_count)) {
+ ; /* the usage message has already been printed */
+ } else if (word_count == 2 && MR_trace_is_natural_number(words[1], &n)) {
+ MR_trace_set_level_and_report(MR_trace_current_level() + n, detailed,
+ MR_print_optionals);
+ } else if (word_count == 1) {
+ MR_trace_set_level_and_report(MR_trace_current_level() + 1, detailed,
+ MR_print_optionals);
+ } else {
+ MR_trace_usage_cur_cmd();
+ }
+
+ return KEEP_INTERACTING;
+}
+
+MR_Next
+MR_trace_cmd_down(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
+ MR_Event_Info *event_info, MR_Code **jumpaddr)
+{
+ int n;
+ MR_bool detailed;
+
+ detailed = MR_FALSE;
+ if (! MR_trace_options_detailed(&detailed, &words, &word_count)) {
+ ; /* the usage message has already been printed */
+ } else if (word_count == 2 && MR_trace_is_natural_number(words[1], &n)) {
+ MR_trace_set_level_and_report(MR_trace_current_level() - n, detailed,
+ MR_print_optionals);
+ } else if (word_count == 1) {
+ MR_trace_set_level_and_report(MR_trace_current_level() - 1, detailed,
+ MR_print_optionals);
+ } else {
+ MR_trace_usage_cur_cmd();
+ }
+
+ return KEEP_INTERACTING;
+}
+
+MR_Next
+MR_trace_cmd_vars(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
+ MR_Event_Info *event_info, MR_Code **jumpaddr)
+{
+ if (word_count == 1) {
+ const char *problem;
+
+ problem = MR_trace_list_vars(MR_mdb_out);
+ if (problem != NULL) {
+ fflush(MR_mdb_out);
+ fprintf(MR_mdb_err, "mdb: %s.\n", problem);
+ }
+ } else {
+ MR_trace_usage_cur_cmd();
+ }
+
+ return KEEP_INTERACTING;
+}
+
+MR_Next
+MR_trace_cmd_held_vars(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
+ MR_Event_Info *event_info, MR_Code **jumpaddr)
+{
+ if (word_count == 1) {
+ MR_trace_list_held_vars(MR_mdb_out);
+ } else {
+ MR_trace_usage_cur_cmd();
+ }
+
+ return KEEP_INTERACTING;
+}
+
+MR_Next
+MR_trace_cmd_print(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
+ MR_Event_Info *event_info, MR_Code **jumpaddr)
+{
+ MR_Browse_Format format;
+ MR_bool xml;
+ int n;
+
+ if (! MR_trace_options_format(&format, &xml, &words, &word_count)) {
+ ; /* the usage message has already been printed */
+ } else if (xml) {
+ /* the --xml option is not valid for print */
+ MR_trace_usage_cur_cmd();
+ } else if (word_count == 1) {
+ const char *problem;
+
+ problem = MR_trace_browse_one_goal(MR_mdb_out,
+ MR_trace_browse_goal_internal,
+ MR_BROWSE_CALLER_PRINT, format);
+
+ if (problem != NULL) {
+ fflush(MR_mdb_out);
+ fprintf(MR_mdb_err, "mdb: %s.\n", problem);
+ }
+ } else if (word_count == 2) {
+ const char *problem;
+
+ if (MR_streq(words[1], "*")) {
+ problem = MR_trace_browse_all(MR_mdb_out,
+ MR_trace_browse_internal, format);
+ } else if (MR_streq(words[1], "goal")) {
+ problem = MR_trace_browse_one_goal(MR_mdb_out,
+ MR_trace_browse_goal_internal, MR_BROWSE_CALLER_PRINT, format);
+ } else if (MR_streq(words[1], "exception")) {
+ problem = MR_trace_browse_exception(event_info,
+ MR_trace_browse_internal, MR_BROWSE_CALLER_PRINT, format);
+ } else if (MR_streq(words[1], "proc_body")) {
+ problem = MR_trace_browse_proc_body(event_info,
+ MR_trace_browse_internal, MR_BROWSE_CALLER_PRINT, format);
+ } else {
+ problem = MR_trace_parse_browse_one(MR_mdb_out, MR_TRUE, words[1],
+ MR_trace_browse_internal, MR_BROWSE_CALLER_PRINT, format,
+ MR_FALSE);
+ }
+
+ if (problem != NULL) {
+ fflush(MR_mdb_out);
+ fprintf(MR_mdb_err, "mdb: %s.\n", problem);
+ }
+ } else if (word_count == 3 && MR_streq(words[1], "action")
+ && MR_trace_is_natural_number(words[2], &n))
+ {
+ const char *problem;
+
+ problem = MR_trace_browse_action(MR_mdb_out, n,
+ MR_trace_browse_goal_internal,
+ MR_BROWSE_CALLER_PRINT, format);
+
+ if (problem != NULL) {
+ fflush(MR_mdb_out);
+ fprintf(MR_mdb_err, "mdb: %s.\n", problem);
+ }
+ } else {
+ MR_trace_usage_cur_cmd();
+ }
+
+ return KEEP_INTERACTING;
+}
+
+MR_Next
+MR_trace_cmd_browse(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
+ MR_Event_Info *event_info, MR_Code **jumpaddr)
+{
+ MR_Browse_Format format;
+ MR_bool xml;
+ int n;
+ MR_GoalBrowser goal_browser;
+ MR_Browser browser;
+
+ if (! MR_trace_options_format(&format, &xml, &words, &word_count)) {
+ ; /* the usage message has already been printed */
+ } else {
+ if (xml) {
+ goal_browser = MR_trace_browse_goal_xml;
+ browser = MR_trace_browse_xml;
+ } else {
+ goal_browser = MR_trace_browse_goal_internal;
+ browser = MR_trace_browse_internal;
+ }
+
+ if (word_count == 1) {
+ const char *problem;
+
+ problem = MR_trace_browse_one_goal(MR_mdb_out, goal_browser,
+ MR_BROWSE_CALLER_BROWSE, format);
+
+ if (problem != NULL) {
+ fflush(MR_mdb_out);
+ fprintf(MR_mdb_err, "mdb: %s.\n", problem);
+ }
+ } else if (word_count == 2) {
+ const char *problem;
+
+ if (MR_streq(words[1], "goal")) {
+ problem = MR_trace_browse_one_goal(MR_mdb_out, goal_browser,
+ MR_BROWSE_CALLER_BROWSE, format);
+ } else if (MR_streq(words[1], "exception")) {
+ problem = MR_trace_browse_exception(event_info, browser,
+ MR_BROWSE_CALLER_BROWSE, format);
+ } else if (MR_streq(words[1], "proc_body")) {
+ problem = MR_trace_browse_proc_body(event_info, browser,
+ MR_BROWSE_CALLER_BROWSE, format);
+ } else {
+ problem = MR_trace_parse_browse_one(MR_mdb_out, MR_FALSE,
+ words[1], browser, MR_BROWSE_CALLER_BROWSE, format,
+ MR_TRUE);
+ }
+
+ if (problem != NULL) {
+ fflush(MR_mdb_out);
+ fprintf(MR_mdb_err, "mdb: %s.\n", problem);
+ }
+ } else if (word_count == 3 && MR_streq(words[1], "action")
+ && MR_trace_is_natural_number(words[2], &n))
+ {
+ const char *problem;
+
+ problem = MR_trace_browse_action(MR_mdb_out, n, goal_browser,
+ MR_BROWSE_CALLER_BROWSE, format);
+
+ if (problem != NULL) {
+ fflush(MR_mdb_out);
+ fprintf(MR_mdb_err, "mdb: %s.\n", problem);
+ }
+ } else {
+ MR_trace_usage_cur_cmd();
+ }
+ }
+
+ return KEEP_INTERACTING;
+}
+
+MR_Next
+MR_trace_cmd_stack(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
+ MR_Event_Info *event_info, MR_Code **jumpaddr)
+{
+ MR_bool detailed;
+ int frame_limit = 0;
+ int line_limit = MR_stack_default_line_limit;
+ int spec_line_limit;
+
+ detailed = MR_FALSE;
+ if (! MR_trace_options_stack_trace(&detailed, &frame_limit,
+ &words, &word_count))
+ {
+ ; /* the usage message has already been printed */
+ } else if (word_count == 1) {
+ MR_trace_cmd_stack_2(event_info, detailed, frame_limit, line_limit);
+ } else if (word_count == 2 &&
+ MR_trace_is_natural_number(words[1], &spec_line_limit))
+ {
+ MR_trace_cmd_stack_2(event_info, detailed, frame_limit,
+ spec_line_limit);
+ } else {
+ MR_trace_usage_cur_cmd();
+ }
+
+ return KEEP_INTERACTING;
+}
+
+MR_Next
+MR_trace_cmd_current(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
+ MR_Event_Info *event_info, MR_Code **jumpaddr)
+{
+ if (word_count == 1) {
+ MR_trace_event_print_internal_report(event_info);
+ } else {
+ MR_trace_usage_cur_cmd();
+ }
+
+ return KEEP_INTERACTING;
+}
+
+MR_Next
+MR_trace_cmd_view(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
+ MR_Event_Info *event_info, MR_Code **jumpaddr)
+{
+ const char *window_cmd = NULL;
+ const char *server_cmd = NULL;
+ const char *server_name = NULL;
+ int timeout = 8; /* seconds */
+ MR_bool force = MR_FALSE;
+ MR_bool verbose = MR_FALSE;
+ MR_bool split = MR_FALSE;
+ MR_bool close_window = MR_FALSE;
+ const char *msg;
+
+ if (! MR_trace_options_view(&window_cmd, &server_cmd, &server_name,
+ &timeout, &force, &verbose, &split, &close_window,
+ &words, &word_count))
+ {
+ ; /* the usage message has already been printed */
+ } else if (word_count != 1) {
+ MR_trace_usage_cur_cmd();
+ } else if (close_window) {
+ MR_trace_maybe_close_source_window(verbose);
+ } else {
+ msg = MR_trace_new_source_window(window_cmd, server_cmd, server_name,
+ timeout, force, verbose, split);
+ if (msg != NULL) {
+ fflush(MR_mdb_out);
+ fprintf(MR_mdb_err, "mdb: %s.\n", msg);
+ }
+
+ MR_trace_maybe_sync_source_window(event_info, verbose);
+ }
+
+ return KEEP_INTERACTING;
+}
+
+MR_Next
+MR_trace_cmd_hold(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
+ MR_Event_Info *event_info, MR_Code **jumpaddr)
+{
+ char *event_var_name;
+ char *held_var_name;
+ MR_TypeInfo type_info;
+ MR_Word value;
+ const char *ignored_name;
+ const char *problem;
+ MR_bool bad_subterm;
+
+ if (word_count == 2) {
+ event_var_name = words[1];
+ held_var_name = words[1];
+ } else if (word_count == 3) {
+ event_var_name = words[1];
+ held_var_name = words[2];
+ } else {
+ MR_trace_usage_cur_cmd();
+ return KEEP_INTERACTING;
+ }
+
+ if (strpbrk(held_var_name, "^/") != NULL) {
+ /* Don't allow path separators in variable names. */
+ MR_trace_usage_cur_cmd();
+ return KEEP_INTERACTING;
+ }
+
+ if (held_var_name[0] == '$') {
+ /* Ignore any unneeded initial $ signs. */
+ held_var_name = &held_var_name[1];
+ }
+
+ problem = MR_trace_parse_lookup_var_path(event_var_name, &type_info,
+ &value, &bad_subterm);
+ if (problem != NULL) {
+ fflush(MR_mdb_out);
+ fprintf(MR_mdb_err, "mdb: %s%s.\n",
+ (bad_subterm? "there is no path " : ""), problem);
+ return KEEP_INTERACTING;
+ }
+
+ if (! MR_add_hold_var(held_var_name, type_info, value)) {
+ fflush(MR_mdb_out);
+ fprintf(MR_mdb_err, "mdb: there is already a held variable $%s\n",
+ held_var_name);
+ }
+
+ return KEEP_INTERACTING;
+}
+
+MR_Next
+MR_trace_cmd_diff(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
+ MR_Event_Info *event_info, MR_Code **jumpaddr)
+{
+ int start;
+ int max;
+ char *name1;
+ char *name2;
+ MR_TypeInfo type_info1;
+ MR_TypeInfo type_info2;
+ MR_Word value1;
+ MR_Word value2;
+ MR_Word univ1;
+ MR_Word univ2;
+ const char *problem1;
+ const char *problem2;
+ MR_bool bad_subterm1;
+ MR_bool bad_subterm2;
+
+ start = 0;
+ max = 20;
+ if (! MR_trace_options_diff(&start, &max, &words, &word_count)) {
+ /* the usage message has already been printed */
+ return KEEP_INTERACTING;
+ } else if (word_count != 3) {
+ MR_trace_usage_cur_cmd();
+ return KEEP_INTERACTING;
+ }
+
+ name1 = words[1];
+ name2 = words[2];
+ problem1 = MR_trace_parse_lookup_var_path(name1, &type_info1, &value1,
+ &bad_subterm1);
+ problem2 = MR_trace_parse_lookup_var_path(name2, &type_info2, &value2,
+ &bad_subterm2);
+ if (problem1 != NULL) {
+ fflush(MR_mdb_out);
+ fprintf(MR_mdb_err, "mdb: %s%s.\n",
+ (bad_subterm1? "arg1: there is no path " : ""), problem1);
+ return KEEP_INTERACTING;
+ }
+ if (problem2 != NULL) {
+ fflush(MR_mdb_out);
+ fprintf(MR_mdb_err, "mdb: %s%s.\n",
+ (bad_subterm2? "arg2: there is no path " : ""), problem2);
+ return KEEP_INTERACTING;
+ }
+
+ MR_TRACE_CALL_MERCURY(
+ MR_new_univ_on_hp(univ1, type_info1, value1);
+ MR_new_univ_on_hp(univ2, type_info2, value2);
+ ML_report_diffs(start, max, univ1, univ2);
+ );
+
+ return KEEP_INTERACTING;
+}
+
+MR_Next
+MR_trace_cmd_dump(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
+ MR_Event_Info *event_info, MR_Code **jumpaddr)
+{
+ MR_bool verbose = MR_FALSE;
+ MR_Word browser_term;
+ const char *problem = NULL;
+ MR_bool xml = MR_FALSE;
+
+ /*
+ ** Set this to NULL to avoid uninitialization warnings.
+ */
+ browser_term = (MR_Word) NULL;
+
+ if (! MR_trace_options_dump(&xml, &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], "goal")) {
+ const char *name;
+ MR_Word arg_list;
+ MR_bool is_func;
+
+ problem = NULL;
+ MR_convert_goal_to_synthetic_term(&name, &arg_list, &is_func);
+ browser_term = MR_synthetic_to_browser_term(name, arg_list,
+ is_func);
+ } else if (MR_streq(words[1], "exception")) {
+ MR_Word exception;
+
+ exception = MR_trace_get_exception_value();
+ if (exception == (MR_Word) NULL) {
+ problem = "missing exception value";
+ } else {
+ browser_term = MR_univ_to_browser_term(exception);
+ }
+ } else if (MR_streq(words[1], "proc_body")) {
+ const MR_Proc_Layout *entry;
+ MR_Word rep;
+
+ entry = event_info->MR_event_sll->MR_sll_entry;
+
+ if (entry->MR_sle_body_bytes == NULL) {
+ problem = "current procedure has no body bytecodes";
+ } else {
+ MR_TRACE_CALL_MERCURY(
+ MR_DD_trace_read_rep(entry->MR_sle_body_bytes,
+ event_info->MR_event_sll, &rep);
+ );
+
+ browser_term = MR_type_value_to_browser_term(
+ (MR_TypeInfo) ML_proc_rep_type(), rep);
+ }
+ } else {
+ MR_Var_Spec var_spec;
+ MR_TypeInfo type_info;
+ MR_Word value;
+ const char *name;
+
+ MR_convert_arg_to_var_spec(words[1], &var_spec);
+ problem = MR_lookup_unambiguous_var_spec(var_spec,
+ &type_info, &value, &name);
+ if (problem == NULL) {
+ browser_term = MR_type_value_to_browser_term(type_info, value);
+ }
+ }
+
+ if (problem != NULL) {
+ fflush(MR_mdb_out);
+ fprintf(MR_mdb_err, "mdb: %s.\n", problem);
+ } else {
+ if (xml) {
+ MR_trace_save_term_xml(words[2], browser_term);
+ } else {
+ MR_trace_save_term(words[2], browser_term);
+ }
+ }
+ }
+
+ return KEEP_INTERACTING;
+}
+
+/*
+** list [num]
+** List num lines of context around the line number of the context of the
+** current point (i.e., level in the call stack). If num is not given,
+** the number of context lines defaults to the value of the context_lines
+** setting.
+**
+** TODO: add the following (use MR_parse_source_locn()):
+** list filename:num[-num]
+** List a range of lines from a given file. If only one number is
+** given, the default number of lines of context is used.
+*/
+
+MR_Next
+MR_trace_cmd_list(char **words, int word_count,
+ MR_Trace_Cmd_Info *cmd, MR_Event_Info *event_info, MR_Code **jumpaddr)
+{
+ const MR_Proc_Layout *entry_ptr;
+ const char *filename;
+ int lineno;
+ MR_Word *base_sp_ptr;
+ MR_Word *base_curfr_ptr;
+ MR_bool num = MR_num_context_lines;
+ MR_String aligned_filename;
+
+ if (word_count > 2) {
+ MR_trace_usage_cur_cmd();
+ return KEEP_INTERACTING;
+ }
+
+ if (word_count == 2 && !MR_trace_is_natural_number(words[1], &num)) {
+ MR_trace_usage_cur_cmd();
+ return KEEP_INTERACTING;
+ }
+
+ MR_trace_current_level_details(&entry_ptr, &filename, &lineno,
+ &base_sp_ptr, &base_curfr_ptr);
+
+ MR_TRACE_USE_HP(
+ MR_make_aligned_string(aligned_filename, (MR_String) filename);
+ );
+
+ MR_TRACE_CALL_MERCURY(
+ ML_LISTING_list_file(MR_mdb_out, MR_mdb_err, (char *) aligned_filename,
+ lineno - num, lineno + num, lineno, MR_listing_path);
+ );
+
+ return KEEP_INTERACTING;
+}
+
+/****************************************************************************/
+
+static void
+MR_trace_set_level_and_report(int ancestor_level, MR_bool detailed,
+ MR_bool print_optionals)
+{
+ const char *problem;
+ const MR_Proc_Layout *entry;
+ MR_Word *base_sp;
+ MR_Word *base_curfr;
+ const char *filename;
+ int lineno;
+ int indent;
+
+ problem = MR_trace_set_level(ancestor_level, print_optionals);
+ if (problem == NULL) {
+ fprintf(MR_mdb_out, "Ancestor level set to %d:\n",
+ ancestor_level);
+ MR_trace_current_level_details(&entry, &filename, &lineno,
+ &base_sp, &base_curfr);
+ fprintf(MR_mdb_out, "%4d ", ancestor_level);
+ if (detailed) {
+ /*
+ ** We want to print the trace info first regardless
+ ** of the value of MR_context_position.
+ */
+
+ MR_print_call_trace_info(MR_mdb_out, entry, base_sp, base_curfr);
+ indent = 26;
+ } else {
+ indent = 5;
+ }
+
+ MR_print_proc_id_trace_and_context(MR_mdb_out, MR_FALSE,
+ MR_context_position, entry, base_sp, base_curfr, "",
+ filename, lineno, MR_FALSE, "", 0, indent);
+ } else {
+ fflush(MR_mdb_out);
+ fprintf(MR_mdb_err, "%s.\n", problem);
+ }
+}
+
+void
+MR_trace_browse_internal(MR_Word type_info, MR_Word value,
+ MR_Browse_Caller_Type caller, MR_Browse_Format format)
+{
+ switch (caller) {
+
+ case MR_BROWSE_CALLER_BROWSE:
+ MR_trace_browse(type_info, value, format);
+ break;
+
+ case MR_BROWSE_CALLER_PRINT:
+ case MR_BROWSE_CALLER_PRINT_ALL:
+ fprintf(MR_mdb_out, "\t");
+ fflush(MR_mdb_out);
+ MR_trace_print(type_info, value, caller, format);
+ break;
+
+ default:
+ MR_fatal_error("MR_trace_browse_internal: unknown caller type");
+ }
+}
+
+void
+MR_trace_browse_goal_internal(MR_ConstString name, MR_Word arg_list,
+ MR_Word is_func, MR_Browse_Caller_Type caller, MR_Browse_Format format)
+{
+ switch (caller) {
+
+ case MR_BROWSE_CALLER_BROWSE:
+ MR_trace_browse_goal(name, arg_list, is_func, format);
+ break;
+
+ case MR_BROWSE_CALLER_PRINT:
+ MR_trace_print_goal(name, arg_list, is_func, caller, format);
+ break;
+
+ case MR_BROWSE_CALLER_PRINT_ALL:
+ MR_fatal_error("MR_trace_browse_goal_internal: bad caller type");
+
+ default:
+ MR_fatal_error("MR_trace_browse_goal_internal:"
+ " unknown caller type");
+ }
+}
+
+static const char *
+MR_trace_browse_exception(MR_Event_Info *event_info, MR_Browser browser,
+ MR_Browse_Caller_Type caller, MR_Browse_Format format)
+{
+ MR_TypeInfo type_info;
+ MR_Word value;
+ MR_Word exception;
+
+ if (event_info->MR_trace_port != MR_PORT_EXCEPTION) {
+ return "command only available from EXCP ports";
+ }
+
+ exception = MR_trace_get_exception_value();
+ if (exception == (MR_Word) NULL) {
+ return "missing exception value";
+ }
+
+ MR_unravel_univ(exception, type_info, value);
+
+ (*browser)((MR_Word) type_info, value, caller, format);
+
+ return (const char *) NULL;
+}
+
+static const char *
+MR_trace_browse_proc_body(MR_Event_Info *event_info, MR_Browser browser,
+ MR_Browse_Caller_Type caller, MR_Browse_Format format)
+{
+ const MR_Proc_Layout *entry;
+ MR_Word rep;
+
+ entry = event_info->MR_event_sll->MR_sll_entry;
+
+ if (entry->MR_sle_body_bytes == NULL) {
+ return "current procedure has no body info";
+ }
+
+ MR_TRACE_CALL_MERCURY(
+ MR_DD_trace_read_rep(entry->MR_sle_body_bytes,
+ event_info->MR_event_sll, &rep);
+ );
+
+ (*browser)(ML_proc_rep_type(), rep, caller, format);
+ return (const char *) NULL;
+}
+
+static void
+MR_trace_browse_xml(MR_Word type_info, MR_Word value,
+ MR_Browse_Caller_Type caller, MR_Browse_Format format)
+{
+ MR_Word browser_term;
+
+ browser_term = MR_type_value_to_browser_term((MR_TypeInfo) type_info,
+ value);
+
+ MR_trace_save_and_invoke_xml_browser(browser_term);
+}
+
+static void
+MR_trace_browse_goal_xml(MR_ConstString name, MR_Word arg_list,
+ MR_Word is_func, MR_Browse_Caller_Type caller, MR_Browse_Format format)
+{
+ MR_Word browser_term;
+
+ browser_term = MR_synthetic_to_browser_term(name, arg_list, is_func);
+ MR_trace_save_and_invoke_xml_browser(browser_term);
+}
+
+static void
+MR_trace_cmd_stack_2(MR_Event_Info *event_info, MR_bool detailed,
+ int frame_limit, int line_limit)
+{
+ const MR_Label_Layout *layout;
+ MR_Word *saved_regs;
+ const char *msg;
+
+ layout = event_info->MR_event_sll;
+ saved_regs = event_info->MR_saved_regs;
+
+ MR_trace_init_modules();
+ msg = MR_dump_stack_from_layout(MR_mdb_out, layout,
+ MR_saved_sp(saved_regs), MR_saved_curfr(saved_regs),
+ detailed, MR_context_position != MR_CONTEXT_NOWHERE,
+ frame_limit, line_limit, &MR_dump_stack_record_print);
+
+ if (msg != NULL) {
+ fflush(MR_mdb_out);
+ fprintf(MR_mdb_err, "%s.\n", msg);
+ }
+}
+
+/*
+** Implement the `view' command. First, check if there is a server attached.
+** If so, either stop it or abort the command, depending on whether '-f'
+** was given. Then, if a server name was not supplied, start a new server
+** with a unique name (which has been MR_malloc'd), otherwise attach to the
+** server with the supplied name (and make a MR_malloc'd copy of the name).
+*/
+
+static const char *
+MR_trace_new_source_window(const char *window_cmd, const char *server_cmd,
+ const char *server_name, int timeout, MR_bool force,
+ MR_bool verbose, MR_bool split)
+{
+ const char *msg;
+
+ if (MR_trace_source_server.server_name != NULL) {
+ /*
+ ** We are already attached to a server.
+ */
+ if (force) {
+ MR_trace_maybe_close_source_window(verbose);
+ } else {
+ return "error: server already open (use '-f' to force)";
+ }
+ }
+
+ MR_trace_source_server.split = split;
+ if (server_cmd != NULL) {
+ MR_trace_source_server.server_cmd = MR_copy_string(server_cmd);
+ } else {
+ MR_trace_source_server.server_cmd = NULL;
+ }
+
+ if (server_name == NULL) {
+ msg = MR_trace_source_open_server(&MR_trace_source_server,
+ window_cmd, timeout, verbose);
+ } else {
+ MR_trace_source_server.server_name = MR_copy_string(server_name);
+ msg = MR_trace_source_attach(&MR_trace_source_server, timeout,
+ verbose);
+ if (msg != NULL) {
+ /*
+ ** Something went wrong, so we should free the
+ ** strings we allocated just above.
+ */
+ MR_free(MR_trace_source_server.server_name);
+ MR_trace_source_server.server_name = NULL;
+ MR_free(MR_trace_source_server.server_cmd);
+ MR_trace_source_server.server_cmd = NULL;
+ }
+ }
+
+ return msg;
+}
+
+void
+MR_trace_maybe_sync_source_window(MR_Event_Info *event_info, MR_bool verbose)
+{
+ const MR_Label_Layout *parent;
+ const char *filename;
+ int lineno;
+ const char *parent_filename;
+ int parent_lineno;
+ const char *problem; /* not used */
+ MR_Word *base_sp, *base_curfr;
+ const char *msg;
+
+ if (MR_trace_source_server.server_name != NULL) {
+ lineno = 0;
+ filename = "";
+ parent_lineno = 0;
+ parent_filename = "";
+
+ /*
+ ** At interface ports we send both the parent context and
+ ** the current context. Otherwise, we just send the current
+ ** context.
+ */
+ if (MR_port_is_interface(event_info->MR_trace_port)) {
+ base_sp = MR_saved_sp(event_info->MR_saved_regs);
+ base_curfr = MR_saved_curfr(event_info->MR_saved_regs);
+ parent = MR_find_nth_ancestor(event_info->MR_event_sll, 1,
+ &base_sp, &base_curfr, &problem);
+ if (parent != NULL) {
+ (void) MR_find_context(parent, &parent_filename,
+ &parent_lineno);
+ }
+ }
+
+ if (filename[0] == '\0') {
+ (void) MR_find_context(event_info->MR_event_sll,
+ &filename, &lineno);
+ }
+
+ msg = MR_trace_source_sync(&MR_trace_source_server, filename, lineno,
+ parent_filename, parent_lineno, verbose);
+ if (msg != NULL) {
+ fflush(MR_mdb_out);
+ fprintf(MR_mdb_err, "mdb: %s.\n", msg);
+ }
+ }
+}
+
+void
+MR_trace_maybe_close_source_window(MR_bool verbose)
+{
+ const char *msg;
+
+ if (MR_trace_source_server.server_name != NULL) {
+ msg = MR_trace_source_close(&MR_trace_source_server, verbose);
+ if (msg != NULL) {
+ fflush(MR_mdb_out);
+ fprintf(MR_mdb_err, "mdb: %s.\n", msg);
+ }
+
+ MR_free(MR_trace_source_server.server_name);
+ MR_trace_source_server.server_name = NULL;
+ MR_free(MR_trace_source_server.server_cmd);
+ MR_trace_source_server.server_cmd = NULL;
+ }
+}
+
+/****************************************************************************/
+
+const char *const MR_trace_print_cmd_args[] =
+ { "-f", "-p", "-v", "--flat", "--pretty", "--verbose",
+ "exception", "goal", "*", NULL };
+
+/*
+** It is better to have a single completion where possible,
+** so don't include `-d' here.
+*/
+
+const char *const MR_trace_stack_cmd_args[] =
+ { "--detailed", NULL };
+
+const char *const MR_trace_view_cmd_args[] =
+ { "-c", "-f", "-n", "-s", "-t", "-v", "-w", "-2",
+ "--close", "--verbose", "--force", "--split-screen",
+ "--window-command", "--server-command", "--server-name",
+ "--timeout", NULL };
+
+/****************************************************************************/
+
+static struct MR_option MR_trace_detailed_opts[] =
+{
+ { "detailed", MR_no_argument, NULL, 'd' },
+ { NULL, MR_no_argument, NULL, 0 }
+};
+
+static MR_bool
+MR_trace_options_detailed(MR_bool *detailed, char ***words, int *word_count)
+{
+ int c;
+
+ MR_optind = 0;
+ while ((c = MR_getopt_long(*word_count, *words, "d",
+ MR_trace_detailed_opts, NULL)) != EOF)
+ {
+ switch (c) {
+
+ case 'd':
+ *detailed = MR_TRUE;
+ 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 MR_bool
+MR_trace_options_stack_trace(MR_bool *detailed, int *frame_limit,
+ char ***words, int *word_count)
+{
+ int c;
+
+ MR_optind = 0;
+ while ((c = MR_getopt_long(*word_count, *words, "df:",
+ MR_trace_detailed_opts, NULL)) != EOF)
+ {
+ switch (c) {
+
+ case 'd':
+ *detailed = MR_TRUE;
+ break;
+
+ case 'f':
+ if (! MR_trace_is_natural_number(MR_optarg, frame_limit)) {
+ MR_trace_usage_cur_cmd();
+ return MR_FALSE;
+ }
+ 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_format_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' },
+ { "xml", MR_no_argument, NULL, 'x' },
+ { NULL, MR_no_argument, NULL, 0 }
+};
+
+static MR_bool
+MR_trace_options_format(MR_Browse_Format *format, MR_bool *xml, char ***words,
+ int *word_count)
+{
+ int c;
+
+ *format = MR_BROWSE_DEFAULT_FORMAT;
+ *xml = MR_FALSE;
+ MR_optind = 0;
+ while ((c = MR_getopt_long(*word_count, *words, "frvpx",
+ MR_trace_format_opts, NULL)) != EOF)
+ {
+ switch (c) {
+
+ case 'f':
+ *format = MR_BROWSE_FORMAT_FLAT;
+ break;
+
+ case 'r':
+ *format = MR_BROWSE_FORMAT_RAW_PRETTY;
+ break;
+
+ case 'v':
+ *format = MR_BROWSE_FORMAT_VERBOSE;
+ break;
+
+ case 'p':
+ *format = MR_BROWSE_FORMAT_PRETTY;
+ break;
+
+ case 'x':
+ *xml = MR_TRUE;
+ 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_view_opts[] =
+{
+ { "close", MR_no_argument, NULL, 'c' },
+ { "window-command", MR_required_argument, NULL, 'w' },
+ { "server-command", MR_required_argument, NULL, 's' },
+ { "server-name", MR_required_argument, NULL, 'n' },
+ { "timeout", MR_required_argument, NULL, 't' },
+ { "force", MR_no_argument, NULL, 'f' },
+ { "verbose", MR_no_argument, NULL, 'v' },
+ { "split-screen", MR_no_argument, NULL, '2' },
+ { NULL, MR_no_argument, NULL, 0 }
+};
+
+static MR_bool
+MR_trace_options_view(const char **window_cmd, const char **server_cmd,
+ const char **server_name, int *timeout, MR_bool *force,
+ MR_bool *verbose, MR_bool *split, MR_bool *close_window,
+ char ***words, int *word_count)
+{
+ int c;
+ MR_bool no_close = MR_FALSE;
+
+ MR_optind = 0;
+ while ((c = MR_getopt_long(*word_count, *words, "cw:s:n:t:fv2",
+ MR_trace_view_opts, NULL)) != EOF)
+ {
+ /*
+ ** Option '-c' is mutually incompatible with '-f', '-t',
+ ** '-s', '-n', '-w' and '-2'.
+ */
+ switch (c) {
+
+ case 'c':
+ if (no_close) {
+ MR_trace_usage_cur_cmd();
+ return MR_FALSE;
+ }
+
+ *close_window = MR_TRUE;
+ break;
+
+ case 'w':
+ if (*close_window) {
+ MR_trace_usage_cur_cmd();
+ return MR_FALSE;
+ }
+
+ *window_cmd = MR_optarg;
+ no_close = MR_TRUE;
+ break;
+
+ case 's':
+ if (*close_window) {
+ MR_trace_usage_cur_cmd();
+ return MR_FALSE;
+ }
+
+ *server_cmd = MR_optarg;
+ no_close = MR_TRUE;
+ break;
+
+ case 'n':
+ if (*close_window) {
+ MR_trace_usage_cur_cmd();
+ return MR_FALSE;
+ }
+
+ *server_name = MR_optarg;
+ no_close = MR_TRUE;
+ break;
+
+ case 't':
+ if (*close_window ||
+ ! MR_trace_is_natural_number(MR_optarg, timeout))
+ {
+ MR_trace_usage_cur_cmd();
+ return MR_FALSE;
+ }
+
+ no_close = MR_TRUE;
+ break;
+
+ case 'f':
+ if (*close_window) {
+ MR_trace_usage_cur_cmd();
+ return MR_FALSE;
+ }
+
+ *force = MR_TRUE;
+ no_close = MR_TRUE;
+ break;
+
+ case 'v':
+ *verbose = MR_TRUE;
+ break;
+
+ case '2':
+ if (*close_window) {
+ MR_trace_usage_cur_cmd();
+ return MR_FALSE;
+ }
+
+ *split = MR_TRUE;
+ no_close = MR_TRUE;
+ 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_diff_opts[] =
+{
+ { "start", MR_required_argument, NULL, 's' },
+ { "max", MR_required_argument, NULL, 'm' },
+ { NULL, MR_no_argument, NULL, 0 }
+};
+
+static MR_bool
+MR_trace_options_diff(int *start, int *max, char ***words, int *word_count)
+{
+ int c;
+
+ MR_optind = 0;
+ while ((c = MR_getopt_long(*word_count, *words, "m:s:",
+ MR_trace_diff_opts, NULL)) != EOF)
+ {
+ switch (c) {
+
+ case 'm':
+ if (! MR_trace_is_natural_number(MR_optarg, max)) {
+ MR_trace_usage_cur_cmd();
+ return MR_FALSE;
+ }
+ break;
+
+ case 's':
+ if (! MR_trace_is_natural_number(MR_optarg, start)) {
+ MR_trace_usage_cur_cmd();
+ return MR_FALSE;
+ }
+ 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_dump_opts[] =
+{
+ { "xml", MR_no_argument, NULL, 'x' },
+ { NULL, MR_no_argument, NULL, 0 }
+};
+
+static MR_bool
+MR_trace_options_dump(MR_bool *xml, char ***words, int *word_count)
+{
+ int c;
+
+ MR_optind = 0;
+ while ((c = MR_getopt_long(*word_count, *words, "x",
+ MR_trace_dump_opts, NULL)) != EOF)
+ {
+ switch (c) {
+
+ case 'x':
+ *xml = MR_TRUE;
+ 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;
+}
+
+/****************************************************************************/
Index: trace/mercury_trace_cmd_browsing.h
===================================================================
RCS file: trace/mercury_trace_cmd_browsing.h
diff -N trace/mercury_trace_cmd_browsing.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ trace/mercury_trace_cmd_browsing.h 3 Apr 2006 12:37:21 -0000
@@ -0,0 +1,50 @@
+/*
+** 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.
+*/
+
+#include "mercury_std.h"
+#include "mercury_types.h"
+
+#include "mercury_trace.h"
+#include "mercury_trace_cmds.h"
+#include "mercury_trace_browse.h"
+
+extern MR_TraceCmdFunc MR_trace_cmd_level;
+extern MR_TraceCmdFunc MR_trace_cmd_up;
+extern MR_TraceCmdFunc MR_trace_cmd_down;
+extern MR_TraceCmdFunc MR_trace_cmd_vars;
+extern MR_TraceCmdFunc MR_trace_cmd_held_vars;
+extern MR_TraceCmdFunc MR_trace_cmd_print;
+extern MR_TraceCmdFunc MR_trace_cmd_browse;
+extern MR_TraceCmdFunc MR_trace_cmd_stack;
+extern MR_TraceCmdFunc MR_trace_cmd_current;
+extern MR_TraceCmdFunc MR_trace_cmd_view;
+extern MR_TraceCmdFunc MR_trace_cmd_hold;
+extern MR_TraceCmdFunc MR_trace_cmd_diff;
+extern MR_TraceCmdFunc MR_trace_cmd_dump;
+extern MR_TraceCmdFunc MR_trace_cmd_list;
+
+/*
+** If we are attached to a source server, then find the appropriate
+** context and ask the server to point to it, otherwise do nothing.
+*/
+
+extern void MR_trace_maybe_sync_source_window(
+ MR_Event_Info *event_info, MR_bool verbose);
+
+extern void MR_trace_browse_internal(MR_Word type_info,
+ MR_Word value, MR_Browse_Caller_Type caller,
+ MR_Browse_Format format);
+extern void MR_trace_browse_goal_internal(MR_ConstString name,
+ MR_Word arg_list, MR_Word is_func,
+ MR_Browse_Caller_Type caller,
+ MR_Browse_Format format);
+
+extern const char *const MR_trace_print_cmd_args[];
+extern const char *const MR_trace_stack_cmd_args[];
+extern const char *const MR_trace_view_cmd_args[];
Index: trace/mercury_trace_cmd_dd.c
===================================================================
RCS file: trace/mercury_trace_cmd_dd.c
diff -N trace/mercury_trace_cmd_dd.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ trace/mercury_trace_cmd_dd.c 3 Apr 2006 12:50:30 -0000
@@ -0,0 +1,353 @@
+/*
+** 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 "dd" 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_trace_internal.h"
+#include "mercury_trace_cmds.h"
+#include "mercury_trace_cmd_dd.h"
+#include "mercury_trace_cmd_parameter.h"
+#include "mercury_trace_declarative.h"
+#include "mercury_trace_tables.h"
+#include "mercury_trace_util.h"
+
+/****************************************************************************/
+
+static MR_bool MR_trace_options_dd(MR_bool *assume_all_io_is_tabled,
+ MR_Unsigned *default_depth, MR_Unsigned *num_nodes,
+ MR_Decl_Search_Mode *search_mode,
+ MR_bool *search_mode_was_set,
+ MR_bool *search_mode_requires_trace_counts,
+ char **pass_trace_counts_file,
+ char **fail_trace_counts_file,
+ MR_bool *new_session, MR_bool *testing, MR_bool *debug,
+ char ***words, int *word_count);
+
+/****************************************************************************/
+
+MR_Next
+MR_trace_cmd_dd(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
+ MR_Event_Info *event_info, MR_Code **jumpaddr)
+{
+ MR_Decl_Search_Mode search_mode;
+ MR_bool search_mode_was_set = MR_FALSE;
+ MR_bool new_session = MR_TRUE;
+ MR_bool search_mode_requires_trace_counts = MR_FALSE;
+ char *pass_trace_counts_file;
+ char *fail_trace_counts_file;
+ MR_String problem;
+ MR_bool testing = MR_FALSE;
+ MR_bool debug = MR_FALSE;
+ const char *filename;
+ MR_Decl_Mode decl_mode;
+
+ MR_trace_decl_assume_all_io_is_tabled = MR_FALSE;
+ MR_edt_default_depth_limit = MR_TRACE_DECL_INITIAL_DEPTH;
+ search_mode = MR_trace_get_default_search_mode();
+ pass_trace_counts_file = MR_dice_pass_trace_counts_file;
+ fail_trace_counts_file = MR_dice_fail_trace_counts_file;
+ MR_trace_decl_debug_debugger_mode = MR_FALSE;
+
+ if (! MR_trace_options_dd(&MR_trace_decl_assume_all_io_is_tabled,
+ &MR_edt_default_depth_limit, &MR_edt_desired_nodes_in_subtree,
+ &search_mode, &search_mode_was_set,
+ &search_mode_requires_trace_counts,
+ &pass_trace_counts_file, &fail_trace_counts_file, &new_session,
+ &testing, &MR_trace_decl_debug_debugger_mode, &words, &word_count))
+ {
+ ; /* the usage message has already been printed */
+ } else if (word_count <= 2) {
+ if (word_count == 2 && MR_trace_decl_debug_debugger_mode) {
+ decl_mode = MR_DECL_DUMP;
+ filename = (const char *) words[1];
+ } else {
+ decl_mode = MR_DECL_NODUMP;
+ filename = (const char *) NULL;
+ }
+ if (MR_trace_have_unhid_events) {
+ fflush(MR_mdb_out);
+ fprintf(MR_mdb_err,
+ "mdb: dd doesn't work after `unhide_events on'.\n");
+ return KEEP_INTERACTING;
+ }
+ if (search_mode_requires_trace_counts && (
+ pass_trace_counts_file == NULL || fail_trace_counts_file == NULL))
+ {
+ fflush(MR_mdb_out);
+ fprintf(MR_mdb_err,
+ "mdb: you need to supply passing and failing trace count "
+ "files\nbefore using the specified search mode.\n");
+ return KEEP_INTERACTING;
+ }
+ if (pass_trace_counts_file != NULL && fail_trace_counts_file != NULL) {
+ if (! MR_trace_decl_init_suspicion_table(pass_trace_counts_file,
+ fail_trace_counts_file, &problem))
+ {
+ fflush(MR_mdb_out);
+ fprintf(MR_mdb_err, "mdb: %s\n", problem);
+ return KEEP_INTERACTING;
+ }
+ }
+
+ MR_trace_decl_set_testing_flag(testing);
+
+ if (search_mode_was_set || new_session) {
+ MR_trace_decl_set_fallback_search_mode(search_mode);
+ }
+
+ if (MR_trace_start_decl_debug(decl_mode, filename, new_session, cmd,
+ event_info, jumpaddr))
+ {
+ return STOP_INTERACTING;
+ }
+ } else {
+ MR_trace_usage_cur_cmd();
+ }
+
+ return KEEP_INTERACTING;
+}
+
+MR_Next
+MR_trace_cmd_trust(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
+ MR_Event_Info *event_info, MR_Code **jumpaddr)
+{
+ MR_Proc_Spec spec;
+ MR_Matches_Info matches;
+
+ if (word_count == 2) {
+ spec.MR_proc_module = NULL;
+ spec.MR_proc_name = NULL;
+ spec.MR_proc_arity = -1;
+ spec.MR_proc_mode = -1;
+ spec.MR_proc_prefix = (MR_Proc_Prefix) -1;
+
+ MR_register_all_modules_and_procs(MR_mdb_out, MR_TRUE);
+
+ /* First see if the argument is a module name */
+ spec.MR_proc_module = words[1];
+ matches = MR_search_for_matching_procedures(&spec);
+ if (matches.match_proc_next > 0) {
+ MR_decl_add_trusted_module(words[1]);
+ fprintf(MR_mdb_out, "Trusting module %s\n", words[1]);
+ } else if (MR_parse_proc_spec(words[1], &spec)) {
+ /* Check to see if the argument is a pred/func */
+ matches = MR_search_for_matching_procedures(&spec);
+ MR_filter_user_preds(&matches);
+ if (matches.match_proc_next == 0) {
+ fprintf(MR_mdb_err,
+ "mdb: there is no such module, predicate or function.\n");
+ } else if (matches.match_proc_next == 1) {
+ MR_decl_add_trusted_pred_or_func(matches.match_procs[0]);
+ fprintf(MR_mdb_out, "Trusting ");
+ MR_print_pred_id_and_nl(MR_mdb_out, matches.match_procs[0]);
+ } else {
+ int i;
+ char buf[80];
+ char *line2;
+
+ fprintf(MR_mdb_out, "Ambiguous predicate or function"
+ " specification. The matches are:\n");
+ for (i = 0; i < matches.match_proc_next; i++) {
+ fprintf(MR_mdb_out, "%d: ", i);
+ MR_print_pred_id_and_nl(MR_mdb_out,
+ matches.match_procs[i]);
+ }
+ sprintf(buf, "\nWhich predicate or function "
+ "do you want to trust (0-%d or *)? ",
+ matches.match_proc_next - 1);
+ line2 = MR_trace_getline(buf, MR_mdb_in, MR_mdb_out);
+ if (line2 == NULL) {
+ /* This means the user input EOF. */
+ fprintf(MR_mdb_out, "none of them\n");
+ } else if (MR_streq(line2, "*")) {
+ for (i = 0; i < matches.match_proc_next; i++) {
+ MR_decl_add_trusted_pred_or_func(
+ matches.match_procs[i]);
+
+ fprintf(MR_mdb_out, "Trusting ");
+ MR_print_pred_id_and_nl(MR_mdb_out,
+ matches.match_procs[i]);
+ }
+ MR_free(line2);
+ } else if(MR_trace_is_natural_number(line2, &i)) {
+ if (0 <= i && i < matches.match_proc_next) {
+ MR_decl_add_trusted_pred_or_func(
+ matches.match_procs[i]);
+
+ fprintf(MR_mdb_out, "Trusting ");
+ MR_print_pred_id_and_nl(MR_mdb_out,
+ matches.match_procs[i]);
+ } else {
+ fprintf(MR_mdb_out, "no such match\n");
+ }
+ MR_free(line2);
+ } else {
+ fprintf(MR_mdb_out, "none of them\n");
+ MR_free(line2);
+ }
+ }
+ }
+ } else if (word_count == 3 &&
+ ((MR_streq(words[1], "std") && MR_streq(words[2], "lib"))
+ || (MR_streq(words[1], "standard") && MR_streq(words[2], "library"))))
+ {
+ MR_decl_trust_standard_library();
+ fprintf(MR_mdb_out, "Trusting the Mercury standard library\n");
+ } else {
+ MR_trace_usage_cur_cmd();
+ }
+
+ return KEEP_INTERACTING;
+}
+
+MR_Next
+MR_trace_cmd_untrust(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
+ MR_Event_Info *event_info, MR_Code **jumpaddr)
+{
+ int i;
+
+ if (word_count == 2 && MR_trace_is_natural_number(words[1], &i)) {
+ if (!MR_decl_remove_trusted(i)) {
+ fprintf(MR_mdb_err, "mdb: no such trusted object\n");
+ }
+ } else {
+ MR_trace_usage_cur_cmd();
+ }
+ return KEEP_INTERACTING;
+}
+
+MR_Next
+MR_trace_cmd_trusted(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
+ MR_Event_Info *event_info, MR_Code **jumpaddr)
+{
+ if (word_count == 1) {
+ MR_decl_print_all_trusted(MR_mdb_out, MR_FALSE);
+ } else {
+ MR_trace_usage_cur_cmd();
+ }
+ return KEEP_INTERACTING;
+}
+
+/****************************************************************************/
+
+const char *const MR_trace_dd_cmd_args[] =
+ { "-s", "-a", "-d", "-n", "--search-mode",
+ "--assume-all-io-is-tabled", "--depth", "--nodes",
+ "td", "top_down", "dq" "divide_and_query", "sdq",
+ "suspicion_divide_and_query", NULL };
+
+/****************************************************************************/
+
+static struct MR_option MR_trace_dd_opts[] =
+{
+ { "assume-all-io-is-tabled", MR_no_argument, NULL, 'a' },
+ { "debug", MR_no_argument, NULL, 'z' },
+ { "depth", MR_required_argument, NULL, 'd' },
+ { "nodes", MR_required_argument, NULL, 'n' },
+ { "resume", MR_no_argument, NULL, 'r' },
+ { "search-mode", MR_required_argument, NULL, 's' },
+ { "pass-trace-counts", MR_required_argument, NULL, 'p' },
+ { "pass-trace-count", MR_required_argument, NULL, 'p' },
+ { "fail-trace-counts", MR_required_argument, NULL, 'f' },
+ { "fail-trace-count", MR_required_argument, NULL, 'f' },
+ { "resume", MR_no_argument, NULL, 'r' },
+ { "test", MR_no_argument, NULL, 't' },
+ { NULL, MR_no_argument, NULL, 0 }
+};
+
+static MR_bool
+MR_trace_options_dd(MR_bool *assume_all_io_is_tabled,
+ MR_Unsigned *default_depth, MR_Unsigned *num_nodes,
+ MR_Decl_Search_Mode *search_mode, MR_bool *search_mode_was_set,
+ MR_bool *search_mode_requires_trace_counts,
+ char **pass_trace_counts_file, char **fail_trace_counts_file,
+ MR_bool *new_session, MR_bool *testing, MR_bool *debug,
+ char ***words, int *word_count)
+{
+ int c;
+
+ MR_optind = 0;
+ while ((c = MR_getopt_long(*word_count, *words, "ad:f:n:p:rs:tz",
+ MR_trace_dd_opts, NULL)) != EOF)
+ {
+ switch (c) {
+
+ case 'a':
+ *assume_all_io_is_tabled = MR_TRUE;
+ break;
+
+ case 'd':
+ if (! MR_trace_is_unsigned(MR_optarg, default_depth)) {
+ MR_trace_usage_cur_cmd();
+ return MR_FALSE;
+ }
+ break;
+
+ case 'f':
+ *fail_trace_counts_file = MR_copy_string(MR_optarg);
+ break;
+
+ case 'n':
+ if (! MR_trace_is_unsigned(MR_optarg, num_nodes)) {
+ MR_trace_usage_cur_cmd();
+ return MR_FALSE;
+ }
+ break;
+
+ case 'p':
+ *pass_trace_counts_file = MR_copy_string(MR_optarg);
+ break;
+
+ case 'r':
+ *new_session = MR_FALSE;
+ break;
+
+ case 's':
+ if (MR_trace_is_valid_search_mode_string(MR_optarg,
+ search_mode, search_mode_requires_trace_counts))
+ {
+ *search_mode_was_set = MR_TRUE;
+ } else {
+ MR_trace_usage_cur_cmd();
+ return MR_FALSE;
+ }
+ break;
+
+ case 't':
+ *testing = MR_TRUE;
+ break;
+
+ case 'z':
+ *debug = MR_TRUE;
+ 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;
+}
Index: trace/mercury_trace_cmd_dd.h
===================================================================
RCS file: trace/mercury_trace_cmd_dd.h
diff -N trace/mercury_trace_cmd_dd.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ trace/mercury_trace_cmd_dd.h 3 Apr 2006 09:51:05 -0000
@@ -0,0 +1,20 @@
+/*
+** 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.
+*/
+
+#include "mercury_imp.h"
+#include "mercury_stack_trace.h" /* for MR_Context_Position */
+
+#include "mercury_trace_cmds.h"
+
+extern MR_TraceCmdFunc MR_trace_cmd_dd;
+extern MR_TraceCmdFunc MR_trace_cmd_trust;
+extern MR_TraceCmdFunc MR_trace_cmd_untrust;
+extern MR_TraceCmdFunc MR_trace_cmd_trusted;
+
+extern const char *const MR_trace_dd_cmd_args[];
Index: trace/mercury_trace_cmd_developer.c
===================================================================
RCS file: trace/mercury_trace_cmd_developer.c
diff -N trace/mercury_trace_cmd_developer.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ trace/mercury_trace_cmd_developer.c 3 Apr 2006 12:50:37 -0000
@@ -0,0 +1,2243 @@
+/*
+** 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 "developer" 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_types.h"
+#include "mercury_trace_base.h"
+
+#include "mercury_trace_internal.h"
+#include "mercury_trace_cmds.h"
+#include "mercury_trace_cmd_developer.h"
+#include "mercury_trace_cmd_parameter.h"
+#include "mercury_trace_tables.h"
+#include "mercury_trace_util.h"
+
+#include <stdio.h>
+
+/****************************************************************************/
+
+static void MR_trace_cmd_nondet_stack_2(MR_Event_Info *event_info,
+ MR_bool detailed, int frame_limit, int line_limit);
+
+static const MR_Proc_Layout
+ *MR_find_single_matching_proc(MR_Proc_Spec *spec,
+ MR_bool verbose);
+
+/*
+** The following data structures describe the information we have about the
+** input arguments of tabled procedures. We use them to decode the call tables
+** of such procedures.
+**
+** We use one MR_Call_Table_Arg structure for each input argument.
+**
+** The step field specifies what data structure the tabling system uses to
+** implement the trie nodes at the level of the call table corresponding to
+** the relevant argument. At the moment, we support only four values of this
+** field, MR_TABLE_STEP_INT, MR_TABLE_STEP_FLOAT, MR_TABLE_STEP_STRING and
+** MR_TABLE_STEP_PROMISE_IMPLIED. The first three of these implicitly select
+** the corresponding alternative in the arg_values union; the last one
+** indicates the absence of a step.
+**
+** The start_node field specifies the start node of the relevant trie. For the
+** first input argument, this will be the tabling pointer variable for the
+** given procedure. For later input arguments, it will be the trie node you
+** reach after following the current values of the previous arguments through
+** the call table.
+**
+** The MR_{Int,Float,String}_Table_Arg_Values structs have the same fields and
+** the same meanings, differing only in the types of the values they store.
+** Each struct is used for one of two things.
+**
+** 1. To describe a value supplied by the user on the mdb command line.
+** In this case, the only field that matters is the cur_value field.
+**
+** 2. To describe the set of values you can find in a trie node, the one given
+** by the start_node field, and to specify which is the current one.
+** In this case, all the fields matter.
+**
+** The code that manipulates these structures distinguishes between the two
+** uses based on argument number.
+**
+** The values array is managed with the macros in mercury_array_macros.h,
+** so its size is given by the value_next field. The cur_index field gives the
+** index of the current value, while the cur_value field gives the current
+** value itself. (The contents of the cur_value field can be deduced from the
+** contents of the other fields with use 2, but not with use 1.)
+**
+** The valid field in the MR_Call_Table_Arg structure gives the validity
+** of the values subfield of its arg_values field; if it is false, then the
+** array is logically considered empty.
+*/
+
+typedef struct {
+ MR_Integer *MR_ctai_values;
+ int MR_ctai_value_next;
+ int MR_ctai_cur_index;
+ MR_Integer MR_ctai_cur_value;
+} MR_Int_Table_Arg_Values;
+
+typedef struct {
+ MR_Float *MR_ctaf_values;
+ int MR_ctaf_value_next;
+ int MR_ctaf_cur_index;
+ MR_Float MR_ctaf_cur_value;
+} MR_Float_Table_Arg_Values;
+
+typedef struct {
+ MR_ConstString *MR_ctas_values;
+ int MR_ctas_value_next;
+ int MR_ctas_cur_index;
+ MR_ConstString MR_ctas_cur_value;
+} MR_String_Table_Arg_Values;
+
+typedef union {
+ MR_Int_Table_Arg_Values MR_cta_values_int;
+ MR_Float_Table_Arg_Values MR_cta_values_float;
+ MR_String_Table_Arg_Values MR_cta_values_string;
+} MR_Table_Arg_Values;
+
+typedef struct {
+ MR_Table_Trie_Step MR_cta_step;
+ int MR_cta_unfiltered_arg_num;
+ MR_TrieNode MR_cta_start_node;
+ MR_bool MR_cta_valid;
+ MR_Table_Arg_Values MR_cta_arg_values;
+} MR_Call_Table_Arg;
+
+#define MR_cta_int_values MR_cta_arg_values.MR_cta_values_int.\
+ MR_ctai_values
+#define MR_cta_int_value_next MR_cta_arg_values.MR_cta_values_int.\
+ MR_ctai_value_next
+#define MR_cta_int_cur_index MR_cta_arg_values.MR_cta_values_int.\
+ MR_ctai_cur_index
+#define MR_cta_int_cur_value MR_cta_arg_values.MR_cta_values_int.\
+ MR_ctai_cur_value
+
+#define MR_cta_float_values MR_cta_arg_values.MR_cta_values_float.\
+ MR_ctaf_values
+#define MR_cta_float_value_next MR_cta_arg_values.MR_cta_values_float.\
+ MR_ctaf_value_next
+#define MR_cta_float_cur_index MR_cta_arg_values.MR_cta_values_float.\
+ MR_ctaf_cur_index
+#define MR_cta_float_cur_value MR_cta_arg_values.MR_cta_values_float.\
+ MR_ctaf_cur_value
+
+#define MR_cta_string_values MR_cta_arg_values.MR_cta_values_string.\
+ MR_ctas_values
+#define MR_cta_string_value_next MR_cta_arg_values.MR_cta_values_string.\
+ MR_ctas_value_next
+#define MR_cta_string_cur_index MR_cta_arg_values.MR_cta_values_string.\
+ MR_ctas_cur_index
+#define MR_cta_string_cur_value MR_cta_arg_values.MR_cta_values_string.\
+ MR_ctas_cur_value
+
+/*
+** These functions fill in the data structure describing one input argument
+** of a tabled procedure with a constant value given on the mdb command line.
+** They return true if they succeed, and false if they fail (e.g. because the
+** string given on the mdb command line does not describe a value of the
+** required type).
+*/
+
+static MR_bool MR_trace_fill_in_int_table_arg_slot(
+ MR_TrieNode *table_cur_ptr,
+ int arg_num, MR_ConstString given_arg,
+ MR_Call_Table_Arg *call_table_arg_ptr);
+static MR_bool MR_trace_fill_in_float_table_arg_slot(
+ MR_TrieNode *table_cur_ptr,
+ int arg_num, MR_ConstString given_arg,
+ MR_Call_Table_Arg *call_table_arg_ptr);
+static MR_bool MR_trace_fill_in_string_table_arg_slot(
+ MR_TrieNode *table_cur_ptr,
+ int arg_num, MR_ConstString given_arg,
+ MR_Call_Table_Arg *call_table_arg_ptr);
+
+/*
+** These functions fill in the data structure describing one input argument
+** of a tabled procedure with the next value taken from the given trie node.
+** They return true if there are no more values in the trie node, and false
+** otherwise.
+*/
+
+static MR_bool MR_update_int_table_arg_slot(MR_TrieNode *table_cur_ptr,
+ MR_Call_Table_Arg *call_table_arg_ptr);
+static MR_bool MR_update_float_table_arg_slot(MR_TrieNode *table_cur_ptr,
+ MR_Call_Table_Arg *call_table_arg_ptr);
+static MR_bool MR_update_string_table_arg_slot(MR_TrieNode *table_cur_ptr,
+ MR_Call_Table_Arg *call_table_arg_ptr);
+
+/* Prints the given subgoal of the given procedure to MR_mdb_out. */
+static void MR_trace_cmd_table_print_tip(const MR_Proc_Layout *proc,
+ int filtered_num_inputs,
+ MR_Call_Table_Arg *call_table_args, MR_TrieNode table);
+
+/* Prints the given subgoal of the given procedure to MR_mdb_out. */
+static void MR_trace_print_subgoal(const MR_Proc_Layout *proc,
+ MR_Subgoal *subgoal);
+static void MR_trace_print_subgoal_debug(const MR_Proc_Layout *proc,
+ MR_SubgoalDebug *subgoal_debug);
+
+/* Prints the given generator of the given procedure to MR_mdb_out. */
+static void MR_trace_print_generator(const MR_Proc_Layout *proc,
+ MR_Generator *generator);
+static void MR_trace_print_generator_debug(const MR_Proc_Layout *proc,
+ MR_GenDebug *generator_debug);
+
+/* Prints the given consumer of the given procedure to MR_mdb_out. */
+static void MR_trace_print_consumer(const MR_Proc_Layout *proc,
+ MR_Consumer *consumer);
+static void MR_trace_print_consumer_debug(const MR_Proc_Layout *proc,
+ MR_ConsumerDebug *consumer_debug);
+
+/* Prints the requested information inside the given MR_TypeCtorInfo. */
+static void MR_print_type_ctor_info(FILE *fp,
+ MR_TypeCtorInfo type_ctor_info,
+ MR_bool print_rep, MR_bool print_functors);
+
+/* Prints the requested information inside the given MR_TypeClassDeclInfo. */
+static void MR_print_class_decl_info(FILE *fp,
+ MR_TypeClassDeclInfo *type_class_decl_info,
+ MR_bool print_methods, MR_bool print_instances);
+
+/* Print the given pseudo-typeinfo. */
+static void MR_print_pseudo_type_info(FILE *fp,
+ MR_PseudoTypeInfo pseudo);
+
+/****************************************************************************/
+
+static MR_bool MR_trace_options_nondet_stack(MR_bool *detailed,
+ int *frame_limit, char ***words, int *word_count);
+static MR_bool MR_trace_options_stats(char **filename, char ***words,
+ int *word_count);
+static MR_bool MR_trace_options_type_ctor(MR_bool *print_rep,
+ MR_bool *print_functors, char ***words,
+ int *word_count);
+static MR_bool MR_trace_options_class_decl(MR_bool *print_methods,
+ MR_bool *print_instances, char ***words,
+ int *word_count);
+static MR_bool MR_trace_options_all_procedures(MR_bool *separate,
+ MR_bool *uci, char **module, char ***words,
+ int *word_count);
+static MR_bool MR_trace_options_ambiguity(const char **outfile,
+ char ***words, int *word_count);
+
+/****************************************************************************/
+
+MR_Next
+MR_trace_cmd_var_details(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
+ MR_Event_Info *event_info, MR_Code **jumpaddr)
+{
+ int n;
+
+ if (word_count == 1) {
+ const char *problem;
+
+ problem = MR_trace_list_var_details(MR_mdb_out);
+ if (problem != NULL) {
+ fflush(MR_mdb_out);
+ fprintf(MR_mdb_err, "mdb: %s.\n", problem);
+ }
+ } else {
+ MR_trace_usage_cur_cmd();
+ }
+
+ return KEEP_INTERACTING;
+}
+
+MR_Next
+MR_trace_cmd_term_size(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
+ MR_Event_Info *event_info, MR_Code **jumpaddr)
+{
+ int n;
+
+ if (word_count == 2) {
+ const char *problem;
+
+ if (MR_streq(words[1], "*")) {
+ problem = MR_trace_print_size_all(MR_mdb_out);
+ } else {
+ problem = MR_trace_print_size_one(MR_mdb_out, words[1]);
+ }
+
+ if (problem != NULL) {
+ fflush(MR_mdb_out);
+ fprintf(MR_mdb_err, "mdb: %s.\n", problem);
+ }
+ } else {
+ MR_trace_usage_cur_cmd();
+ }
+
+ return KEEP_INTERACTING;
+}
+
+MR_Next
+MR_trace_cmd_flag(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
+ MR_Event_Info *event_info, MR_Code **jumpaddr)
+{
+ const char *name;
+ MR_bool *flagptr;
+ int i;
+ MR_bool found;
+ const char *set_word;
+
+ /* Set this to NULL to avoid uninitialization warnings. */
+ flagptr = NULL;
+
+ if (word_count == 1) {
+ for (i = 0; i < MR_MAXFLAG; i++) {
+ /*
+ ** The true values of the debugging flags are stored in
+ ** MR_saved_debug_state inside the call tree of MR_trace_event.
+ */
+
+ flagptr = &MR_saved_debug_state.MR_sds_debugflags[
+ MR_debug_flag_info[i].MR_debug_flag_index];
+ name = MR_debug_flag_info[i].MR_debug_flag_name;
+ if (*flagptr) {
+ fprintf(MR_mdb_out, "Flag %s is set.\n", name);
+ } else {
+ fprintf(MR_mdb_out, "Flag %s is clear.\n", name);
+ }
+ }
+
+ return KEEP_INTERACTING;
+ } else if (word_count == 2) {
+ name = words[1];
+ set_word = NULL;
+ } else if (word_count == 3) {
+ name = words[1];
+ set_word = words[2];
+ } else {
+ MR_trace_usage_cur_cmd();
+ return KEEP_INTERACTING;
+ }
+
+ found = MR_FALSE;
+ for (i = 0; i < MR_MAXFLAG; i++) {
+ if (MR_streq(MR_debug_flag_info[i].MR_debug_flag_name, name)) {
+ /*
+ ** The true values of the debugging flags are stored in
+ ** MR_saved_debug_state inside the call tree of MR_trace_event.
+ */
+
+ flagptr = &MR_saved_debug_state.MR_sds_debugflags[
+ MR_debug_flag_info[i].MR_debug_flag_index];
+ found = MR_TRUE;
+ break;
+ }
+ }
+
+ if (!found) {
+ fprintf(MR_mdb_out, "There is no flag named %s.\n", name);
+ return KEEP_INTERACTING;
+ }
+
+ if (set_word != NULL) {
+ if (MR_streq(set_word, "on")) {
+ *flagptr = MR_TRUE;
+ fprintf(MR_mdb_out, "Flag %s is now set.\n", name);
+ } else if (MR_streq(set_word, "off")) {
+ *flagptr = MR_FALSE;
+ fprintf(MR_mdb_out, "Flag %s is now clear.\n", name);
+ } else {
+ MR_trace_usage_cur_cmd();
+ }
+ } else {
+ if (*flagptr) {
+ fprintf(MR_mdb_out, "Flag %s is set.\n", name);
+ } else {
+ fprintf(MR_mdb_out, "Flag %s is clear.\n", name);
+ }
+ }
+
+ return KEEP_INTERACTING;
+}
+
+MR_Next
+MR_trace_cmd_subgoal(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
+ MR_Event_Info *event_info, MR_Code **jumpaddr)
+{
+#ifdef MR_USE_MINIMAL_MODEL_STACK_COPY
+
+ MR_SubgoalDebug *subgoal_debug;
+ MR_Subgoal *subgoal;
+ int n;
+
+ if (word_count == 2 && MR_trace_is_natural_number(words[1], &n)) {
+ MR_trace_init_modules();
+
+ subgoal_debug = MR_lookup_subgoal_debug_num(n);
+ if (subgoal_debug == NULL) {
+ fprintf(MR_mdb_out, "no such subgoal\n");
+ } else {
+ MR_trace_print_subgoal_debug(NULL, subgoal_debug);
+ }
+ } else {
+ MR_trace_usage_cur_cmd();
+ }
+
+#else /* MR_USE_MINIMAL_MODEL_STACK_COPY */
+
+ fprintf(MR_mdb_out, "mdb: the `subgoal' command is available "
+ "only in stack copy minimal model tabling grades.\n");
+
+#endif /* MR_USE_MINIMAL_MODEL_STACK_COPY */
+
+ return KEEP_INTERACTING;
+}
+
+MR_Next
+MR_trace_cmd_consumer(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
+ MR_Event_Info *event_info, MR_Code **jumpaddr)
+{
+#ifdef MR_USE_MINIMAL_MODEL_STACK_COPY
+
+ MR_ConsumerDebug *consumer_debug;
+ MR_Consumer *consumer;
+ int n;
+
+ if (word_count == 2 && MR_trace_is_natural_number(words[1], &n)) {
+ MR_trace_init_modules();
+
+ consumer_debug = MR_lookup_consumer_debug_num(n);
+ if (consumer_debug == NULL) {
+ fprintf(MR_mdb_out, "no such consumer\n");
+ } else {
+ MR_trace_print_consumer_debug(NULL, consumer_debug);
+ }
+ } else {
+ MR_trace_usage_cur_cmd();
+ }
+
+#else /* MR_USE_MINIMAL_MODEL_STACK_COPY */
+
+ fprintf(MR_mdb_out, "mdb: the `consumer' command is available "
+ "only in stack copy minimal model tabling grades.\n");
+
+#endif /* MR_USE_MINIMAL_MODEL_STACK_COPY */
+
+ return KEEP_INTERACTING;
+}
+
+MR_Next
+MR_trace_cmd_gen_stack(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
+ MR_Event_Info *event_info, MR_Code **jumpaddr)
+{
+#ifdef MR_USE_MINIMAL_MODEL_STACK_COPY
+
+ if (word_count == 1) {
+ MR_bool saved_tabledebug;
+
+ MR_trace_init_modules();
+ saved_tabledebug = MR_tabledebug;
+ MR_tabledebug = MR_TRUE;
+ MR_print_gen_stack(MR_mdb_out);
+ MR_tabledebug = saved_tabledebug;
+ } else {
+ MR_trace_usage_cur_cmd();
+ }
+
+#else /* MR_USE_MINIMAL_MODEL_STACK_COPY */
+
+ fprintf(MR_mdb_out, "mdb: the `gen_stack' command is available "
+ "only in stack copy minimal model tabling grades.\n");
+
+#endif /* MR_USE_MINIMAL_MODEL_STACK_COPY */
+
+ return KEEP_INTERACTING;
+}
+
+MR_Next
+MR_trace_cmd_cut_stack(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
+ MR_Event_Info *event_info, MR_Code **jumpaddr)
+{
+#ifdef MR_USE_MINIMAL_MODEL_STACK_COPY
+
+ if (word_count == 1) {
+ MR_bool saved_tabledebug;
+
+ MR_trace_init_modules();
+ saved_tabledebug = MR_tabledebug;
+ MR_tabledebug = MR_TRUE;
+ MR_print_cut_stack(MR_mdb_out);
+ MR_tabledebug = saved_tabledebug;
+ } else {
+ MR_trace_usage_cur_cmd();
+ }
+
+#else /* MR_USE_MINIMAL_MODEL_STACK_COPY */
+
+ fprintf(MR_mdb_out, "mdb: the `cut_stack' command is available "
+ "only in stack copy minimal model tabling grades.\n");
+
+#endif /* MR_USE_MINIMAL_MODEL_STACK_COPY */
+
+ return KEEP_INTERACTING;
+}
+
+MR_Next
+MR_trace_cmd_pneg_stack(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
+ MR_Event_Info *event_info, MR_Code **jumpaddr)
+{
+#ifdef MR_USE_MINIMAL_MODEL_STACK_COPY
+
+ if (word_count == 1) {
+ MR_bool saved_tabledebug;
+
+ MR_trace_init_modules();
+ saved_tabledebug = MR_tabledebug;
+ MR_tabledebug = MR_TRUE;
+ MR_print_pneg_stack(MR_mdb_out);
+ MR_tabledebug = saved_tabledebug;
+ } else {
+ MR_trace_usage_cur_cmd();
+ }
+
+#else /* MR_USE_MINIMAL_MODEL_STACK_COPY */
+
+ fprintf(MR_mdb_out, "mdb: the `pneg_stack' command is available "
+ "only in stack copy minimal model tabling grades.\n");
+
+#endif /* MR_USE_MINIMAL_MODEL_STACK_COPY */
+
+ return KEEP_INTERACTING;
+}
+
+MR_Next
+MR_trace_cmd_mm_stacks(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
+ MR_Event_Info *event_info, MR_Code **jumpaddr)
+{
+#ifdef MR_USE_MINIMAL_MODEL_STACK_COPY
+
+ if (word_count == 1) {
+ MR_bool saved_tabledebug;
+
+ MR_trace_init_modules();
+ saved_tabledebug = MR_tabledebug;
+ MR_tabledebug = MR_TRUE;
+ MR_print_gen_stack(MR_mdb_out);
+ fprintf(MR_mdb_out, "\n");
+ MR_print_cut_stack(MR_mdb_out);
+ fprintf(MR_mdb_out, "\n");
+ MR_print_pneg_stack(MR_mdb_out);
+ MR_tabledebug = saved_tabledebug;
+ } else {
+ MR_trace_usage_cur_cmd();
+ }
+
+#else /* MR_USE_MINIMAL_MODEL_STACK_COPY */
+
+ fprintf(MR_mdb_out, "mdb: the `pneg_stack' command is available "
+ "only in stack copy minimal model tabling grades.\n");
+
+#endif /* MR_USE_MINIMAL_MODEL_STACK_COPY */
+
+ return KEEP_INTERACTING;
+}
+
+MR_Next
+MR_trace_cmd_nondet_stack(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
+ MR_Event_Info *event_info, MR_Code **jumpaddr)
+{
+ MR_bool detailed;
+ int frame_limit = 0;
+ int line_limit = MR_stack_default_line_limit;
+ int spec_line_limit;
+
+ detailed = MR_FALSE;
+ if (! MR_trace_options_nondet_stack(&detailed, &frame_limit,
+ &words, &word_count))
+ {
+ ; /* the usage message has already been printed */
+ } else if (word_count == 1) {
+ MR_trace_cmd_nondet_stack_2(event_info, detailed, frame_limit,
+ line_limit);
+ } else if (word_count == 2 &&
+ MR_trace_is_natural_number(words[1], &spec_line_limit))
+ {
+ MR_trace_cmd_nondet_stack_2(event_info, detailed, frame_limit,
+ spec_line_limit);
+ } else {
+ MR_trace_usage_cur_cmd();
+ }
+
+ return KEEP_INTERACTING;
+}
+
+MR_Next
+MR_trace_cmd_stack_regs(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
+ MR_Event_Info *event_info, MR_Code **jumpaddr)
+{
+ MR_Word *saved_regs;
+
+ saved_regs = event_info->MR_saved_regs;
+
+ if (word_count == 1) {
+ MR_print_stack_regs(MR_mdb_out, saved_regs);
+ } else {
+ MR_trace_usage_cur_cmd();
+ }
+
+ return KEEP_INTERACTING;
+}
+
+MR_Next
+MR_trace_cmd_all_regs(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
+ MR_Event_Info *event_info, MR_Code **jumpaddr)
+{
+ MR_Word *saved_regs;
+
+ saved_regs = event_info->MR_saved_regs;
+
+ if (word_count == 1) {
+ MR_print_stack_regs(MR_mdb_out, saved_regs);
+ MR_print_heap_regs(MR_mdb_out, saved_regs);
+ MR_print_tabling_regs(MR_mdb_out, saved_regs);
+ MR_print_succip_reg(MR_mdb_out, saved_regs);
+ MR_print_r_regs(MR_mdb_out, saved_regs);
+#ifdef MR_DEEP_PROFILING
+ MR_print_deep_prof_vars(MR_mdb_out, "mdb all_regs");
+#endif
+ } else {
+ MR_trace_usage_cur_cmd();
+ }
+
+ return KEEP_INTERACTING;
+}
+
+MR_Next
+MR_trace_cmd_debug_vars(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
+ MR_Event_Info *event_info, MR_Code **jumpaddr)
+{
+ if (word_count == 1) {
+ MR_print_debug_vars(MR_mdb_out, event_info);
+ } else {
+ MR_trace_usage_cur_cmd();
+ }
+
+ return KEEP_INTERACTING;
+}
+
+MR_Next
+MR_trace_cmd_stats(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
+ MR_Event_Info *event_info, MR_Code **jumpaddr)
+{
+ char *filename;
+ FILE *fp;
+ MR_bool should_close;
+
+ filename = NULL;
+ if (! MR_trace_options_stats(&filename, &words, &word_count)) {
+ /* the usage message has already been printed */
+ return KEEP_INTERACTING;
+ }
+
+ if (word_count != 2) {
+ MR_trace_usage_cur_cmd();
+ }
+
+ if (filename != NULL) {
+ fp = fopen(filename, "w");
+ if (fp == NULL) {
+ fflush(MR_mdb_out);
+ fprintf(MR_mdb_err, "mdb: error opening `%s': %s.\n",
+ filename, strerror(errno));
+ return KEEP_INTERACTING;
+ }
+
+ should_close = MR_TRUE;
+ } else {
+ fp = MR_mdb_out;
+ should_close = MR_FALSE;
+ }
+
+ if (MR_streq(words[1], "procs")) {
+ MR_proc_layout_stats(fp);
+ } else if (MR_streq(words[1], "labels")) {
+ MR_label_layout_stats(fp);
+ } else if (MR_streq(words[1], "var_names")) {
+ MR_var_name_stats(fp);
+ } else if (MR_streq(words[1], "io_tabling")) {
+ MR_io_tabling_stats(fp);
+ } else {
+ MR_trace_usage_cur_cmd();
+ }
+
+ if (should_close) {
+ (void) fclose(fp);
+ }
+
+ return KEEP_INTERACTING;
+}
+
+MR_Next
+MR_trace_cmd_print_optionals(char **words, int word_count,
+ MR_Trace_Cmd_Info *cmd, MR_Event_Info *event_info, MR_Code **jumpaddr)
+{
+ if (word_count == 2 && MR_streq(words[1], "off")) {
+ MR_print_optionals = MR_FALSE;
+ MR_trace_set_level(MR_trace_current_level(), MR_print_optionals);
+ } else if (word_count == 2 && MR_streq(words[1], "on")) {
+ MR_print_optionals = MR_TRUE;
+ MR_trace_set_level(MR_trace_current_level(), MR_print_optionals);
+ } else if (word_count == 1) {
+ fprintf(MR_mdb_out, "optional values are %sbeing printed\n",
+ MR_print_optionals? "" : "not ");
+ } else {
+ MR_trace_usage_cur_cmd();
+ }
+
+ return KEEP_INTERACTING;
+}
+
+MR_Next
+MR_trace_cmd_unhide_events(char **words, int word_count,
+ MR_Trace_Cmd_Info *cmd, MR_Event_Info *event_info, MR_Code **jumpaddr)
+{
+ if (word_count == 2 && MR_streq(words[1], "off")) {
+ MR_trace_unhide_events = MR_FALSE;
+ fprintf(MR_mdb_out, "Hidden events are hidden.\n");
+ } else if (word_count == 2 && MR_streq(words[1], "on")) {
+ MR_trace_unhide_events = MR_TRUE;
+ MR_trace_have_unhid_events = MR_TRUE;
+ fprintf(MR_mdb_out, "Hidden events are exposed.\n");
+ } else if (word_count == 1) {
+ fprintf(MR_mdb_out, "Hidden events are %s.\n",
+ MR_trace_unhide_events? "exposed" : "hidden");
+ } else {
+ MR_trace_usage_cur_cmd();
+ }
+
+ return KEEP_INTERACTING;
+}
+
+MR_Next
+MR_trace_cmd_table(char **words, int word_count,
+ MR_Trace_Cmd_Info *cmd, MR_Event_Info *event_info, MR_Code **jumpaddr)
+{
+ MR_Call_Table_Arg *call_table_args;
+ const MR_Proc_Layout *proc;
+ MR_Proc_Spec spec;
+ const MR_Table_Gen *table_gen;
+ MR_TrieNode table_cur;
+ int num_inputs;
+ int filtered_num_inputs;
+ int cur_arg;
+ int filtered_cur_arg;
+ int num_tips;
+
+ if (word_count < 2) {
+ MR_trace_usage_cur_cmd();
+ return KEEP_INTERACTING;
+ }
+
+ if (! MR_parse_proc_spec(words[1], &spec)) {
+ fflush(MR_mdb_out);
+ fprintf(MR_mdb_err, "mdb: invalid procedure specification.\n");
+ return KEEP_INTERACTING;
+ }
+
+ proc = MR_find_single_matching_proc(&spec, MR_TRUE);
+ if (proc == NULL) {
+ return KEEP_INTERACTING;
+ }
+
+ switch (MR_sle_eval_method(proc)) {
+ case MR_EVAL_METHOD_NORMAL:
+ MR_print_proc_id(MR_mdb_out, proc);
+ fprintf(MR_mdb_out, " isn't tabled.\n");
+ return KEEP_INTERACTING;
+
+ case MR_EVAL_METHOD_LOOP_CHECK:
+ case MR_EVAL_METHOD_MEMO_STRICT:
+ case MR_EVAL_METHOD_MEMO_FAST_LOOSE:
+ case MR_EVAL_METHOD_MEMO_SPECIFIED:
+ case MR_EVAL_METHOD_MINIMAL_STACK_COPY:
+ case MR_EVAL_METHOD_MINIMAL_OWN_STACKS:
+ break;
+
+ case MR_EVAL_METHOD_TABLE_IO:
+ case MR_EVAL_METHOD_TABLE_IO_DECL:
+ case MR_EVAL_METHOD_TABLE_IO_UNITIZE:
+ case MR_EVAL_METHOD_TABLE_IO_UNITIZE_DECL:
+ fprintf(MR_mdb_out,
+ "IO tabled predicates do not have their own tables.\n");
+ return KEEP_INTERACTING;
+ }
+
+ /*
+ ** words[0] is the command, words[1] is the procedure spec;
+ ** words[2] is the first argument. We step over the command and the
+ ** procedure spec, to leave words[] containing only the argument
+ ** values.
+ */
+
+ words += 2;
+ word_count -= 2;
+
+ table_gen = proc->MR_sle_table_info.MR_table_gen;
+ num_inputs = table_gen->MR_table_gen_num_inputs;
+
+ if (word_count > num_inputs) {
+ fprintf(MR_mdb_out, "There are only %d input arguments.\n",
+ num_inputs);
+ return KEEP_INTERACTING;
+ }
+
+ call_table_args = MR_GC_NEW_ARRAY(MR_Call_Table_Arg, num_inputs);
+ if (call_table_args == NULL) {
+ MR_fatal_error("MR_trace_cmd_table: "
+ "couldn't allocate call_table_args");
+ }
+
+ table_cur = proc->MR_sle_tabling_pointer;
+ for (cur_arg = 0, filtered_cur_arg = 0; cur_arg < num_inputs; cur_arg++) {
+ switch (table_gen->MR_table_gen_input_steps[cur_arg]) {
+ case MR_TABLE_STEP_INT:
+ case MR_TABLE_STEP_FLOAT:
+ case MR_TABLE_STEP_STRING:
+ /* these are OK */
+ call_table_args[filtered_cur_arg].MR_cta_step =
+ table_gen->MR_table_gen_input_steps[filtered_cur_arg];
+ call_table_args[filtered_cur_arg].MR_cta_valid = MR_FALSE;
+ call_table_args[filtered_cur_arg].MR_cta_unfiltered_arg_num =
+ cur_arg;
+ filtered_cur_arg++;
+
+ case MR_TABLE_STEP_PROMISE_IMPLIED:
+ /* this argument doesn't exist in the table */
+ break;
+
+ default:
+ fprintf(MR_mdb_out, "Sorry, can handle only "
+ "integer, float and string arguments for now.\n");
+ MR_GC_free(call_table_args);
+ return KEEP_INTERACTING;
+ }
+ }
+
+ filtered_num_inputs = filtered_cur_arg;
+ if (word_count > filtered_num_inputs) {
+ fprintf(MR_mdb_out,
+ "Sorry, this procedure has only %d tabled arguments\n",
+ filtered_num_inputs);
+ MR_GC_free(call_table_args);
+ return KEEP_INTERACTING;
+ }
+
+ /*
+ ** Set up the values of the input arguments supplied on the command
+ ** line, to enable us to print them out in each call table entry.
+ */
+
+ for (filtered_cur_arg = 0;
+ filtered_cur_arg < word_count;
+ filtered_cur_arg++)
+ {
+ MR_bool success;
+
+ switch (call_table_args[filtered_cur_arg].MR_cta_step) {
+ case MR_TABLE_STEP_INT:
+ success = MR_trace_fill_in_int_table_arg_slot(&table_cur,
+ filtered_cur_arg + 1, words[filtered_cur_arg],
+ &call_table_args[filtered_cur_arg]);
+ break;
+
+ case MR_TABLE_STEP_FLOAT:
+ success = MR_trace_fill_in_float_table_arg_slot(&table_cur,
+ filtered_cur_arg + 1, words[filtered_cur_arg],
+ &call_table_args[filtered_cur_arg]);
+ break;
+
+ case MR_TABLE_STEP_STRING:
+ success = MR_trace_fill_in_string_table_arg_slot(&table_cur,
+ filtered_cur_arg + 1, words[filtered_cur_arg],
+ &call_table_args[filtered_cur_arg]);
+ break;
+
+ default:
+ MR_fatal_error("arg not int, float or string after check");
+ }
+
+ if (! success) {
+ /* the error message has already been printed */
+ MR_GC_free(call_table_args);
+ return KEEP_INTERACTING;
+ }
+ }
+
+ if (word_count == filtered_num_inputs) {
+ /*
+ ** The user specified values for all the input arguments,
+ ** so what we print is a single entry, not a table of entries,
+ ** and we don't need to loop over all the entries.
+ */
+
+ MR_trace_cmd_table_print_tip(proc, filtered_num_inputs,
+ call_table_args, table_cur);
+ MR_GC_free(call_table_args);
+ return KEEP_INTERACTING;
+ }
+
+ /*
+ ** The user left the values of some input arguments unspecified,
+ ** so we print a table of entries. Here we print the header.
+ */
+
+ switch (MR_sle_eval_method(proc)) {
+ case MR_EVAL_METHOD_LOOP_CHECK:
+ fprintf(MR_mdb_out, "loopcheck table for ");
+ MR_print_proc_id(MR_mdb_out, proc);
+ fprintf(MR_mdb_out, ":\n");
+ break;
+
+ case MR_EVAL_METHOD_MEMO_STRICT:
+ case MR_EVAL_METHOD_MEMO_FAST_LOOSE:
+ case MR_EVAL_METHOD_MEMO_SPECIFIED:
+ fprintf(MR_mdb_out, "memo table for ");
+ MR_print_proc_id(MR_mdb_out, proc);
+ fprintf(MR_mdb_out, ":\n");
+ break;
+
+ case MR_EVAL_METHOD_MINIMAL_STACK_COPY:
+ case MR_EVAL_METHOD_MINIMAL_OWN_STACKS:
+ fprintf(MR_mdb_out, "minimal model table for ");
+ MR_print_proc_id(MR_mdb_out, proc);
+ fprintf(MR_mdb_out, ":\n");
+ break;
+
+ case MR_EVAL_METHOD_NORMAL:
+ case MR_EVAL_METHOD_TABLE_IO:
+ case MR_EVAL_METHOD_TABLE_IO_DECL:
+ case MR_EVAL_METHOD_TABLE_IO_UNITIZE:
+ case MR_EVAL_METHOD_TABLE_IO_UNITIZE_DECL:
+ MR_fatal_error("MR_trace_cmd_table: bad eval method");
+ }
+
+ /*
+ ** This loop prints the entries in the table.
+ **
+ ** If we knew in advance that the user left (say) two input argument
+ ** positions unspecified, we could use a loop structure such as:
+ **
+ ** for value1 in <values in the trie at node start_node[0]>
+ ** cur_value[1] = value1
+ ** start_node[1] = follow value1 in start_node[0]
+ ** for value2 in <values in the trie at node start_node[1]>
+ ** cur_value[2] = value2
+ ** start_node[2] = follow value2 in start_node[1]
+ ** print <fixed args>, cur_value[1], cur_value[2]
+ ** end for
+ ** end for
+ **
+ ** However, we don't know in advance how many input arguments the user
+ ** left unspecified. We therefore simulate the above with a single
+ ** loop, which can function as any one of the above nested loops.
+ **
+ ** The value of cur_arg controls which one it is simulating at any
+ ** given time. Initially, cur_arg grows as we enter each of the above
+ ** loops one after another, at each stage recording the set of values
+ ** in the current trie node in the values array of the relevant
+ ** argument.
+ **
+ ** We number the input arguments from 0 to filtered_num_inputs-1.
+ ** When cur_arg becomes equal to filtered_num_inputs, this means that
+ ** we have values for all the tabled input arguments, so we print the
+ ** corresponding call table entry. We then initiate backtracking:
+ ** we decrement cur_arg to get the next value of the last argument.
+ ** We also do this whenever we run out of values in any trie.
+ **
+ ** We stop when we are about to backtrack out of the outermost loop.
+ */
+
+ cur_arg = word_count;
+ num_tips = 0;
+ for (;;) {
+ MR_bool no_more;
+ MR_bool start_backtrack;
+
+ switch (call_table_args[cur_arg].MR_cta_step) {
+ case MR_TABLE_STEP_INT:
+ no_more = MR_update_int_table_arg_slot(&table_cur,
+ &call_table_args[cur_arg]);
+ break;
+
+ case MR_TABLE_STEP_FLOAT:
+ no_more = MR_update_float_table_arg_slot(&table_cur,
+ &call_table_args[cur_arg]);
+ break;
+
+ case MR_TABLE_STEP_STRING:
+ no_more = MR_update_string_table_arg_slot(&table_cur,
+ &call_table_args[cur_arg]);
+ break;
+
+ default:
+ MR_fatal_error("arg not int, float or string after check");
+ }
+
+ if (no_more) {
+ /*
+ ** There aren't any more values in the current trie
+ ** of input argument cur_arg.
+ */
+
+ start_backtrack = MR_TRUE;
+ } else {
+ /*
+ ** There is at least one more value in the current trie
+ ** of input argument cur_arg, so go on to the next trie
+ ** (if there is one).
+ */
+
+ cur_arg++;
+
+ if (cur_arg >= filtered_num_inputs) {
+ MR_trace_cmd_table_print_tip(proc, filtered_num_inputs,
+ call_table_args, table_cur);
+ num_tips++;
+ start_backtrack = MR_TRUE;
+ } else {
+ start_backtrack = MR_FALSE;
+ }
+ }
+
+ if (start_backtrack) {
+ cur_arg--;
+ table_cur = call_table_args[cur_arg].MR_cta_start_node;
+
+ if (cur_arg < word_count) {
+ break;
+ }
+ }
+ }
+
+ fprintf(MR_mdb_out, "end of table (%d %s)\n",
+ num_tips, (num_tips == 1 ? "entry" : "entries"));
+ MR_GC_free(call_table_args);
+ return KEEP_INTERACTING;
+}
+
+MR_Next
+MR_trace_cmd_type_ctor(char **words, int word_count,
+ MR_Trace_Cmd_Info *cmd, MR_Event_Info *event_info, MR_Code **jumpaddr)
+{
+ const char *module_name;
+ const char *name;
+ int arity;
+ MR_bool print_rep;
+ MR_bool print_functors;
+ MR_TypeCtorInfo type_ctor_info;
+
+ MR_do_init_modules_type_tables();
+
+ print_rep = MR_FALSE;
+ print_functors = MR_FALSE;
+ if (! MR_trace_options_type_ctor(&print_rep, &print_functors,
+ &words, &word_count))
+ {
+ ; /* the usage message has already been printed */
+ } else if (word_count == 4 &&
+ MR_trace_is_natural_number(words[3], &arity))
+ {
+ module_name = words[1];
+ name = words[2];
+ type_ctor_info = MR_lookup_type_ctor_info(module_name, name, arity);
+ if (type_ctor_info != NULL) {
+ MR_print_type_ctor_info(MR_mdb_out, type_ctor_info, print_rep,
+ print_functors);
+ } else {
+ fprintf(MR_mdb_out, "there is no such type constructor\n");
+ }
+ } else {
+ MR_trace_usage_cur_cmd();
+ }
+
+ return KEEP_INTERACTING;
+}
+
+MR_Next
+MR_trace_cmd_class_decl(char **words, int word_count,
+ MR_Trace_Cmd_Info *cmd, MR_Event_Info *event_info, MR_Code **jumpaddr)
+{
+ const char *module_name;
+ const char *name;
+ int arity;
+ MR_bool print_methods;
+ MR_bool print_instances;
+ MR_TypeClassDeclInfo *type_class_decl_info;
+
+ MR_do_init_modules_type_tables();
+
+ print_methods = MR_FALSE;
+ print_instances = MR_FALSE;
+ if (! MR_trace_options_class_decl(&print_methods, &print_instances,
+ &words, &word_count))
+ {
+ ; /* the usage message has already been printed */
+ } else if (word_count == 4 &&
+ MR_trace_is_natural_number(words[3], &arity))
+ {
+ module_name = words[1];
+ name = words[2];
+ type_class_decl_info = MR_lookup_type_class_decl_info(module_name,
+ name, arity);
+ if (type_class_decl_info != NULL) {
+ MR_print_class_decl_info(MR_mdb_out, type_class_decl_info,
+ print_methods, print_instances);
+ } else {
+ fprintf(MR_mdb_out, "there is no such type class\n");
+ }
+ } else {
+ MR_trace_usage_cur_cmd();
+ }
+
+ return KEEP_INTERACTING;
+}
+
+MR_Next
+MR_trace_cmd_all_type_ctors(char **words, int word_count,
+ MR_Trace_Cmd_Info *cmd, MR_Event_Info *event_info, MR_Code **jumpaddr)
+{
+ MR_bool print_rep;
+ MR_bool print_functors;
+ MR_Dlist *list;
+ MR_Dlist *element_ptr;
+ MR_TypeCtorInfo type_ctor_info;
+ const char *module_name;
+ int count;
+
+ MR_do_init_modules_type_tables();
+
+ print_rep = MR_FALSE;
+ print_functors = MR_FALSE;
+ if (! MR_trace_options_type_ctor(&print_rep, &print_functors,
+ &words, &word_count))
+ {
+ ; /* the usage message has already been printed */
+ } else if (word_count == 1 || word_count == 2) {
+ if (word_count == 2) {
+ module_name = words[1];
+ } else {
+ module_name = NULL;
+ }
+
+ list = MR_all_type_ctor_infos(NULL);
+ count = 0;
+ MR_for_dlist(element_ptr, list) {
+ type_ctor_info = (MR_TypeCtorInfo) MR_dlist_data(element_ptr);
+ if (module_name != NULL && strcmp(module_name,
+ type_ctor_info->MR_type_ctor_module_name) != 0)
+ {
+ continue;
+ }
+
+ if (count > 0) {
+ fprintf(MR_mdb_out, "\n");
+ }
+ MR_print_type_ctor_info(MR_mdb_out, type_ctor_info, print_rep,
+ print_functors);
+ count++;
+ }
+
+ fprintf(MR_mdb_out, "\nnumber of type constructors ");
+ if (module_name == NULL) {
+ fprintf(MR_mdb_out, "in the program: %d\n", count);
+ } else {
+ fprintf(MR_mdb_out, "in module %s: %d\n", module_name, count);
+ }
+ } else {
+ MR_trace_usage_cur_cmd();
+ }
+
+ return KEEP_INTERACTING;
+}
+
+MR_Next
+MR_trace_cmd_all_class_decls(char **words, int word_count,
+ MR_Trace_Cmd_Info *cmd, MR_Event_Info *event_info, MR_Code **jumpaddr)
+{
+ MR_bool print_methods;
+ MR_bool print_instances;
+ MR_Dlist *list;
+ MR_Dlist *element_ptr;
+ MR_TypeClassDeclInfo *type_class_decl_info;
+ const char *module_name;
+ int count;
+
+ MR_do_init_modules_type_tables();
+
+ print_methods = MR_FALSE;
+ print_instances = MR_FALSE;
+ if (! MR_trace_options_class_decl(&print_methods, &print_instances,
+ &words, &word_count))
+ {
+ ; /* the usage message has already been printed */
+ } else if (word_count == 1 || word_count == 2) {
+ if (word_count == 2) {
+ module_name = words[1];
+ } else {
+ module_name = NULL;
+ }
+ list = MR_all_type_class_decl_infos(NULL);
+ count = 0;
+ MR_for_dlist(element_ptr, list) {
+ type_class_decl_info = (MR_TypeClassDeclInfo *)
+ MR_dlist_data(element_ptr);
+ if (module_name != NULL && strcmp(module_name,
+ type_class_decl_info->MR_tcd_info_decl->
+ MR_tc_decl_id->MR_tc_id_module_name) != 0)
+ {
+ continue;
+ }
+
+ if (count > 0) {
+ fprintf(MR_mdb_out, "\n");
+ }
+ MR_print_class_decl_info(MR_mdb_out, type_class_decl_info,
+ print_methods, print_instances);
+ count++;
+ }
+
+ fprintf(MR_mdb_out, "\nnumber of type classes ");
+ if (module_name == NULL) {
+ fprintf(MR_mdb_out, "in the program: %d\n", count);
+ } else {
+ fprintf(MR_mdb_out, "in module %s: %d\n", module_name, count);
+ }
+ } else {
+ MR_trace_usage_cur_cmd();
+ }
+
+ return KEEP_INTERACTING;
+}
+
+MR_Next
+MR_trace_cmd_all_procedures(char **words, int word_count,
+ MR_Trace_Cmd_Info *cmd, MR_Event_Info *event_info, MR_Code **jumpaddr)
+{
+ const char *filename;
+ MR_bool separate;
+ MR_bool uci;
+ FILE *fp;
+ char *module;
+
+ MR_register_all_modules_and_procs(MR_mdb_out, MR_TRUE);
+
+ separate = MR_FALSE;
+ uci = MR_FALSE;
+ module = NULL;
+ if (! MR_trace_options_all_procedures(&separate, &uci, &module,
+ &words, &word_count))
+ {
+ ; /* the usage message has already been printed */
+ } else if (word_count == 2) {
+ filename = words[1];
+ fp = fopen(filename, "w");
+ if (fp == NULL) {
+ fflush(MR_mdb_out);
+ fprintf(MR_mdb_err, "mdb: error opening `%s': %s.\n",
+ filename, strerror(errno));
+ return KEEP_INTERACTING;
+ }
+
+ MR_dump_module_tables(fp, separate, uci, module);
+ if (fclose(fp) != 0) {
+ fprintf(MR_mdb_err, "mdb: error writing to `%s': %s.\n",
+ filename, strerror(errno));
+ return KEEP_INTERACTING;
+ } else {
+ fprintf(MR_mdb_out, "mdb: wrote table to `%s'.\n", filename);
+ }
+ } else {
+ MR_trace_usage_cur_cmd();
+ }
+
+ return KEEP_INTERACTING;
+}
+
+MR_Next
+MR_trace_cmd_ambiguity(char **words, int word_count,
+ MR_Trace_Cmd_Info *cmd, MR_Event_Info *event_info, MR_Code **jumpaddr)
+{
+ const char *filename;
+ FILE *fp;
+ int i;
+
+ filename = NULL;
+ if (! MR_trace_options_ambiguity(&filename, &words, &word_count)) {
+ ; /* the usage message has already been printed */
+ } else {
+ MR_register_all_modules_and_procs(MR_mdb_out, MR_TRUE);
+
+ if (filename == NULL) {
+ fp = MR_mdb_out;
+ } else {
+ fp = fopen(filename, "w");
+ if (fp == NULL) {
+ fflush(MR_mdb_out);
+ fprintf(MR_mdb_err, "mdb: error opening `%s': %s.\n",
+ filename, strerror(errno));
+ return KEEP_INTERACTING;
+ }
+ }
+
+ /*
+ ** The words on the command line after the command name and the already
+ ** processed options are a list of modules names. If this list is not
+ ** empty, then we consider only the modules named here when looking for
+ ** ambiguities.
+ */
+
+ MR_print_ambiguities(fp, &words[1], word_count - 1);
+
+ if (filename != NULL) {
+ fprintf(MR_mdb_out, "mdb: wrote report to `%s'.\n", filename);
+ fclose(fp);
+ }
+ }
+
+ return KEEP_INTERACTING;
+}
+
+/****************************************************************************/
+
+static void
+MR_trace_cmd_nondet_stack_2(MR_Event_Info *event_info, MR_bool detailed,
+ int frame_limit, int line_limit)
+{
+ const MR_Label_Layout *layout;
+ MR_Word *saved_regs;
+
+ layout = event_info->MR_event_sll;
+ saved_regs = event_info->MR_saved_regs;
+
+ MR_trace_init_modules();
+ if (detailed) {
+ int saved_level;
+
+ saved_level = MR_trace_current_level();
+ MR_dump_nondet_stack_from_layout(MR_mdb_out, NULL, frame_limit,
+ line_limit, MR_saved_maxfr(saved_regs), layout,
+ MR_saved_sp(saved_regs), MR_saved_curfr(saved_regs));
+ MR_trace_set_level(saved_level, MR_print_optionals);
+ } else {
+ MR_dump_nondet_stack(MR_mdb_out, NULL, frame_limit, line_limit,
+ MR_saved_maxfr(saved_regs));
+ }
+}
+
+static const MR_Proc_Layout *
+MR_find_single_matching_proc(MR_Proc_Spec *spec, MR_bool verbose)
+{
+ MR_Matches_Info matches;
+ int n;
+ int i;
+
+ MR_register_all_modules_and_procs(MR_mdb_out, verbose);
+ matches = MR_search_for_matching_procedures(spec);
+ if (matches.match_proc_next == 0) {
+ fflush(MR_mdb_out);
+ fprintf(MR_mdb_err, "mdb: there is no such procedure.\n");
+ return NULL;
+ } else if (matches.match_proc_next == 1) {
+ return matches.match_procs[0];
+ } else {
+ char buf[100];
+ char *line2;
+
+ fflush(MR_mdb_out);
+ fprintf(MR_mdb_err, "Ambiguous procedure specification. "
+ "The matches are:\n");
+ for (i = 0; i < matches.match_proc_next; i++) {
+ fprintf(MR_mdb_out, "%d: ", i);
+ MR_print_proc_id_and_nl(MR_mdb_out, matches.match_procs[i]);
+ }
+
+ sprintf(buf, "\nWhich procedure's table do you want to print (0-%d)? ",
+ matches.match_proc_next - 1);
+ line2 = MR_trace_getline(buf, MR_mdb_in, MR_mdb_out);
+ n = -1;
+ if (line2 == NULL || !MR_trace_is_natural_number(line2, &n)) {
+ n = -1;
+ fprintf(MR_mdb_out, "none of them\n");
+ } else if (n < 0 || n >= matches.match_proc_next) {
+ n = -1;
+ fprintf(MR_mdb_out, "invalid choice\n");
+ }
+
+ if (line2 != NULL) {
+ MR_free(line2);
+ }
+
+ if (n >= 0) {
+ return matches.match_procs[n];
+ } else {
+ return NULL;
+ }
+ }
+}
+
+static MR_bool
+MR_trace_fill_in_int_table_arg_slot(MR_TrieNode *table_cur_ptr,
+ int arg_num, MR_ConstString given_arg,
+ MR_Call_Table_Arg *call_table_arg_ptr)
+{
+ MR_Integer n;
+ MR_TrieNode table_next;
+
+ if (! MR_trace_is_integer(given_arg, &n)) {
+ fprintf(MR_mdb_out, "argument %d is not an integer.\n", arg_num);
+ return MR_FALSE;
+ }
+
+ table_next = MR_int_hash_lookup(*table_cur_ptr, n);
+ if (table_next == NULL) {
+ fprintf(MR_mdb_out,
+ "call table does not contain %" MR_INTEGER_LENGTH_MODIFIER "d"
+ " in argument position %d.\n", n, arg_num);
+ return MR_FALSE;
+ }
+
+ call_table_arg_ptr->MR_cta_start_node = *table_cur_ptr;
+ call_table_arg_ptr->MR_cta_valid = MR_TRUE;
+ call_table_arg_ptr->MR_cta_int_values = NULL;
+ call_table_arg_ptr->MR_cta_int_value_next = -1;
+ call_table_arg_ptr->MR_cta_int_cur_index = -1;
+ call_table_arg_ptr->MR_cta_int_cur_value = n;
+ *table_cur_ptr = table_next;
+
+ return MR_TRUE;
+}
+
+static MR_bool
+MR_trace_fill_in_float_table_arg_slot(MR_TrieNode *table_cur_ptr,
+ int arg_num, MR_ConstString given_arg,
+ MR_Call_Table_Arg *call_table_arg_ptr)
+{
+ MR_Float f;
+ MR_TrieNode table_next;
+
+ if (! MR_trace_is_float(given_arg, &f)) {
+ fprintf(MR_mdb_out, "argument %d is not a float.\n", arg_num);
+ return MR_FALSE;
+ }
+
+ table_next = MR_float_hash_lookup(*table_cur_ptr, f);
+ if (table_next == NULL) {
+ fprintf(MR_mdb_out,
+ "call table does not contain %f in argument position %d.\n",
+ f, arg_num);
+ return MR_FALSE;
+ }
+
+ call_table_arg_ptr->MR_cta_start_node = *table_cur_ptr;
+ call_table_arg_ptr->MR_cta_valid = MR_TRUE;
+ call_table_arg_ptr->MR_cta_float_values = NULL;
+ call_table_arg_ptr->MR_cta_float_value_next = -1;
+ call_table_arg_ptr->MR_cta_float_cur_index = -1;
+ call_table_arg_ptr->MR_cta_float_cur_value = f;
+ *table_cur_ptr = table_next;
+
+ return MR_TRUE;
+}
+
+static MR_bool
+MR_trace_fill_in_string_table_arg_slot(MR_TrieNode *table_cur_ptr,
+ int arg_num, MR_ConstString given_arg,
+ MR_Call_Table_Arg *call_table_arg_ptr)
+{
+ MR_ConstString s;
+ MR_TrieNode table_next;
+
+ s = given_arg;
+
+ table_next = MR_string_hash_lookup(*table_cur_ptr, s);
+ if (table_next == NULL) {
+ fprintf(MR_mdb_out,
+ "call table does not contain %s in argument position %d.\n",
+ s, arg_num);
+ return MR_FALSE;
+ }
+
+ call_table_arg_ptr->MR_cta_start_node = *table_cur_ptr;
+ call_table_arg_ptr->MR_cta_valid = MR_TRUE;
+ call_table_arg_ptr->MR_cta_string_values = NULL;
+ call_table_arg_ptr->MR_cta_string_value_next = -1;
+ call_table_arg_ptr->MR_cta_string_cur_index = -1;
+ call_table_arg_ptr->MR_cta_string_cur_value = s;
+ *table_cur_ptr = table_next;
+
+ return MR_TRUE;
+}
+
+static MR_bool
+MR_update_int_table_arg_slot(MR_TrieNode *table_cur_ptr,
+ MR_Call_Table_Arg *call_table_arg_ptr)
+{
+ MR_TrieNode table_next;
+ MR_Integer *values;
+ int value_next;
+
+ if (call_table_arg_ptr->MR_cta_valid
+ && call_table_arg_ptr->MR_cta_int_values != NULL)
+ {
+ call_table_arg_ptr->MR_cta_int_cur_index++;
+ } else {
+ if (! MR_get_int_hash_table_contents(*table_cur_ptr,
+ &values, &value_next))
+ {
+ /* there are no values in this trie node */
+ call_table_arg_ptr->MR_cta_valid = MR_FALSE;
+ return MR_TRUE;
+ }
+
+ call_table_arg_ptr->MR_cta_start_node = *table_cur_ptr;
+ call_table_arg_ptr->MR_cta_valid = MR_TRUE;
+ call_table_arg_ptr->MR_cta_int_values = values;
+ call_table_arg_ptr->MR_cta_int_value_next = value_next;
+ call_table_arg_ptr->MR_cta_int_cur_index = 0;
+ }
+
+ if (call_table_arg_ptr->MR_cta_int_cur_index
+ >= call_table_arg_ptr->MR_cta_int_value_next)
+ {
+ /* we have already returned all the values in this trie node */
+ call_table_arg_ptr->MR_cta_valid = MR_FALSE;
+ return MR_TRUE;
+ }
+
+ call_table_arg_ptr->MR_cta_int_cur_value =
+ call_table_arg_ptr->MR_cta_int_values[
+ call_table_arg_ptr->MR_cta_int_cur_index];
+
+ table_next = MR_int_hash_lookup(call_table_arg_ptr->MR_cta_start_node,
+ call_table_arg_ptr->MR_cta_int_cur_value);
+
+ if (table_next == NULL) {
+ MR_fatal_error("MR_update_int_table_arg_slot: bad lookup");
+ }
+
+ *table_cur_ptr = table_next;
+ return MR_FALSE;
+}
+
+static MR_bool
+MR_update_float_table_arg_slot(MR_TrieNode *table_cur_ptr,
+ MR_Call_Table_Arg *call_table_arg_ptr)
+{
+ MR_TrieNode table_next;
+ MR_Float *values;
+ int value_next;
+
+ if (call_table_arg_ptr->MR_cta_valid
+ && call_table_arg_ptr->MR_cta_float_values != NULL)
+ {
+ call_table_arg_ptr->MR_cta_float_cur_index++;
+ } else {
+ if (! MR_get_float_hash_table_contents(*table_cur_ptr,
+ &values, &value_next))
+ {
+ /* there are no values in this trie node */
+ call_table_arg_ptr->MR_cta_valid = MR_FALSE;
+ return MR_TRUE;
+ }
+
+ call_table_arg_ptr->MR_cta_start_node = *table_cur_ptr;
+ call_table_arg_ptr->MR_cta_valid = MR_TRUE;
+ call_table_arg_ptr->MR_cta_float_values = values;
+ call_table_arg_ptr->MR_cta_float_value_next = value_next;
+ call_table_arg_ptr->MR_cta_float_cur_index = 0;
+ }
+
+ if (call_table_arg_ptr->MR_cta_float_cur_index
+ >= call_table_arg_ptr->MR_cta_float_value_next)
+ {
+ /* we have already returned all the values in this trie node */
+ call_table_arg_ptr->MR_cta_valid = MR_FALSE;
+ return MR_TRUE;
+ }
+
+ call_table_arg_ptr->MR_cta_float_cur_value =
+ call_table_arg_ptr->MR_cta_float_values[
+ call_table_arg_ptr->MR_cta_float_cur_index];
+
+ table_next = MR_float_hash_lookup(call_table_arg_ptr->MR_cta_start_node,
+ call_table_arg_ptr->MR_cta_float_cur_value);
+
+ if (table_next == NULL) {
+ MR_fatal_error("MR_update_float_table_arg_slot: bad lookup");
+ }
+
+ *table_cur_ptr = table_next;
+ return MR_FALSE;
+}
+
+static MR_bool
+MR_update_string_table_arg_slot(MR_TrieNode *table_cur_ptr,
+ MR_Call_Table_Arg *call_table_arg_ptr)
+{
+ MR_TrieNode table_next;
+ MR_ConstString *values;
+ int value_next;
+
+ if (call_table_arg_ptr->MR_cta_valid
+ && call_table_arg_ptr->MR_cta_string_values != NULL)
+ {
+ call_table_arg_ptr->MR_cta_string_cur_index++;
+ } else {
+ if (! MR_get_string_hash_table_contents(*table_cur_ptr,
+ &values, &value_next))
+ {
+ /* there are no values in this trie node */
+ call_table_arg_ptr->MR_cta_valid = MR_FALSE;
+ return MR_TRUE;
+ }
+
+ call_table_arg_ptr->MR_cta_start_node = *table_cur_ptr;
+ call_table_arg_ptr->MR_cta_valid = MR_TRUE;
+ call_table_arg_ptr->MR_cta_string_values = values;
+ call_table_arg_ptr->MR_cta_string_value_next = value_next;
+ call_table_arg_ptr->MR_cta_string_cur_index = 0;
+ }
+
+ if (call_table_arg_ptr->MR_cta_string_cur_index
+ >= call_table_arg_ptr->MR_cta_string_value_next)
+ {
+ /* we have already returned all the values in this trie node */
+ call_table_arg_ptr->MR_cta_valid = MR_FALSE;
+ return MR_TRUE;
+ }
+
+ call_table_arg_ptr->MR_cta_string_cur_value =
+ call_table_arg_ptr->MR_cta_string_values[
+ call_table_arg_ptr->MR_cta_string_cur_index];
+
+ table_next = MR_string_hash_lookup(
+ call_table_arg_ptr->MR_cta_start_node,
+ call_table_arg_ptr->MR_cta_string_cur_value);
+
+ if (table_next == NULL) {
+ MR_fatal_error("MR_update_string_table_arg_slot: bad lookup");
+ }
+
+ *table_cur_ptr = table_next;
+ return MR_FALSE;
+}
+
+static void
+MR_trace_cmd_table_print_tip(const MR_Proc_Layout *proc,
+ int num_filtered_inputs, MR_Call_Table_Arg *call_table_args,
+ MR_TrieNode table)
+{
+ int i;
+ MR_EvalMethod eval_method;
+
+ fprintf(MR_mdb_out, "<");
+ for (i = 0; i < num_filtered_inputs; i++) {
+ if (i > 0) {
+ fprintf(MR_mdb_out, ", ");
+ }
+
+ switch (call_table_args[i].MR_cta_step) {
+ case MR_TABLE_STEP_INT:
+ fprintf(MR_mdb_out, "%" MR_INTEGER_LENGTH_MODIFIER "d",
+ call_table_args[i].MR_cta_int_cur_value);
+ break;
+
+ case MR_TABLE_STEP_FLOAT:
+ fprintf(MR_mdb_out, "%f",
+ call_table_args[i].MR_cta_float_cur_value);
+ break;
+
+ case MR_TABLE_STEP_STRING:
+ fprintf(MR_mdb_out, "\"%s\"",
+ call_table_args[i].MR_cta_string_cur_value);
+ break;
+
+ default:
+ MR_fatal_error("arg not int, float or string after check");
+ }
+ }
+
+ fprintf(MR_mdb_out, ">: ");
+
+ eval_method = MR_sle_eval_method(proc);
+ switch (eval_method) {
+ case MR_EVAL_METHOD_MINIMAL_STACK_COPY:
+ {
+ MR_Subgoal *subgoal;
+ int subgoal_num;
+
+ fprintf(MR_mdb_out, "trie node %p\n", table);
+ subgoal = table->MR_subgoal;
+ if (subgoal == NULL) {
+ fprintf(MR_mdb_out, "uninitialized\n");
+ } else {
+ MR_trace_print_subgoal(proc, subgoal);
+ }
+ }
+ break;
+
+ case MR_EVAL_METHOD_MINIMAL_OWN_STACKS:
+ {
+ MR_GeneratorPtr generator;
+
+ fprintf(MR_mdb_out, "trie node %p\n", table);
+ generator = table->MR_generator;
+ if (generator == NULL) {
+ fprintf(MR_mdb_out, "uninitialized\n");
+ } else {
+ MR_trace_print_generator(proc, generator);
+ }
+ }
+ break;
+
+ case MR_EVAL_METHOD_MEMO_STRICT:
+ case MR_EVAL_METHOD_MEMO_FAST_LOOSE:
+ case MR_EVAL_METHOD_MEMO_SPECIFIED:
+ {
+ MR_Determinism detism;
+
+ detism = proc->MR_sle_detism;
+ if (MR_DETISM_DET_STACK(detism)) {
+ MR_print_memo_tip(MR_mdb_out, proc, table);
+ } else {
+ MR_MemoNonRecordPtr record;
+
+ record = table->MR_memo_non_record;
+ MR_print_memo_non_record(MR_mdb_out, proc, record);
+ }
+ }
+ break;
+
+ case MR_EVAL_METHOD_LOOP_CHECK:
+ MR_print_loopcheck_tip(MR_mdb_out, proc, table);
+ break;
+
+ case MR_EVAL_METHOD_NORMAL:
+ case MR_EVAL_METHOD_TABLE_IO:
+ case MR_EVAL_METHOD_TABLE_IO_DECL:
+ case MR_EVAL_METHOD_TABLE_IO_UNITIZE:
+ case MR_EVAL_METHOD_TABLE_IO_UNITIZE_DECL:
+ MR_fatal_error("MR_trace_cmd_table_print_tip: bad eval method");
+ break;
+ }
+}
+
+static void
+MR_trace_print_subgoal(const MR_Proc_Layout *proc, MR_Subgoal *subgoal)
+{
+#ifdef MR_USE_MINIMAL_MODEL_STACK_COPY
+ MR_print_subgoal(MR_mdb_out, proc, subgoal);
+#else
+ fprintf(MR_mdb_out, "minimal model tabling is not enabled\n");
+#endif
+}
+
+static void
+MR_trace_print_subgoal_debug(const MR_Proc_Layout *proc,
+ MR_SubgoalDebug *subgoal_debug)
+{
+#ifdef MR_USE_MINIMAL_MODEL_STACK_COPY
+ MR_print_subgoal_debug(MR_mdb_out, proc, subgoal_debug);
+#else
+ fprintf(MR_mdb_out, "minimal model tabling is not enabled\n");
+#endif
+}
+
+static void
+MR_trace_print_generator(const MR_Proc_Layout *proc, MR_Generator *generator)
+{
+#ifdef MR_USE_MINIMAL_MODEL_OWN_STACKS
+ MR_print_generator(MR_mdb_out, proc, generator);
+#else
+ fprintf(MR_mdb_out, "minimal model tabling is not enabled\n");
+#endif
+}
+
+static void
+MR_trace_print_generator_debug(const MR_Proc_Layout *proc,
+ MR_GenDebug *generator_debug)
+{
+#ifdef MR_USE_MINIMAL_MODEL_OWN_STACKS
+ MR_print_gen_debug(MR_mdb_out, proc, generator_debug);
+#else
+ fprintf(MR_mdb_out, "minimal model tabling is not enabled\n");
+#endif
+}
+
+static void
+MR_trace_print_consumer(const MR_Proc_Layout *proc, MR_Consumer *consumer)
+{
+#if defined(MR_USE_MINIMAL_MODEL_STACK_COPY) \
+ || defined(MR_USE_MINIMAL_MODEL_OWN_STACKS)
+ MR_print_consumer(MR_mdb_out, proc, consumer);
+#else
+ fprintf(MR_mdb_out, "minimal model tabling is not enabled\n");
+#endif
+}
+
+static void
+MR_trace_print_consumer_debug(const MR_Proc_Layout *proc,
+ MR_ConsumerDebug *consumer_debug)
+{
+#if defined(MR_USE_MINIMAL_MODEL_STACK_COPY)
+ MR_print_consumer_debug(MR_mdb_out, proc, consumer_debug);
+#elif defined(MR_USE_MINIMAL_MODEL_STACK_COPY)
+ MR_print_cons_debug(MR_mdb_out, proc, consumer_debug);
+#else
+ fprintf(MR_mdb_out, "minimal model tabling is not enabled\n");
+#endif
+}
+
+static void
+MR_print_type_ctor_info(FILE *fp, MR_TypeCtorInfo type_ctor_info,
+ MR_bool print_rep, MR_bool print_functors)
+{
+ MR_TypeCtorRep rep;
+ MR_EnumFunctorDesc *enum_functor;
+ MR_DuFunctorDesc *du_functor;
+ MR_MaybeResAddrFunctorDesc *maybe_res_functor;
+ MR_NotagFunctorDesc *notag_functor;
+ int num_functors;
+ int i;
+
+ fprintf(fp, "type constructor %s.%s/%d",
+ type_ctor_info->MR_type_ctor_module_name,
+ type_ctor_info->MR_type_ctor_name,
+ (int) type_ctor_info->MR_type_ctor_arity);
+
+ rep = MR_type_ctor_rep(type_ctor_info);
+ if (print_rep) {
+ fprintf(fp, ": %s\n", MR_ctor_rep_name[MR_GET_ENUM_VALUE(rep)]);
+ } else {
+ fprintf(fp, "\n");
+ }
+
+ if (print_functors) {
+ num_functors = type_ctor_info->MR_type_ctor_num_functors;
+ switch (rep) {
+ case MR_TYPECTOR_REP_ENUM:
+ case MR_TYPECTOR_REP_ENUM_USEREQ:
+ for (i = 0; i < num_functors; i++) {
+ enum_functor = type_ctor_info->MR_type_ctor_functors.
+ MR_functors_enum[i];
+ if (i > 0) {
+ fprintf(fp, ", ");
+ }
+ fprintf(fp, "%s/0", enum_functor->MR_enum_functor_name);
+ }
+ fprintf(fp, "\n");
+ break;
+
+ case MR_TYPECTOR_REP_DU:
+ case MR_TYPECTOR_REP_DU_USEREQ:
+ for (i = 0; i < num_functors; i++) {
+ du_functor = type_ctor_info->MR_type_ctor_functors.
+ MR_functors_du[i];
+ if (i > 0) {
+ fprintf(fp, ", ");
+ }
+ fprintf(fp, "%s/%d", du_functor->MR_du_functor_name,
+ du_functor-> MR_du_functor_orig_arity);
+ }
+ fprintf(fp, "\n");
+ break;
+
+ case MR_TYPECTOR_REP_RESERVED_ADDR:
+ case MR_TYPECTOR_REP_RESERVED_ADDR_USEREQ:
+ for (i = 0; i < num_functors; i++) {
+ maybe_res_functor = &type_ctor_info->MR_type_ctor_functors.
+ MR_functors_res[i];
+ if (i > 0) {
+ fprintf(fp, ", ");
+ }
+ fprintf(fp, "%s/%d", maybe_res_functor->MR_maybe_res_name,
+ (int) maybe_res_functor-> MR_maybe_res_arity);
+ }
+ fprintf(fp, "\n");
+ break;
+
+ case MR_TYPECTOR_REP_NOTAG:
+ case MR_TYPECTOR_REP_NOTAG_USEREQ:
+ case MR_TYPECTOR_REP_NOTAG_GROUND:
+ case MR_TYPECTOR_REP_NOTAG_GROUND_USEREQ:
+ notag_functor = type_ctor_info->MR_type_ctor_functors.
+ MR_functors_notag;
+ fprintf(fp, "%s/1\n", notag_functor->MR_notag_functor_name);
+ break;
+
+ default:
+ break;
+ }
+ }
+}
+
+static void
+MR_print_class_decl_info(FILE *fp, MR_TypeClassDeclInfo *type_class_decl_info,
+ MR_bool print_methods, MR_bool print_instances)
+{
+ MR_TypeClassDecl type_class_decl;
+ const MR_TypeClassId *type_class_id;
+ const MR_TypeClassMethod *method;
+ MR_Instance instance;
+ MR_Dlist *list;
+ MR_Dlist *element_ptr;
+ int num_methods;
+ int i;
+
+ type_class_decl = type_class_decl_info->MR_tcd_info_decl;
+ type_class_id = type_class_decl->MR_tc_decl_id;
+ fprintf(fp, "type class %s.%s/%d\n",
+ type_class_id->MR_tc_id_module_name,
+ type_class_id->MR_tc_id_name,
+ type_class_id->MR_tc_id_arity);
+
+ if (print_methods) {
+ num_methods = type_class_id->MR_tc_id_num_methods;
+ fprintf(fp, "methods: ");
+
+ for (i = 0; i < num_methods; i++) {
+ if (i > 0) {
+ fprintf(fp, ", ");
+ }
+
+ method = &type_class_id->MR_tc_id_methods[i];
+ if (method->MR_tc_method_pred_func == MR_FUNCTION) {
+ fprintf(fp, "func ");
+ } else {
+ fprintf(fp, "pred ");
+ }
+
+ fprintf(fp, "%s/%d", method->MR_tc_method_name,
+ method->MR_tc_method_arity);
+ }
+
+ fprintf(fp, "\n");
+ }
+
+ if (print_instances) {
+ list = type_class_decl_info->MR_tcd_info_instances;
+ MR_for_dlist (element_ptr, list) {
+ instance = (MR_Instance) MR_dlist_data(element_ptr);
+
+ if (instance->MR_tc_inst_type_class != type_class_decl) {
+ MR_fatal_error("instance/type class mismatch");
+ }
+
+ fprintf(fp, "instance ");
+
+ for (i = 0; i < type_class_id->MR_tc_id_arity; i++) {
+ if (i > 0) {
+ fprintf(fp, ", ");
+ }
+
+ MR_print_pseudo_type_info(fp,
+ instance->MR_tc_inst_type_args[i]);
+ }
+
+ fprintf(fp, "\n");
+ }
+ }
+}
+
+static void
+MR_print_pseudo_type_info(FILE *fp, MR_PseudoTypeInfo pseudo)
+{
+ MR_TypeCtorInfo type_ctor_info;
+ MR_PseudoTypeInfo *pseudo_args;
+ MR_Integer tvar_num;
+ int arity;
+ int i;
+
+ if (MR_PSEUDO_TYPEINFO_IS_VARIABLE(pseudo)) {
+ tvar_num = (MR_Integer) pseudo;
+ fprintf(fp, "T%d", (int) tvar_num);
+ } else {
+ type_ctor_info = MR_PSEUDO_TYPEINFO_GET_TYPE_CTOR_INFO(pseudo);
+ fprintf(fp, "%s.%s",
+ type_ctor_info->MR_type_ctor_module_name,
+ type_ctor_info->MR_type_ctor_name);
+ if (MR_type_ctor_has_variable_arity(type_ctor_info)) {
+ arity = MR_PSEUDO_TYPEINFO_GET_VAR_ARITY_ARITY(pseudo);
+ pseudo_args = (MR_PseudoTypeInfo *)
+ &pseudo->MR_pti_var_arity_arity;
+ } else {
+ arity = type_ctor_info->MR_type_ctor_arity;
+ pseudo_args = (MR_PseudoTypeInfo *) &pseudo->MR_pti_type_ctor_info;
+ }
+
+ if (type_ctor_info->MR_type_ctor_arity > 0) {
+ fprintf(fp, "(");
+ for (i = 1; i <= arity; i++) {
+ if (i > 1) {
+ fprintf(fp, ", ");
+ }
+
+ MR_print_pseudo_type_info(fp, pseudo_args[i]);
+ }
+ fprintf(fp, ")");
+ }
+ }
+}
+
+/****************************************************************************/
+
+/*
+** It is better to have a single completion where possible,
+** so don't include `-d' here.
+*/
+
+const char *const MR_trace_nondet_stack_cmd_args[] =
+ { "--detailed", NULL };
+
+const char *const MR_trace_stats_cmd_args[] =
+ { "procs", "labels", "var_names", "io_tabling", NULL };
+
+/****************************************************************************/
+
+static struct MR_option MR_trace_nondet_stack_opts[] =
+{
+ { "detailed", MR_no_argument, NULL, 'd' },
+ { "frame-limit", MR_required_argument, NULL, 'f' },
+ { NULL, MR_no_argument, NULL, 0 }
+};
+
+static MR_bool
+MR_trace_options_nondet_stack(MR_bool *detailed, int *frame_limit,
+ char ***words, int *word_count)
+{
+ int c;
+
+ MR_optind = 0;
+ while ((c = MR_getopt_long(*word_count, *words, "df:",
+ MR_trace_nondet_stack_opts, NULL)) != EOF)
+ {
+ switch (c) {
+
+ case 'd':
+ *detailed = MR_TRUE;
+ break;
+
+ case 'f':
+ if (! MR_trace_is_natural_number(MR_optarg, frame_limit)) {
+ MR_trace_usage_cur_cmd();
+ return MR_FALSE;
+ }
+ 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_stats_opts[] =
+{
+ { "file", MR_required_argument, NULL, 'f' },
+ { NULL, MR_no_argument, NULL, 0 }
+};
+
+static MR_bool
+MR_trace_options_stats(char **filename, char ***words, int *word_count)
+{
+ int c;
+
+ MR_optind = 0;
+ while ((c = MR_getopt_long(*word_count, *words, "f:",
+ MR_trace_stats_opts, NULL)) != EOF)
+ {
+ switch (c) {
+
+ case 'f':
+ *filename = MR_optarg;
+ 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_type_ctor_opts[] =
+{
+ { "print-rep", MR_no_argument, NULL, 'r' },
+ { "print-functors", MR_no_argument, NULL, 'f' },
+ { NULL, MR_no_argument, NULL, 0 }
+};
+
+static MR_bool
+MR_trace_options_type_ctor(MR_bool *print_rep, MR_bool *print_functors,
+ char ***words, int *word_count)
+{
+ int c;
+
+ MR_optind = 0;
+ while ((c = MR_getopt_long(*word_count, *words, "rf",
+ MR_trace_type_ctor_opts, NULL)) != EOF)
+ {
+ switch (c) {
+
+ case 'f':
+ *print_functors = MR_TRUE;
+ break;
+
+ case 'r':
+ *print_rep = MR_TRUE;
+ 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_class_decl_opts[] =
+{
+ { "print-methods", MR_no_argument, NULL, 'm' },
+ { "print-instances", MR_no_argument, NULL, 'i' },
+ { NULL, MR_no_argument, NULL, 0 }
+};
+
+static MR_bool
+MR_trace_options_class_decl(MR_bool *print_methods, MR_bool *print_instances,
+ char ***words, int *word_count)
+{
+ int c;
+
+ MR_optind = 0;
+ while ((c = MR_getopt_long(*word_count, *words, "mi",
+ MR_trace_class_decl_opts, NULL)) != EOF)
+ {
+ switch (c) {
+
+ case 'm':
+ *print_methods = MR_TRUE;
+ break;
+
+ case 'i':
+ *print_instances = MR_TRUE;
+ 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_all_procedures_opts[] =
+{
+ { "separate", MR_no_argument, NULL, 's' },
+ { "uci", MR_no_argument, NULL, 'u' },
+ { "module", MR_required_argument, NULL, 'm' },
+ { NULL, MR_no_argument, NULL, 0 }
+};
+
+static MR_bool
+MR_trace_options_all_procedures(MR_bool *separate, MR_bool *uci, char **module,
+ char ***words, int *word_count)
+{
+ int c;
+
+ MR_optind = 0;
+ while ((c = MR_getopt_long(*word_count, *words, "sum:",
+ MR_trace_all_procedures_opts, NULL)) != EOF)
+ {
+ switch (c) {
+
+ case 's':
+ *separate = MR_TRUE;
+ break;
+
+ case 'u':
+ *uci = MR_TRUE;
+ break;
+
+ case 'm':
+ *module = MR_optarg;
+ 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_ambiguity_opts[] =
+{
+ { "outputfile", MR_required_argument, NULL, 'o' },
+ { NULL, MR_no_argument, NULL, 0 }
+};
+
+static MR_bool
+MR_trace_options_ambiguity(const char **outfile,
+ char ***words, int *word_count)
+{
+ int c;
+
+ MR_optind = 0;
+ while ((c = MR_getopt_long(*word_count, *words, "o:",
+ MR_trace_ambiguity_opts, NULL)) != EOF)
+ {
+ switch (c) {
+
+ case 'o':
+ *outfile = MR_optarg;
+ 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;
+}
Index: trace/mercury_trace_cmd_developer.h
===================================================================
RCS file: trace/mercury_trace_cmd_developer.h
diff -N trace/mercury_trace_cmd_developer.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ trace/mercury_trace_cmd_developer.h 3 Apr 2006 11:26:29 -0000
@@ -0,0 +1,40 @@
+/*
+** 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.
+*/
+
+#include "mercury_imp.h"
+
+#include "mercury_trace_cmds.h"
+
+extern MR_TraceCmdFunc MR_trace_cmd_var_details;
+extern MR_TraceCmdFunc MR_trace_cmd_term_size;
+extern MR_TraceCmdFunc MR_trace_cmd_flag;
+extern MR_TraceCmdFunc MR_trace_cmd_subgoal;
+extern MR_TraceCmdFunc MR_trace_cmd_consumer;
+extern MR_TraceCmdFunc MR_trace_cmd_gen_stack;
+extern MR_TraceCmdFunc MR_trace_cmd_cut_stack;
+extern MR_TraceCmdFunc MR_trace_cmd_pneg_stack;
+extern MR_TraceCmdFunc MR_trace_cmd_mm_stacks;
+extern MR_TraceCmdFunc MR_trace_cmd_nondet_stack;
+extern MR_TraceCmdFunc MR_trace_cmd_stack_regs;
+extern MR_TraceCmdFunc MR_trace_cmd_all_regs;
+extern MR_TraceCmdFunc MR_trace_cmd_debug_vars;
+extern MR_TraceCmdFunc MR_trace_cmd_stats;
+extern MR_TraceCmdFunc MR_trace_cmd_print_optionals;
+extern MR_TraceCmdFunc MR_trace_cmd_unhide_events;
+extern MR_TraceCmdFunc MR_trace_cmd_table;
+extern MR_TraceCmdFunc MR_trace_cmd_type_ctor;
+extern MR_TraceCmdFunc MR_trace_cmd_class_decl;
+extern MR_TraceCmdFunc MR_trace_cmd_all_type_ctors;
+extern MR_TraceCmdFunc MR_trace_cmd_all_class_decls;
+extern MR_TraceCmdFunc MR_trace_cmd_all_procedures;
+extern MR_TraceCmdFunc MR_trace_cmd_ambiguity;
+extern MR_TraceCmdFunc MR_trace_cmd_dice;
+
+extern const char *const MR_trace_nondet_stack_cmd_args[];
+extern const char *const MR_trace_stats_cmd_args[];
Index: trace/mercury_trace_cmd_exp.c
===================================================================
RCS file: trace/mercury_trace_cmd_exp.c
diff -N trace/mercury_trace_cmd_exp.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ trace/mercury_trace_cmd_exp.c 3 Apr 2006 12:50:42 -0000
@@ -0,0 +1,363 @@
+/*
+** 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 "exp" 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_trace_internal.h"
+#include "mercury_trace_cmds.h"
+#include "mercury_trace_cmd_exp.h"
+#include "mercury_trace_cmd_parameter.h"
+#include "mercury_trace_util.h"
+
+#include "mdbcomp.slice_and_dice.mh"
+
+#include <stdio.h>
+
+/****************************************************************************/
+
+/*
+** The default number of lines to display for a dice.
+*/
+
+#define MR_DEFAULT_DICE_LINES 50
+
+static void MR_trace_print_dice(char *pass_trace_counts_file,
+ char *fail_trace_counts_file, char *sort_str,
+ int number_of_lines, char *out_str, char *module);
+
+static MR_bool MR_trace_options_dice(char **pass_trace_counts_file,
+ char **fail_trace_count_file, char **sort_str,
+ int *number_of_lines, char **out_file, char **module,
+ char ***words, int *word_count);
+
+/****************************************************************************/
+
+MR_Next
+MR_trace_cmd_histogram_all(char **words, int word_count,
+ MR_Trace_Cmd_Info *cmd, MR_Event_Info *event_info, MR_Code **jumpaddr)
+{
+#ifdef MR_TRACE_HISTOGRAM
+
+ if (word_count == 2) {
+ FILE *fp;
+
+ fp = fopen(words[1], "w");
+ if (fp == NULL) {
+ fflush(MR_mdb_out);
+ fprintf(MR_mdb_err, "mdb: cannot open file `%s' for output: %s.\n",
+ words[1], strerror(errno));
+ } else {
+ MR_trace_print_histogram(fp, "All-inclusive",
+ MR_trace_histogram_all,
+ MR_trace_histogram_hwm);
+ if (fclose(fp) != 0) {
+ fflush(MR_mdb_out);
+ fprintf(MR_mdb_err, "mdb: error closing file `%s': %s.\n",
+ words[1], strerror(errno));
+ }
+ }
+ } else {
+ MR_trace_usage_cur_cmd();
+ }
+
+#else /* MR_TRACE_HISTOGRAM */
+
+ fprintf(MR_mdb_out, "mdb: the `histogram_all' command is available "
+ "only when histogram gathering is enabled.\n");
+
+#endif /* MR_TRACE_HISTOGRAM */
+
+ return KEEP_INTERACTING;
+}
+
+MR_Next
+MR_trace_cmd_histogram_exp(char **words, int word_count,
+ MR_Trace_Cmd_Info *cmd, MR_Event_Info *event_info, MR_Code **jumpaddr)
+{
+#ifdef MR_TRACE_HISTOGRAM
+
+ if (word_count == 2) {
+ FILE *fp;
+
+ fp = fopen(words[1], "w");
+ if (fp == NULL) {
+ fflush(MR_mdb_out);
+ fprintf(MR_mdb_err, "mdb: cannot open file `%s' for output: %s.\n",
+ words[1], strerror(errno));
+ } else {
+ MR_trace_print_histogram(fp, "Experimental",
+ MR_trace_histogram_exp,
+ MR_trace_histogram_hwm);
+ if (fclose(fp) != 0) {
+ fflush(MR_mdb_out);
+ fprintf(MR_mdb_err, "mdb: error closing file `%s': %s.\n",
+ words[1], strerror(errno));
+ }
+ }
+ } else {
+ MR_trace_usage_cur_cmd();
+ }
+
+#else /* MR_TRACE_HISTOGRAM */
+
+ fprintf(MR_mdb_out, "mdb: the `histogram_exp' command is available "
+ "only when histogram gathering is enabled.\n");
+
+#endif /* MR_TRACE_HISTOGRAM */
+
+ return KEEP_INTERACTING;
+}
+
+MR_Next
+MR_trace_cmd_clear_histogram(char **words, int word_count,
+ MR_Trace_Cmd_Info *cmd, MR_Event_Info *event_info, MR_Code **jumpaddr)
+{
+#ifdef MR_TRACE_HISTOGRAM
+
+ if (word_count == 1) {
+ int i;
+
+ for (i = 0; i <= MR_trace_histogram_hwm; i++) {
+ MR_trace_histogram_exp[i] = 0;
+ }
+ } else {
+ MR_trace_usage_cur_cmd();
+ }
+
+#else /* MR_TRACE_HISTOGRAM */
+
+ fprintf(MR_mdb_out, "mdb: the `clear_histogram' command is available "
+ "only when histogram gathering is enabled.\n");
+
+#endif /* MR_TRACE_HISTOGRAM */
+
+ return KEEP_INTERACTING;
+}
+
+MR_Next
+MR_trace_cmd_dice(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
+ MR_Event_Info *event_info, MR_Code **jumpaddr)
+{
+ char *pass_trace_counts_file;
+ char *fail_trace_counts_file;
+ char *sort_str;
+ char *out_file;
+ char *module;
+ int number_of_lines;
+
+ sort_str = NULL;
+ out_file = NULL;
+ module = NULL;
+ number_of_lines = MR_DEFAULT_DICE_LINES;
+
+ pass_trace_counts_file = MR_dice_pass_trace_counts_file;
+ fail_trace_counts_file = MR_dice_fail_trace_counts_file;
+
+ if (! MR_trace_options_dice(&pass_trace_counts_file,
+ &fail_trace_counts_file, &sort_str, &number_of_lines, &out_file,
+ &module, &words, &word_count))
+ {
+ ; /* the usage message has already been printed */
+ } else if (word_count == 1) {
+ if (pass_trace_counts_file == NULL) {
+ fflush(MR_mdb_out);
+ fprintf(MR_mdb_err, "mdb: No passing trace counts file specified."
+ "\nmdb: Specify one with the -p option or using the `set' "
+ "command.\n");
+ } else if (fail_trace_counts_file == NULL) {
+ fflush(MR_mdb_out);
+ fprintf(MR_mdb_err, "mdb: No failing trace counts file specified."
+ "\nmdb: Specify one with the -f option or using the `set' "
+ "command.\n");
+ } else {
+ if (sort_str == NULL) {
+ sort_str = MR_copy_string("");
+ }
+
+ if (module == NULL) {
+ module = MR_copy_string("");
+ }
+ MR_trace_print_dice(pass_trace_counts_file, fail_trace_counts_file,
+ sort_str, number_of_lines, out_file, module);
+ }
+ } else {
+ MR_trace_usage_cur_cmd();
+ }
+
+ if (out_file != NULL) {
+ free(out_file);
+ }
+
+ if (sort_str != NULL) {
+ free(sort_str);
+ }
+
+ if (module != NULL) {
+ free(module);
+ }
+
+ return KEEP_INTERACTING;
+}
+
+/****************************************************************************/
+
+static void
+MR_trace_print_dice(char *pass_trace_counts_file,
+ char *fail_trace_count_file, char *sort_str, int number_of_lines,
+ char *out_file, char *module)
+{
+ MR_String dice;
+ MR_String problem;
+ MR_String aligned_pass_trace_counts_file;
+ MR_String aligned_fail_trace_count_file;
+ MR_String aligned_sort_str;
+ MR_String aligned_module;
+ FILE *fp;
+
+ MR_TRACE_USE_HP(
+ MR_make_aligned_string(aligned_pass_trace_counts_file,
+ (MR_String) pass_trace_counts_file);
+ MR_make_aligned_string(aligned_fail_trace_count_file,
+ (MR_String) fail_trace_count_file);
+ MR_make_aligned_string(aligned_sort_str, (MR_String) sort_str);
+ if (module == NULL) {
+ MR_make_aligned_string(aligned_module, (MR_String) "");
+ } else {
+ MR_make_aligned_string(aligned_module, (MR_String) module);
+ }
+ );
+
+ MR_TRACE_CALL_MERCURY(
+ MR_MDB_read_dice_to_string(aligned_pass_trace_counts_file,
+ aligned_fail_trace_count_file, aligned_sort_str,
+ number_of_lines, aligned_module, &dice, &problem);
+ );
+
+ /* The string in dice is a sequence of complete lines */
+ if (MR_streq(problem, "")) {
+ if (out_file == NULL) {
+ fprintf(MR_mdb_out, "%s", dice);
+ } else {
+ fp = fopen(out_file, "w");
+ if (fp != NULL) {
+ fprintf(fp, "%s", dice);
+ if (fclose(fp) != 0) {
+ fflush(MR_mdb_out);
+ fprintf(MR_mdb_err, "mdb: Error closing file `%s': %s\n",
+ out_file, strerror(errno));
+ }
+ } else {
+ fflush(MR_mdb_out);
+ fprintf(MR_mdb_err, "mdb: Error opening file `%s': %s\n",
+ out_file, strerror(errno));
+ }
+ }
+ } else {
+ fflush(MR_mdb_out);
+ fprintf(MR_mdb_err, "mdb: %s\n", problem);
+ }
+}
+
+/****************************************************************************/
+
+static struct MR_option MR_trace_dice_opts[] =
+{
+ { "pass-trace-counts", MR_required_argument, NULL, 'p' },
+ { "pass-trace-count", MR_required_argument, NULL, 'p' },
+ { "fail-trace-counts", MR_required_argument, NULL, 'f' },
+ { "fail-trace-count", MR_required_argument, NULL, 'f' },
+ { "sort", MR_required_argument, NULL, 's' },
+ { "top", MR_required_argument, NULL, 'n' },
+ { "output-to-file", MR_required_argument, NULL, 'o' },
+ { "module", MR_required_argument, NULL, 'm' },
+ { NULL, MR_no_argument, NULL, 0 }
+};
+
+static MR_bool
+MR_trace_options_dice(char **pass_trace_counts_file,
+ char **fail_trace_counts_file, char **sort_str, int *n, char **out_file,
+ char **module, char ***words, int *word_count)
+{
+ int c;
+
+ MR_optind = 0;
+ while ((c = MR_getopt_long(*word_count, *words, "p:f:s:n:o:m:",
+ MR_trace_dice_opts, NULL)) != EOF)
+ {
+ switch (c) {
+
+ case 'p':
+ /*
+ ** Don't free *pass_trace_counts_file even if non-NULL,
+ ** since its initial value comes from a global variable,
+ ** and thus will still be used after the dice command.
+ ** The waste of not freeing of the string allocated by
+ ** MR_copy_string if this option is duplicated can be
+ ** easily lived with.
+ */
+
+ *pass_trace_counts_file = MR_copy_string(MR_optarg);
+ break;
+
+ case 'f':
+ /*
+ ** Don't free *fail_trace_counts_file even if non-NULL,
+ ** since its initial value comes from a global variable,
+ ** and thus will still be used after the dice command.
+ ** The waste of not freeing of the string allocated by
+ ** MR_copy_string if this option is duplicated can be
+ ** easily lived with.
+ */
+
+ *fail_trace_counts_file = MR_copy_string(MR_optarg);
+ break;
+
+ case 's':
+ *sort_str = MR_copy_string(MR_optarg);
+ break;
+
+ case 'n':
+ if (! MR_trace_is_natural_number(MR_optarg, n)) {
+ MR_trace_usage_cur_cmd();
+ return MR_FALSE;
+ }
+ break;
+
+ case 'o':
+ *out_file = MR_copy_string(MR_optarg);
+ break;
+
+ case 'm':
+ *module = MR_copy_string(MR_optarg);
+ 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;
+}
Index: trace/mercury_trace_cmd_exp.h
===================================================================
RCS file: trace/mercury_trace_cmd_exp.h
diff -N trace/mercury_trace_cmd_exp.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ trace/mercury_trace_cmd_exp.h 3 Apr 2006 11:16:03 -0000
@@ -0,0 +1,17 @@
+/*
+** 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.
+*/
+
+#include "mercury_imp.h"
+
+#include "mercury_trace_cmds.h"
+
+extern MR_TraceCmdFunc MR_trace_cmd_histogram_all;
+extern MR_TraceCmdFunc MR_trace_cmd_histogram_exp;
+extern MR_TraceCmdFunc MR_trace_cmd_clear_histogram;
+extern MR_TraceCmdFunc MR_trace_cmd_dice;
Index: trace/mercury_trace_cmd_forward.c
===================================================================
RCS file: trace/mercury_trace_cmd_forward.c
diff -N trace/mercury_trace_cmd_forward.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ trace/mercury_trace_cmd_forward.c 3 Apr 2006 12:50:48 -0000
@@ -0,0 +1,443 @@
+/*
+** 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 "forward" 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_trace_internal.h"
+#include "mercury_trace_cmds.h"
+#include "mercury_trace_cmd_forward.h"
+#include "mercury_trace_cmd_parameter.h"
+#include "mercury_trace_util.h"
+
+/****************************************************************************/
+
+static MR_bool MR_trace_options_movement_cmd(MR_Trace_Cmd_Info *cmd,
+ char ***words, int *word_count);
+
+/****************************************************************************/
+
+MR_Next
+MR_trace_cmd_step(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
+ MR_Event_Info *event_info, MR_Code **jumpaddr)
+{
+ int n;
+
+ cmd->MR_trace_strict = MR_FALSE;
+ cmd->MR_trace_print_level = MR_default_print_level;
+ MR_init_trace_check_integrity(cmd);
+ if (! MR_trace_options_movement_cmd(cmd, &words, &word_count)) {
+ ; /* the usage message has already been printed */
+ } else if (word_count == 1) {
+ cmd->MR_trace_cmd = MR_CMD_GOTO;
+ cmd->MR_trace_stop_event = MR_trace_event_number + 1;
+ return STOP_INTERACTING;
+ } else if (word_count == 2 && MR_trace_is_natural_number(words[1], &n)) {
+ cmd->MR_trace_cmd = MR_CMD_GOTO;
+ cmd->MR_trace_stop_event = MR_trace_event_number + n;
+ return STOP_INTERACTING;
+ } else {
+ MR_trace_usage_cur_cmd();
+ }
+
+ return KEEP_INTERACTING;
+}
+
+MR_Next
+MR_trace_cmd_goto(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
+ MR_Event_Info *event_info, MR_Code **jumpaddr)
+{
+ MR_Unsigned n;
+
+ cmd->MR_trace_strict = MR_TRUE;
+ cmd->MR_trace_print_level = MR_default_print_level;
+ MR_init_trace_check_integrity(cmd);
+ if (! MR_trace_options_movement_cmd(cmd, &words, &word_count)) {
+ ; /* the usage message has already been printed */
+ } else if (word_count == 2 && MR_trace_is_unsigned(words[1], &n)) {
+ if (MR_trace_event_number < n) {
+ cmd->MR_trace_cmd = MR_CMD_GOTO;
+ cmd->MR_trace_stop_event = n;
+ return STOP_INTERACTING;
+ } else {
+ /* XXX this message is misleading */
+ fflush(MR_mdb_out);
+ fprintf(MR_mdb_err, "The debugger cannot go to a past event.\n");
+ }
+ } else {
+ MR_trace_usage_cur_cmd();
+ }
+
+ return KEEP_INTERACTING;
+}
+
+MR_Next
+MR_trace_cmd_next(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
+ MR_Event_Info *event_info, MR_Code **jumpaddr)
+{
+ MR_Unsigned depth;
+ int stop_depth;
+ int n;
+
+ depth = event_info->MR_call_depth;
+ cmd->MR_trace_strict = MR_TRUE;
+ cmd->MR_trace_print_level = MR_default_print_level;
+ MR_init_trace_check_integrity(cmd);
+ if (! MR_trace_options_movement_cmd(cmd, &words, &word_count)) {
+ ; /* the usage message has already been printed */
+ return KEEP_INTERACTING;
+ } else if (word_count == 2 && MR_trace_is_natural_number(words[1], &n)) {
+ stop_depth = depth - n;
+ } else if (word_count == 1) {
+ stop_depth = depth;
+ } else {
+ MR_trace_usage_cur_cmd();
+ return KEEP_INTERACTING;
+ }
+
+ if (depth == stop_depth && MR_port_is_final(event_info->MR_trace_port)) {
+ MR_trace_do_noop();
+ } else {
+ cmd->MR_trace_cmd = MR_CMD_NEXT;
+ cmd->MR_trace_stop_depth = stop_depth;
+ return STOP_INTERACTING;
+ }
+
+ return KEEP_INTERACTING;
+}
+
+MR_Next
+MR_trace_cmd_finish(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
+ MR_Event_Info *event_info, MR_Code **jumpaddr)
+{
+ MR_Unsigned depth;
+ int stop_depth;
+ int n;
+
+ depth = event_info->MR_call_depth;
+ cmd->MR_trace_strict = MR_TRUE;
+ cmd->MR_trace_print_level = MR_default_print_level;
+ MR_init_trace_check_integrity(cmd);
+ if (! MR_trace_options_movement_cmd(cmd, &words, &word_count)) {
+ ; /* the usage message has already been printed */
+ return KEEP_INTERACTING;
+ } else if (word_count == 2 && MR_trace_is_natural_number(words[1], &n)) {
+ stop_depth = depth - n;
+ } else if (word_count == 1) {
+ stop_depth = depth;
+ } else {
+ MR_trace_usage_cur_cmd();
+ return KEEP_INTERACTING;
+ }
+
+ if (depth == stop_depth && MR_port_is_final(event_info->MR_trace_port)) {
+ MR_trace_do_noop();
+ } else {
+ cmd->MR_trace_cmd = MR_CMD_FINISH;
+ cmd->MR_trace_stop_depth = stop_depth;
+ return STOP_INTERACTING;
+ }
+
+ return KEEP_INTERACTING;
+}
+
+MR_Next
+MR_trace_cmd_fail(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
+ MR_Event_Info *event_info, MR_Code **jumpaddr)
+{
+ MR_Determinism detism;
+ MR_Unsigned depth;
+ int stop_depth;
+ int n;
+
+ detism = event_info->MR_event_sll->MR_sll_entry->MR_sle_detism;
+ depth = event_info->MR_call_depth;
+
+ cmd->MR_trace_strict = MR_TRUE;
+ cmd->MR_trace_print_level = MR_default_print_level;
+ MR_init_trace_check_integrity(cmd);
+ if (! MR_trace_options_movement_cmd(cmd, &words, &word_count)) {
+ ; /* the usage message has already been printed */
+ return KEEP_INTERACTING;
+ } else if (word_count == 2 && MR_trace_is_natural_number(words[1], &n)) {
+ stop_depth = depth - n;
+ } else if (word_count == 1) {
+ stop_depth = depth;
+ } else {
+ MR_trace_usage_cur_cmd();
+ return KEEP_INTERACTING;
+ }
+
+ if (MR_DETISM_DET_STACK(detism)) {
+ fflush(MR_mdb_out);
+ fprintf(MR_mdb_err, "mdb: cannot continue until failure: "
+ "selected procedure has determinism %s.\n",
+ MR_detism_names[detism]);
+ return KEEP_INTERACTING;
+ }
+
+ if (depth == stop_depth && event_info->MR_trace_port == MR_PORT_FAIL) {
+ MR_trace_do_noop();
+ } else if (depth == stop_depth &&
+ event_info->MR_trace_port == MR_PORT_EXCEPTION)
+ {
+ fflush(MR_mdb_out);
+ fprintf(MR_mdb_err, "mdb: cannot continue until failure: "
+ "the call has raised an exception.\n");
+ } else {
+ cmd->MR_trace_cmd = MR_CMD_FAIL;
+ cmd->MR_trace_stop_depth = stop_depth;
+ return STOP_INTERACTING;
+ }
+
+ return KEEP_INTERACTING;
+}
+
+MR_Next
+MR_trace_cmd_exception(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
+ MR_Event_Info *event_info, MR_Code **jumpaddr)
+{
+ cmd->MR_trace_strict = MR_TRUE;
+ cmd->MR_trace_print_level = MR_default_print_level;
+ MR_init_trace_check_integrity(cmd);
+ if (! MR_trace_options_movement_cmd(cmd, &words, &word_count)) {
+ ; /* the usage message has already been printed */
+ } else if (word_count == 1) {
+ if (event_info->MR_trace_port != MR_PORT_EXCEPTION) {
+ cmd->MR_trace_cmd = MR_CMD_EXCP;
+ return STOP_INTERACTING;
+ } else {
+ MR_trace_do_noop();
+ }
+ } else {
+ MR_trace_usage_cur_cmd();
+ }
+
+ return KEEP_INTERACTING;
+}
+
+MR_Next
+MR_trace_cmd_return(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
+ MR_Event_Info *event_info, MR_Code **jumpaddr)
+{
+ cmd->MR_trace_strict = MR_TRUE;
+ cmd->MR_trace_print_level = MR_default_print_level;
+ MR_init_trace_check_integrity(cmd);
+ if (! MR_trace_options_movement_cmd(cmd, &words, &word_count)) {
+ ; /* the usage message has already been printed */
+ } else if (word_count == 1) {
+ if (event_info->MR_trace_port == MR_PORT_EXIT) {
+ cmd->MR_trace_cmd = MR_CMD_RETURN;
+ return STOP_INTERACTING;
+ } else {
+ MR_trace_do_noop();
+ }
+ } else {
+ MR_trace_usage_cur_cmd();
+ }
+
+ return KEEP_INTERACTING;
+}
+
+MR_Next
+MR_trace_cmd_forward(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
+ MR_Event_Info *event_info, MR_Code **jumpaddr)
+{
+ cmd->MR_trace_strict = MR_TRUE;
+ cmd->MR_trace_print_level = MR_default_print_level;
+ MR_init_trace_check_integrity(cmd);
+ if (! MR_trace_options_movement_cmd(cmd, &words, &word_count)) {
+ ; /* the usage message has already been printed */
+ } else if (word_count == 1) {
+ MR_Trace_Port port;
+
+ port = event_info->MR_trace_port;
+ if (port == MR_PORT_FAIL ||
+ port == MR_PORT_REDO ||
+ port == MR_PORT_EXCEPTION)
+ {
+ cmd->MR_trace_cmd = MR_CMD_RESUME_FORWARD;
+ return STOP_INTERACTING;
+ } else {
+ MR_trace_do_noop();
+ }
+ } else {
+ MR_trace_usage_cur_cmd();
+ }
+
+ return KEEP_INTERACTING;
+}
+
+MR_Next
+MR_trace_cmd_mindepth(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
+ MR_Event_Info *event_info, MR_Code **jumpaddr)
+{
+ int newdepth;
+
+ cmd->MR_trace_strict = MR_TRUE;
+ cmd->MR_trace_print_level = MR_default_print_level;
+ MR_init_trace_check_integrity(cmd);
+ if (! MR_trace_options_movement_cmd(cmd, &words, &word_count)) {
+ ; /* the usage message has already been printed */
+ } else if (word_count == 2 &&
+ MR_trace_is_natural_number(words[1], &newdepth))
+ {
+ cmd->MR_trace_cmd = MR_CMD_MIN_DEPTH;
+ cmd->MR_trace_stop_depth = newdepth;
+ return STOP_INTERACTING;
+ } else {
+ MR_trace_usage_cur_cmd();
+ }
+
+ return KEEP_INTERACTING;
+}
+
+MR_Next
+MR_trace_cmd_maxdepth(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
+ MR_Event_Info *event_info, MR_Code **jumpaddr)
+{
+ int newdepth;
+
+ cmd->MR_trace_strict = MR_TRUE;
+ cmd->MR_trace_print_level = MR_default_print_level;
+ MR_init_trace_check_integrity(cmd);
+ if (! MR_trace_options_movement_cmd(cmd, &words, &word_count)) {
+ ; /* the usage message has already been printed */
+ } else if (word_count == 2 &&
+ MR_trace_is_natural_number(words[1], &newdepth))
+ {
+ cmd->MR_trace_cmd = MR_CMD_MAX_DEPTH;
+ cmd->MR_trace_stop_depth = newdepth;
+ return STOP_INTERACTING;
+ } else {
+ MR_trace_usage_cur_cmd();
+ }
+
+ return KEEP_INTERACTING;
+}
+
+MR_Next
+MR_trace_cmd_continue(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
+ MR_Event_Info *event_info, MR_Code **jumpaddr)
+{
+ cmd->MR_trace_strict = MR_FALSE;
+ cmd->MR_trace_print_level = (MR_Trace_Cmd_Type) -1;
+ MR_init_trace_check_integrity(cmd);
+ if (! MR_trace_options_movement_cmd(cmd, &words, &word_count)) {
+ ; /* the usage message has already been printed */
+ } else if (word_count == 1) {
+ cmd->MR_trace_cmd = MR_CMD_TO_END;
+ if (cmd->MR_trace_print_level == (MR_Trace_Cmd_Type) -1) {
+ /*
+ ** The user did not specify the print level;
+ ** select the intelligent default.
+ */
+ if (cmd->MR_trace_strict) {
+ cmd->MR_trace_print_level = MR_PRINT_LEVEL_NONE;
+ } else {
+ cmd->MR_trace_print_level = MR_PRINT_LEVEL_SOME;
+ }
+ }
+ return STOP_INTERACTING;
+ } else {
+ MR_trace_usage_cur_cmd();
+ }
+
+ return KEEP_INTERACTING;
+}
+
+/****************************************************************************/
+
+const char *const MR_trace_movement_cmd_args[] =
+ { "-N", "-S", "-a", "-i", "-n", "-s",
+ "--none", "--some", "--all", "--integrity",
+ "--strict", "--no-strict", NULL };
+
+/****************************************************************************/
+
+static struct MR_option MR_trace_movement_cmd_opts[] =
+{
+ { "all", MR_no_argument, NULL, 'a' },
+ { "none", MR_no_argument, NULL, 'n' },
+ { "some", MR_no_argument, NULL, 's' },
+ { "nostrict", MR_no_argument, NULL, 'N' },
+ { "strict", MR_no_argument, NULL, 'S' },
+#ifdef MR_TRACE_CHECK_INTEGRITY
+ { "integrity", MR_no_argument, NULL, 'i' },
+#endif
+ { NULL, MR_no_argument, NULL, 0 }
+};
+
+static MR_bool
+MR_trace_options_movement_cmd(MR_Trace_Cmd_Info *cmd,
+ char ***words, int *word_count)
+{
+ int c;
+
+#ifdef MR_TRACE_CHECK_INTEGRITY
+ #define MR_TRACE_MOVEMENT_OPTS "NSains"
+#else
+ #define MR_TRACE_MOVEMENT_OPTS "NSans"
+#endif
+
+ MR_optind = 0;
+ while ((c = MR_getopt_long(*word_count, *words, MR_TRACE_MOVEMENT_OPTS,
+ MR_trace_movement_cmd_opts, NULL)) != EOF)
+ {
+ switch (c) {
+
+ case 'N':
+ cmd->MR_trace_strict = MR_FALSE;
+ break;
+
+ case 'S':
+ cmd->MR_trace_strict = MR_TRUE;
+ break;
+
+ case 'a':
+ cmd->MR_trace_print_level = MR_PRINT_LEVEL_ALL;
+ break;
+
+ case 'n':
+ cmd->MR_trace_print_level = MR_PRINT_LEVEL_NONE;
+ break;
+
+ case 's':
+ cmd->MR_trace_print_level = MR_PRINT_LEVEL_SOME;
+ break;
+
+#ifdef MR_TRACE_CHECK_INTEGRITY
+ case 'i':
+ cmd->MR_trace_check_integrity = MR_TRUE;
+ break;
+#endif
+
+ default:
+ MR_trace_usage_cur_cmd();
+ return MR_FALSE;
+ }
+ }
+
+ *words = *words + MR_optind - 1;
+ *word_count = *word_count - MR_optind + 1;
+ return MR_TRUE;
+}
Index: trace/mercury_trace_cmd_forward.h
===================================================================
RCS file: trace/mercury_trace_cmd_forward.h
diff -N trace/mercury_trace_cmd_forward.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ trace/mercury_trace_cmd_forward.h 3 Apr 2006 10:01:11 -0000
@@ -0,0 +1,26 @@
+/*
+** 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.
+*/
+
+#include "mercury_imp.h"
+
+#include "mercury_trace.h"
+
+extern MR_TraceCmdFunc MR_trace_cmd_step;
+extern MR_TraceCmdFunc MR_trace_cmd_goto;
+extern MR_TraceCmdFunc MR_trace_cmd_next;
+extern MR_TraceCmdFunc MR_trace_cmd_finish;
+extern MR_TraceCmdFunc MR_trace_cmd_fail;
+extern MR_TraceCmdFunc MR_trace_cmd_exception;
+extern MR_TraceCmdFunc MR_trace_cmd_return;
+extern MR_TraceCmdFunc MR_trace_cmd_forward;
+extern MR_TraceCmdFunc MR_trace_cmd_mindepth;
+extern MR_TraceCmdFunc MR_trace_cmd_maxdepth;
+extern MR_TraceCmdFunc MR_trace_cmd_continue;
+
+extern const char *const MR_trace_movement_cmd_args[];
Index: trace/mercury_trace_cmd_help.c
===================================================================
RCS file: trace/mercury_trace_cmd_help.c
diff -N trace/mercury_trace_cmd_help.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ trace/mercury_trace_cmd_help.c 3 Apr 2006 12:50:51 -0000
@@ -0,0 +1,152 @@
+/*
+** 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 "help" 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_array_macros.h"
+#include "mercury_trace_internal.h"
+#include "mercury_trace_cmds.h"
+#include "mercury_trace_cmd_help.h"
+#include "mercury_trace_help.h"
+#include "mercury_trace_util.h"
+
+/****************************************************************************/
+
+/* The initial number of lines in documentation entries. */
+#define MR_INIT_DOC_CHARS 800
+
+static const char *MR_trace_read_help_text(void);
+
+/****************************************************************************/
+
+MR_Next
+MR_trace_cmd_document_category(char **words, int word_count,
+ MR_Trace_Cmd_Info *cmd, MR_Event_Info *event_info, MR_Code **jumpaddr)
+{
+ int slot;
+ const char *msg;
+ const char *help_text;
+
+ help_text = MR_trace_read_help_text();
+ if (word_count != 3) {
+ MR_trace_usage_cur_cmd();
+ } else if (! MR_trace_is_natural_number(words[1], &slot)) {
+ MR_trace_usage_cur_cmd();
+ } else {
+ msg = MR_trace_add_cat(words[2], slot, help_text);
+ if (msg != NULL) {
+ fflush(MR_mdb_out);
+ fprintf(MR_mdb_err,
+ "Document category `%s' not added: %s.\n", words[2], msg);
+ }
+ }
+
+ return KEEP_INTERACTING;
+}
+
+MR_Next
+MR_trace_cmd_document(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
+ MR_Event_Info *event_info, MR_Code **jumpaddr)
+{
+ int slot;
+ const char *msg;
+ const char *help_text;
+
+ help_text = MR_trace_read_help_text();
+ if (word_count != 4) {
+ MR_trace_usage_cur_cmd();
+ } else if (! MR_trace_is_natural_number(words[2], &slot)) {
+ MR_trace_usage_cur_cmd();
+ } else {
+ msg = MR_trace_add_item(words[1], words[3], slot, help_text);
+ if (msg != NULL) {
+ fflush(MR_mdb_out);
+ fprintf(MR_mdb_err,
+ "Document item `%s' in category `%s' not added: %s.\n",
+ words[3], words[1], msg);
+ }
+ }
+
+ return KEEP_INTERACTING;
+}
+
+MR_Next
+MR_trace_cmd_help(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
+ MR_Event_Info *event_info, MR_Code **jumpaddr)
+{
+ if (word_count == 1) {
+ MR_trace_help();
+ } else if (word_count == 2) {
+ MR_trace_help_word(words[1]);
+ } else if (word_count == 3) {
+ MR_trace_help_cat_item(words[1], words[2]);
+ } else {
+ MR_trace_usage_cur_cmd();
+ }
+
+ return KEEP_INTERACTING;
+}
+
+/****************************************************************************/
+
+/*
+** Read lines until we find one that contains only "end".
+** Return the lines concatenated together.
+** The memory returned is allocated with MR_malloc();
+** it is the caller's responsibility to MR_free() it when appropriate.
+*/
+
+static const char *
+MR_trace_read_help_text(void)
+{
+ char *text;
+ char *doc_chars = NULL;
+ int doc_char_max = 0;
+ int next_char_slot;
+ int line_len;
+ int i;
+
+ next_char_slot = 0;
+ while ((text = MR_trace_getline("cat> ", MR_mdb_in, MR_mdb_out)) != NULL) {
+ if (MR_streq(text, "end")) {
+ MR_free(text);
+ break;
+ }
+
+ line_len = strlen(text);
+ MR_ensure_big_enough(next_char_slot + line_len + 2, doc_char, char,
+ MR_INIT_DOC_CHARS);
+ for (i = 0; i < line_len; i++) {
+ doc_chars[next_char_slot + i] = text[i];
+ }
+
+ next_char_slot += line_len;
+ doc_chars[next_char_slot] = '\n';
+ next_char_slot += 1;
+ MR_free(text);
+ }
+
+ MR_ensure_big_enough(next_char_slot, doc_char, char, MR_INIT_DOC_CHARS);
+ doc_chars[next_char_slot] = '\0';
+ return doc_chars;
+}
Index: trace/mercury_trace_cmd_help.h
===================================================================
RCS file: trace/mercury_trace_cmd_help.h
diff -N trace/mercury_trace_cmd_help.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ trace/mercury_trace_cmd_help.h 3 Apr 2006 10:38:26 -0000
@@ -0,0 +1,16 @@
+/*
+** 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.
+*/
+
+#include "mercury_imp.h"
+
+#include "mercury_trace_cmds.h"
+
+extern MR_TraceCmdFunc MR_trace_cmd_document_category;
+extern MR_TraceCmdFunc MR_trace_cmd_document;
+extern MR_TraceCmdFunc MR_trace_cmd_help;
Index: trace/mercury_trace_cmd_misc.c
===================================================================
RCS file: trace/mercury_trace_cmd_misc.c
diff -N trace/mercury_trace_cmd_misc.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ trace/mercury_trace_cmd_misc.c 3 Apr 2006 12:50:55 -0000
@@ -0,0 +1,328 @@
+/*
+** 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 "misc" 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_trace_internal.h"
+#include "mercury_trace_cmds.h"
+#include "mercury_trace_cmd_misc.h"
+#include "mercury_trace_cmd_parameter.h"
+#include "mercury_trace_alias.h"
+#include "mercury_trace_declarative.h"
+#include "mercury_trace_spy.h"
+
+#include "mdb.listing.mh"
+
+/****************************************************************************/
+
+static MR_bool MR_trace_options_ignore(MR_bool *ignore_errors,
+ char ***words, int *word_count);
+static MR_bool MR_trace_options_confirmed(MR_bool *confirmed,
+ char ***words, int *word_count);
+
+/****************************************************************************/
+
+MR_Next
+MR_trace_cmd_source(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
+ MR_Event_Info *event_info, MR_Code **jumpaddr)
+{
+ MR_bool ignore_errors;
+
+ 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) {
+ /*
+ ** 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);
+ } else {
+ MR_trace_usage_cur_cmd();
+ }
+
+ return KEEP_INTERACTING;
+}
+
+MR_Next
+MR_trace_cmd_save(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
+ MR_Event_Info *event_info, MR_Code **jumpaddr)
+{
+ if (word_count == 2) {
+ FILE *fp;
+ MR_bool found_error;
+ MR_Word path_list;
+
+ fp = fopen(words[1], "w");
+ if (fp == NULL) {
+ fflush(MR_mdb_out);
+ fprintf(MR_mdb_err, "mdb: error opening `%s': %s.\n",
+ words[1], strerror(errno));
+ return KEEP_INTERACTING;
+ }
+
+ MR_trace_print_all_aliases(fp, MR_TRUE);
+ switch (MR_default_print_level) {
+ case MR_PRINT_LEVEL_NONE:
+ fprintf(fp, "printlevel none\n");
+ break;
+
+ case MR_PRINT_LEVEL_SOME:
+ fprintf(fp, "printlevel some\n");
+ break;
+
+ case MR_PRINT_LEVEL_ALL:
+ fprintf(fp, "printlevel all\n");
+ break;
+ }
+
+ if (MR_echo_commands) {
+ fprintf(fp, "echo on\n");
+ } else {
+ fprintf(fp, "echo off\n");
+ }
+
+ if (MR_scroll_control) {
+ fprintf(fp, "scroll on\n");
+ } else {
+ fprintf(fp, "scroll off\n");
+ }
+
+ fprintf(fp, "scroll %d\n", MR_scroll_limit);
+ fprintf(fp, "stack_default_limit %d\n", MR_stack_default_line_limit);
+
+ switch (MR_context_position) {
+ case MR_CONTEXT_NOWHERE:
+ fprintf(fp, "context nowhere\n");
+ break;
+
+ case MR_CONTEXT_AFTER:
+ fprintf(fp, "context after\n");
+ break;
+
+ case MR_CONTEXT_BEFORE:
+ fprintf(fp, "context before\n");
+ break;
+
+ case MR_CONTEXT_PREVLINE:
+ fprintf(fp, "context prevline\n");
+ break;
+
+ case MR_CONTEXT_NEXTLINE:
+ fprintf(fp, "context nextline\n");
+ break;
+ }
+
+ if (MR_print_goal_paths) {
+ fprintf(fp, "goal_paths on\n");
+ } else {
+ fprintf(fp, "goal_paths off\n");
+ }
+
+ found_error = MR_save_spy_points(fp, MR_mdb_err);
+
+ switch (MR_default_breakpoint_scope) {
+ case MR_SPY_ALL:
+ fprintf(fp, "scope all\n");
+ break;
+
+ case MR_SPY_INTERFACE:
+ fprintf(fp, "scope interface\n");
+ break;
+
+ case MR_SPY_ENTRY:
+ fprintf(fp, "scope entry\n");
+ break;
+
+ case MR_SPY_LINENO:
+ case MR_SPY_SPECIFIC:
+ MR_fatal_error("save cmd: invalid default scope");
+ }
+
+ MR_trace_print_all_browser_params(fp, MR_TRUE);
+ MR_decl_print_all_trusted(fp, MR_TRUE);
+
+ if (MR_dice_fail_trace_counts_file != NULL) {
+ fprintf(fp, "fail_trace_counts %s\n",
+ MR_dice_fail_trace_counts_file);
+ }
+ if (MR_dice_pass_trace_counts_file != NULL) {
+ fprintf(fp, "pass_trace_counts %s\n",
+ MR_dice_pass_trace_counts_file);
+ }
+
+ fprintf(fp, "list_context_lines %d\n", MR_num_context_lines);
+ MR_TRACE_CALL_MERCURY(
+ path_list = ML_LISTING_get_list_path(MR_listing_path);
+ if (! MR_list_is_empty(path_list)) {
+ fprintf(fp, "list_path");
+ while (! MR_list_is_empty(path_list)) {
+ fprintf(fp, " %s", (const char *) MR_list_head(path_list));
+ path_list = MR_list_tail(path_list);
+ }
+ fprintf(fp, "\n");
+ }
+ );
+
+ if (found_error) {
+ fflush(MR_mdb_out);
+ fprintf(MR_mdb_err, "mdb: could not save debugger state to %s.\n",
+ words[1]);
+ (void) fclose(fp);
+ } else if (fclose(fp) != 0) {
+ fflush(MR_mdb_out);
+ fprintf(MR_mdb_err, "mdb: error closing `%s': %s.\n",
+ words[1], strerror(errno));
+ } else {
+ fprintf(MR_mdb_out, "Debugger state saved to %s.\n", words[1]);
+ }
+ } else {
+ MR_trace_usage_cur_cmd();
+ }
+
+ return KEEP_INTERACTING;
+}
+
+MR_Next
+MR_trace_cmd_quit(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
+ MR_Event_Info *event_info, MR_Code **jumpaddr)
+{
+ MR_bool confirmed;
+
+ confirmed = MR_FALSE;
+ if (! MR_trace_options_confirmed(&confirmed, &words, &word_count)) {
+ ; /* the usage message has already been printed */
+ } else if (word_count == 1) {
+ if (! confirmed) {
+ char *line2;
+
+ line2 = MR_trace_getline("mdb: are you sure you want to quit? ",
+ MR_mdb_in, MR_mdb_out);
+ if (line2 == NULL) {
+ /* This means the user input EOF. */
+ confirmed = MR_TRUE;
+ } else {
+ int i = 0;
+ while (line2[i] != '\0' && MR_isspace(line2[i])) {
+ i++;
+ }
+
+ if (line2[i] == 'y' || line2[i] == 'Y') {
+ confirmed = MR_TRUE;
+ }
+
+ MR_free(line2);
+ }
+ }
+
+ if (confirmed) {
+ MR_trace_maybe_close_source_window(MR_FALSE);
+ exit(EXIT_SUCCESS);
+ }
+ } else {
+ MR_trace_usage_cur_cmd();
+ }
+
+ return KEEP_INTERACTING;
+}
+
+/****************************************************************************/
+
+/*
+** It's better to have a single completion where possible,
+** so don't include `-i' here.
+*/
+
+const char *const MR_trace_source_cmd_args[] =
+ { "--ignore-errors", NULL };
+
+const char *const MR_trace_quit_cmd_args[] =
+ { "-y", NULL };
+
+/****************************************************************************/
+
+static struct MR_option MR_trace_ignore_opts[] =
+{
+ { "ignore-errors", MR_no_argument, NULL, 'i' },
+ { NULL, MR_no_argument, NULL, 0 }
+};
+
+static MR_bool
+MR_trace_options_ignore(MR_bool *ignore_errors, char ***words, int *word_count)
+{
+ int c;
+
+ MR_optind = 0;
+ while ((c = MR_getopt_long(*word_count, *words, "i",
+ MR_trace_ignore_opts, NULL)) != EOF)
+ {
+ switch (c) {
+
+ case 'i':
+ *ignore_errors = MR_TRUE;
+ 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 MR_bool
+MR_trace_options_confirmed(MR_bool *confirmed, char ***words, int *word_count)
+{
+ int c;
+
+ MR_optind = 0;
+ while ((c = MR_getopt(*word_count, *words, "NYny")) != EOF) {
+ switch (c) {
+
+ case 'n':
+ case 'N':
+ *confirmed = MR_FALSE;
+ break;
+
+ case 'y':
+ case 'Y':
+ *confirmed = MR_TRUE;
+ 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;
+}
+
+/****************************************************************************/
Index: trace/mercury_trace_cmd_misc.h
===================================================================
RCS file: trace/mercury_trace_cmd_misc.h
diff -N trace/mercury_trace_cmd_misc.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ trace/mercury_trace_cmd_misc.h 3 Apr 2006 10:31:24 -0000
@@ -0,0 +1,18 @@
+/*
+** 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.
+*/
+
+#include "mercury_trace_cmds.h"
+
+extern MR_TraceCmdFunc MR_trace_cmd_source;
+extern MR_TraceCmdFunc MR_trace_cmd_save;
+extern MR_TraceCmdFunc MR_trace_cmd_quit;
+
+extern const char *const MR_trace_source_cmd_args[];
+extern const char *const MR_trace_quit_cmd_args[];
+
Index: trace/mercury_trace_cmd_parameter.c
===================================================================
RCS file: trace/mercury_trace_cmd_parameter.c
diff -N trace/mercury_trace_cmd_parameter.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ trace/mercury_trace_cmd_parameter.c 3 Apr 2006 12:51:00 -0000
@@ -0,0 +1,997 @@
+/*
+** 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_trace.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[2], &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, 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, 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, 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 n;
+
+ if (word_count == 2 && MR_trace_is_natural_number(words[1], &n)) {
+ MR_TRACE_CALL_MERCURY(
+ ML_BROWSE_set_num_io_actions(n,
+ MR_trace_browser_persistent_state,
+ &MR_trace_browser_persistent_state);
+ );
+ } else if (word_count == 1) {
+ MR_TRACE_CALL_MERCURY(
+ ML_BROWSE_get_num_io_actions(
+ MR_trace_browser_persistent_state, &n);
+ );
+ fprintf(MR_mdb_out,
+ "The maximum number of I/O actions printed is %d\n",
+ n);
+ } 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;
+}
Index: trace/mercury_trace_cmd_parameter.h
===================================================================
RCS file: trace/mercury_trace_cmd_parameter.h
diff -N trace/mercury_trace_cmd_parameter.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ trace/mercury_trace_cmd_parameter.h 3 Apr 2006 12:41:04 -0000
@@ -0,0 +1,136 @@
+/*
+** 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.
+*/
+
+#include "mercury_std.h"
+#include "mercury_types.h"
+#include "mercury_stack_trace.h" /* for MR_Context_Position */
+
+#include "mercury_trace_cmds.h"
+#include "mercury_trace_spy.h" /* for MR_Spy_When */
+
+/*
+** Options to pass to mmc when compiling queries.
+*/
+
+extern char *MR_mmc_options;
+
+/*
+** The default print level governs whether we out reports for events at which
+** we don't stop.
+*/
+
+extern MR_Trace_Print_Level MR_default_print_level;
+
+/*
+** These variables say (a) whether the printing of event sequences will pause
+** after each screenful of events, (b) how may events constitute a screenful
+** (although we count only events, not how many lines they take up), and (c)
+** how many events we have printed so far in this screenful.
+*/
+
+extern MR_bool MR_scroll_control;
+extern int MR_scroll_limit;
+extern int MR_scroll_next;
+
+/*
+** This variable controls the number of stack frame lines printed by the stack
+** and nondet_stack commands if the user doesn't override it.
+*/
+
+extern int MR_stack_default_line_limit;
+
+/*
+** We echo each command just as it is executed iff this variable is MR_TRUE.
+*/
+
+extern MR_bool MR_echo_commands;
+
+/*
+** We include values of sometimes-useful types such as typeinfos in the set of
+** variables whose values we collect at events for possible later printing
+** only if MR_print_optionals is true.
+*/
+
+extern MR_bool MR_print_optionals;
+
+/*
+** This variable holds either the name of a file which contains a list of
+** the file names of passing test case trace counts, or the name of a single
+** file of passing test case trace counts.
+*/
+
+extern char *MR_dice_pass_trace_counts_file;
+
+/*
+** This variable holds either the name of a file which contains a list of
+** the file names of failing test case trace counts, or the name of a single
+** file of failing test case trace counts.
+*/
+
+extern char *MR_dice_fail_trace_counts_file;
+
+/*
+** MR_context_position specifies whether we print context at events,
+** and if so, where.
+*/
+
+extern MR_Context_Position MR_context_position;
+
+/*
+** MR_print_goal_paths specifies whether we print goal paths at events.
+*/
+
+extern MR_bool MR_print_goal_paths;
+
+/*
+** MR_listing_path holds the current value of the listings structure
+** as defined in browser/listing.m. You need to ensure that it is initialized
+** before accessing it.
+*/
+
+extern MR_Word MR_listing_path;
+extern void MR_trace_listing_path_ensure_init(void);
+
+/*
+** MR_num_context_lines holds the current number of context lines to be
+** printed before and after the current callee/caller's file context.
+*/
+
+extern int MR_num_context_lines;
+
+extern MR_Spy_When MR_default_breakpoint_scope;
+
+extern MR_TraceCmdFunc MR_trace_cmd_mmc_options;
+extern MR_TraceCmdFunc MR_trace_cmd_printlevel;
+extern MR_TraceCmdFunc MR_trace_cmd_scroll;
+extern MR_TraceCmdFunc MR_trace_cmd_stack_default_limit;
+extern MR_TraceCmdFunc MR_trace_cmd_context;
+extern MR_TraceCmdFunc MR_trace_cmd_goal_paths;
+extern MR_TraceCmdFunc MR_trace_cmd_scope;
+extern MR_TraceCmdFunc MR_trace_cmd_echo;
+extern MR_TraceCmdFunc MR_trace_cmd_list_context_lines;
+extern MR_TraceCmdFunc MR_trace_cmd_list_path;
+extern MR_TraceCmdFunc MR_trace_cmd_push_list_dir;
+extern MR_TraceCmdFunc MR_trace_cmd_pop_list_dir;
+extern MR_TraceCmdFunc MR_trace_cmd_fail_trace_counts;
+extern MR_TraceCmdFunc MR_trace_cmd_pass_trace_counts;
+extern MR_TraceCmdFunc MR_trace_cmd_max_io_actions;
+extern MR_TraceCmdFunc MR_trace_cmd_xml_browser_cmd;
+extern MR_TraceCmdFunc MR_trace_cmd_xml_tmp_filename;
+extern MR_TraceCmdFunc MR_trace_cmd_format;
+extern MR_TraceCmdFunc MR_trace_cmd_format_param;
+extern MR_TraceCmdFunc MR_trace_cmd_alias;
+extern MR_TraceCmdFunc MR_trace_cmd_unalias;
+
+extern const char *const MR_trace_printlevel_cmd_args[];
+extern const char *const MR_trace_on_off_args[];
+extern const char *const MR_trace_context_cmd_args[];
+extern const char *const MR_trace_scope_cmd_args[];
+extern const char *const MR_trace_format_cmd_args[];
+extern const char *const MR_trace_format_param_cmd_args[];
Index: trace/mercury_trace_cmd_queries.c
===================================================================
RCS file: trace/mercury_trace_cmd_queries.c
diff -N trace/mercury_trace_cmd_queries.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ trace/mercury_trace_cmd_queries.c 3 Apr 2006 12:51:04 -0000
@@ -0,0 +1,58 @@
+/*
+** 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 "queries" 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_trace_internal.h"
+#include "mercury_trace_cmds.h"
+#include "mercury_trace_cmd_queries.h"
+#include "mercury_trace_cmd_parameter.h"
+#include "mercury_trace_browse.h"
+
+/****************************************************************************/
+
+MR_Next
+MR_trace_cmd_query(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
+ MR_Event_Info *event_info, MR_Code **jumpaddr)
+{
+ MR_trace_query(MR_NORMAL_QUERY, MR_mmc_options, word_count - 1, words + 1);
+ return KEEP_INTERACTING;
+}
+
+MR_Next
+MR_trace_cmd_cc_query(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
+ MR_Event_Info *event_info, MR_Code **jumpaddr)
+{
+ MR_trace_query(MR_CC_QUERY, MR_mmc_options, word_count - 1, words + 1);
+ return KEEP_INTERACTING;
+}
+
+MR_Next
+MR_trace_cmd_io_query(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
+ MR_Event_Info *event_info, MR_Code **jumpaddr)
+{
+ MR_trace_query(MR_IO_QUERY, MR_mmc_options, word_count - 1, words + 1);
+ return KEEP_INTERACTING;
+}
+
+/****************************************************************************/
Index: trace/mercury_trace_cmd_queries.h
===================================================================
RCS file: trace/mercury_trace_cmd_queries.h
diff -N trace/mercury_trace_cmd_queries.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ trace/mercury_trace_cmd_queries.h 3 Apr 2006 11:32:58 -0000
@@ -0,0 +1,16 @@
+/*
+** 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.
+*/
+
+#include "mercury_imp.h"
+
+#include "mercury_trace_cmds.h"
+
+extern MR_TraceCmdFunc MR_trace_cmd_query;
+extern MR_TraceCmdFunc MR_trace_cmd_cc_query;
+extern MR_TraceCmdFunc MR_trace_cmd_io_query;
Index: trace/mercury_trace_cmd_table_io.c
===================================================================
RCS file: trace/mercury_trace_cmd_table_io.c
diff -N trace/mercury_trace_cmd_table_io.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ trace/mercury_trace_cmd_table_io.c 3 Apr 2006 12:51:09 -0000
@@ -0,0 +1,152 @@
+/*
+** 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 "table_io" 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_trace_internal.h"
+#include "mercury_trace_cmds.h"
+#include "mercury_trace_cmd_table_io.h"
+
+/****************************************************************************/
+
+static void MR_print_unsigned_var(FILE *fp, const char *var,
+ MR_Unsigned value);
+
+/****************************************************************************/
+
+MR_Next
+MR_trace_cmd_table_io(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
+ MR_Event_Info *event_info, MR_Code **jumpaddr)
+{
+ if (word_count == 1) {
+ if (! MR_io_tabling_allowed) {
+ fprintf(MR_mdb_err,
+ "This executable wasn't prepared for I/O tabling.\n");
+ return KEEP_INTERACTING;
+ }
+
+ if (MR_io_tabling_phase == MR_IO_TABLING_BEFORE) {
+ fprintf(MR_mdb_out, "I/O tabling has not yet started.\n");
+ } else if (MR_io_tabling_phase == MR_IO_TABLING_DURING) {
+ fprintf(MR_mdb_out, "I/O tabling has started.\n");
+ } else if (MR_io_tabling_phase == MR_IO_TABLING_AFTER) {
+ fprintf(MR_mdb_out, "I/O tabling has stopped.\n");
+ } else {
+ MR_fatal_error("I/O tabling in impossible phase.\n");
+ }
+ } else if (word_count == 2 &&
+ (MR_streq(words[1], "start") || MR_streq(words[1], "begin")))
+ {
+ if (! MR_io_tabling_allowed) {
+ fprintf(MR_mdb_err,
+ "This executable wasn't prepared for I/O tabling.\n");
+ return KEEP_INTERACTING;
+ }
+
+ if (MR_io_tabling_phase == MR_IO_TABLING_BEFORE) {
+ MR_io_tabling_phase = MR_IO_TABLING_DURING;
+ MR_io_tabling_start = MR_io_tabling_counter;
+ MR_io_tabling_end = MR_IO_ACTION_MAX;
+ MR_io_tabling_start_event_num = event_info->MR_event_number;
+#ifdef MR_DEBUG_RETRY
+ MR_io_tabling_debug = MR_TRUE;
+#endif
+ fprintf(MR_mdb_out, "I/O tabling started.\n");
+ } else if (MR_io_tabling_phase == MR_IO_TABLING_DURING) {
+ fprintf(MR_mdb_out, "I/O tabling has already started.\n");
+ } else if (MR_io_tabling_phase == MR_IO_TABLING_AFTER) {
+ fprintf(MR_mdb_out, "I/O tabling has already stopped.\n");
+ } else {
+ MR_fatal_error("I/O tabling in impossible phase.\n");
+ }
+ } else if (word_count == 2 &&
+ (MR_streq(words[1], "stop") || MR_streq(words[1], "end")))
+ {
+ if (! MR_io_tabling_allowed) {
+ fprintf(MR_mdb_err,
+ "This executable wasn't prepared for I/O tabling.\n");
+ return KEEP_INTERACTING;
+ }
+
+ if (MR_io_tabling_phase == MR_IO_TABLING_BEFORE) {
+ fprintf(MR_mdb_out, "I/O tabling has not yet started.\n");
+ } else if (MR_io_tabling_phase == MR_IO_TABLING_DURING) {
+ MR_io_tabling_phase = MR_IO_TABLING_AFTER;
+ MR_io_tabling_end = MR_io_tabling_counter_hwm;
+ MR_io_tabling_stop_event_num = event_info->MR_event_number;
+ fprintf(MR_mdb_out, "I/O tabling stopped.\n");
+ } else if (MR_io_tabling_phase == MR_IO_TABLING_AFTER) {
+ fprintf(MR_mdb_out, "I/O tabling has already stopped.\n");
+ } else {
+ MR_fatal_error("I/O tabling in impossible phase.\n");
+ }
+ } else if (word_count == 2 && MR_streq(words[1], "stats")) {
+ if (! MR_io_tabling_allowed) {
+ fprintf(MR_mdb_err,
+ "This executable wasn't prepared for I/O tabling.\n");
+ return KEEP_INTERACTING;
+ }
+
+ fprintf(MR_mdb_out, "phase = %d\n", MR_io_tabling_phase);
+ MR_print_unsigned_var(MR_mdb_out, "counter", MR_io_tabling_counter);
+ MR_print_unsigned_var(MR_mdb_out, "hwm", MR_io_tabling_counter_hwm);
+ MR_print_unsigned_var(MR_mdb_out, "start", MR_io_tabling_start);
+ MR_print_unsigned_var(MR_mdb_out, "end", MR_io_tabling_end);
+ } else if (word_count == 2 && MR_streq(words[1], "allow")) {
+ /*
+ ** The "table_io allow" command allows the programmer to give
+ ** the command "table_io start" even in grades in which there
+ ** is no guarantee that all I/O primitives are tabled. It is
+ ** for developers only, because if it is used on programs in
+ ** which some but not all I/O primitives are tabled, the
+ ** results of turning on I/O tabling can be weird.
+ */
+
+ MR_io_tabling_allowed = MR_TRUE;
+ } else {
+ MR_trace_usage_cur_cmd();
+ }
+
+ return KEEP_INTERACTING;
+}
+
+/****************************************************************************/
+
+static void
+MR_print_unsigned_var(FILE *fp, const char *var, MR_Unsigned value)
+{
+ fprintf(fp, "%s = %" MR_INTEGER_LENGTH_MODIFIER "u\n", var, value);
+}
+
+/****************************************************************************/
+
+/*
+** "table_io allow" is deliberately not documented as it is developer only.
+** "table_io begin" and "table_io end" are deliberately not documented in an
+** effort to encourage consistent use of start/stop.
+*/
+
+const char *const MR_trace_table_io_cmd_args[] =
+ { "stats", "start", "stop", NULL };
+
+/****************************************************************************/
Index: trace/mercury_trace_cmd_table_io.h
===================================================================
RCS file: trace/mercury_trace_cmd_table_io.h
diff -N trace/mercury_trace_cmd_table_io.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ trace/mercury_trace_cmd_table_io.h 3 Apr 2006 11:31:28 -0000
@@ -0,0 +1,16 @@
+/*
+** 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.
+*/
+
+#include "mercury_imp.h"
+
+#include "mercury_trace_cmds.h"
+
+extern MR_TraceCmdFunc MR_trace_cmd_table_io;
+
+extern const char *const MR_trace_table_io_cmd_args[];
Index: trace/mercury_trace_cmds.h
===================================================================
RCS file: trace/mercury_trace_cmds.h
diff -N trace/mercury_trace_cmds.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ trace/mercury_trace_cmds.h 3 Apr 2006 12:43:30 -0000
@@ -0,0 +1,58 @@
+/*
+** 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.
+*/
+
+#include "mercury_std.h"
+#include "mercury_types.h"
+
+#include "mercury_trace.h"
+#include "mercury_trace_completion.h"
+
+#ifndef MERCURY_TRACE_CMDS_H
+#define MERCURY_TRACE_CMDS_H
+
+typedef enum {
+ KEEP_INTERACTING,
+ STOP_INTERACTING
+} MR_Next;
+
+typedef MR_Next MR_TraceCmdFunc(char **words, int word_count,
+ MR_Trace_Cmd_Info *cmd, MR_Event_Info *event_info,
+ MR_Code **jumpaddr);
+
+/*
+** We keep a table of the available commands. The information we have about
+** each command is stored in a value of type MR_Trace_Command_Info.
+**
+** The name of the command itself is stored in the name field; the category
+** field contains name of the category to which the command belongs,
+** e.g. "browsing".
+**
+** The code that the command loop should execute to handle a command of a given
+** type is the function pointed to by the function field.
+**
+** Some commands take fixed strings as arguments. The arg_strings field
+** is a NULL terminated array of those strings, or NULL if there are
+** no fixed strings.
+**
+** The arg_completer field contains the address of a function for more
+** arbitrary completion, e.g. on predicate names. This field should not be
+** null; if the command cannot use a completion function, the field should
+** contain MR_trace_null_completer.
+*/
+
+typedef struct
+{
+ const char *MR_cmd_category;
+ const char *MR_cmd_name;
+ MR_TraceCmdFunc *MR_cmd_function;
+ const char *const *MR_cmd_arg_strings;
+ const MR_Make_Completer MR_cmd_arg_completer;
+} MR_Trace_Command_Info;
+
+#endif /* MERCURY_TRACE_CMDS_H */
Index: trace/mercury_trace_external.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/trace/mercury_trace_external.c,v
retrieving revision 1.79
diff -u -b -r1.79 mercury_trace_external.c
--- trace/mercury_trace_external.c 8 Feb 2006 21:54:33 -0000 1.79
+++ trace/mercury_trace_external.c 3 Apr 2006 09:30:49 -0000
@@ -1,4 +1,7 @@
/*
+** 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.
@@ -57,49 +60,79 @@
*/
typedef enum {
- MR_REQUEST_HELLO_REPLY = 0, /* initiate debugging session */
- MR_REQUEST_FORWARD_MOVE = 1, /* go to the next matching trace event */
- MR_REQUEST_CURRENT_VARS = 2, /* report data for current_vars query */
- MR_REQUEST_CURRENT_SLOTS = 3, /* report data for current_slots query */
- MR_REQUEST_NO_TRACE = 4, /* continue to end, not tracing */
- MR_REQUEST_ABORT_PROG = 5, /* abort the current execution */
- MR_REQUEST_ERROR = 6, /* something went wrong */
- MR_REQUEST_CURRENT_LIVE_VAR_NAMES
- = 7, /* report data for
- current_live_var_names query */
- MR_REQUEST_CURRENT_NTH_VAR
- = 8, /* report data for
- current_nth_var query */
- MR_REQUEST_RETRY = 9, /* restart the execution to the call
- port of the current event */
- MR_REQUEST_STACK = 10,/* print the ancestors list */
- MR_REQUEST_NONDET_STACK = 11,/* print the nondet stack */
- MR_REQUEST_STACK_REGS = 12,/* prints the contents of the virtual
- machine registers. */
- MR_REQUEST_INTERACTIVE_QUERY_NORMAL
- = 13,/* wait for a normal interactive query */
- MR_REQUEST_INTERACTIVE_QUERY_CC
- = 14,/* wait for a cc interactive query */
- MR_REQUEST_INTERACTIVE_QUERY_IO
- = 15,/* wait for a io interactive query */
- MR_REQUEST_MMC_OPTIONS = 16,/* pass down new options to compile
- queries with */
- MR_REQUEST_BROWSE = 17,/* call the term browser */
- MR_REQUEST_LINK_COLLECT = 18,/* dynamically link the collect module */
- MR_REQUEST_COLLECT = 19,/* collecting monitoring informations */
- MR_REQUEST_CURRENT_GRADE = 20,/* retrieving the grade of the current
- program has been compiled with */
- MR_REQUEST_COLLECT_ARG_ON
- = 21,/* switch the arguments collecting on */
- MR_REQUEST_COLLECT_ARG_OFF
- = 22 /* switch the arguments collecting off */
+ /* initiate debugging session */
+ MR_REQUEST_HELLO_REPLY = 0,
+
+ /* go to the next matching trace event */
+ MR_REQUEST_FORWARD_MOVE = 1,
+
+ /* report data for current_vars query */
+ MR_REQUEST_CURRENT_VARS = 2,
+
+ /* report data for current_slots query */
+ MR_REQUEST_CURRENT_SLOTS = 3,
+
+ /* continue to end, not tracing */
+ MR_REQUEST_NO_TRACE = 4,
+
+ /* abort the current execution */
+ MR_REQUEST_ABORT_PROG = 5,
+
+ /* something went wrong */
+ MR_REQUEST_ERROR = 6,
+
+ /* report data for current_live_var_names query */
+ MR_REQUEST_CURRENT_LIVE_VAR_NAMES = 7,
+
+ /* report data for current_nth_var query */
+ MR_REQUEST_CURRENT_NTH_VAR = 8,
+
+ /* restart the execution to the call port of the current event */
+ MR_REQUEST_RETRY = 9,
+
+ /* print the ancestors list */
+ MR_REQUEST_STACK = 10,
+
+ /* print the nondet stack */
+ MR_REQUEST_NONDET_STACK = 11,
+
+ /* prints the contents of the virtual machine registers. */
+ MR_REQUEST_STACK_REGS = 12,
+
+ /* wait for a normal interactive query */
+ MR_REQUEST_INTERACTIVE_QUERY_NORMAL = 13,
+
+ /* wait for a cc interactive query */
+ MR_REQUEST_INTERACTIVE_QUERY_CC = 14,
+
+ /* wait for a io interactive query */
+ MR_REQUEST_INTERACTIVE_QUERY_IO = 15,
+ /* pass down new options to compile queries with */
+ MR_REQUEST_MMC_OPTIONS = 16,
+
+ /* call the term browser */
+ MR_REQUEST_BROWSE = 17,
+ /* dynamically link the collect module */
+ MR_REQUEST_LINK_COLLECT = 18,
+
+ /* collecting monitoring informations */
+ MR_REQUEST_COLLECT = 19,
+
+ /* retrieving the grade of the current program has been compiled with */
+ MR_REQUEST_CURRENT_GRADE = 20,
+
+ /* switch the arguments collecting on */
+ MR_REQUEST_COLLECT_ARG_ON = 21,
+
+ /* switch the arguments collecting off */
+ MR_REQUEST_COLLECT_ARG_OFF = 22
} MR_debugger_request_type;
MercuryFile MR_debugger_socket_in;
MercuryFile MR_debugger_socket_out;
-static MR_String MR_mmc_options;
+static MR_String MR_external_mmc_options;
/*
** Type of a static variable that indicates in which mode the external
@@ -107,8 +140,10 @@
** (1) `MR_searching', it tries to find an event that matches a forward
** move request,
** (2) `MR_reading_request', it reads a new request on the socket,
-** (3) `MR_collecting', it is collecting information (after a `collect' request).
+** (3) `MR_collecting', it is collecting information (after a `collect'
+** request).
*/
+
typedef enum {
MR_searching, MR_reading_request, MR_collecting
} MR_external_debugger_mode_type;
@@ -162,25 +197,24 @@
** (See the "Function attributes" section of "C extensions"
** chapter of the GNU C manual for detailed documentation.)
*/
+
#ifdef __GNUC__
#define MR_LIKE_PRINTF(format_argnum, vars_argnum) \
__attribute__ ((format (printf, (format_argnum), (vars_argnum))))
#else
#define MR_LIKE_PRINTF(n, m) /* nothing */
#endif
+
static void MR_send_message_to_socket_format(const char *format, ...)
MR_LIKE_PRINTF(1, 2);
static void MR_send_message_to_socket(const char *message);
-static void MR_read_request_from_socket(
- MR_Word *debugger_request_ptr,
+static void MR_read_request_from_socket(MR_Word *debugger_request_ptr,
MR_Integer *debugger_request_type_ptr);
static MR_bool MR_found_match(const MR_Label_Layout *layout,
- MR_Trace_Port port, MR_Unsigned seqno,
- MR_Unsigned depth,
- /* XXX registers */
- const char *path, MR_Word search_data);
+ MR_Trace_Port port, MR_Unsigned seqno, MR_Unsigned depth,
+ /* XXX registers */ const char *path, MR_Word search_data);
static void MR_output_current_slots(const MR_Label_Layout *layout,
MR_Trace_Port port, MR_Unsigned seqno,
MR_Unsigned depth, const char *path, int lineno);
@@ -194,8 +228,7 @@
static MR_Word MR_trace_make_nth_var(MR_Word debugger_request);
static int MR_get_var_number(MR_Word debugger_request);
static void MR_print_proc_id_to_socket(const MR_Proc_Layout *entry,
- const char *extra,
- MR_Word *base_sp, MR_Word *base_curfr);
+ const char *extra, MR_Word *base_sp, MR_Word *base_curfr);
static void MR_dump_stack_record_print_to_socket(FILE *fp,
const MR_Proc_Layout *entry_layout, int count,
int start_level, MR_Word *base_sp, MR_Word *base_curfr,
@@ -283,15 +316,16 @@
char *inet_socket;
struct sockaddr_un unix_address;
struct sockaddr_in inet_address;
- struct sockaddr* addr;
+ struct sockaddr *addr;
MR_Word debugger_request;
MR_Integer debugger_request_type;
/*
- ** MR_mmc_options contains the options to pass to mmc when compiling
- ** queries. We initialize it to the MR_String "".
+ ** MR_external_mmc_options contains the options to pass to mmc
+ ** when compiling queries. We initialize it to the MR_String "".
*/
- MR_TRACE_CALL_MERCURY(ML_DI_init_mercury_string(&MR_mmc_options));
+
+ MR_TRACE_CALL_MERCURY(ML_DI_init_mercury_string(&MR_external_mmc_options));
/*
** We presume that the user's program has been invoked from
@@ -301,6 +335,7 @@
** environment variable to tell the user's program which socket
** it needs to connect to.
*/
+
unix_socket = getenv("MERCURY_DEBUGGER_UNIX_SOCKET");
inet_socket = getenv("MERCURY_DEBUGGER_INET_SOCKET");
if (unix_socket == NULL && inet_socket == NULL) {
@@ -520,8 +555,7 @@
if (MR_found_match(layout, port, seqno, depth,
/* XXX registers, */ path, search_data))
{
- MR_send_message_to_socket(
- "forward_move_match_found");
+ MR_send_message_to_socket("forward_move_match_found");
external_debugger_mode = MR_reading_request;
} else {
goto done;
@@ -544,8 +578,7 @@
/* loop to process requests read from the debugger socket */
for(;;) {
- MR_read_request_from_socket(
- &debugger_request, &debugger_request_type);
+ MR_read_request_from_socket(&debugger_request, &debugger_request_type);
switch((int) debugger_request_type) {
case MR_REQUEST_ABORT_PROG:
exit(EXIT_SUCCESS);
@@ -562,14 +595,11 @@
case MR_REQUEST_CURRENT_LIVE_VAR_NAMES:
if (MR_debug_socket) {
fprintf(stderr, "\nMercury runtime: "
- "MR_REQUEST_CURRENT_LIVE_VAR"
- "_NAMES\n");
+ "MR_REQUEST_CURRENT_LIVE_VAR_NAMES\n");
}
- var_names_list =
- MR_trace_make_var_names_list();
+ var_names_list = MR_trace_make_var_names_list();
type_list = MR_trace_make_type_list();
- MR_output_current_live_var_names(var_names_list,
- type_list);
+ MR_output_current_live_var_names(var_names_list, type_list);
break;
case MR_REQUEST_CURRENT_VARS:
@@ -578,10 +608,8 @@
"REQUEST_CURRENT_VARS\n");
}
var_list = MR_trace_make_var_list();
- var_names_list =
- MR_trace_make_var_names_list();
- MR_output_current_vars(var_list,
- var_names_list);
+ var_names_list = MR_trace_make_var_names_list();
+ MR_output_current_vars(var_list, var_names_list);
break;
case MR_REQUEST_CURRENT_NTH_VAR:
@@ -592,13 +620,14 @@
var = MR_trace_make_nth_var(debugger_request);
MR_output_current_nth_var(var);
break;
+
case MR_REQUEST_CURRENT_SLOTS:
if (MR_debug_socket) {
fprintf(stderr, "\nMercury runtime: "
"REQUEST_CURRENT_SLOTS\n");
}
- MR_output_current_slots(layout, port, seqno,
- depth, path, lineno);
+ MR_output_current_slots(layout, port, seqno, depth, path,
+ lineno);
break;
case MR_REQUEST_RETRY:
@@ -606,19 +635,18 @@
fprintf(stderr, "\nMercury runtime: "
"REQUEST_RETRY\n");
}
+
retry_result = MR_trace_retry(event_info, 0,
- MR_RETRY_IO_ONLY_IF_SAFE,
- MR_FALSE, "", &unsafe_retry,
+ MR_RETRY_IO_ONLY_IF_SAFE, MR_FALSE, "", &unsafe_retry,
&message, NULL, NULL, &jumpaddr);
if (retry_result == MR_RETRY_OK_DIRECT) {
MR_send_message_to_socket("ok");
cmd->MR_trace_cmd = MR_CMD_GOTO;
- cmd->MR_trace_stop_event =
- MR_trace_event_number + 1;
+ cmd->MR_trace_stop_event = MR_trace_event_number + 1;
goto done;
} else {
- MR_send_message_to_socket_format(
- "error(\"%s\").\n", message);
+ MR_send_message_to_socket_format("error(\"%s\").\n",
+ message);
}
break;
@@ -628,16 +656,14 @@
"REQUEST_STACK\n");
}
MR_trace_init_modules();
- message = MR_dump_stack_from_layout(
- stdout, layout,
- MR_saved_sp(saved_regs),
- MR_saved_curfr(saved_regs),
+ message = MR_dump_stack_from_layout(stdout, layout,
+ MR_saved_sp(saved_regs), MR_saved_curfr(saved_regs),
include_trace_data, MR_FALSE, 0, 0,
&MR_dump_stack_record_print_to_socket);
MR_send_message_to_socket("end_stack");
if (message != NULL) {
- MR_send_message_to_socket_format(
- "error(\"%s\").\n", message);
+ MR_send_message_to_socket_format("error(\"%s\").\n",
+ message);
} else {
MR_send_message_to_socket("ok");
}
@@ -650,14 +676,12 @@
}
MR_trace_init_modules();
/*
- ** XXX As in stack dump, we could send the
- ** output of this function on the socket. But
- ** the outputs are done via fprintf() and
- ** printlabel(), so we would need to define new
- ** fprintf() and printlabel() and pass them
- ** down as parameters of
- ** MR_dump_nondet_stack() (as we do
- ** with MR_dump_stack_record_print()).
+ ** XXX As in stack dump, we could send the output of this
+ ** function on the socket. But the outputs are done via
+ ** fprintf() and printlabel(), so we would need to define new
+ ** fprintf() and printlabel() and pass them down as parameters
+ ** of MR_dump_nondet_stack() (as we do with
+ ** MR_dump_stack_record_print()).
*/
MR_dump_nondet_stack(stdout, NULL, 0, 0,
MR_saved_maxfr(saved_regs));
@@ -671,25 +695,20 @@
}
MR_send_message_to_socket_format(
"stack_regs(%lu, %lu, %lu).\n",
- (unsigned long)
- MR_saved_sp(saved_regs),
- (unsigned long)
- MR_saved_curfr(saved_regs),
- (unsigned long)
- MR_saved_maxfr(saved_regs));
+ (unsigned long) MR_saved_sp(saved_regs),
+ (unsigned long) MR_saved_curfr(saved_regs),
+ (unsigned long) MR_saved_maxfr(saved_regs));
break;
case MR_REQUEST_INTERACTIVE_QUERY_NORMAL:
if (MR_debug_socket) {
fprintf(stderr, "\nMercury runtime: "
- "REQUEST_INTERACTIVE_QUERY"
- "_NORMAL\n");
+ "REQUEST_INTERACTIVE_QUERY_NORMAL\n");
}
- MR_get_list_modules_to_import(
- debugger_request, &modules_list_length,
- &modules_list);
+ MR_get_list_modules_to_import(debugger_request,
+ &modules_list_length, &modules_list);
MR_trace_query_external(MR_NORMAL_QUERY,
- MR_mmc_options, modules_list_length,
+ MR_external_mmc_options, modules_list_length,
modules_list);
break;
@@ -698,12 +717,10 @@
fprintf(stderr, "\nMercury runtime: "
"REQUEST_INTERACTIVE_QUERY_IO\n");
}
- MR_get_list_modules_to_import(
- debugger_request, &modules_list_length,
- &modules_list);
- MR_trace_query_external(MR_IO_QUERY,
- MR_mmc_options, modules_list_length,
- modules_list);
+ MR_get_list_modules_to_import(debugger_request,
+ &modules_list_length, &modules_list);
+ MR_trace_query_external(MR_IO_QUERY, MR_external_mmc_options,
+ modules_list_length, modules_list);
break;
case MR_REQUEST_INTERACTIVE_QUERY_CC:
@@ -711,12 +728,10 @@
fprintf(stderr, "\nMercury runtime: "
"REQUEST_INTERACTIVE_QUERY_CC\n");
}
- MR_get_list_modules_to_import(
- debugger_request, &modules_list_length,
- &modules_list);
- MR_trace_query_external(MR_CC_QUERY,
- MR_mmc_options, modules_list_length,
- modules_list);
+ MR_get_list_modules_to_import(debugger_request,
+ &modules_list_length, &modules_list);
+ MR_trace_query_external(MR_CC_QUERY, MR_external_mmc_options,
+ modules_list_length, modules_list);
break;
case MR_REQUEST_MMC_OPTIONS:
@@ -724,8 +739,7 @@
fprintf(stderr, "\nMercury runtime: "
"REQUEST_MMC_OPTIONS\n");
}
- MR_get_mmc_options(debugger_request,
- &MR_mmc_options);
+ MR_get_mmc_options(debugger_request, &MR_external_mmc_options);
MR_send_message_to_socket("mmc_options_ok");
break;
@@ -738,14 +752,14 @@
fprintf(stderr, "\nMercury runtime: "
"REQUEST_BROWSE\n");
}
- MR_get_variable_name(debugger_request,
- &var_name);
+ MR_get_variable_name(debugger_request, &var_name);
var_spec.MR_var_spec_kind = MR_VAR_SPEC_NAME;
var_spec.MR_var_spec_name = var_name;
MR_trace_browse_one_external(var_spec);
MR_send_message_to_socket("browser_end");
break;
}
+
case MR_REQUEST_NO_TRACE:
cmd->MR_trace_cmd = MR_CMD_TO_END;
external_debugger_mode = MR_searching;
@@ -763,8 +777,7 @@
MR_get_object_file_name(debugger_request,
&MR_object_file_name);
MR_TRACE_CALL_MERCURY(
- ML_CL_link_collect(
- MR_object_file_name,
+ ML_CL_link_collect(MR_object_file_name,
(MR_Word *) &cmd->MR_filter_ptr,
(MR_Word *) &initialize_ptr,
(MR_Word *) &post_process_ptr,
@@ -772,51 +785,45 @@
(MR_Word *) &get_collect_var_type_ptr,
&collect_lib_maybe_handle,
&result
- ));
+ )
+ );
collect_linked = (result == 'y');
if (collect_linked) {
- MR_send_message_to_socket(
- "link_collect_succeeded");
+ MR_send_message_to_socket("link_collect_succeeded");
MR_TRACE_CALL_MERCURY(
(*get_collect_var_type_ptr)(
&MR_accumulator_variable_type));
- MR_accumulator_variable =
- MR_make_permanent(
+ MR_accumulator_variable = MR_make_permanent(
MR_accumulator_variable,
- (MR_TypeInfo)
- MR_accumulator_variable_type);
+ (MR_TypeInfo) MR_accumulator_variable_type);
} else {
- MR_send_message_to_socket(
- "link_collect_failed");
+ MR_send_message_to_socket("link_collect_failed");
}
break;
}
case MR_REQUEST_COLLECT:
- {
if (MR_debug_socket) {
fprintf(stderr, "\nMercury runtime: "
"REQUEST_COLLECT\n");
}
if (collect_linked) {
- MR_send_message_to_socket(
- "collect_linked");
+ MR_send_message_to_socket("collect_linked");
external_debugger_mode = MR_collecting;
MR_TRACE_CALL_MERCURY(
- (*initialize_ptr)(&MR_accumulator_variable));
+ (*initialize_ptr)(&MR_accumulator_variable)
+ );
/*
- ** In order to perform the collect from
- ** the current event, we need to call
- ** filter once here.
+ ** In order to perform the collect from the current
+ ** event, we need to call filter once here.
*/
- MR_COLLECT_filter(cmd->MR_filter_ptr,
- seqno, depth, port, layout, path,
- lineno, &stop_collecting);
+
+ MR_COLLECT_filter(cmd->MR_filter_ptr, seqno, depth,
+ port, layout, path, lineno, &stop_collecting);
if (stop_collecting) {
MR_send_collect_result();
- MR_send_message_to_socket(
- "execution_continuing");
+ MR_send_message_to_socket("execution_continuing");
break;
} else {
/*
@@ -824,38 +831,29 @@
** to MR_COLLECT_filter() are done in
** MR_trace_real().
*/
- cmd->MR_trace_cmd =
- MR_CMD_COLLECT;
- cmd->MR_trace_must_check =
- MR_FALSE;
+
+ cmd->MR_trace_cmd = MR_CMD_COLLECT;
+ cmd->MR_trace_must_check = MR_FALSE;
cmd->MR_trace_strict = MR_TRUE;
- MR_init_trace_check_integrity(
- cmd);
- cmd->MR_trace_print_level =
- MR_PRINT_LEVEL_NONE;
+ MR_init_trace_check_integrity(cmd);
+ cmd->MR_trace_print_level = MR_PRINT_LEVEL_NONE;
goto done;
}
} else {
- MR_send_message_to_socket(
- "collect_not_linked");
+ MR_send_message_to_socket("collect_not_linked");
break;
}
- }
case MR_REQUEST_CURRENT_GRADE:
- {
if (MR_debug_socket) {
fprintf(stderr, "\nMercury runtime: "
"REQUEST_CURRENT_GRADE\n");
}
- MR_send_message_to_socket_format(
- "grade(\"%s\").\n",
+ MR_send_message_to_socket_format("grade(\"%s\").\n",
MR_GRADE_OPT);
break;
- }
case MR_REQUEST_COLLECT_ARG_ON:
- {
if (MR_debug_socket) {
fprintf(stderr, "\nMercury runtime: "
"REQUEST_COLLECT_ARG_ON\n");
@@ -863,9 +861,8 @@
MR_collect_arguments = MR_TRUE;
MR_send_message_to_socket("collect_arg_on_ok");
break;
- }
+
case MR_REQUEST_COLLECT_ARG_OFF:
- {
if (MR_debug_socket) {
fprintf(stderr, "\nMercury runtime: "
"REQUEST_COLLECT_ARG_OFF\n");
@@ -873,7 +870,7 @@
MR_collect_arguments = MR_FALSE;
MR_send_message_to_socket("collect_arg_off_ok");
break;
- }
+
default:
MR_fatal_error("unexpected request read from "
"debugger socket");
@@ -955,9 +952,7 @@
MR_output_current_vars(MR_Word var_list, MR_Word string_list)
{
MR_TRACE_CALL_MERCURY(
- ML_DI_output_current_vars(
- var_list,
- string_list,
+ ML_DI_output_current_vars(var_list, string_list,
&MR_debugger_socket_out);
);
}
@@ -966,9 +961,7 @@
MR_output_current_nth_var(MR_Word var)
{
MR_TRACE_CALL_MERCURY(
- ML_DI_output_current_nth_var(
- var,
- &MR_debugger_socket_out);
+ ML_DI_output_current_nth_var(var, &MR_debugger_socket_out);
);
}
@@ -976,25 +969,20 @@
MR_output_current_live_var_names(MR_Word var_names_list, MR_Word type_list)
{
MR_TRACE_CALL_MERCURY(
- ML_DI_output_current_live_var_names(
- var_names_list,
- type_list,
+ ML_DI_output_current_live_var_names(var_names_list, type_list,
&MR_debugger_socket_out);
);
}
static void
-MR_read_request_from_socket(
- MR_Word *debugger_request_ptr,
+MR_read_request_from_socket(MR_Word *debugger_request_ptr,
MR_Integer *debugger_request_type_ptr)
{
fflush(MR_file(MR_debugger_socket_in));
MR_TRACE_CALL_MERCURY(
- ML_DI_read_request_from_socket(
- &MR_debugger_socket_in,
- debugger_request_ptr,
- debugger_request_type_ptr);
+ ML_DI_read_request_from_socket(&MR_debugger_socket_in,
+ debugger_request_ptr, debugger_request_type_ptr);
);
}
@@ -1053,6 +1041,7 @@
search_data);
);
}
+
return result;
}
@@ -1103,8 +1092,7 @@
);
for (i = var_count; i > 0; i--) {
- problem = MR_trace_return_var_info(i, NULL,
- &type_info, &value);
+ problem = MR_trace_return_var_info(i, NULL, &type_info, &value);
if (problem != NULL) {
MR_fatal_error(problem);
}
@@ -1194,8 +1182,8 @@
type_info_string = ML_type_name((MR_Word) type_info);
);
MR_TRACE_USE_HP(
- type_list = MR_string_list_cons(
- (MR_Word) type_info_string, type_list);
+ type_list = MR_string_list_cons((MR_Word) type_info_string,
+ type_list);
);
}
@@ -1217,11 +1205,9 @@
MR_Word univ;
var_number = MR_get_var_number(debugger_request);
- /* debugger_request should be of the form:
- current_nth_var(var_number) */
+ /* debugger_request should be of the form: current_nth_var(var_number) */
- problem = MR_trace_return_var_info(var_number, NULL,
- &type_info, &value);
+ problem = MR_trace_return_var_info(var_number, NULL, &type_info, &value);
if (problem == NULL) {
MR_TRACE_USE_HP(
MR_new_univ_on_hp(univ, type_info, value);
@@ -1231,6 +1217,7 @@
** Should never occur since we check in the external debugger
** process if a variable is live before retrieving it.
*/
+
MR_fatal_error(problem);
}
@@ -1301,26 +1288,24 @@
if (base_sp != NULL && base_curfr != NULL) {
MR_bool print_details = MR_FALSE;
if (MR_PROC_LAYOUT_HAS_EXEC_TRACE(entry)) {
- MR_Integer maybe_from_full =
- entry->MR_sle_maybe_from_full;
+ MR_Integer maybe_from_full = entry->MR_sle_maybe_from_full;
if (maybe_from_full > 0) {
/*
- ** for procedures compiled with shallow
- ** tracing, the details will be valid only
- ** if the value of MR_from_full saved in
+ ** For procedures compiled with shallow tracing, the details
+ ** will be valid only if the value of MR_from_full saved in
** the appropriate stack slot was MR_TRUE.
*/
if (MR_DETISM_DET_STACK(entry->MR_sle_detism)) {
- print_details = MR_based_stackvar(
- base_sp, maybe_from_full);
+ print_details = MR_based_stackvar(base_sp,
+ maybe_from_full);
} else {
- print_details = MR_based_framevar(
- base_curfr, maybe_from_full);
+ print_details = MR_based_framevar(base_curfr,
+ maybe_from_full);
}
} else {
/*
- ** for procedures compiled with full tracing,
- ** always print out the details
+ ** For procedures compiled with full tracing,
+ ** always print out the details.
*/
print_details = MR_TRUE;
}
@@ -1329,21 +1314,15 @@
if (MR_DETISM_DET_STACK(entry->MR_sle_detism)) {
MR_send_message_to_socket_format(
"detail(%lu, %lu, %lu).\n",
- (unsigned long)
- MR_event_num_stackvar(base_sp) + 1,
- (unsigned long)
- MR_call_num_stackvar(base_sp),
- (unsigned long)
- MR_call_depth_stackvar(base_sp));
+ (unsigned long) MR_event_num_stackvar(base_sp) + 1,
+ (unsigned long) MR_call_num_stackvar(base_sp),
+ (unsigned long) MR_call_depth_stackvar(base_sp));
} else {
MR_send_message_to_socket_format(
"detail(%lu, %lu, %lu).\n",
- (unsigned long)
- MR_event_num_framevar(base_curfr) + 1,
- (unsigned long)
- MR_call_num_framevar(base_curfr),
- (unsigned long)
- MR_call_depth_framevar(base_curfr));
+ (unsigned long) MR_event_num_framevar(base_curfr) + 1,
+ (unsigned long) MR_call_num_framevar(base_curfr),
+ (unsigned long) MR_call_depth_framevar(base_curfr));
}
}
}
@@ -1368,9 +1347,7 @@
} else {
if (entry->MR_sle_user.MR_user_pred_or_func == MR_PREDICATE) {
MR_send_message_to_socket("pred");
- } else if (entry->MR_sle_user.MR_user_pred_or_func ==
- MR_FUNCTION)
- {
+ } else if (entry->MR_sle_user.MR_user_pred_or_func == MR_FUNCTION) {
MR_send_message_to_socket("func");
} else {
MR_fatal_error("procedure is not pred or func");
@@ -1387,8 +1364,7 @@
if (strcmp(entry->MR_sle_user.MR_user_decl_module,
entry->MR_sle_user.MR_user_def_module) != 0)
{
- MR_send_message_to_socket_format(
- "def_module(\"%s\").\n",
+ MR_send_message_to_socket_format("def_module(\"%s\").\n",
entry->MR_sle_user.MR_user_def_module);
}
}
@@ -1403,10 +1379,8 @@
MR_Integer *modules_list_length_ptr, MR_Word *modules_list_ptr)
{
MR_TRACE_CALL_MERCURY(
- ML_DI_get_list_modules_to_import(
- debugger_request,
- modules_list_length_ptr,
- modules_list_ptr);
+ ML_DI_get_list_modules_to_import(debugger_request,
+ modules_list_length_ptr, modules_list_ptr);
);
}
@@ -1414,19 +1388,16 @@
MR_get_mmc_options(MR_Word debugger_request, MR_String *mmc_options_ptr)
{
MR_TRACE_CALL_MERCURY(
- ML_DI_get_mmc_options(
- debugger_request,
- mmc_options_ptr);
+ ML_DI_get_mmc_options(debugger_request, mmc_options_ptr);
);
}
static void
-MR_get_object_file_name(MR_Word debugger_request, MR_String *object_file_name_ptr)
+MR_get_object_file_name(MR_Word debugger_request,
+ MR_String *object_file_name_ptr)
{
MR_TRACE_CALL_MERCURY(
- ML_DI_get_object_file_name(
- debugger_request,
- object_file_name_ptr);
+ ML_DI_get_object_file_name(debugger_request, object_file_name_ptr);
);
}
@@ -1434,9 +1405,7 @@
MR_get_variable_name(MR_Word debugger_request, MR_String *var_name_ptr)
{
MR_TRACE_CALL_MERCURY(
- ML_DI_get_variable_name(
- debugger_request,
- var_name_ptr);
+ ML_DI_get_variable_name(debugger_request, var_name_ptr);
);
}
@@ -1506,13 +1475,15 @@
lineno,
MR_accumulator_variable,
&MR_accumulator_variable,
- &result));
+ &result)
+ );
*stop_collecting = (result == 'y');
}
/*
** This function retrieves the line number of the current goal.
*/
+
int
MR_get_line_number(MR_Word *saved_regs, const MR_Label_Layout *layout,
MR_Trace_Port port)
@@ -1521,25 +1492,26 @@
const MR_Label_Layout *parent_layout;
const char *problem;
int lineno = 0;
- MR_Word *base_sp, *base_curfr;
+ MR_Word *base_sp;
+ MR_Word *base_curfr;
- if MR_port_is_interface(port)
+ if MR_port_is_interface(port) {
/*
- ** At external events, we want the line number
- ** where the call is made, not the one where the
- ** procedure is defined.
+ ** At external events, we want the line number where the call is made,
+ ** not the one where the procedure is defined.
*/
- {
+
base_sp = MR_saved_sp(saved_regs);
base_curfr = MR_saved_curfr(saved_regs);
- parent_layout = MR_find_nth_ancestor(layout, 1,
- &base_sp, &base_curfr, &problem);
+ parent_layout = MR_find_nth_ancestor(layout, 1, &base_sp, &base_curfr,
+ &problem);
if (parent_layout != NULL) {
(void) MR_find_context(parent_layout, &filename, &lineno);
}
} else {
(void) MR_find_context(layout, &filename, &lineno);
- } ;
+ }
+
return lineno;
}
@@ -1547,16 +1519,15 @@
MR_send_collect_result(void)
{
MR_TRACE_CALL_MERCURY(
- (*post_process_ptr)(
- MR_accumulator_variable,
- &MR_collected_variable);
+ (*post_process_ptr)(MR_accumulator_variable, &MR_collected_variable);
+
+ (*send_collect_result_ptr)(MR_collected_variable,
+ (MR_Word) &MR_debugger_socket_out)
+ );
- (*send_collect_result_ptr)(
- MR_collected_variable,
- (MR_Word) &MR_debugger_socket_out));
#if defined(MR_HAVE_DLFCN_H) && defined(MR_HAVE_DLCLOSE)
- MR_TRACE_CALL_MERCURY(
- ML_CL_unlink_collect(collect_lib_maybe_handle));
+ MR_TRACE_CALL_MERCURY(ML_CL_unlink_collect(collect_lib_maybe_handle));
#endif
}
+
#endif /* MR_USE_EXTERNAL_DEBUGGER */
Index: trace/mercury_trace_internal.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/trace/mercury_trace_internal.c,v
retrieving revision 1.222
diff -u -b -r1.222 mercury_trace_internal.c
--- trace/mercury_trace_internal.c 31 Mar 2006 05:12:18 -0000 1.222
+++ trace/mercury_trace_internal.c 3 Apr 2006 12:38:24 -0000
@@ -8,7 +8,9 @@
*/
/*
-** This file contains the code of the internal, in-process debugger.
+** This file contains the top level of the code of the internal, in-process
+** debugger. The functions implementing the commands themselves are in the
+** files mercury_trac_cmd_*.c.
**
** Main author: Zoltan Somogyi.
*/
@@ -23,6 +25,7 @@
#include "mercury_trace.h"
#include "mercury_trace_internal.h"
+#include "mercury_trace_cmds.h"
#include "mercury_trace_declarative.h"
#include "mercury_trace_alias.h"
#include "mercury_trace_help.h"
@@ -35,6 +38,19 @@
#include "mercury_trace_readline.h"
#include "mercury_trace_source.h"
+#include "mercury_trace_cmd_forward.h"
+#include "mercury_trace_cmd_backward.h"
+#include "mercury_trace_cmd_browsing.h"
+#include "mercury_trace_cmd_breakpoint.h"
+#include "mercury_trace_cmd_queries.h"
+#include "mercury_trace_cmd_table_io.h"
+#include "mercury_trace_cmd_parameter.h"
+#include "mercury_trace_cmd_help.h"
+#include "mercury_trace_cmd_dd.h"
+#include "mercury_trace_cmd_misc.h"
+#include "mercury_trace_cmd_exp.h"
+#include "mercury_trace_cmd_developer.h"
+
#include "mdb.browse.mh"
#include "mdb.listing.mh"
#include "mdb.diff.mh"
@@ -86,28 +102,10 @@
/* The initial size of arrays of words. */
#define MR_INIT_WORD_COUNT 20
-/* The initial number of lines in documentation entries. */
-#define MR_INIT_DOC_CHARS 800
-
/* An upper bound on the maximum number of characters in a number. */
/* If a number has more than this many chars, the user is in trouble. */
#define MR_NUMBER_LEN 80
-/*
-** The default number of lines to display for a dice.
-*/
-
-#define MR_DEFAULT_DICE_LINES 50
-
-/*
-** The message to print for retries through un-io-tabled areas, when
-** the MR_RETRY_IO_INTERACTIVE option is given.
-*/
-
-#define MR_UNTABLED_IO_RETRY_MESSAGE \
- "Retry across I/O operations is not always safe.\n" \
- "Are you sure you want to do it? "
-
#define MDBRC_FILENAME ".mdbrc"
#define DEFAULT_MDBRC_FILENAME "mdbrc"
@@ -141,32 +139,6 @@
FILE *MR_mdb_out;
FILE *MR_mdb_err;
-static MR_Trace_Print_Level MR_default_print_level = MR_PRINT_LEVEL_SOME;
-
-/*
-** These variables say (a) whether the printing of event sequences will pause
-** after each screenful of events, (b) how may events constitute a screenful
-** (although we count only events, not how many lines they take up), and (c)
-** how many events we have printed so far in this screenful.
-*/
-
-static MR_bool MR_scroll_control = MR_TRUE;
-static int MR_scroll_limit = 24;
-static int MR_scroll_next = 0;
-
-/*
-** This variable controls the number of stack frame lines printed by the stack
-** and nondet_stack commands if the user doesn't override it.
-*/
-
-static int MR_stack_default_line_limit = 0;
-
-/*
-** We echo each command just as it is executed iff this variable is MR_TRUE.
-*/
-
-static MR_bool MR_echo_commands = MR_FALSE;
-
/*
** MR_have_mdb_window and MR_mdb_window_pid are set by
** mercury_trace_internal.c after the xterm window for
@@ -184,258 +156,14 @@
** The details of the source server, if any.
*/
-static MR_Trace_Source_Server MR_trace_source_server =
+MR_Trace_Source_Server MR_trace_source_server =
{ NULL, NULL, MR_FALSE };
-/*
-** We print confirmation of commands (e.g. new aliases) if this is MR_TRUE.
-*/
-
-static MR_bool MR_trace_internal_interacting = MR_FALSE;
-
-/*
-** We include values of sometimes-useful types such as typeinfos in the set of
-** variables whose values we collect at events for possible later printing
-** only if MR_print_optionals is true.
-*/
-
-static MR_bool MR_print_optionals = MR_FALSE;
-
-/*
-** This variable holds either the name of a file which contains a list of
-** the file names of passing test case trace counts, or the name of a single
-** file of passing test case trace counts.
-*/
-
-static char *MR_dice_pass_trace_counts_file = NULL;
-
-/*
-** This variable holds either the name of a file which contains a list of
-** the file names of failing test case trace counts, or the name of a single
-** file of failing test case trace counts.
-*/
-
-static char *MR_dice_fail_trace_counts_file = NULL;
-
-/*
-** MR_context_position specifies whether we print context at events,
-** and if so, where.
-*/
-
-static MR_Context_Position MR_context_position = MR_CONTEXT_AFTER;
-
-/*
-** MR_print_goal_paths specifies whether we print goal paths at events.
-*/
-
-static MR_bool MR_print_goal_paths = MR_TRUE;
-
-/*
-** MR_listing_path holds the current value of the listings structure
-** as defined in browser/listing.m.
-*/
-
-static MR_Word MR_listing_path;
-
-/*
-** MR_num_context_lines holds the current number of context lines to be
-** printed before and after the current callee/caller's file context.
-*/
-
-static int MR_num_context_lines = 2;
-
-typedef struct MR_Line_Struct {
- char *MR_line_contents;
- struct MR_Line_Struct *MR_line_next;
-} MR_Line;
+MR_bool MR_trace_internal_interacting = MR_FALSE;
static MR_Line *MR_line_head = NULL;
static MR_Line *MR_line_tail = NULL;
-typedef enum {
- KEEP_INTERACTING,
- STOP_INTERACTING
-} MR_Next;
-
-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.",
-};
-
-static MR_Spy_When MR_default_breakpoint_scope = MR_SPY_INTERFACE;
-
-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",
-};
-
-typedef enum {
- MR_MULTIMATCH_ASK, MR_MULTIMATCH_ALL, MR_MULTIMATCH_ONE
-} MR_MultiMatch;
-
-/*
-** We keep a table of the available commands. The information we have about
-** each command is stored in a value of type MR_Trace_Command_Info.
-**
-** The name of the command itself is stored in the name field; the category
-** field contains name of the category to which the command belongs,
-** e.g. "browsing".
-**
-** The code that the command loop should execute to handle a command of a given
-** type is the function pointed to by the function field.
-**
-** Some commands take fixed strings as arguments. The arg_strings field
-** is a NULL terminated array of those strings, or NULL if there are
-** no fixed strings.
-**
-** The arg_completer field contains the address of a function for more
-** arbitrary completion, e.g. on predicate names. This field should not be
-** null; if the command cannot use a completion function, the field should
-** contain MR_trace_null_completer.
-*/
-
-typedef MR_Next MR_Trace_Command_Function(char **words, int word_count,
- MR_Trace_Cmd_Info *cmd, MR_Event_Info *event_info, MR_Code **jumpaddr);
-
-typedef struct
-{
- const char *MR_cmd_category;
- const char *MR_cmd_name;
- MR_Trace_Command_Function *MR_cmd_function;
- const char *const *MR_cmd_arg_strings;
- const MR_Make_Completer MR_cmd_arg_completer;
-} MR_Trace_Command_Info;
-
-/*
-** The following data structures describe the information we have about the
-** input arguments of tabled procedures. We use them to decode the call tables
-** of such procedures.
-**
-** We use one MR_Call_Table_Arg structure for each input argument.
-**
-** The step field specifies what data structure the tabling system uses to
-** implement the trie nodes at the level of the call table corresponding to
-** the relevant argument. At the moment, we support only four values of this
-** field, MR_TABLE_STEP_INT, MR_TABLE_STEP_FLOAT, MR_TABLE_STEP_STRING and
-** MR_TABLE_STEP_PROMISE_IMPLIED. The first three of these implicitly select
-** the corresponding alternative in the arg_values union; the last one
-** indicates the absence of a step.
-**
-** The start_node field specifies the start node of the relevant trie. For the
-** first input argument, this will be the tabling pointer variable for the
-** given procedure. For later input arguments, it will be the trie node you
-** reach after following the current values of the previous arguments through
-** the call table.
-**
-** The MR_{Int,Float,String}_Table_Arg_Values structs have the same fields and
-** the same meanings, differing only in the types of the values they store.
-** Each struct is used for one of two things.
-**
-** 1. To describe a value supplied by the user on the mdb command line.
-** In this case, the only field that matters is the cur_value field.
-**
-** 2. To describe the set of values you can find in a trie node, the one given
-** by the start_node field, and to specify which is the current one.
-** In this case, all the fields matter.
-**
-** The code that manipulates these structures distinguishes between the two
-** uses based on argument number.
-**
-** The values array is managed with the macros in mercury_array_macros.h,
-** so its size is given by the value_next field. The cur_index field gives the
-** index of the current value, while the cur_value field gives the current
-** value itself. (The contents of the cur_value field can be deduced from the
-** contents of the other fields with use 2, but not with use 1.)
-**
-** The valid field in the MR_Call_Table_Arg structure gives the validity
-** of the values subfield of its arg_values field; if it is false, then the
-** array is logically considered empty.
-*/
-
-typedef struct {
- MR_Integer *MR_ctai_values;
- int MR_ctai_value_next;
- int MR_ctai_cur_index;
- MR_Integer MR_ctai_cur_value;
-} MR_Int_Table_Arg_Values;
-
-typedef struct {
- MR_Float *MR_ctaf_values;
- int MR_ctaf_value_next;
- int MR_ctaf_cur_index;
- MR_Float MR_ctaf_cur_value;
-} MR_Float_Table_Arg_Values;
-
-typedef struct {
- MR_ConstString *MR_ctas_values;
- int MR_ctas_value_next;
- int MR_ctas_cur_index;
- MR_ConstString MR_ctas_cur_value;
-} MR_String_Table_Arg_Values;
-
-typedef union {
- MR_Int_Table_Arg_Values MR_cta_values_int;
- MR_Float_Table_Arg_Values MR_cta_values_float;
- MR_String_Table_Arg_Values MR_cta_values_string;
-} MR_Table_Arg_Values;
-
-typedef struct {
- MR_Table_Trie_Step MR_cta_step;
- int MR_cta_unfiltered_arg_num;
- MR_TrieNode MR_cta_start_node;
- MR_bool MR_cta_valid;
- MR_Table_Arg_Values MR_cta_arg_values;
-} MR_Call_Table_Arg;
-
-#define MR_cta_int_values MR_cta_arg_values.MR_cta_values_int.\
- MR_ctai_values
-#define MR_cta_int_value_next MR_cta_arg_values.MR_cta_values_int.\
- MR_ctai_value_next
-#define MR_cta_int_cur_index MR_cta_arg_values.MR_cta_values_int.\
- MR_ctai_cur_index
-#define MR_cta_int_cur_value MR_cta_arg_values.MR_cta_values_int.\
- MR_ctai_cur_value
-
-#define MR_cta_float_values MR_cta_arg_values.MR_cta_values_float.\
- MR_ctaf_values
-#define MR_cta_float_value_next MR_cta_arg_values.MR_cta_values_float.\
- MR_ctaf_value_next
-#define MR_cta_float_cur_index MR_cta_arg_values.MR_cta_values_float.\
- MR_ctaf_cur_index
-#define MR_cta_float_cur_value MR_cta_arg_values.MR_cta_values_float.\
- MR_ctaf_cur_value
-
-#define MR_cta_string_values MR_cta_arg_values.MR_cta_values_string.\
- MR_ctas_values
-#define MR_cta_string_value_next MR_cta_arg_values.MR_cta_values_string.\
- MR_ctas_value_next
-#define MR_cta_string_cur_index MR_cta_arg_values.MR_cta_values_string.\
- MR_ctas_cur_index
-#define MR_cta_string_cur_value MR_cta_arg_values.MR_cta_values_string.\
- MR_ctas_cur_value
-
static void MR_trace_internal_ensure_init(void);
static MR_bool MR_trace_internal_create_mdb_window(void);
static void MR_trace_internal_kill_mdb_window(void);
@@ -445,332 +173,28 @@
static MR_Next MR_trace_debug_cmd(char *line, MR_Trace_Cmd_Info *cmd,
MR_Event_Info *event_info, MR_Code **jumpaddr);
-typedef MR_Next MR_TraceCmdFunc(char **words, int word_count,
- MR_Trace_Cmd_Info *cmd, MR_Event_Info *event_info,
- MR_Code **jumpaddr);
-
static MR_TraceCmdFunc MR_trace_handle_cmd;
-static MR_TraceCmdFunc MR_trace_cmd_step;
-static MR_TraceCmdFunc MR_trace_cmd_goto;
-static MR_TraceCmdFunc MR_trace_cmd_next;
-static MR_TraceCmdFunc MR_trace_cmd_finish;
-static MR_TraceCmdFunc MR_trace_cmd_fail;
-static MR_TraceCmdFunc MR_trace_cmd_exception;
-static MR_TraceCmdFunc MR_trace_cmd_return;
-static MR_TraceCmdFunc MR_trace_cmd_forward;
-static MR_TraceCmdFunc MR_trace_cmd_mindepth;
-static MR_TraceCmdFunc MR_trace_cmd_maxdepth;
-static MR_TraceCmdFunc MR_trace_cmd_continue;
-static MR_TraceCmdFunc MR_trace_cmd_retry;
-static MR_TraceCmdFunc MR_trace_cmd_level;
-static MR_TraceCmdFunc MR_trace_cmd_up;
-static MR_TraceCmdFunc MR_trace_cmd_down;
-static MR_TraceCmdFunc MR_trace_cmd_vars;
-static MR_TraceCmdFunc MR_trace_cmd_held_vars;
-static MR_TraceCmdFunc MR_trace_cmd_print;
-static MR_TraceCmdFunc MR_trace_cmd_browse;
-static MR_TraceCmdFunc MR_trace_cmd_stack;
-static MR_TraceCmdFunc MR_trace_cmd_current;
-static MR_TraceCmdFunc MR_trace_cmd_set;
-static MR_TraceCmdFunc MR_trace_cmd_view;
-static MR_TraceCmdFunc MR_trace_cmd_hold;
-static MR_TraceCmdFunc MR_trace_cmd_diff;
-static MR_TraceCmdFunc MR_trace_cmd_dump;
-static MR_TraceCmdFunc MR_trace_cmd_list;
-static MR_TraceCmdFunc MR_trace_cmd_set_list_dir_path;
-static MR_TraceCmdFunc MR_trace_cmd_push_list_dir;
-static MR_TraceCmdFunc MR_trace_cmd_pop_list_dir;
-static MR_TraceCmdFunc MR_trace_cmd_break;
-static MR_TraceCmdFunc MR_trace_cmd_condition;
-static MR_TraceCmdFunc MR_trace_cmd_ignore;
-static MR_TraceCmdFunc MR_trace_cmd_break_print;
-static MR_TraceCmdFunc MR_trace_cmd_enable;
-static MR_TraceCmdFunc MR_trace_cmd_disable;
-static MR_TraceCmdFunc MR_trace_cmd_delete;
-static MR_TraceCmdFunc MR_trace_cmd_register;
-static MR_TraceCmdFunc MR_trace_cmd_modules;
-static MR_TraceCmdFunc MR_trace_cmd_procedures;
-static MR_TraceCmdFunc MR_trace_cmd_query;
-static MR_TraceCmdFunc MR_trace_cmd_cc_query;
-static MR_TraceCmdFunc MR_trace_cmd_io_query;
-static MR_TraceCmdFunc MR_trace_cmd_printlevel;
-static MR_TraceCmdFunc MR_trace_cmd_mmc_options;
-static MR_TraceCmdFunc MR_trace_cmd_scroll;
-static MR_TraceCmdFunc MR_trace_cmd_stack_default_limit;
-static MR_TraceCmdFunc MR_trace_cmd_context;
-static MR_TraceCmdFunc MR_trace_cmd_goal_paths;
-static MR_TraceCmdFunc MR_trace_cmd_scope;
-static MR_TraceCmdFunc MR_trace_cmd_echo;
-static MR_TraceCmdFunc MR_trace_cmd_alias;
-static MR_TraceCmdFunc MR_trace_cmd_unalias;
-static MR_TraceCmdFunc MR_trace_cmd_document_category;
-static MR_TraceCmdFunc MR_trace_cmd_document;
-static MR_TraceCmdFunc MR_trace_cmd_help;
-static MR_TraceCmdFunc MR_trace_cmd_histogram_all;
-static MR_TraceCmdFunc MR_trace_cmd_histogram_exp;
-static MR_TraceCmdFunc MR_trace_cmd_clear_histogram;
-static MR_TraceCmdFunc MR_trace_cmd_var_details;
-static MR_TraceCmdFunc MR_trace_cmd_term_size;
-static MR_TraceCmdFunc MR_trace_cmd_flag;
-static MR_TraceCmdFunc MR_trace_cmd_subgoal;
-static MR_TraceCmdFunc MR_trace_cmd_consumer;
-static MR_TraceCmdFunc MR_trace_cmd_gen_stack;
-static MR_TraceCmdFunc MR_trace_cmd_cut_stack;
-static MR_TraceCmdFunc MR_trace_cmd_pneg_stack;
-static MR_TraceCmdFunc MR_trace_cmd_mm_stacks;
-static MR_TraceCmdFunc MR_trace_cmd_nondet_stack;
-static MR_TraceCmdFunc MR_trace_cmd_stack_regs;
-static MR_TraceCmdFunc MR_trace_cmd_all_regs;
-static MR_TraceCmdFunc MR_trace_cmd_debug_vars;
-static MR_TraceCmdFunc MR_trace_cmd_table_io;
-static MR_TraceCmdFunc MR_trace_cmd_stats;
-static MR_TraceCmdFunc MR_trace_cmd_proc_body;
-static MR_TraceCmdFunc MR_trace_cmd_print_optionals;
-static MR_TraceCmdFunc MR_trace_cmd_unhide_events;
-static MR_TraceCmdFunc MR_trace_cmd_table;
-static MR_TraceCmdFunc MR_trace_cmd_type_ctor;
-static MR_TraceCmdFunc MR_trace_cmd_class_decl;
-static MR_TraceCmdFunc MR_trace_cmd_all_type_ctors;
-static MR_TraceCmdFunc MR_trace_cmd_all_class_decls;
-static MR_TraceCmdFunc MR_trace_cmd_all_procedures;
-static MR_TraceCmdFunc MR_trace_cmd_ambiguity;
-static MR_TraceCmdFunc MR_trace_cmd_save;
-static MR_TraceCmdFunc MR_trace_cmd_quit;
-static MR_TraceCmdFunc MR_trace_cmd_dd;
-static MR_TraceCmdFunc MR_trace_cmd_trust;
-static MR_TraceCmdFunc MR_trace_cmd_untrust;
-static MR_TraceCmdFunc MR_trace_cmd_trusted;
-static MR_TraceCmdFunc MR_trace_cmd_dice;
-
-static void MR_maybe_print_spy_point(int slot, const char *problem);
-static void MR_print_unsigned_var(FILE *fp, const char *var,
- MR_Unsigned value);
-static MR_bool MR_parse_source_locn(char *word, const char **file,
- int *line);
-static const char *MR_trace_new_source_window(const char *window_cmd,
- const char *server_cmd, const char *server_name,
- int timeout, MR_bool force, MR_bool verbose,
- MR_bool split);
-static void MR_trace_maybe_sync_source_window(
- MR_Event_Info *event_info, MR_bool verbose);
-static void MR_trace_maybe_close_source_window(MR_bool verbose);
-
-static void MR_trace_cmd_stack_2(MR_Event_Info *event_info,
- MR_bool detailed, int frame_limit, int line_limit);
-static void MR_trace_cmd_nondet_stack_2(MR_Event_Info *event_info,
- MR_bool detailed, int frame_limit, int line_limit);
-static MR_Spy_Print_List MR_add_to_print_list_end(MR_Browse_Format format,
- char *word, MR_bool warn,
- MR_Spy_Print_List print_list);
-
-static MR_bool MR_trace_options_movement_cmd(MR_Trace_Cmd_Info *cmd,
- char ***words, int *word_count);
-static MR_bool MR_trace_options_retry(MR_Retry_Across_Io *across_io,
- MR_bool *assume_all_io_is_tabled,
- char ***words, int *word_count);
-static MR_bool MR_trace_options_when_action_multi_ignore(MR_Spy_When *when,
- MR_Spy_Action *action, MR_MultiMatch *multi_match,
- MR_Spy_Ignore_When *ignore_when, int *ignore_count,
- MR_Spy_Print_List *print_list,
- char ***words, int *word_count);
-static MR_bool MR_trace_options_condition(int *break_num,
- MR_bool *require_var, MR_bool *require_path,
- char ***words, int *word_count);
-static MR_bool MR_trace_options_ignore_count(
- MR_Spy_Ignore_When *ignore_when,
- int *ignore_count, char ***words, int *word_count);
-static MR_bool MR_trace_options_quiet(MR_bool *verbose, char ***words,
- int *word_count);
-static MR_bool MR_trace_options_ignore(MR_bool *ignore_errors,
- char ***words, int *word_count);
-static MR_bool MR_trace_options_break_print(MR_Browse_Format *format,
- MR_bool *at_start, MR_bool *warn, char ***words,
- int *word_count);
-static MR_bool MR_trace_options_detailed(MR_bool *detailed, char ***words,
- int *word_count);
-static MR_bool MR_trace_options_stack_trace(MR_bool *detailed,
- int *frame_limit, char ***words, int *word_count);
-static MR_bool MR_trace_options_confirmed(MR_bool *confirmed,
- char ***words, int *word_count);
-static MR_bool MR_trace_options_format(MR_Browse_Format *format,
- MR_bool *xml, char ***words, int *word_count);
-static MR_bool MR_trace_options_param_set(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);
-static MR_bool MR_trace_options_view(const char **window_cmd,
- const char **server_cmd, const char **server_name,
- int *timeout, MR_bool *force, MR_bool *verbose,
- MR_bool *split, MR_bool *close_window, char ***words,
- int *word_count);
-static MR_bool MR_trace_options_dd(MR_bool *assume_all_io_is_tabled,
- MR_Unsigned *default_depth, MR_Unsigned *num_nodes,
- MR_Decl_Search_Mode *search_mode,
- MR_bool *search_mode_was_set,
- MR_bool *search_mode_requires_trace_counts,
- char **pass_trace_counts_file,
- char **fail_trace_counts_file,
- MR_bool *new_session, MR_bool *testing, MR_bool *debug,
- char ***words, int *word_count);
-static MR_bool MR_trace_options_stats(char **filename, char ***words,
- int *word_count);
-static MR_bool MR_trace_options_type_ctor(MR_bool *print_rep,
- MR_bool *print_functors, char ***words,
- int *word_count);
-static MR_bool MR_trace_options_class_decl(MR_bool *print_methods,
- MR_bool *print_instances, char ***words,
- int *word_count);
-static MR_bool MR_trace_options_all_procedures(MR_bool *separate,
- MR_bool *uci, char **module, char ***words,
- int *word_count);
-static MR_bool MR_trace_options_ambiguity(const char **outfile,
- char ***words, int *word_count);
-static MR_bool MR_trace_options_diff(int *start, int *max,
- char ***words, int *word_count);
-static MR_bool MR_trace_options_dump(MR_bool *xml,
- char ***words, int *word_count);
-static MR_bool MR_trace_options_dice(char **pass_trace_counts_file,
- char **fail_trace_count_file, char **sort_str,
- int *number_of_lines, char **out_file, char **module,
- char ***words, int *word_count);
-static void MR_trace_usage_cur_cmd(void);
-static void MR_trace_do_noop(void);
static void MR_mdb_print_proc_id_and_nl(void *data,
const MR_Proc_Layout *entry_layout);
static int MR_trace_var_print_list(MR_Spy_Print_List print_list);
-static void MR_trace_print_dice(char *pass_trace_counts_file,
- char *fail_trace_counts_file, char *sort_str,
- int number_of_lines, char *out_str, char *module);
-static void MR_trace_listing_path_ensure_init(void);
-
-static const MR_Proc_Layout *MR_find_single_matching_proc(MR_Proc_Spec *spec,
- MR_bool verbose);
-
-/*
-** These functions fill in the data structure describing one input argument
-** of a tabled procedure with a constant value given on the mdb command line.
-** They return true if they succeed, and false if they fail (e.g. because the
-** string given on the mdb command line does not describe a value of the
-** required type).
-*/
-
-static MR_bool MR_trace_fill_in_int_table_arg_slot(
- MR_TrieNode *table_cur_ptr,
- int arg_num, MR_ConstString given_arg,
- MR_Call_Table_Arg *call_table_arg_ptr);
-static MR_bool MR_trace_fill_in_float_table_arg_slot(
- MR_TrieNode *table_cur_ptr,
- int arg_num, MR_ConstString given_arg,
- MR_Call_Table_Arg *call_table_arg_ptr);
-static MR_bool MR_trace_fill_in_string_table_arg_slot(
- MR_TrieNode *table_cur_ptr,
- int arg_num, MR_ConstString given_arg,
- MR_Call_Table_Arg *call_table_arg_ptr);
-
-/*
-** These functions fill in the data structure describing one input argument
-** of a tabled procedure with the next value taken from the given trie node.
-** They return true if there are no more values in the trie node, and false
-** otherwise.
-*/
-static MR_bool MR_update_int_table_arg_slot(MR_TrieNode *table_cur_ptr,
- MR_Call_Table_Arg *call_table_arg_ptr);
-static MR_bool MR_update_float_table_arg_slot(MR_TrieNode *table_cur_ptr,
- MR_Call_Table_Arg *call_table_arg_ptr);
-static MR_bool MR_update_string_table_arg_slot(MR_TrieNode *table_cur_ptr,
- MR_Call_Table_Arg *call_table_arg_ptr);
-
-/* Prints the given subgoal of the given procedure to MR_mdb_out. */
-static void MR_trace_cmd_table_print_tip(const MR_Proc_Layout *proc,
- int filtered_num_inputs,
- MR_Call_Table_Arg *call_table_args, MR_TrieNode table);
-
-/* Prints the given subgoal of the given procedure to MR_mdb_out. */
-static void MR_trace_print_subgoal(const MR_Proc_Layout *proc,
- MR_Subgoal *subgoal);
-static void MR_trace_print_subgoal_debug(const MR_Proc_Layout *proc,
- MR_SubgoalDebug *subgoal_debug);
-
-/* Prints the given generator of the given procedure to MR_mdb_out. */
-static void MR_trace_print_generator(const MR_Proc_Layout *proc,
- MR_Generator *generator);
-static void MR_trace_print_generator_debug(const MR_Proc_Layout *proc,
- MR_GenDebug *generator_debug);
-
-/* Prints the given consumer of the given procedure to MR_mdb_out. */
-static void MR_trace_print_consumer(const MR_Proc_Layout *proc,
- MR_Consumer *consumer);
-static void MR_trace_print_consumer_debug(const MR_Proc_Layout *proc,
- MR_ConsumerDebug *consumer_debug);
-
-/* Prints the requested information inside the given MR_TypeCtorInfo. */
-static void MR_print_type_ctor_info(FILE *fp,
- MR_TypeCtorInfo type_ctor_info,
- MR_bool print_rep, MR_bool print_functors);
-/* Prints the requested information inside the given MR_TypeClassDeclInfo. */
-static void MR_print_class_decl_info(FILE *fp,
- MR_TypeClassDeclInfo *type_class_decl_info,
- MR_bool print_methods, MR_bool print_instances);
-/* Print the given pseudo-typeinfo. */
-static void MR_print_pseudo_type_info(FILE *fp,
- MR_PseudoTypeInfo pseudo);
-
-static void MR_trace_set_level_and_report(int ancestor_level,
- MR_bool detailed, MR_bool print_optionals);
-static void MR_trace_browse_internal(MR_Word type_info, MR_Word value,
- MR_Browse_Caller_Type caller, MR_Browse_Format format);
-static void MR_trace_browse_goal_internal(MR_ConstString name,
- MR_Word arg_list, MR_Word is_func,
- MR_Browse_Caller_Type caller, MR_Browse_Format format);
-static const char *MR_trace_browse_exception(MR_Event_Info *event_info,
- MR_Browser browser, MR_Browse_Caller_Type caller,
- MR_Browse_Format format);
-static const char *MR_trace_browse_proc_body(MR_Event_Info *event_info,
- MR_Browser browser, MR_Browse_Caller_Type caller,
- MR_Browse_Format format);
-
-/* Functions to invoke the user's XML browser on terms or goals */
-static void MR_trace_browse_xml(MR_Word type_info, MR_Word value,
- MR_Browse_Caller_Type caller, MR_Browse_Format format);
-static void MR_trace_browse_goal_xml(MR_ConstString name,
- MR_Word arg_list, MR_Word is_func,
- MR_Browse_Caller_Type caller, MR_Browse_Format format);
-
-static const char *MR_trace_read_help_text(void);
static const char *MR_trace_parse_line(char *line, char ***words,
int *word_max, int *word_count);
static const char *MR_trace_break_into_words(char *line, char ***words_ptr,
int *word_max_ptr, int *word_count_ptr);
static const char *MR_trace_break_off_one_word(char *line, int char_pos,
int *new_char_pos_ptr);
-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);
-static char *MR_trace_getline_queue(void);
static MR_bool MR_trace_continue_line(char *ptr, MR_bool *single_quoted,
MR_bool *double_quoted);
static MR_Code *MR_trace_event_internal_report(MR_Trace_Cmd_Info *cmd,
MR_Spy_Print_List print_list,
MR_Event_Info *event_info);
-static void MR_insert_line_at_head(const char *line);
-static void MR_insert_line_at_tail(const char *line);
-
-static void MR_trace_event_print_internal_report(
- MR_Event_Info *event_info);
-
-static const MR_Trace_Command_Info *MR_trace_valid_command(
- const char *command);
-
static char *MR_trace_command_completer_next(const char *word,
size_t word_len, MR_Completer_Data *data);
-static MR_SavedDebugState MR_saved_debug_state;
+MR_SavedDebugState MR_saved_debug_state;
MR_Code *
MR_trace_event_internal(MR_Trace_Cmd_Info *cmd, MR_bool interactive,
@@ -798,6 +222,8 @@
#endif
MR_trace_internal_ensure_init();
+ MR_trace_browse_ensure_init();
+ MR_trace_listing_path_ensure_init();
if (MR_spy_point_cond_problem != NULL) {
fprintf(MR_mdb_err, "mdb: couldn't evaluate break point condition\n");
@@ -1252,160 +678,65 @@
MR_free(buf);
}
-static void
-MR_trace_set_level_and_report(int ancestor_level, MR_bool detailed,
- MR_bool print_optionals)
+MR_bool
+MR_trace_source(const char *filename, MR_bool ignore_errors)
{
- const char *problem;
- const MR_Proc_Layout *entry;
- MR_Word *base_sp;
- MR_Word *base_curfr;
- const char *filename;
- int lineno;
- int indent;
-
- problem = MR_trace_set_level(ancestor_level, print_optionals);
- if (problem == NULL) {
- fprintf(MR_mdb_out, "Ancestor level set to %d:\n",
- ancestor_level);
- MR_trace_current_level_details(&entry, &filename, &lineno,
- &base_sp, &base_curfr);
- fprintf(MR_mdb_out, "%4d ", ancestor_level);
- if (detailed) {
- /*
- ** We want to print the trace info first regardless
- ** of the value of MR_context_position.
- */
-
- MR_print_call_trace_info(MR_mdb_out, entry, base_sp, base_curfr);
- indent = 26;
- } else {
- indent = 5;
- }
+ FILE *fp;
- MR_print_proc_id_trace_and_context(MR_mdb_out, MR_FALSE,
- MR_context_position, entry, base_sp, base_curfr, "",
- filename, lineno, MR_FALSE, "", 0, indent);
- } else {
- fflush(MR_mdb_out);
- fprintf(MR_mdb_err, "%s.\n", problem);
+ if ((fp = fopen(filename, "r")) != NULL) {
+ MR_trace_source_from_open_file(fp);
+ fclose(fp);
+ return MR_TRUE;
}
-}
-
-static void
-MR_trace_browse_internal(MR_Word type_info, MR_Word value,
- MR_Browse_Caller_Type caller, MR_Browse_Format format)
-{
- switch (caller) {
-
- case MR_BROWSE_CALLER_BROWSE:
- MR_trace_browse(type_info, value, format);
- break;
- case MR_BROWSE_CALLER_PRINT:
- case MR_BROWSE_CALLER_PRINT_ALL:
- fprintf(MR_mdb_out, "\t");
+ if (! ignore_errors) {
fflush(MR_mdb_out);
- MR_trace_print(type_info, value, caller, format);
- break;
-
- default:
- MR_fatal_error("MR_trace_browse_internal: unknown caller type");
+ fprintf(MR_mdb_err, "%s: %s.\n", filename, strerror(errno));
}
-}
-static void
-MR_trace_browse_xml(MR_Word type_info, MR_Word value,
- MR_Browse_Caller_Type caller, MR_Browse_Format format)
-{
- MR_Word browser_term;
-
- browser_term = MR_type_value_to_browser_term((MR_TypeInfo) type_info,
- value);
-
- MR_trace_save_and_invoke_xml_browser(browser_term);
+ return MR_FALSE;
}
-static void
-MR_trace_browse_goal_internal(MR_ConstString name, MR_Word arg_list,
- MR_Word is_func, MR_Browse_Caller_Type caller, MR_Browse_Format format)
+void
+MR_trace_source_from_open_file(FILE *fp)
{
- switch (caller) {
+ char *contents;
+ MR_Line *line;
+ MR_Line *prev_line;
+ MR_Line *old_head;
- case MR_BROWSE_CALLER_BROWSE:
- MR_trace_browse_goal(name, arg_list, is_func, format);
- break;
+ prev_line = NULL;
+ old_head = MR_line_head;
- case MR_BROWSE_CALLER_PRINT:
- MR_trace_print_goal(name, arg_list, is_func, caller, format);
- break;
+ /*
+ ** Insert the sourced commands at the front of the command queue,
+ ** preserving their order in the sourced file.
+ */
- case MR_BROWSE_CALLER_PRINT_ALL:
- MR_fatal_error("MR_trace_browse_goal_internal: bad caller type");
+ while ((contents = MR_trace_readline_raw(fp)) != NULL) {
+ line = MR_NEW(MR_Line);
+ line->MR_line_contents = MR_copy_string(contents);
- default:
- MR_fatal_error("MR_trace_browse_goal_internal:"
- " unknown caller type");
+ if (prev_line == NULL) {
+ MR_line_head = line;
+ } else {
+ prev_line->MR_line_next = line;
}
-}
-
-static void
-MR_trace_browse_goal_xml(MR_ConstString name, MR_Word arg_list,
- MR_Word is_func, MR_Browse_Caller_Type caller, MR_Browse_Format format)
-{
- MR_Word browser_term;
-
- browser_term = MR_synthetic_to_browser_term(name, arg_list, is_func);
- MR_trace_save_and_invoke_xml_browser(browser_term);
-}
-
-static const char *
-MR_trace_browse_exception(MR_Event_Info *event_info, MR_Browser browser,
- MR_Browse_Caller_Type caller, MR_Browse_Format format)
-{
- MR_TypeInfo type_info;
- MR_Word value;
- MR_Word exception;
- if (event_info->MR_trace_port != MR_PORT_EXCEPTION) {
- return "command only available from EXCP ports";
+ prev_line = line;
}
- exception = MR_trace_get_exception_value();
- if (exception == (MR_Word) NULL) {
- return "missing exception value";
+ if (prev_line != NULL) {
+ prev_line->MR_line_next = old_head;
+ if (MR_line_tail == NULL) {
+ MR_line_tail = prev_line;
}
-
- MR_unravel_univ(exception, type_info, value);
-
- (*browser)((MR_Word) type_info, value, caller, format);
-
- return (const char *) NULL;
-}
-
-static const char *
-MR_trace_browse_proc_body(MR_Event_Info *event_info, MR_Browser browser,
- MR_Browse_Caller_Type caller, MR_Browse_Format format)
-{
- const MR_Proc_Layout *entry;
- MR_Word rep;
-
- entry = event_info->MR_event_sll->MR_sll_entry;
-
- if (entry->MR_sle_body_bytes == NULL) {
- return "current procedure has no body info";
}
- MR_TRACE_CALL_MERCURY(
- MR_DD_trace_read_rep(entry->MR_sle_body_bytes,
- event_info->MR_event_sll, &rep);
- );
-
- (*browser)(ML_proc_rep_type(), rep, caller, format);
- return (const char *) NULL;
+ MR_trace_internal_interacting = MR_FALSE;
}
-static void
+void
MR_trace_do_noop(void)
{
fflush(MR_mdb_out);
@@ -1490,9 +821,6 @@
return count;
}
-/* Options to pass to mmc when compiling queries. */
-static char *MR_mmc_options = NULL;
-
static MR_Next
MR_trace_debug_cmd(char *line, MR_Trace_Cmd_Info *cmd,
MR_Event_Info *event_info, MR_Code **jumpaddr)
@@ -1585,6185 +913,60 @@
return KEEP_INTERACTING;
}
-static MR_Next
-MR_trace_cmd_step(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
- MR_Event_Info *event_info, MR_Code **jumpaddr)
+void
+MR_trace_usage_cur_cmd(void)
{
- int n;
-
- cmd->MR_trace_strict = MR_FALSE;
- cmd->MR_trace_print_level = MR_default_print_level;
- MR_init_trace_check_integrity(cmd);
- if (! MR_trace_options_movement_cmd(cmd, &words, &word_count)) {
- ; /* the usage message has already been printed */
- } else if (word_count == 1) {
- cmd->MR_trace_cmd = MR_CMD_GOTO;
- cmd->MR_trace_stop_event = MR_trace_event_number + 1;
- return STOP_INTERACTING;
- } else if (word_count == 2 && MR_trace_is_natural_number(words[1], &n)) {
- cmd->MR_trace_cmd = MR_CMD_GOTO;
- cmd->MR_trace_stop_event = MR_trace_event_number + n;
- return STOP_INTERACTING;
- } else {
- MR_trace_usage_cur_cmd();
- }
-
- return KEEP_INTERACTING;
+ /* MR_current_cmd_category is unused now, for but could be used later. */
+ fflush(MR_mdb_out);
+ fprintf(MR_mdb_err,
+ "mdb: %s: usage error -- type `help %s' for help.\n",
+ MR_current_cmd_name, MR_current_cmd_name);
}
-static MR_Next
-MR_trace_cmd_goto(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
- MR_Event_Info *event_info, MR_Code **jumpaddr)
+/*
+** Given a text line, break it up into words composed of non-space characters
+** separated by space characters. Make each word a NULL-terminated string,
+** overwriting some spaces in the line array in the process.
+**
+** If the first word is a number but the second is not, swap the two.
+** If the first word has a number prefix, separate it out.
+**
+** On return *words will point to an array of strings, with space for
+** *words_max strings. The number of strings (words) filled in will be
+** given by *word_count.
+**
+** The space for the *words array is allocated with MR_malloc().
+** It is the caller's responsibility to free it when appropriate.
+** The elements of the *words array point to memory from the line array.
+** The lifetime of the elements of the *words array expires when
+** the line array is MR_free()'d or further modified or when
+** MR_trace_parse_line is called again, whichever comes first.
+**
+** The return value is NULL if everything went OK, and an error message
+** otherwise.
+*/
+
+static const char *
+MR_trace_parse_line(char *line, char ***words, int *word_max, int *word_count)
{
- MR_Unsigned n;
+ char **raw_words;
+ int raw_word_max;
+ int raw_word_count;
+ static char count_buf[MR_NUMBER_LEN + 1];
+ char *s;
+ int i;
+ const char *problem;
- cmd->MR_trace_strict = MR_TRUE;
- cmd->MR_trace_print_level = MR_default_print_level;
- MR_init_trace_check_integrity(cmd);
- if (! MR_trace_options_movement_cmd(cmd, &words, &word_count)) {
- ; /* the usage message has already been printed */
- } else if (word_count == 2 && MR_trace_is_unsigned(words[1], &n)) {
- if (MR_trace_event_number < n) {
- cmd->MR_trace_cmd = MR_CMD_GOTO;
- cmd->MR_trace_stop_event = n;
- return STOP_INTERACTING;
- } else {
- /* XXX this message is misleading */
- fflush(MR_mdb_out);
- fprintf(MR_mdb_err, "The debugger cannot go to a past event.\n");
- }
- } else {
- MR_trace_usage_cur_cmd();
- }
+ /*
+ ** Handle a possible number prefix on the first word on the line,
+ ** separating it out into a word on its own.
+ */
- return KEEP_INTERACTING;
-}
-
-static MR_Next
-MR_trace_cmd_next(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
- MR_Event_Info *event_info, MR_Code **jumpaddr)
-{
- MR_Unsigned depth;
- int stop_depth;
- int n;
-
- depth = event_info->MR_call_depth;
- cmd->MR_trace_strict = MR_TRUE;
- cmd->MR_trace_print_level = MR_default_print_level;
- MR_init_trace_check_integrity(cmd);
- if (! MR_trace_options_movement_cmd(cmd, &words, &word_count)) {
- ; /* the usage message has already been printed */
- return KEEP_INTERACTING;
- } else if (word_count == 2 && MR_trace_is_natural_number(words[1], &n)) {
- stop_depth = depth - n;
- } else if (word_count == 1) {
- stop_depth = depth;
- } else {
- MR_trace_usage_cur_cmd();
- return KEEP_INTERACTING;
- }
-
- if (depth == stop_depth && MR_port_is_final(event_info->MR_trace_port)) {
- MR_trace_do_noop();
- } else {
- cmd->MR_trace_cmd = MR_CMD_NEXT;
- cmd->MR_trace_stop_depth = stop_depth;
- return STOP_INTERACTING;
- }
-
- return KEEP_INTERACTING;
-}
-
-static MR_Next
-MR_trace_cmd_finish(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
- MR_Event_Info *event_info, MR_Code **jumpaddr)
-{
- MR_Unsigned depth;
- int stop_depth;
- int n;
-
- depth = event_info->MR_call_depth;
- cmd->MR_trace_strict = MR_TRUE;
- cmd->MR_trace_print_level = MR_default_print_level;
- MR_init_trace_check_integrity(cmd);
- if (! MR_trace_options_movement_cmd(cmd, &words, &word_count)) {
- ; /* the usage message has already been printed */
- return KEEP_INTERACTING;
- } else if (word_count == 2 && MR_trace_is_natural_number(words[1], &n)) {
- stop_depth = depth - n;
- } else if (word_count == 1) {
- stop_depth = depth;
- } else {
- MR_trace_usage_cur_cmd();
- return KEEP_INTERACTING;
- }
-
- if (depth == stop_depth && MR_port_is_final(event_info->MR_trace_port)) {
- MR_trace_do_noop();
- } else {
- cmd->MR_trace_cmd = MR_CMD_FINISH;
- cmd->MR_trace_stop_depth = stop_depth;
- return STOP_INTERACTING;
- }
-
- return KEEP_INTERACTING;
-}
-
-static MR_Next
-MR_trace_cmd_fail(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
- MR_Event_Info *event_info, MR_Code **jumpaddr)
-{
- MR_Determinism detism;
- MR_Unsigned depth;
- int stop_depth;
- int n;
-
- detism = event_info->MR_event_sll->MR_sll_entry->MR_sle_detism;
- depth = event_info->MR_call_depth;
-
- cmd->MR_trace_strict = MR_TRUE;
- cmd->MR_trace_print_level = MR_default_print_level;
- MR_init_trace_check_integrity(cmd);
- if (! MR_trace_options_movement_cmd(cmd, &words, &word_count)) {
- ; /* the usage message has already been printed */
- return KEEP_INTERACTING;
- } else if (word_count == 2 && MR_trace_is_natural_number(words[1], &n)) {
- stop_depth = depth - n;
- } else if (word_count == 1) {
- stop_depth = depth;
- } else {
- MR_trace_usage_cur_cmd();
- return KEEP_INTERACTING;
- }
-
- if (MR_DETISM_DET_STACK(detism)) {
- fflush(MR_mdb_out);
- fprintf(MR_mdb_err, "mdb: cannot continue until failure: "
- "selected procedure has determinism %s.\n",
- MR_detism_names[detism]);
- return KEEP_INTERACTING;
- }
-
- if (depth == stop_depth && event_info->MR_trace_port == MR_PORT_FAIL) {
- MR_trace_do_noop();
- } else if (depth == stop_depth &&
- event_info->MR_trace_port == MR_PORT_EXCEPTION)
- {
- fflush(MR_mdb_out);
- fprintf(MR_mdb_err, "mdb: cannot continue until failure: "
- "the call has raised an exception.\n");
- } else {
- cmd->MR_trace_cmd = MR_CMD_FAIL;
- cmd->MR_trace_stop_depth = stop_depth;
- return STOP_INTERACTING;
- }
-
- return KEEP_INTERACTING;
-}
-
-static MR_Next
-MR_trace_cmd_exception(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
- MR_Event_Info *event_info, MR_Code **jumpaddr)
-{
- cmd->MR_trace_strict = MR_TRUE;
- cmd->MR_trace_print_level = MR_default_print_level;
- MR_init_trace_check_integrity(cmd);
- if (! MR_trace_options_movement_cmd(cmd, &words, &word_count)) {
- ; /* the usage message has already been printed */
- } else if (word_count == 1) {
- if (event_info->MR_trace_port != MR_PORT_EXCEPTION) {
- cmd->MR_trace_cmd = MR_CMD_EXCP;
- return STOP_INTERACTING;
- } else {
- MR_trace_do_noop();
- }
- } else {
- MR_trace_usage_cur_cmd();
- }
-
- return KEEP_INTERACTING;
-}
-
-static MR_Next
-MR_trace_cmd_return(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
- MR_Event_Info *event_info, MR_Code **jumpaddr)
-{
- cmd->MR_trace_strict = MR_TRUE;
- cmd->MR_trace_print_level = MR_default_print_level;
- MR_init_trace_check_integrity(cmd);
- if (! MR_trace_options_movement_cmd(cmd, &words, &word_count)) {
- ; /* the usage message has already been printed */
- } else if (word_count == 1) {
- if (event_info->MR_trace_port == MR_PORT_EXIT) {
- cmd->MR_trace_cmd = MR_CMD_RETURN;
- return STOP_INTERACTING;
- } else {
- MR_trace_do_noop();
- }
- } else {
- MR_trace_usage_cur_cmd();
- }
-
- return KEEP_INTERACTING;
-}
-
-static MR_Next
-MR_trace_cmd_forward(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
- MR_Event_Info *event_info, MR_Code **jumpaddr)
-{
- cmd->MR_trace_strict = MR_TRUE;
- cmd->MR_trace_print_level = MR_default_print_level;
- MR_init_trace_check_integrity(cmd);
- if (! MR_trace_options_movement_cmd(cmd, &words, &word_count)) {
- ; /* the usage message has already been printed */
- } else if (word_count == 1) {
- MR_Trace_Port port;
-
- port = event_info->MR_trace_port;
- if (port == MR_PORT_FAIL ||
- port == MR_PORT_REDO ||
- port == MR_PORT_EXCEPTION)
- {
- cmd->MR_trace_cmd = MR_CMD_RESUME_FORWARD;
- return STOP_INTERACTING;
- } else {
- MR_trace_do_noop();
- }
- } else {
- MR_trace_usage_cur_cmd();
- }
-
- return KEEP_INTERACTING;
-}
-
-static MR_Next
-MR_trace_cmd_mindepth(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
- MR_Event_Info *event_info, MR_Code **jumpaddr)
-{
- int newdepth;
-
- cmd->MR_trace_strict = MR_TRUE;
- cmd->MR_trace_print_level = MR_default_print_level;
- MR_init_trace_check_integrity(cmd);
- if (! MR_trace_options_movement_cmd(cmd, &words, &word_count)) {
- ; /* the usage message has already been printed */
- } else if (word_count == 2 &&
- MR_trace_is_natural_number(words[1], &newdepth))
- {
- cmd->MR_trace_cmd = MR_CMD_MIN_DEPTH;
- cmd->MR_trace_stop_depth = newdepth;
- return STOP_INTERACTING;
- } else {
- MR_trace_usage_cur_cmd();
- }
-
- return KEEP_INTERACTING;
-}
-
-static MR_Next
-MR_trace_cmd_maxdepth(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
- MR_Event_Info *event_info, MR_Code **jumpaddr)
-{
- int newdepth;
-
- cmd->MR_trace_strict = MR_TRUE;
- cmd->MR_trace_print_level = MR_default_print_level;
- MR_init_trace_check_integrity(cmd);
- if (! MR_trace_options_movement_cmd(cmd, &words, &word_count)) {
- ; /* the usage message has already been printed */
- } else if (word_count == 2 &&
- MR_trace_is_natural_number(words[1], &newdepth))
- {
- cmd->MR_trace_cmd = MR_CMD_MAX_DEPTH;
- cmd->MR_trace_stop_depth = newdepth;
- return STOP_INTERACTING;
- } else {
- MR_trace_usage_cur_cmd();
- }
-
- return KEEP_INTERACTING;
-}
-
-static MR_Next
-MR_trace_cmd_continue(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
- MR_Event_Info *event_info, MR_Code **jumpaddr)
-{
- cmd->MR_trace_strict = MR_FALSE;
- cmd->MR_trace_print_level = (MR_Trace_Cmd_Type) -1;
- MR_init_trace_check_integrity(cmd);
- if (! MR_trace_options_movement_cmd(cmd, &words, &word_count)) {
- ; /* the usage message has already been printed */
- } else if (word_count == 1) {
- cmd->MR_trace_cmd = MR_CMD_TO_END;
- if (cmd->MR_trace_print_level == (MR_Trace_Cmd_Type) -1) {
- /*
- ** The user did not specify the print level;
- ** select the intelligent default.
- */
- if (cmd->MR_trace_strict) {
- cmd->MR_trace_print_level = MR_PRINT_LEVEL_NONE;
- } else {
- cmd->MR_trace_print_level = MR_PRINT_LEVEL_SOME;
- }
- }
- return STOP_INTERACTING;
- } else {
- MR_trace_usage_cur_cmd();
- }
-
- return KEEP_INTERACTING;
-}
-
-static MR_Next
-MR_trace_cmd_retry(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
- MR_Event_Info *event_info, MR_Code **jumpaddr)
-{
- int n;
- int ancestor_level;
- MR_Retry_Across_Io across_io;
- const char *problem;
- MR_Retry_Result result;
- MR_bool assume_all_io_is_tabled;
- MR_bool unsafe_retry;
-
- ancestor_level = 0;
- across_io = MR_RETRY_IO_INTERACTIVE;
- assume_all_io_is_tabled = MR_FALSE;
- if (! MR_trace_options_retry(&across_io, &assume_all_io_is_tabled,
- &words, &word_count))
- {
- ; /* the usage message has already been printed */
- } else if (word_count == 2 && MR_trace_is_natural_number(words[1], &n)) {
- ancestor_level = n;
- } else if (word_count == 1) {
- ancestor_level = 0;
- } else {
- MR_trace_usage_cur_cmd();
- return KEEP_INTERACTING;
- }
-
- if (ancestor_level == 0 && MR_port_is_entry(event_info->MR_trace_port)) {
- MR_trace_do_noop();
- return KEEP_INTERACTING;
- }
-
- result = MR_trace_retry(event_info, ancestor_level,
- across_io, assume_all_io_is_tabled, MR_UNTABLED_IO_RETRY_MESSAGE,
- &unsafe_retry, &problem, MR_mdb_in, MR_mdb_out,
- jumpaddr);
- switch (result) {
-
- case MR_RETRY_OK_DIRECT:
- cmd->MR_trace_cmd = MR_CMD_GOTO;
- cmd->MR_trace_stop_event = MR_trace_event_number + 1;
- cmd->MR_trace_strict = MR_FALSE;
- cmd->MR_trace_print_level = MR_default_print_level;
- return STOP_INTERACTING;
-
- case MR_RETRY_OK_FINISH_FIRST:
- cmd->MR_trace_cmd = MR_CMD_FINISH;
- cmd->MR_trace_stop_depth = event_info->MR_call_depth - ancestor_level;
- cmd->MR_trace_strict = MR_TRUE;
- cmd->MR_trace_print_level = MR_PRINT_LEVEL_NONE;
-
- /* Arrange to retry the call once it is finished. */
- /* XXX we should use the same options as the original retry */
- MR_insert_line_at_head("retry -o");
- return STOP_INTERACTING;
-
- case MR_RETRY_OK_FAIL_FIRST:
- cmd->MR_trace_cmd = MR_CMD_FAIL;
- cmd->MR_trace_stop_depth = event_info->MR_call_depth - ancestor_level;
- cmd->MR_trace_strict = MR_TRUE;
- cmd->MR_trace_print_level = MR_PRINT_LEVEL_NONE;
-
- /* Arrange to retry the call once it is finished. */
- /* XXX we should use the same options as the original retry */
- MR_insert_line_at_head("retry -o");
- return STOP_INTERACTING;
-
- case MR_RETRY_ERROR:
- fflush(MR_mdb_out);
- fprintf(MR_mdb_err, "%s\n", problem);
- return KEEP_INTERACTING;
- }
-
- MR_fatal_error("unrecognized retry result");
-}
-
-static MR_Next
-MR_trace_cmd_level(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
- MR_Event_Info *event_info, MR_Code **jumpaddr)
-{
- int n;
- MR_bool detailed;
-
- detailed = MR_FALSE;
- if (! MR_trace_options_detailed(&detailed, &words, &word_count)) {
- ; /* the usage message has already been printed */
- } else if (word_count == 2 && MR_trace_is_natural_number(words[1], &n)) {
- MR_trace_set_level_and_report(n, detailed, MR_print_optionals);
- } else {
- MR_trace_usage_cur_cmd();
- }
-
- return KEEP_INTERACTING;
-}
-
-static MR_Next
-MR_trace_cmd_up(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
- MR_Event_Info *event_info, MR_Code **jumpaddr)
-{
- int n;
- MR_bool detailed;
-
- detailed = MR_FALSE;
- if (! MR_trace_options_detailed(&detailed, &words, &word_count)) {
- ; /* the usage message has already been printed */
- } else if (word_count == 2 && MR_trace_is_natural_number(words[1], &n)) {
- MR_trace_set_level_and_report(MR_trace_current_level() + n, detailed,
- MR_print_optionals);
- } else if (word_count == 1) {
- MR_trace_set_level_and_report(MR_trace_current_level() + 1, detailed,
- MR_print_optionals);
- } else {
- MR_trace_usage_cur_cmd();
- }
-
- return KEEP_INTERACTING;
-}
-
-static MR_Next
-MR_trace_cmd_down(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
- MR_Event_Info *event_info, MR_Code **jumpaddr)
-{
- int n;
- MR_bool detailed;
-
- detailed = MR_FALSE;
- if (! MR_trace_options_detailed(&detailed, &words, &word_count)) {
- ; /* the usage message has already been printed */
- } else if (word_count == 2 && MR_trace_is_natural_number(words[1], &n)) {
- MR_trace_set_level_and_report(MR_trace_current_level() - n, detailed,
- MR_print_optionals);
- } else if (word_count == 1) {
- MR_trace_set_level_and_report(MR_trace_current_level() - 1, detailed,
- MR_print_optionals);
- } else {
- MR_trace_usage_cur_cmd();
- }
-
- return KEEP_INTERACTING;
-}
-
-static MR_Next
-MR_trace_cmd_vars(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
- MR_Event_Info *event_info, MR_Code **jumpaddr)
-{
- if (word_count == 1) {
- const char *problem;
-
- problem = MR_trace_list_vars(MR_mdb_out);
- if (problem != NULL) {
- fflush(MR_mdb_out);
- fprintf(MR_mdb_err, "mdb: %s.\n", problem);
- }
- } else {
- MR_trace_usage_cur_cmd();
- }
-
- return KEEP_INTERACTING;
-}
-
-static MR_Next
-MR_trace_cmd_held_vars(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
- MR_Event_Info *event_info, MR_Code **jumpaddr)
-{
- if (word_count == 1) {
- MR_trace_list_held_vars(MR_mdb_out);
- } else {
- MR_trace_usage_cur_cmd();
- }
-
- return KEEP_INTERACTING;
-}
-
-static MR_Next
-MR_trace_cmd_print(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
- MR_Event_Info *event_info, MR_Code **jumpaddr)
-{
- MR_Browse_Format format;
- MR_bool xml;
- int n;
-
- if (! MR_trace_options_format(&format, &xml, &words, &word_count)) {
- ; /* the usage message has already been printed */
- } else if (xml) {
- /* the --xml option is not valid for print */
- MR_trace_usage_cur_cmd();
- } else if (word_count == 1) {
- const char *problem;
-
- problem = MR_trace_browse_one_goal(MR_mdb_out,
- MR_trace_browse_goal_internal,
- MR_BROWSE_CALLER_PRINT, format);
-
- if (problem != NULL) {
- fflush(MR_mdb_out);
- fprintf(MR_mdb_err, "mdb: %s.\n", problem);
- }
- } else if (word_count == 2) {
- const char *problem;
-
- if (MR_streq(words[1], "*")) {
- problem = MR_trace_browse_all(MR_mdb_out,
- MR_trace_browse_internal, format);
- } else if (MR_streq(words[1], "goal")) {
- problem = MR_trace_browse_one_goal(MR_mdb_out,
- MR_trace_browse_goal_internal, MR_BROWSE_CALLER_PRINT, format);
- } else if (MR_streq(words[1], "exception")) {
- problem = MR_trace_browse_exception(event_info,
- MR_trace_browse_internal, MR_BROWSE_CALLER_PRINT, format);
- } else if (MR_streq(words[1], "proc_body")) {
- problem = MR_trace_browse_proc_body(event_info,
- MR_trace_browse_internal, MR_BROWSE_CALLER_PRINT, format);
- } else {
- problem = MR_trace_parse_browse_one(MR_mdb_out, MR_TRUE, words[1],
- MR_trace_browse_internal, MR_BROWSE_CALLER_PRINT, format,
- MR_FALSE);
- }
-
- if (problem != NULL) {
- fflush(MR_mdb_out);
- fprintf(MR_mdb_err, "mdb: %s.\n", problem);
- }
- } else if (word_count == 3 && MR_streq(words[1], "action")
- && MR_trace_is_natural_number(words[2], &n))
- {
- const char *problem;
-
- problem = MR_trace_browse_action(MR_mdb_out, n,
- MR_trace_browse_goal_internal,
- MR_BROWSE_CALLER_PRINT, format);
-
- if (problem != NULL) {
- fflush(MR_mdb_out);
- fprintf(MR_mdb_err, "mdb: %s.\n", problem);
- }
- } else {
- MR_trace_usage_cur_cmd();
- }
-
- return KEEP_INTERACTING;
-}
-
-static MR_Next
-MR_trace_cmd_browse(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
- MR_Event_Info *event_info, MR_Code **jumpaddr)
-{
- MR_Browse_Format format;
- MR_bool xml;
- int n;
- MR_GoalBrowser goal_browser;
- MR_Browser browser;
-
- if (! MR_trace_options_format(&format, &xml, &words, &word_count)) {
- ; /* the usage message has already been printed */
- } else {
- if (xml) {
- goal_browser = MR_trace_browse_goal_xml;
- browser = MR_trace_browse_xml;
- } else {
- goal_browser = MR_trace_browse_goal_internal;
- browser = MR_trace_browse_internal;
- }
-
- if (word_count == 1) {
- const char *problem;
-
- problem = MR_trace_browse_one_goal(MR_mdb_out, goal_browser,
- MR_BROWSE_CALLER_BROWSE, format);
-
- if (problem != NULL) {
- fflush(MR_mdb_out);
- fprintf(MR_mdb_err, "mdb: %s.\n", problem);
- }
- } else if (word_count == 2) {
- const char *problem;
-
- if (MR_streq(words[1], "goal")) {
- problem = MR_trace_browse_one_goal(MR_mdb_out, goal_browser,
- MR_BROWSE_CALLER_BROWSE, format);
- } else if (MR_streq(words[1], "exception")) {
- problem = MR_trace_browse_exception(event_info, browser,
- MR_BROWSE_CALLER_BROWSE, format);
- } else if (MR_streq(words[1], "proc_body")) {
- problem = MR_trace_browse_proc_body(event_info, browser,
- MR_BROWSE_CALLER_BROWSE, format);
- } else {
- problem = MR_trace_parse_browse_one(MR_mdb_out, MR_FALSE,
- words[1], browser, MR_BROWSE_CALLER_BROWSE, format,
- MR_TRUE);
- }
-
- if (problem != NULL) {
- fflush(MR_mdb_out);
- fprintf(MR_mdb_err, "mdb: %s.\n", problem);
- }
- } else if (word_count == 3 && MR_streq(words[1], "action")
- && MR_trace_is_natural_number(words[2], &n))
- {
- const char *problem;
-
- problem = MR_trace_browse_action(MR_mdb_out, n, goal_browser,
- MR_BROWSE_CALLER_BROWSE, format);
-
- if (problem != NULL) {
- fflush(MR_mdb_out);
- fprintf(MR_mdb_err, "mdb: %s.\n", problem);
- }
- } else {
- MR_trace_usage_cur_cmd();
- }
- }
-
- return KEEP_INTERACTING;
-}
-
-static MR_Next
-MR_trace_cmd_stack(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
- MR_Event_Info *event_info, MR_Code **jumpaddr)
-{
- MR_bool detailed;
- int frame_limit = 0;
- int line_limit = MR_stack_default_line_limit;
- int spec_line_limit;
-
- detailed = MR_FALSE;
- if (! MR_trace_options_stack_trace(&detailed, &frame_limit,
- &words, &word_count))
- {
- ; /* the usage message has already been printed */
- } else if (word_count == 1) {
- MR_trace_cmd_stack_2(event_info, detailed, frame_limit, line_limit);
- } else if (word_count == 2 &&
- MR_trace_is_natural_number(words[1], &spec_line_limit))
- {
- MR_trace_cmd_stack_2(event_info, detailed, frame_limit,
- spec_line_limit);
- } else {
- MR_trace_usage_cur_cmd();
- }
-
- return KEEP_INTERACTING;
-}
-
-static void
-MR_trace_cmd_stack_2(MR_Event_Info *event_info, MR_bool detailed,
- int frame_limit, int line_limit)
-{
- const MR_Label_Layout *layout;
- MR_Word *saved_regs;
- const char *msg;
-
- layout = event_info->MR_event_sll;
- saved_regs = event_info->MR_saved_regs;
-
- MR_trace_init_modules();
- msg = MR_dump_stack_from_layout(MR_mdb_out, layout,
- MR_saved_sp(saved_regs), MR_saved_curfr(saved_regs),
- detailed, MR_context_position != MR_CONTEXT_NOWHERE,
- frame_limit, line_limit, &MR_dump_stack_record_print);
-
- if (msg != NULL) {
- fflush(MR_mdb_out);
- fprintf(MR_mdb_err, "%s.\n", msg);
- }
-}
-
-static MR_Next
-MR_trace_cmd_current(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
- MR_Event_Info *event_info, MR_Code **jumpaddr)
-{
- if (word_count == 1) {
- MR_trace_event_print_internal_report(event_info);
- } else {
- MR_trace_usage_cur_cmd();
- }
-
- return KEEP_INTERACTING;
-}
-
-static MR_Next
-MR_trace_cmd_set(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
- MR_Event_Info *event_info, MR_Code **jumpaddr)
-{
- MR_Browse_Format format;
- 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;
- int max_io_actions;
-
- if (word_count >= 3 && MR_streq(words[1], "list_context_lines")) {
- if (word_count > 3
- || !MR_trace_is_natural_number(words[2], &MR_num_context_lines)) {
- MR_trace_usage_cur_cmd();
- }
- } else if (word_count >= 3 && MR_streq(words[1], "list_path")) {
- MR_trace_cmd_set_list_dir_path(words, word_count, cmd, event_info,
- jumpaddr);
- } else if (word_count == 3 &&
- ( MR_streq(words[1], "fail_trace_count")
- || MR_streq(words[1], "fail_trace_counts")))
- {
- 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[2]);
- } else if (word_count == 3 &&
- ( MR_streq(words[1], "pass_trace_count")
- || MR_streq(words[1], "pass_trace_counts")))
- {
- 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[2]);
- } else if (word_count == 3 &&
- MR_streq(words[1], "max_io_actions") &&
- MR_trace_is_natural_number(words[2], &max_io_actions))
- {
- MR_TRACE_CALL_MERCURY(
- ML_BROWSE_set_num_io_actions_from_mdb(max_io_actions,
- MR_trace_browser_persistent_state,
- &MR_trace_browser_persistent_state);
- );
- } else if (! MR_trace_options_param_set(&print_set, &browse_set,
- &print_all_set, &flat_format, &raw_pretty_format, &verbose_format,
- &pretty_format, &words, &word_count))
- {
- ; /* the usage message has already been printed */
- }
- else if (word_count != 3 ||
- ! MR_trace_set_browser_param(print_set, browse_set, print_all_set,
- flat_format, raw_pretty_format, verbose_format, pretty_format,
- words[1], words[2]))
- {
- MR_trace_usage_cur_cmd();
- }
-
- return KEEP_INTERACTING;
-}
-
-static MR_Next
-MR_trace_cmd_view(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
- MR_Event_Info *event_info, MR_Code **jumpaddr)
-{
- const char *window_cmd = NULL;
- const char *server_cmd = NULL;
- const char *server_name = NULL;
- int timeout = 8; /* seconds */
- MR_bool force = MR_FALSE;
- MR_bool verbose = MR_FALSE;
- MR_bool split = MR_FALSE;
- MR_bool close_window = MR_FALSE;
- const char *msg;
-
- if (! MR_trace_options_view(&window_cmd, &server_cmd, &server_name,
- &timeout, &force, &verbose, &split, &close_window,
- &words, &word_count))
- {
- ; /* the usage message has already been printed */
- } else if (word_count != 1) {
- MR_trace_usage_cur_cmd();
- } else if (close_window) {
- MR_trace_maybe_close_source_window(verbose);
- } else {
- msg = MR_trace_new_source_window(window_cmd, server_cmd, server_name,
- timeout, force, verbose, split);
- if (msg != NULL) {
- fflush(MR_mdb_out);
- fprintf(MR_mdb_err, "mdb: %s.\n", msg);
- }
-
- MR_trace_maybe_sync_source_window(event_info, verbose);
- }
-
- return KEEP_INTERACTING;
-}
-
-static MR_Next
-MR_trace_cmd_hold(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
- MR_Event_Info *event_info, MR_Code **jumpaddr)
-{
- char *event_var_name;
- char *held_var_name;
- MR_TypeInfo type_info;
- MR_Word value;
- const char *ignored_name;
- const char *problem;
- MR_bool bad_subterm;
-
- if (word_count == 2) {
- event_var_name = words[1];
- held_var_name = words[1];
- } else if (word_count == 3) {
- event_var_name = words[1];
- held_var_name = words[2];
- } else {
- MR_trace_usage_cur_cmd();
- return KEEP_INTERACTING;
- }
-
- if (strpbrk(held_var_name, "^/") != NULL) {
- /* Don't allow path separators in variable names. */
- MR_trace_usage_cur_cmd();
- return KEEP_INTERACTING;
- }
-
- if (held_var_name[0] == '$') {
- /* Ignore any unneeded initial $ signs. */
- held_var_name = &held_var_name[1];
- }
-
- problem = MR_trace_parse_lookup_var_path(event_var_name, &type_info,
- &value, &bad_subterm);
- if (problem != NULL) {
- fflush(MR_mdb_out);
- fprintf(MR_mdb_err, "mdb: %s%s.\n",
- (bad_subterm? "there is no path " : ""), problem);
- return KEEP_INTERACTING;
- }
-
- if (! MR_add_hold_var(held_var_name, type_info, value)) {
- fflush(MR_mdb_out);
- fprintf(MR_mdb_err, "mdb: there is already a held variable $%s\n",
- held_var_name);
- }
-
- return KEEP_INTERACTING;
-}
-
-static MR_Next
-MR_trace_cmd_diff(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
- MR_Event_Info *event_info, MR_Code **jumpaddr)
-{
- int start;
- int max;
- char *name1;
- char *name2;
- MR_TypeInfo type_info1;
- MR_TypeInfo type_info2;
- MR_Word value1;
- MR_Word value2;
- MR_Word univ1;
- MR_Word univ2;
- const char *problem1;
- const char *problem2;
- MR_bool bad_subterm1;
- MR_bool bad_subterm2;
-
- start = 0;
- max = 20;
- if (! MR_trace_options_diff(&start, &max, &words, &word_count)) {
- /* the usage message has already been printed */
- return KEEP_INTERACTING;
- } else if (word_count != 3) {
- MR_trace_usage_cur_cmd();
- return KEEP_INTERACTING;
- }
-
- name1 = words[1];
- name2 = words[2];
- problem1 = MR_trace_parse_lookup_var_path(name1, &type_info1, &value1,
- &bad_subterm1);
- problem2 = MR_trace_parse_lookup_var_path(name2, &type_info2, &value2,
- &bad_subterm2);
- if (problem1 != NULL) {
- fflush(MR_mdb_out);
- fprintf(MR_mdb_err, "mdb: %s%s.\n",
- (bad_subterm1? "arg1: there is no path " : ""), problem1);
- return KEEP_INTERACTING;
- }
- if (problem2 != NULL) {
- fflush(MR_mdb_out);
- fprintf(MR_mdb_err, "mdb: %s%s.\n",
- (bad_subterm2? "arg2: there is no path " : ""), problem2);
- return KEEP_INTERACTING;
- }
-
- MR_TRACE_CALL_MERCURY(
- MR_new_univ_on_hp(univ1, type_info1, value1);
- MR_new_univ_on_hp(univ2, type_info2, value2);
- ML_report_diffs(start, max, univ1, univ2);
- );
-
- return KEEP_INTERACTING;
-}
-
-static MR_Next
-MR_trace_cmd_dump(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
- MR_Event_Info *event_info, MR_Code **jumpaddr)
-{
- MR_bool verbose = MR_FALSE;
- MR_Word browser_term;
- const char *problem = NULL;
- MR_bool xml = MR_FALSE;
-
- /*
- ** Set this to NULL to avoid uninitialization warnings.
- */
- browser_term = (MR_Word) NULL;
-
- if (! MR_trace_options_dump(&xml, &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], "goal")) {
- const char *name;
- MR_Word arg_list;
- MR_bool is_func;
-
- problem = NULL;
- MR_convert_goal_to_synthetic_term(&name, &arg_list, &is_func);
- browser_term = MR_synthetic_to_browser_term(name, arg_list,
- is_func);
- } else if (MR_streq(words[1], "exception")) {
- MR_Word exception;
-
- exception = MR_trace_get_exception_value();
- if (exception == (MR_Word) NULL) {
- problem = "missing exception value";
- } else {
- browser_term = MR_univ_to_browser_term(exception);
- }
- } else if (MR_streq(words[1], "proc_body")) {
- const MR_Proc_Layout *entry;
- MR_Word rep;
-
- entry = event_info->MR_event_sll->MR_sll_entry;
-
- if (entry->MR_sle_body_bytes == NULL) {
- problem = "current procedure has no body bytecodes";
- } else {
- MR_TRACE_CALL_MERCURY(
- MR_DD_trace_read_rep(entry->MR_sle_body_bytes,
- event_info->MR_event_sll, &rep);
- );
-
- browser_term = MR_type_value_to_browser_term(
- (MR_TypeInfo) ML_proc_rep_type(), rep);
- }
- } else {
- MR_Var_Spec var_spec;
- MR_TypeInfo type_info;
- MR_Word value;
- const char *name;
-
- MR_convert_arg_to_var_spec(words[1], &var_spec);
- problem = MR_lookup_unambiguous_var_spec(var_spec,
- &type_info, &value, &name);
- if (problem == NULL) {
- browser_term = MR_type_value_to_browser_term(type_info, value);
- }
- }
-
- if (problem != NULL) {
- fflush(MR_mdb_out);
- fprintf(MR_mdb_err, "mdb: %s.\n", problem);
- } else {
- if (xml) {
- MR_trace_save_term_xml(words[2], browser_term);
- } else {
- MR_trace_save_term(words[2], browser_term);
- }
- }
- }
-
- return KEEP_INTERACTING;
-}
-
-/*
-** list [num]
-** List num lines of context around the line number of the context of the
-** current point (i.e., level in the call stack). If num is not given,
-** the number of context lines defaults to the value of the context_lines
-** setting.
-**
-** TODO: add the following (use MR_parse_source_locn()):
-** list filename:num[-num]
-** List a range of lines from a given file. If only one number is
-** given, the default number of lines of context is used.
-*/
-
-static MR_Next
-MR_trace_cmd_list(char **words, int word_count,
- MR_Trace_Cmd_Info *cmd, MR_Event_Info *event_info, MR_Code **jumpaddr)
-{
- const MR_Proc_Layout *entry_ptr;
- const char *filename;
- int lineno;
- MR_Word *base_sp_ptr;
- MR_Word *base_curfr_ptr;
- MR_bool num = MR_num_context_lines;
- MR_String aligned_filename;
-
- MR_trace_listing_path_ensure_init();
-
- if (word_count > 2) {
- MR_trace_usage_cur_cmd();
- return KEEP_INTERACTING;
- }
-
- if (word_count == 2 && !MR_trace_is_natural_number(words[1], &num)) {
- MR_trace_usage_cur_cmd();
- return KEEP_INTERACTING;
- }
-
- MR_trace_current_level_details(&entry_ptr, &filename, &lineno,
- &base_sp_ptr, &base_curfr_ptr);
-
- MR_TRACE_USE_HP(
- MR_make_aligned_string(aligned_filename, (MR_String) filename);
- );
-
- MR_TRACE_CALL_MERCURY(
- ML_LISTING_list_file(MR_mdb_out, MR_mdb_err, (char *) aligned_filename,
- lineno - num, lineno + num, lineno, MR_listing_path);
- );
-
- return KEEP_INTERACTING;
-}
-
-static MR_Next
-MR_trace_cmd_set_list_dir_path(char **words, int word_count,
- MR_Trace_Cmd_Info *cmd, MR_Event_Info *event_info, MR_Code **jumpaddr)
-{
- int i;
- MR_String aligned_word;
-
- MR_trace_listing_path_ensure_init();
-
- 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);
- }
- );
-
- return KEEP_INTERACTING;
-}
-
-static 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;
-
- MR_trace_listing_path_ensure_init();
-
- 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);
- }
- );
-
- return KEEP_INTERACTING;
-}
-
-static 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)
-{
- MR_trace_listing_path_ensure_init();
-
- 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);
- );
-
- return KEEP_INTERACTING;
-}
-
-static void
-MR_trace_listing_path_ensure_init()
-{
- 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;
- }
-}
-
-static MR_Next
-MR_trace_cmd_break(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
- MR_Event_Info *event_info, MR_Code **jumpaddr)
-{
- const MR_Label_Layout *layout;
- MR_Proc_Spec spec;
- MR_Spy_When when;
- MR_Spy_Action action;
- MR_MultiMatch multi_match;
- MR_Spy_Ignore_When ignore_when;
- int ignore_count;
- MR_Spy_Print_List print_list;
- const char *file;
- int line;
- int breakline;
- const char *problem;
-
- layout = event_info->MR_event_sll;
-
- if (word_count == 2 && MR_streq(words[1], "info")) {
- int i;
- int count;
-
- count = 0;
- for (i = 0; i < MR_spy_point_next; i++) {
- if (MR_spy_points[i]->spy_exists) {
- MR_print_spy_point(MR_mdb_out, i, MR_TRUE);
- count++;
- }
- }
-
- if (count == 0) {
- fprintf(MR_mdb_out, "There are no break points.\n");
- }
-
- return KEEP_INTERACTING;
- }
-
- when = MR_default_breakpoint_scope;
- action = MR_SPY_STOP;
- multi_match = MR_MULTIMATCH_ASK;
- /*
- ** The value of ignore_when doesn't matter
- ** while ignore_count contains zero.
- */
- ignore_when = MR_SPY_DONT_IGNORE;
- ignore_count = 0;
- print_list = NULL;
- if (! MR_trace_options_when_action_multi_ignore(&when, &action,
- &multi_match, &ignore_when, &ignore_count, &print_list,
- &words, &word_count))
- {
- ; /* the usage message has already been printed */
- } else if (word_count == 2 && MR_streq(words[1], "here")) {
- int slot;
- MR_Trace_Port port;
-
- port = event_info->MR_trace_port;
- if (ignore_count > 0 && ignore_when == MR_SPY_IGNORE_ENTRY &&
- ! MR_port_is_entry(port))
- {
- fprintf(MR_mdb_out, "That breakpoint "
- "would never become enabled.\n");
- return KEEP_INTERACTING;
- } else if (ignore_count > 0 &&
- ignore_when == MR_SPY_IGNORE_INTERFACE &&
- ! MR_port_is_interface(port))
- {
- fprintf(MR_mdb_out, "That breakpoint "
- "would never become enabled.\n");
- return KEEP_INTERACTING;
- }
-
- MR_register_all_modules_and_procs(MR_mdb_out, MR_TRUE);
- slot = MR_add_proc_spy_point(MR_SPY_SPECIFIC, action, ignore_when,
- ignore_count, layout->MR_sll_entry, layout, print_list, &problem);
- MR_maybe_print_spy_point(slot, problem);
- } else if (word_count == 2 && MR_parse_proc_spec(words[1], &spec)) {
- MR_Matches_Info matches;
- int slot;
-
- MR_register_all_modules_and_procs(MR_mdb_out, MR_TRUE);
- matches = MR_search_for_matching_procedures(&spec);
- if (matches.match_proc_next == 0) {
- fflush(MR_mdb_out);
- fprintf(MR_mdb_err, "mdb: there is no such procedure.\n");
- } else if (matches.match_proc_next == 1) {
- slot = MR_add_proc_spy_point(when, action, ignore_when,
- ignore_count, matches.match_procs[0], NULL, print_list,
- &problem);
- MR_maybe_print_spy_point(slot, problem);
- } else if (multi_match == MR_MULTIMATCH_ALL) {
- int i;
-
- for (i = 0; i < matches.match_proc_next; i++) {
- slot = MR_add_proc_spy_point(when, action, ignore_when,
- ignore_count, matches.match_procs[i], NULL, print_list,
- &problem);
- MR_maybe_print_spy_point(slot, problem);
- }
- } else {
- char buf[80];
- int i;
- char *line2;
-
- fflush(MR_mdb_out);
- fprintf(MR_mdb_err,
- "Ambiguous procedure specification. The matches are:\n");
-
- for (i = 0; i < matches.match_proc_next; i++) {
- fprintf(MR_mdb_out, "%d: ", i);
- MR_print_proc_id_and_nl(MR_mdb_out, matches.match_procs[i]);
- }
-
- if (multi_match == MR_MULTIMATCH_ONE) {
- return KEEP_INTERACTING;
- }
-
- sprintf(buf, "\nWhich do you want to put "
- "a breakpoint on (0-%d or *)? ",
- matches.match_proc_next - 1);
- line2 = MR_trace_getline(buf, MR_mdb_in, MR_mdb_out);
- if (line2 == NULL) {
- /* This means the user input EOF. */
- fprintf(MR_mdb_out, "none of them\n");
- } else if (MR_streq(line2, "*")) {
- for (i = 0; i < matches.match_proc_next; i++) {
- slot = MR_add_proc_spy_point(when, action, ignore_when,
- ignore_count, matches.match_procs[i], NULL, print_list,
- &problem);
- MR_maybe_print_spy_point(slot, problem);
- }
-
- MR_free(line2);
- } else if (MR_trace_is_natural_number(line2, &i)) {
- if (0 <= i && i < matches.match_proc_next) {
- slot = MR_add_proc_spy_point(when, action, ignore_when,
- ignore_count, matches.match_procs[i], NULL, print_list,
- &problem);
- MR_maybe_print_spy_point(slot, problem);
- } else {
- fprintf(MR_mdb_out, "no such match\n");
- }
- MR_free(line2);
- } else {
- fprintf(MR_mdb_out, "none of them\n");
- MR_free(line2);
- }
- }
- } else if (word_count == 2 &&
- MR_parse_source_locn(words[1], &file, &line))
- {
- int slot;
-
- slot = MR_add_line_spy_point(action, ignore_when, ignore_count, file,
- line, print_list, &problem);
- MR_maybe_print_spy_point(slot, problem);
- } else if (word_count == 2 &&
- MR_trace_is_natural_number(words[1], &breakline))
- {
- int slot;
-
- if (MR_find_context(layout, &file, &line)) {
- slot = MR_add_line_spy_point(action, ignore_when, ignore_count,
- file, breakline, print_list, &problem);
- MR_maybe_print_spy_point(slot, problem);
- } else {
- MR_fatal_error("cannot find current filename");
- }
- } else {
- MR_trace_usage_cur_cmd();
- }
-
- return KEEP_INTERACTING;
-}
-
-static MR_Next
-MR_trace_cmd_condition(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
- MR_Event_Info *event_info, MR_Code **jumpaddr)
-{
- int break_num;
- MR_bool require_var;
- MR_bool require_path;
- int i;
- const char *problem;
- MR_CTerm term;
- MR_Spy_Test test;
- char *what_str;
- char *term_str;
- int len;
- char *rest;
- MR_Spy_Cond *cond;
- MR_Var_Spec var_spec;
- char *path;
-
- break_num = MR_most_recent_spy_point;
- require_var = MR_TRUE;
- require_path = MR_TRUE;
- if (! MR_trace_options_condition(&break_num, &require_var, &require_path,
- &words, &word_count))
- {
- /* the usage message has already been printed */
- return KEEP_INTERACTING;
- } else if (word_count < 4) {
- MR_trace_usage_cur_cmd();
- return KEEP_INTERACTING;
- }
-
- if (break_num < 0) {
- fprintf(MR_mdb_err, "There is no breakpoint.\n");
- return KEEP_INTERACTING;
- }
-
- if (! (0 <= break_num && break_num < MR_spy_point_next)) {
- fprintf(MR_mdb_err, "There is no breakpoint %d.\n", break_num);
- return KEEP_INTERACTING;
- }
-
- if (! MR_spy_points[break_num]->spy_exists) {
- fprintf(MR_mdb_err, "Breakpoint %d has been deleted.\n", break_num);
- return KEEP_INTERACTING;
- }
-
- cond = MR_malloc(sizeof(MR_Spy_Cond));
-
- what_str = MR_malloc(strlen(words[1]) + 1);
- strcpy(what_str, words[1]);
-
- problem = MR_trace_parse_var_path(what_str, &var_spec, &path);
- if (problem != NULL) {
- fprintf(MR_mdb_err, "mdb: %s: %s.\n", what_str, problem);
- return KEEP_INTERACTING;
- }
-
- if (MR_streq(words[2], "=") || MR_streq(words[2], "==")) {
- test = MR_SPY_TEST_EQUAL;
- } else if (MR_streq(words[2], "!=") || MR_streq(words[2], "\\=")) {
- test = MR_SPY_TEST_NOT_EQUAL;
- } else {
- fprintf(MR_mdb_err, "invalid condition: should be = or !=\n");
- return KEEP_INTERACTING;
- }
-
- len = 0;
- for (i = 3; i < word_count; i++) {
- len += strlen(words[i]);
- }
-
- term_str = MR_malloc(len + 1);
- len = 0;
- for (i = 3; i < word_count; i++) {
- strcpy(term_str + len, words[i]);
- len += strlen(words[i]);
- }
-
- term = MR_create_cterm(term_str, &rest);
- if (term == NULL) {
- fprintf(MR_mdb_out, "syntax error in term\n");
- return KEEP_INTERACTING;
- }
-
- if (*rest != '\0') {
- fprintf(MR_mdb_out, "syntax error after term\n");
- return KEEP_INTERACTING;
- }
-
- if (MR_spy_points[break_num]->spy_cond != NULL) {
- MR_delete_cterm(MR_spy_points[break_num]->spy_cond->cond_term);
- MR_free(MR_spy_points[break_num]->spy_cond->cond_what_string);
- MR_free(MR_spy_points[break_num]->spy_cond->cond_term_string);
- MR_free(MR_spy_points[break_num]->spy_cond);
- }
-
- cond->cond_var_spec = var_spec;
- cond->cond_path = path;
- cond->cond_test = test;
- cond->cond_term = term;
- cond->cond_term_string = term_str;
- cond->cond_what_string = what_str;
- cond->cond_require_var = require_var;
- cond->cond_require_path = require_path;
-
- MR_spy_points[break_num]->spy_cond = cond;
-
- MR_print_spy_point(MR_mdb_out, break_num, MR_TRUE);
- return KEEP_INTERACTING;
-}
-
-static MR_Next
-MR_trace_cmd_ignore(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
- MR_Event_Info *event_info, MR_Code **jumpaddr)
-{
- int n;
- MR_Spy_Ignore_When ignore_when;
- int ignore_count;
- const char *problem;
-
- ignore_when = MR_SPY_IGNORE_ENTRY;
- ignore_count = 1;
- if (! MR_trace_options_ignore_count(&ignore_when, &ignore_count,
- &words, &word_count))
- {
- ; /* the usage message has already been printed */
- } else if (word_count == 2 && MR_trace_is_natural_number(words[1], &n)) {
- if (0 <= n && n < MR_spy_point_next && MR_spy_points[n]->spy_exists) {
- problem = MR_ignore_spy_point(n, ignore_when, ignore_count);
- MR_maybe_print_spy_point(n, problem);
- } else {
- fflush(MR_mdb_out);
- fprintf(MR_mdb_err, "mdb: break point #%d does not exist.\n", n);
- }
- } else if (word_count == 2 && MR_streq(words[1], "*")) {
- int i;
- int count;
-
- count = 0;
- for (i = 0; i < MR_spy_point_next; i++) {
- if (MR_spy_points[i]->spy_exists) {
- problem = MR_ignore_spy_point(n, ignore_when, ignore_count);
- MR_maybe_print_spy_point(n, problem);
- count++;
- }
- }
-
- if (count == 0) {
- fprintf(MR_mdb_err, "There are no break points.\n");
- }
- } else if (word_count == 1) {
- if (0 <= MR_most_recent_spy_point
- && MR_most_recent_spy_point < MR_spy_point_next
- && MR_spy_points[MR_most_recent_spy_point]->spy_exists)
- {
- n = MR_most_recent_spy_point;
- problem = MR_ignore_spy_point(n, ignore_when, ignore_count);
- MR_maybe_print_spy_point(n, problem);
- } else {
- fflush(MR_mdb_out);
- fprintf(MR_mdb_err, "mdb: there is no most recent break point.\n");
- }
- } else {
- MR_trace_usage_cur_cmd();
- }
-
- return KEEP_INTERACTING;
-}
-
-static MR_Next
-MR_trace_cmd_break_print(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
- MR_Event_Info *event_info, MR_Code **jumpaddr)
-{
- int n;
- int i;
- MR_Browse_Format format;
- MR_bool at_start;
- MR_bool warn;
- MR_Spy_Print_List print_list;
-
- if (! MR_trace_options_break_print(&format, &at_start, &warn,
- &words, &word_count))
- {
- ; /* the usage message has already been printed */
- } else if (word_count > 2 && MR_trace_is_natural_number(words[1], &n)) {
- if (word_count == 3 && MR_streq(words[2], "none")) {
- MR_clear_spy_point_print_list(n);
- MR_print_spy_point(MR_mdb_out, n, MR_TRUE);
- } else if (0 <= n && n < MR_spy_point_next
- && MR_spy_points[n]->spy_exists)
- {
- print_list = NULL;
- for (i = 2; i < word_count; i++) {
- print_list = MR_add_to_print_list_end(format, words[i], warn,
- print_list);
- }
-
- if (at_start) {
- MR_add_spy_point_print_list_start(n, print_list);
- } else {
- MR_add_spy_point_print_list_end(n, print_list);
- }
-
- MR_print_spy_point(MR_mdb_out, n, MR_TRUE);
- } else {
- fflush(MR_mdb_out);
- fprintf(MR_mdb_err, "mdb: break point #%d does not exist.\n", n);
- }
- } else {
- MR_trace_usage_cur_cmd();
- }
-
- return KEEP_INTERACTING;
-}
-
-static MR_Spy_Print_List
-MR_add_to_print_list_end(MR_Browse_Format format, char *word, MR_bool warn,
- MR_Spy_Print_List print_list)
-{
- MR_Spy_Print_List list;
- MR_Spy_Print_List new_list;
- MR_Spy_Print new_node;
-
- new_node = MR_malloc(sizeof(struct MR_Spy_Print_Struct));
- new_node->p_format = format;
- new_node->p_warn = warn;
- if (MR_streq(word, "*")) {
- new_node->p_what = MR_SPY_PRINT_ALL;
- new_node->p_name = NULL;
- } else if (MR_streq(word, "goal")) {
- new_node->p_what = MR_SPY_PRINT_GOAL;
- new_node->p_name = NULL;
- } else {
- new_node->p_what = MR_SPY_PRINT_ONE;
- new_node->p_name = MR_copy_string(word);
- }
-
- new_list = MR_malloc(sizeof(struct MR_Spy_Print_List_Struct));
- new_list->pl_cur = new_node;
- new_list->pl_next = NULL;
-
- list = print_list;
- if (list == NULL) {
- return new_list;
- }
-
- while (list->pl_next != NULL) {
- list = list->pl_next;
- }
-
- list->pl_next = new_list;
- return print_list;
-}
-
-static MR_Next
-MR_trace_cmd_enable(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)) {
- if (0 <= n && n < MR_spy_point_next && MR_spy_points[n]->spy_exists) {
- MR_spy_points[n]->spy_enabled = MR_TRUE;
- MR_print_spy_point(MR_mdb_out, n, MR_FALSE);
- } else {
- fflush(MR_mdb_out);
- fprintf(MR_mdb_err, "mdb: break point #%d does not exist.\n", n);
- }
- } else if (word_count == 2 && MR_streq(words[1], "*")) {
- int i;
- int count;
-
- count = 0;
- for (i = 0; i < MR_spy_point_next; i++) {
- if (MR_spy_points[i]->spy_exists) {
- MR_spy_points[i]->spy_enabled = MR_TRUE;
- MR_print_spy_point(MR_mdb_out, i, MR_FALSE);
- count++;
- }
- }
-
- if (count == 0) {
- fprintf(MR_mdb_err, "There are no break points.\n");
- }
- } else if (word_count == 1) {
- if (0 <= MR_most_recent_spy_point
- && MR_most_recent_spy_point < MR_spy_point_next
- && MR_spy_points[MR_most_recent_spy_point]->spy_exists)
- {
- MR_spy_points[MR_most_recent_spy_point]->spy_enabled = MR_TRUE;
- MR_print_spy_point(MR_mdb_out, MR_most_recent_spy_point, MR_FALSE);
- } else {
- fflush(MR_mdb_out);
- fprintf(MR_mdb_err, "mdb: there is no most recent break point.\n");
- }
- } else {
- MR_trace_usage_cur_cmd();
- }
-
- return KEEP_INTERACTING;
-}
-
-static MR_Next
-MR_trace_cmd_disable(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)) {
- if (0 <= n && n < MR_spy_point_next && MR_spy_points[n]->spy_exists) {
- MR_spy_points[n]->spy_enabled = MR_FALSE;
- MR_print_spy_point(MR_mdb_out, n, MR_FALSE);
- } else {
- fflush(MR_mdb_out);
- fprintf(MR_mdb_err, "mdb: break point #%d does not exist.\n", n);
- }
- } else if (word_count == 2 && MR_streq(words[1], "*")) {
- int i;
- int count;
-
- count = 0;
- for (i = 0; i < MR_spy_point_next; i++) {
- if (MR_spy_points[i]->spy_exists) {
- MR_spy_points[i]->spy_enabled = MR_FALSE;
- MR_print_spy_point(MR_mdb_out, i, MR_FALSE);
- count++;
- }
- }
-
- if (count == 0) {
- fflush(MR_mdb_out);
- fprintf(MR_mdb_err, "There are no break points.\n");
- }
- } else if (word_count == 1) {
- if (0 <= MR_most_recent_spy_point
- && MR_most_recent_spy_point < MR_spy_point_next
- && MR_spy_points[MR_most_recent_spy_point]->spy_exists)
- {
- MR_spy_points[MR_most_recent_spy_point]->spy_enabled = MR_FALSE;
- MR_print_spy_point(MR_mdb_out, MR_most_recent_spy_point, MR_FALSE);
- } else {
- fflush(MR_mdb_out);
- fprintf(MR_mdb_err, "There is no most recent break point.\n");
- }
- } else {
- MR_trace_usage_cur_cmd();
- }
-
- return KEEP_INTERACTING;
-}
-
-static MR_Next
-MR_trace_cmd_delete(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)) {
- if (0 <= n && n < MR_spy_point_next && MR_spy_points[n]->spy_exists) {
- MR_spy_points[n]->spy_exists = MR_FALSE;
- MR_print_spy_point(MR_mdb_out, n, MR_FALSE);
- MR_spy_points[n]->spy_exists = MR_TRUE;
- MR_delete_spy_point(n);
- } else {
- fflush(MR_mdb_out);
- fprintf(MR_mdb_err, "mdb: break point #%d does not exist.\n", n);
- }
- } else if (word_count == 2 && MR_streq(words[1], "*")) {
- int i;
- int count;
-
- count = 0;
- for (i = 0; i < MR_spy_point_next; i++) {
- if (MR_spy_points[i]->spy_exists) {
- MR_spy_points[i]->spy_exists = MR_FALSE;
- MR_print_spy_point(MR_mdb_out, i, MR_FALSE);
- MR_spy_points[i]->spy_exists = MR_TRUE;
- MR_delete_spy_point(i);
- count++;
- }
- }
-
- if (count == 0) {
- fflush(MR_mdb_out);
- fprintf(MR_mdb_err, "There are no break points.\n");
- }
- } else if (word_count == 1) {
- if (0 <= MR_most_recent_spy_point
- && MR_most_recent_spy_point < MR_spy_point_next
- && MR_spy_points[MR_most_recent_spy_point]->spy_exists)
- {
- int slot;
-
- slot = MR_most_recent_spy_point;
- MR_spy_points[slot]->spy_exists = MR_FALSE;
- MR_print_spy_point(MR_mdb_out, slot, MR_FALSE);
- MR_spy_points[slot]->spy_exists = MR_TRUE;
- MR_delete_spy_point(slot);
- } else {
- fflush(MR_mdb_out);
- fprintf(MR_mdb_err, "mdb: there is no most recent break point.\n");
- }
- } else {
- MR_trace_usage_cur_cmd();
- }
-
- return KEEP_INTERACTING;
-}
-
-static MR_Next
-MR_trace_cmd_register(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
- MR_Event_Info *event_info, MR_Code **jumpaddr)
-{
- MR_bool verbose;
-
- if (! MR_trace_options_quiet(&verbose, &words, &word_count)) {
- ; /* the usage message has already been printed */
- } else if (word_count == 1) {
- MR_register_all_modules_and_procs(MR_mdb_out, verbose);
- } else {
- MR_trace_usage_cur_cmd();
- }
-
- return KEEP_INTERACTING;
-}
-
-static MR_Next
-MR_trace_cmd_modules(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
- MR_Event_Info *event_info, MR_Code **jumpaddr)
-{
- if (word_count == 1) {
- MR_register_all_modules_and_procs(MR_mdb_out, MR_TRUE);
- MR_dump_module_list(MR_mdb_out);
- } else {
- MR_trace_usage_cur_cmd();
- }
-
- return KEEP_INTERACTING;
-}
-
-static MR_Next
-MR_trace_cmd_procedures(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
- MR_Event_Info *event_info, MR_Code **jumpaddr)
-{
- if (word_count == 2) {
- MR_register_all_modules_and_procs(MR_mdb_out, MR_TRUE);
- MR_dump_module_procs(MR_mdb_out, words[1]);
- } else {
- MR_trace_usage_cur_cmd();
- }
-
- return KEEP_INTERACTING;
-}
-
-static MR_Next
-MR_trace_cmd_query(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
- MR_Event_Info *event_info, MR_Code **jumpaddr)
-{
- MR_trace_query(MR_NORMAL_QUERY, MR_mmc_options, word_count - 1, words + 1);
- return KEEP_INTERACTING;
-}
-
-static MR_Next
-MR_trace_cmd_cc_query(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
- MR_Event_Info *event_info, MR_Code **jumpaddr)
-{
- MR_trace_query(MR_CC_QUERY, MR_mmc_options, word_count - 1, words + 1);
- return KEEP_INTERACTING;
-}
-
-static MR_Next
-MR_trace_cmd_io_query(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
- MR_Event_Info *event_info, MR_Code **jumpaddr)
-{
- MR_trace_query(MR_IO_QUERY, MR_mmc_options, word_count - 1, words + 1);
- return KEEP_INTERACTING;
-}
-
-static 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;
-}
-
-static 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;
-}
-
-static 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;
-}
-
-static 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 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;
-}
-
-static 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 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;
-}
-
-static 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;
-}
-
-static 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;
-}
-
-static 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;
-}
-
-static MR_Next
-MR_trace_cmd_document_category(char **words, int word_count,
- MR_Trace_Cmd_Info *cmd, MR_Event_Info *event_info, MR_Code **jumpaddr)
-{
- int slot;
- const char *msg;
- const char *help_text;
-
- help_text = MR_trace_read_help_text();
- if (word_count != 3) {
- MR_trace_usage_cur_cmd();
- } else if (! MR_trace_is_natural_number(words[1], &slot)) {
- MR_trace_usage_cur_cmd();
- } else {
- msg = MR_trace_add_cat(words[2], slot, help_text);
- if (msg != NULL) {
- fflush(MR_mdb_out);
- fprintf(MR_mdb_err,
- "Document category `%s' not added: %s.\n", words[2], msg);
- }
- }
-
- return KEEP_INTERACTING;
-}
-
-static MR_Next
-MR_trace_cmd_document(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
- MR_Event_Info *event_info, MR_Code **jumpaddr)
-{
- int slot;
- const char *msg;
- const char *help_text;
-
- help_text = MR_trace_read_help_text();
- if (word_count != 4) {
- MR_trace_usage_cur_cmd();
- } else if (! MR_trace_is_natural_number(words[2], &slot)) {
- MR_trace_usage_cur_cmd();
- } else {
- msg = MR_trace_add_item(words[1], words[3], slot, help_text);
- if (msg != NULL) {
- fflush(MR_mdb_out);
- fprintf(MR_mdb_err,
- "Document item `%s' in category `%s' not added: %s.\n",
- words[3], words[1], msg);
- }
- }
-
- return KEEP_INTERACTING;
-}
-
-static MR_Next
-MR_trace_cmd_help(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
- MR_Event_Info *event_info, MR_Code **jumpaddr)
-{
- if (word_count == 1) {
- MR_trace_help();
- } else if (word_count == 2) {
- MR_trace_help_word(words[1]);
- } else if (word_count == 3) {
- MR_trace_help_cat_item(words[1], words[2]);
- } else {
- MR_trace_usage_cur_cmd();
- }
-
- return KEEP_INTERACTING;
-}
-
-static MR_Next
-MR_trace_cmd_histogram_all(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
- MR_Event_Info *event_info, MR_Code **jumpaddr)
-{
-#ifdef MR_TRACE_HISTOGRAM
-
- if (word_count == 2) {
- FILE *fp;
-
- fp = fopen(words[1], "w");
- if (fp == NULL) {
- fflush(MR_mdb_out);
- fprintf(MR_mdb_err, "mdb: cannot open file `%s' for output: %s.\n",
- words[1], strerror(errno));
- } else {
- MR_trace_print_histogram(fp, "All-inclusive",
- MR_trace_histogram_all,
- MR_trace_histogram_hwm);
- if (fclose(fp) != 0) {
- fflush(MR_mdb_out);
- fprintf(MR_mdb_err, "mdb: error closing file `%s': %s.\n",
- words[1], strerror(errno));
- }
- }
- } else {
- MR_trace_usage_cur_cmd();
- }
-
-#else /* MR_TRACE_HISTOGRAM */
-
- fprintf(MR_mdb_out, "mdb: the `histogram_all' command is available "
- "only when histogram gathering is enabled.\n");
-
-#endif /* MR_TRACE_HISTOGRAM */
-
- return KEEP_INTERACTING;
-}
-
-static MR_Next
-MR_trace_cmd_histogram_exp(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
- MR_Event_Info *event_info, MR_Code **jumpaddr)
-{
-#ifdef MR_TRACE_HISTOGRAM
-
- if (word_count == 2) {
- FILE *fp;
-
- fp = fopen(words[1], "w");
- if (fp == NULL) {
- fflush(MR_mdb_out);
- fprintf(MR_mdb_err, "mdb: cannot open file `%s' for output: %s.\n",
- words[1], strerror(errno));
- } else {
- MR_trace_print_histogram(fp, "Experimental",
- MR_trace_histogram_exp,
- MR_trace_histogram_hwm);
- if (fclose(fp) != 0) {
- fflush(MR_mdb_out);
- fprintf(MR_mdb_err, "mdb: error closing file `%s': %s.\n",
- words[1], strerror(errno));
- }
- }
- } else {
- MR_trace_usage_cur_cmd();
- }
-
-#else /* MR_TRACE_HISTOGRAM */
-
- fprintf(MR_mdb_out, "mdb: the `histogram_exp' command is available "
- "only when histogram gathering is enabled.\n");
-
-#endif /* MR_TRACE_HISTOGRAM */
-
- return KEEP_INTERACTING;
-}
-
-static MR_Next
-MR_trace_cmd_clear_histogram(char **words, int word_count,
- MR_Trace_Cmd_Info *cmd, MR_Event_Info *event_info, MR_Code **jumpaddr)
-{
-#ifdef MR_TRACE_HISTOGRAM
-
- if (word_count == 1) {
- int i;
-
- for (i = 0; i <= MR_trace_histogram_hwm; i++) {
- MR_trace_histogram_exp[i] = 0;
- }
- } else {
- MR_trace_usage_cur_cmd();
- }
-
-#else /* MR_TRACE_HISTOGRAM */
-
- fprintf(MR_mdb_out, "mdb: the `clear_histogram' command is available "
- "only when histogram gathering is enabled.\n");
-
-#endif /* MR_TRACE_HISTOGRAM */
-
- return KEEP_INTERACTING;
-}
-
-static MR_Next
-MR_trace_cmd_var_details(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
- MR_Event_Info *event_info, MR_Code **jumpaddr)
-{
- int n;
-
- if (word_count == 1) {
- const char *problem;
-
- problem = MR_trace_list_var_details(MR_mdb_out);
- if (problem != NULL) {
- fflush(MR_mdb_out);
- fprintf(MR_mdb_err, "mdb: %s.\n", problem);
- }
- } else {
- MR_trace_usage_cur_cmd();
- }
-
- return KEEP_INTERACTING;
-}
-
-static MR_Next
-MR_trace_cmd_term_size(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
- MR_Event_Info *event_info, MR_Code **jumpaddr)
-{
- int n;
-
- if (word_count == 2) {
- const char *problem;
-
- if (MR_streq(words[1], "*")) {
- problem = MR_trace_print_size_all(MR_mdb_out);
- } else {
- problem = MR_trace_print_size_one(MR_mdb_out, words[1]);
- }
-
- if (problem != NULL) {
- fflush(MR_mdb_out);
- fprintf(MR_mdb_err, "mdb: %s.\n", problem);
- }
- } else {
- MR_trace_usage_cur_cmd();
- }
-
- return KEEP_INTERACTING;
-}
-
-static MR_Next
-MR_trace_cmd_flag(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
- MR_Event_Info *event_info, MR_Code **jumpaddr)
-{
- const char *name;
- MR_bool *flagptr;
- int i;
- MR_bool found;
- const char *set_word;
-
- /*
- ** Set this to NULL to avoid uninitialization warnings.
- */
- flagptr = NULL;
-
- if (word_count == 1) {
- for (i = 0; i < MR_MAXFLAG; i++) {
- /*
- ** The true values of the debugging flags are stored
- ** in MR_saved_debug_state inside the call tree
- ** of MR_trace_event.
- */
- flagptr = &MR_saved_debug_state.MR_sds_debugflags[
- MR_debug_flag_info[i].MR_debug_flag_index];
- name = MR_debug_flag_info[i].MR_debug_flag_name;
- if (*flagptr) {
- fprintf(MR_mdb_out, "Flag %s is set.\n", name);
- } else {
- fprintf(MR_mdb_out, "Flag %s is clear.\n", name);
- }
- }
- return KEEP_INTERACTING;
- } else if (word_count == 2) {
- name = words[1];
- set_word = NULL;
- } else if (word_count == 3) {
- name = words[1];
- set_word = words[2];
- } else {
- MR_trace_usage_cur_cmd();
- return KEEP_INTERACTING;
- }
-
- found = MR_FALSE;
- for (i = 0; i < MR_MAXFLAG; i++) {
- if (MR_streq(MR_debug_flag_info[i].MR_debug_flag_name, name)) {
- /*
- ** The true values of the debugging flags are stored
- ** in MR_saved_debug_state inside the call tree
- ** of MR_trace_event.
- */
- flagptr = &MR_saved_debug_state.MR_sds_debugflags[
- MR_debug_flag_info[i].MR_debug_flag_index];
- found = MR_TRUE;
- break;
- }
- }
-
- if (!found) {
- fprintf(MR_mdb_out, "There is no flag named %s.\n", name);
- return KEEP_INTERACTING;
- }
-
- if (set_word != NULL) {
- if (MR_streq(set_word, "on")) {
- *flagptr = MR_TRUE;
- fprintf(MR_mdb_out, "Flag %s is now set.\n", name);
- } else if (MR_streq(set_word, "off")) {
- *flagptr = MR_FALSE;
- fprintf(MR_mdb_out, "Flag %s is now clear.\n", name);
- } else {
- MR_trace_usage_cur_cmd();
- }
- } else {
- if (*flagptr) {
- fprintf(MR_mdb_out, "Flag %s is set.\n", name);
- } else {
- fprintf(MR_mdb_out, "Flag %s is clear.\n", name);
- }
- }
-
- return KEEP_INTERACTING;
-}
-
-static MR_Next
-MR_trace_cmd_subgoal(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
- MR_Event_Info *event_info, MR_Code **jumpaddr)
-{
-#ifdef MR_USE_MINIMAL_MODEL_STACK_COPY
-
- MR_SubgoalDebug *subgoal_debug;
- MR_Subgoal *subgoal;
- int n;
-
- if (word_count == 2 && MR_trace_is_natural_number(words[1], &n)) {
- MR_trace_init_modules();
-
- subgoal_debug = MR_lookup_subgoal_debug_num(n);
- if (subgoal_debug == NULL) {
- fprintf(MR_mdb_out, "no such subgoal\n");
- } else {
- MR_trace_print_subgoal_debug(NULL, subgoal_debug);
- }
- } else {
- MR_trace_usage_cur_cmd();
- }
-
-#else /* MR_USE_MINIMAL_MODEL_STACK_COPY */
-
- fprintf(MR_mdb_out, "mdb: the `subgoal' command is available "
- "only in stack copy minimal model tabling grades.\n");
-
-#endif /* MR_USE_MINIMAL_MODEL_STACK_COPY */
-
- return KEEP_INTERACTING;
-}
-
-static MR_Next
-MR_trace_cmd_consumer(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
- MR_Event_Info *event_info, MR_Code **jumpaddr)
-{
-#ifdef MR_USE_MINIMAL_MODEL_STACK_COPY
-
- MR_ConsumerDebug *consumer_debug;
- MR_Consumer *consumer;
- int n;
-
- if (word_count == 2 && MR_trace_is_natural_number(words[1], &n)) {
- MR_trace_init_modules();
-
- consumer_debug = MR_lookup_consumer_debug_num(n);
- if (consumer_debug == NULL) {
- fprintf(MR_mdb_out, "no such consumer\n");
- } else {
- MR_trace_print_consumer_debug(NULL, consumer_debug);
- }
- } else {
- MR_trace_usage_cur_cmd();
- }
-
-#else /* MR_USE_MINIMAL_MODEL_STACK_COPY */
-
- fprintf(MR_mdb_out, "mdb: the `consumer' command is available "
- "only in stack copy minimal model tabling grades.\n");
-
-#endif /* MR_USE_MINIMAL_MODEL_STACK_COPY */
-
- return KEEP_INTERACTING;
-}
-
-static MR_Next
-MR_trace_cmd_gen_stack(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
- MR_Event_Info *event_info, MR_Code **jumpaddr)
-{
-#ifdef MR_USE_MINIMAL_MODEL_STACK_COPY
-
- if (word_count == 1) {
- MR_bool saved_tabledebug;
-
- MR_trace_init_modules();
- saved_tabledebug = MR_tabledebug;
- MR_tabledebug = MR_TRUE;
- MR_print_gen_stack(MR_mdb_out);
- MR_tabledebug = saved_tabledebug;
- } else {
- MR_trace_usage_cur_cmd();
- }
-
-#else /* MR_USE_MINIMAL_MODEL_STACK_COPY */
-
- fprintf(MR_mdb_out, "mdb: the `gen_stack' command is available "
- "only in stack copy minimal model tabling grades.\n");
-
-#endif /* MR_USE_MINIMAL_MODEL_STACK_COPY */
-
- return KEEP_INTERACTING;
-}
-
-static MR_Next
-MR_trace_cmd_cut_stack(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
- MR_Event_Info *event_info, MR_Code **jumpaddr)
-{
-#ifdef MR_USE_MINIMAL_MODEL_STACK_COPY
-
- if (word_count == 1) {
- MR_bool saved_tabledebug;
-
- MR_trace_init_modules();
- saved_tabledebug = MR_tabledebug;
- MR_tabledebug = MR_TRUE;
- MR_print_cut_stack(MR_mdb_out);
- MR_tabledebug = saved_tabledebug;
- } else {
- MR_trace_usage_cur_cmd();
- }
-
-#else /* MR_USE_MINIMAL_MODEL_STACK_COPY */
-
- fprintf(MR_mdb_out, "mdb: the `cut_stack' command is available "
- "only in stack copy minimal model tabling grades.\n");
-
-#endif /* MR_USE_MINIMAL_MODEL_STACK_COPY */
-
- return KEEP_INTERACTING;
-}
-
-static MR_Next
-MR_trace_cmd_pneg_stack(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
- MR_Event_Info *event_info, MR_Code **jumpaddr)
-{
-#ifdef MR_USE_MINIMAL_MODEL_STACK_COPY
-
- if (word_count == 1) {
- MR_bool saved_tabledebug;
-
- MR_trace_init_modules();
- saved_tabledebug = MR_tabledebug;
- MR_tabledebug = MR_TRUE;
- MR_print_pneg_stack(MR_mdb_out);
- MR_tabledebug = saved_tabledebug;
- } else {
- MR_trace_usage_cur_cmd();
- }
-
-#else /* MR_USE_MINIMAL_MODEL_STACK_COPY */
-
- fprintf(MR_mdb_out, "mdb: the `pneg_stack' command is available "
- "only in stack copy minimal model tabling grades.\n");
-
-#endif /* MR_USE_MINIMAL_MODEL_STACK_COPY */
-
- return KEEP_INTERACTING;
-}
-
-static MR_Next
-MR_trace_cmd_mm_stacks(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
- MR_Event_Info *event_info, MR_Code **jumpaddr)
-{
-#ifdef MR_USE_MINIMAL_MODEL_STACK_COPY
-
- if (word_count == 1) {
- MR_bool saved_tabledebug;
-
- MR_trace_init_modules();
- saved_tabledebug = MR_tabledebug;
- MR_tabledebug = MR_TRUE;
- MR_print_gen_stack(MR_mdb_out);
- fprintf(MR_mdb_out, "\n");
- MR_print_cut_stack(MR_mdb_out);
- fprintf(MR_mdb_out, "\n");
- MR_print_pneg_stack(MR_mdb_out);
- MR_tabledebug = saved_tabledebug;
- } else {
- MR_trace_usage_cur_cmd();
- }
-
-#else /* MR_USE_MINIMAL_MODEL_STACK_COPY */
-
- fprintf(MR_mdb_out, "mdb: the `pneg_stack' command is available "
- "only in stack copy minimal model tabling grades.\n");
-
-#endif /* MR_USE_MINIMAL_MODEL_STACK_COPY */
-
- return KEEP_INTERACTING;
-}
-
-static MR_Next
-MR_trace_cmd_nondet_stack(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
- MR_Event_Info *event_info, MR_Code **jumpaddr)
-{
- MR_bool detailed;
- int frame_limit = 0;
- int line_limit = MR_stack_default_line_limit;
- int spec_line_limit;
-
- detailed = MR_FALSE;
- if (! MR_trace_options_stack_trace(&detailed, &frame_limit,
- &words, &word_count))
- {
- ; /* the usage message has already been printed */
- } else if (word_count == 1) {
- MR_trace_cmd_nondet_stack_2(event_info, detailed, frame_limit,
- line_limit);
- } else if (word_count == 2 &&
- MR_trace_is_natural_number(words[1], &spec_line_limit))
- {
- MR_trace_cmd_nondet_stack_2(event_info, detailed, frame_limit,
- spec_line_limit);
- } else {
- MR_trace_usage_cur_cmd();
- }
-
- return KEEP_INTERACTING;
-}
-
-static void
-MR_trace_cmd_nondet_stack_2(MR_Event_Info *event_info, MR_bool detailed,
- int frame_limit, int line_limit)
-{
- const MR_Label_Layout *layout;
- MR_Word *saved_regs;
-
- layout = event_info->MR_event_sll;
- saved_regs = event_info->MR_saved_regs;
-
- MR_trace_init_modules();
- if (detailed) {
- int saved_level;
-
- saved_level = MR_trace_current_level();
- MR_dump_nondet_stack_from_layout(MR_mdb_out, NULL, frame_limit,
- line_limit, MR_saved_maxfr(saved_regs), layout,
- MR_saved_sp(saved_regs), MR_saved_curfr(saved_regs));
- MR_trace_set_level(saved_level, MR_print_optionals);
- } else {
- MR_dump_nondet_stack(MR_mdb_out, NULL, frame_limit, line_limit,
- MR_saved_maxfr(saved_regs));
- }
-}
-
-static MR_Next
-MR_trace_cmd_stack_regs(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
- MR_Event_Info *event_info, MR_Code **jumpaddr)
-{
- MR_Word *saved_regs;
-
- saved_regs = event_info->MR_saved_regs;
-
- if (word_count == 1) {
- MR_print_stack_regs(MR_mdb_out, saved_regs);
- } else {
- MR_trace_usage_cur_cmd();
- }
-
- return KEEP_INTERACTING;
-}
-
-static MR_Next
-MR_trace_cmd_all_regs(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
- MR_Event_Info *event_info, MR_Code **jumpaddr)
-{
- MR_Word *saved_regs;
-
- saved_regs = event_info->MR_saved_regs;
-
- if (word_count == 1) {
- MR_print_stack_regs(MR_mdb_out, saved_regs);
- MR_print_heap_regs(MR_mdb_out, saved_regs);
- MR_print_tabling_regs(MR_mdb_out, saved_regs);
- MR_print_succip_reg(MR_mdb_out, saved_regs);
- MR_print_r_regs(MR_mdb_out, saved_regs);
-#ifdef MR_DEEP_PROFILING
- MR_print_deep_prof_vars(MR_mdb_out, "mdb all_regs");
-#endif
- } else {
- MR_trace_usage_cur_cmd();
- }
-
- return KEEP_INTERACTING;
-}
-
-static MR_Next
-MR_trace_cmd_debug_vars(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
- MR_Event_Info *event_info, MR_Code **jumpaddr)
-{
- if (word_count == 1) {
- MR_print_debug_vars(MR_mdb_out, event_info);
- } else {
- MR_trace_usage_cur_cmd();
- }
-
- return KEEP_INTERACTING;
-}
-
-static MR_Next
-MR_trace_cmd_table_io(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
- MR_Event_Info *event_info, MR_Code **jumpaddr)
-{
- if (word_count == 1) {
- if (! MR_io_tabling_allowed) {
- fprintf(MR_mdb_err,
- "This executable wasn't prepared for I/O tabling.\n");
- return KEEP_INTERACTING;
- }
-
- if (MR_io_tabling_phase == MR_IO_TABLING_BEFORE) {
- fprintf(MR_mdb_out, "I/O tabling has not yet started.\n");
- } else if (MR_io_tabling_phase == MR_IO_TABLING_DURING) {
- fprintf(MR_mdb_out, "I/O tabling has started.\n");
- } else if (MR_io_tabling_phase == MR_IO_TABLING_AFTER) {
- fprintf(MR_mdb_out, "I/O tabling has stopped.\n");
- } else {
- MR_fatal_error("I/O tabling in impossible phase.\n");
- }
- } else if (word_count == 2 && (MR_streq(words[1], "start")
- || MR_streq(words[1], "begin")))
- {
- if (! MR_io_tabling_allowed) {
- fprintf(MR_mdb_err,
- "This executable wasn't prepared for I/O tabling.\n");
- return KEEP_INTERACTING;
- }
-
- if (MR_io_tabling_phase == MR_IO_TABLING_BEFORE) {
- MR_io_tabling_phase = MR_IO_TABLING_DURING;
- MR_io_tabling_start = MR_io_tabling_counter;
- MR_io_tabling_end = MR_IO_ACTION_MAX;
- MR_io_tabling_start_event_num = event_info->MR_event_number;
-#ifdef MR_DEBUG_RETRY
- MR_io_tabling_debug = MR_TRUE;
-#endif
- fprintf(MR_mdb_out, "I/O tabling started.\n");
- } else if (MR_io_tabling_phase == MR_IO_TABLING_DURING) {
- fprintf(MR_mdb_out, "I/O tabling has already started.\n");
- } else if (MR_io_tabling_phase == MR_IO_TABLING_AFTER) {
- fprintf(MR_mdb_out, "I/O tabling has already stopped.\n");
- } else {
- MR_fatal_error("I/O tabling in impossible phase.\n");
- }
- } else if (word_count == 2 && (MR_streq(words[1], "stop")
- || MR_streq(words[1], "end")))
- {
- if (! MR_io_tabling_allowed) {
- fprintf(MR_mdb_err,
- "This executable wasn't prepared for I/O tabling.\n");
- return KEEP_INTERACTING;
- }
-
- if (MR_io_tabling_phase == MR_IO_TABLING_BEFORE) {
- fprintf(MR_mdb_out, "I/O tabling has not yet started.\n");
- } else if (MR_io_tabling_phase == MR_IO_TABLING_DURING) {
- MR_io_tabling_phase = MR_IO_TABLING_AFTER;
- MR_io_tabling_end = MR_io_tabling_counter_hwm;
- MR_io_tabling_stop_event_num = event_info->MR_event_number;
- fprintf(MR_mdb_out, "I/O tabling stopped.\n");
- } else if (MR_io_tabling_phase == MR_IO_TABLING_AFTER) {
- fprintf(MR_mdb_out, "I/O tabling has already stopped.\n");
- } else {
- MR_fatal_error("I/O tabling in impossible phase.\n");
- }
- } else if (word_count == 2 && MR_streq(words[1], "stats")) {
- if (! MR_io_tabling_allowed) {
- fprintf(MR_mdb_err,
- "This executable wasn't prepared for I/O tabling.\n");
- return KEEP_INTERACTING;
- }
-
- fprintf(MR_mdb_out, "phase = %d\n", MR_io_tabling_phase);
- MR_print_unsigned_var(MR_mdb_out, "counter", MR_io_tabling_counter);
- MR_print_unsigned_var(MR_mdb_out, "hwm", MR_io_tabling_counter_hwm);
- MR_print_unsigned_var(MR_mdb_out, "start", MR_io_tabling_start);
- MR_print_unsigned_var(MR_mdb_out, "end", MR_io_tabling_end);
- } else if (word_count == 2 && MR_streq(words[1], "allow")) {
- /*
- ** The "table_io allow" command allows the programmer to give
- ** the command "table_io start" even in grades in which there
- ** is no guarantee that all I/O primitives are tabled. It is
- ** for developers only, because if it is used on programs in
- ** which some but not all I/O primitives are tabled, the
- ** results of turning on I/O tabling can be weird.
- */
-
- MR_io_tabling_allowed = MR_TRUE;
- } else {
- MR_trace_usage_cur_cmd();
- }
-
- return KEEP_INTERACTING;
-}
-
-static MR_Next
-MR_trace_cmd_stats(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
- MR_Event_Info *event_info, MR_Code **jumpaddr)
-{
- char *filename;
- FILE *fp;
- MR_bool should_close;
-
- filename = NULL;
- if (! MR_trace_options_stats(&filename, &words, &word_count)) {
- /* the usage message has already been printed */
- return KEEP_INTERACTING;
- }
-
- if (word_count != 2) {
- MR_trace_usage_cur_cmd();
- }
-
- if (filename != NULL) {
- fp = fopen(filename, "w");
- if (fp == NULL) {
- fflush(MR_mdb_out);
- fprintf(MR_mdb_err, "mdb: error opening `%s': %s.\n",
- filename, strerror(errno));
- return KEEP_INTERACTING;
- }
-
- should_close = MR_TRUE;
- } else {
- fp = MR_mdb_out;
- should_close = MR_FALSE;
- }
-
- if (MR_streq(words[1], "procs")) {
- MR_proc_layout_stats(fp);
- } else if (MR_streq(words[1], "labels")) {
- MR_label_layout_stats(fp);
- } else if (MR_streq(words[1], "var_names")) {
- MR_var_name_stats(fp);
- } else if (MR_streq(words[1], "io_tabling")) {
- MR_io_tabling_stats(fp);
- } else {
- MR_trace_usage_cur_cmd();
- }
-
- if (should_close) {
- (void) fclose(fp);
- }
-
- return KEEP_INTERACTING;
-}
-
-static MR_Next
-MR_trace_cmd_print_optionals(char **words, int word_count,
- MR_Trace_Cmd_Info *cmd, MR_Event_Info *event_info, MR_Code **jumpaddr)
-{
- if (word_count == 2 && MR_streq(words[1], "off")) {
- MR_print_optionals = MR_FALSE;
- MR_trace_set_level(MR_trace_current_level(), MR_print_optionals);
- } else if (word_count == 2 && MR_streq(words[1], "on")) {
- MR_print_optionals = MR_TRUE;
- MR_trace_set_level(MR_trace_current_level(), MR_print_optionals);
- } else if (word_count == 1) {
- fprintf(MR_mdb_out, "optional values are %sbeing printed\n",
- MR_print_optionals? "" : "not ");
- } else {
- MR_trace_usage_cur_cmd();
- }
-
- return KEEP_INTERACTING;
-}
-
-static MR_Next
-MR_trace_cmd_unhide_events(char **words, int word_count,
- MR_Trace_Cmd_Info *cmd, MR_Event_Info *event_info, MR_Code **jumpaddr)
-{
- if (word_count == 2 && MR_streq(words[1], "off")) {
- MR_trace_unhide_events = MR_FALSE;
- fprintf(MR_mdb_out, "Hidden events are hidden.\n");
- } else if (word_count == 2 && MR_streq(words[1], "on")) {
- MR_trace_unhide_events = MR_TRUE;
- MR_trace_have_unhid_events = MR_TRUE;
- fprintf(MR_mdb_out, "Hidden events are exposed.\n");
- } else if (word_count == 1) {
- fprintf(MR_mdb_out, "Hidden events are %s.\n",
- MR_trace_unhide_events? "exposed" : "hidden");
- } else {
- MR_trace_usage_cur_cmd();
- }
-
- return KEEP_INTERACTING;
-}
-
-static const MR_Proc_Layout *
-MR_find_single_matching_proc(MR_Proc_Spec *spec, MR_bool verbose)
-{
- MR_Matches_Info matches;
- int n;
- int i;
-
- MR_register_all_modules_and_procs(MR_mdb_out, verbose);
- matches = MR_search_for_matching_procedures(spec);
- if (matches.match_proc_next == 0) {
- fflush(MR_mdb_out);
- fprintf(MR_mdb_err, "mdb: there is no such procedure.\n");
- return NULL;
- } else if (matches.match_proc_next == 1) {
- return matches.match_procs[0];
- } else {
- char buf[100];
- char *line2;
-
- fflush(MR_mdb_out);
- fprintf(MR_mdb_err, "Ambiguous procedure specification. "
- "The matches are:\n");
- for (i = 0; i < matches.match_proc_next; i++) {
- fprintf(MR_mdb_out, "%d: ", i);
- MR_print_proc_id_and_nl(MR_mdb_out, matches.match_procs[i]);
- }
-
- sprintf(buf, "\nWhich procedure's table do you want to print (0-%d)? ",
- matches.match_proc_next - 1);
- line2 = MR_trace_getline(buf, MR_mdb_in, MR_mdb_out);
- n = -1;
- if (line2 == NULL || !MR_trace_is_natural_number(line2, &n)) {
- n = -1;
- fprintf(MR_mdb_out, "none of them\n");
- } else if (n < 0 || n >= matches.match_proc_next) {
- n = -1;
- fprintf(MR_mdb_out, "invalid choice\n");
- }
-
- if (line2 != NULL) {
- MR_free(line2);
- }
-
- if (n >= 0) {
- return matches.match_procs[n];
- } else {
- return NULL;
- }
- }
-}
-
-static MR_Next
-MR_trace_cmd_table(char **words, int word_count,
- MR_Trace_Cmd_Info *cmd, MR_Event_Info *event_info, MR_Code **jumpaddr)
-{
- MR_Call_Table_Arg *call_table_args;
- const MR_Proc_Layout *proc;
- MR_Proc_Spec spec;
- const MR_Table_Gen *table_gen;
- MR_TrieNode table_cur;
- int num_inputs;
- int filtered_num_inputs;
- int cur_arg;
- int filtered_cur_arg;
- int num_tips;
-
- if (word_count < 2) {
- MR_trace_usage_cur_cmd();
- return KEEP_INTERACTING;
- }
-
- if (! MR_parse_proc_spec(words[1], &spec)) {
- fflush(MR_mdb_out);
- fprintf(MR_mdb_err, "mdb: invalid procedure specification.\n");
- return KEEP_INTERACTING;
- }
-
- proc = MR_find_single_matching_proc(&spec, MR_TRUE);
- if (proc == NULL) {
- return KEEP_INTERACTING;
- }
-
- switch (MR_sle_eval_method(proc)) {
- case MR_EVAL_METHOD_NORMAL:
- MR_print_proc_id(MR_mdb_out, proc);
- fprintf(MR_mdb_out, " isn't tabled.\n");
- return KEEP_INTERACTING;
-
- case MR_EVAL_METHOD_LOOP_CHECK:
- case MR_EVAL_METHOD_MEMO_STRICT:
- case MR_EVAL_METHOD_MEMO_FAST_LOOSE:
- case MR_EVAL_METHOD_MEMO_SPECIFIED:
- case MR_EVAL_METHOD_MINIMAL_STACK_COPY:
- case MR_EVAL_METHOD_MINIMAL_OWN_STACKS:
- break;
-
- case MR_EVAL_METHOD_TABLE_IO:
- case MR_EVAL_METHOD_TABLE_IO_DECL:
- case MR_EVAL_METHOD_TABLE_IO_UNITIZE:
- case MR_EVAL_METHOD_TABLE_IO_UNITIZE_DECL:
- fprintf(MR_mdb_out,
- "IO tabled predicates do not have their own tables.\n");
- return KEEP_INTERACTING;
- }
-
- /*
- ** words[0] is the command, words[1] is the procedure spec;
- ** words[2] is the first argument. We step over the command and the
- ** procedure spec, to leave words[] containing only the argument
- ** values.
- */
-
- words += 2;
- word_count -= 2;
-
- table_gen = proc->MR_sle_table_info.MR_table_gen;
- num_inputs = table_gen->MR_table_gen_num_inputs;
-
- if (word_count > num_inputs) {
- fprintf(MR_mdb_out, "There are only %d input arguments.\n",
- num_inputs);
- return KEEP_INTERACTING;
- }
-
- call_table_args = MR_GC_NEW_ARRAY(MR_Call_Table_Arg, num_inputs);
- if (call_table_args == NULL) {
- MR_fatal_error("MR_trace_cmd_table: "
- "couldn't allocate call_table_args");
- }
-
- table_cur = proc->MR_sle_tabling_pointer;
- for (cur_arg = 0, filtered_cur_arg = 0; cur_arg < num_inputs; cur_arg++) {
- switch (table_gen->MR_table_gen_input_steps[cur_arg]) {
- case MR_TABLE_STEP_INT:
- case MR_TABLE_STEP_FLOAT:
- case MR_TABLE_STEP_STRING:
- /* these are OK */
- call_table_args[filtered_cur_arg].MR_cta_step =
- table_gen->MR_table_gen_input_steps[filtered_cur_arg];
- call_table_args[filtered_cur_arg].MR_cta_valid = MR_FALSE;
- call_table_args[filtered_cur_arg].MR_cta_unfiltered_arg_num =
- cur_arg;
- filtered_cur_arg++;
-
- case MR_TABLE_STEP_PROMISE_IMPLIED:
- /* this argument doesn't exist in the table */
- break;
-
- default:
- fprintf(MR_mdb_out, "Sorry, can handle only "
- "integer, float and string arguments for now.\n");
- MR_GC_free(call_table_args);
- return KEEP_INTERACTING;
- }
- }
-
- filtered_num_inputs = filtered_cur_arg;
- if (word_count > filtered_num_inputs) {
- fprintf(MR_mdb_out,
- "Sorry, this procedure has only %d tabled arguments\n",
- filtered_num_inputs);
- MR_GC_free(call_table_args);
- return KEEP_INTERACTING;
- }
-
- /*
- ** Set up the values of the input arguments supplied on the command
- ** line, to enable us to print them out in each call table entry.
- */
-
- for (filtered_cur_arg = 0;
- filtered_cur_arg < word_count;
- filtered_cur_arg++)
- {
- MR_bool success;
-
- switch (call_table_args[filtered_cur_arg].MR_cta_step) {
- case MR_TABLE_STEP_INT:
- success = MR_trace_fill_in_int_table_arg_slot(&table_cur,
- filtered_cur_arg + 1, words[filtered_cur_arg],
- &call_table_args[filtered_cur_arg]);
- break;
-
- case MR_TABLE_STEP_FLOAT:
- success = MR_trace_fill_in_float_table_arg_slot(&table_cur,
- filtered_cur_arg + 1, words[filtered_cur_arg],
- &call_table_args[filtered_cur_arg]);
- break;
-
- case MR_TABLE_STEP_STRING:
- success = MR_trace_fill_in_string_table_arg_slot(&table_cur,
- filtered_cur_arg + 1, words[filtered_cur_arg],
- &call_table_args[filtered_cur_arg]);
- break;
-
- default:
- MR_fatal_error("arg not int, float or string after check");
- }
-
- if (! success) {
- /* the error message has already been printed */
- MR_GC_free(call_table_args);
- return KEEP_INTERACTING;
- }
- }
-
- if (word_count == filtered_num_inputs) {
- /*
- ** The user specified values for all the input arguments,
- ** so what we print is a single entry, not a table of entries,
- ** and we don't need to loop over all the entries.
- */
-
- MR_trace_cmd_table_print_tip(proc, filtered_num_inputs,
- call_table_args, table_cur);
- MR_GC_free(call_table_args);
- return KEEP_INTERACTING;
- }
-
- /*
- ** The user left the values of some input arguments unspecified,
- ** so we print a table of entries. Here we print the header.
- */
-
- switch (MR_sle_eval_method(proc)) {
- case MR_EVAL_METHOD_LOOP_CHECK:
- fprintf(MR_mdb_out, "loopcheck table for ");
- MR_print_proc_id(MR_mdb_out, proc);
- fprintf(MR_mdb_out, ":\n");
- break;
-
- case MR_EVAL_METHOD_MEMO_STRICT:
- case MR_EVAL_METHOD_MEMO_FAST_LOOSE:
- case MR_EVAL_METHOD_MEMO_SPECIFIED:
- fprintf(MR_mdb_out, "memo table for ");
- MR_print_proc_id(MR_mdb_out, proc);
- fprintf(MR_mdb_out, ":\n");
- break;
-
- case MR_EVAL_METHOD_MINIMAL_STACK_COPY:
- case MR_EVAL_METHOD_MINIMAL_OWN_STACKS:
- fprintf(MR_mdb_out, "minimal model table for ");
- MR_print_proc_id(MR_mdb_out, proc);
- fprintf(MR_mdb_out, ":\n");
- break;
-
- case MR_EVAL_METHOD_NORMAL:
- case MR_EVAL_METHOD_TABLE_IO:
- case MR_EVAL_METHOD_TABLE_IO_DECL:
- case MR_EVAL_METHOD_TABLE_IO_UNITIZE:
- case MR_EVAL_METHOD_TABLE_IO_UNITIZE_DECL:
- MR_fatal_error("MR_trace_cmd_table: bad eval method");
- }
-
- /*
- ** This loop prints the entries in the table.
- **
- ** If we knew in advance that the user left (say) two input argument
- ** positions unspecified, we could use a loop structure such as:
- **
- ** for value1 in <values in the trie at node start_node[0]>
- ** cur_value[1] = value1
- ** start_node[1] = follow value1 in start_node[0]
- ** for value2 in <values in the trie at node start_node[1]>
- ** cur_value[2] = value2
- ** start_node[2] = follow value2 in start_node[1]
- ** print <fixed args>, cur_value[1], cur_value[2]
- ** end for
- ** end for
- **
- ** However, we don't know in advance how many input arguments the user
- ** left unspecified. We therefore simulate the above with a single
- ** loop, which can function as any one of the above nested loops.
- **
- ** The value of cur_arg controls which one it is simulating at any
- ** given time. Initially, cur_arg grows as we enter each of the above
- ** loops one after another, at each stage recording the set of values
- ** in the current trie node in the values array of the relevant
- ** argument.
- **
- ** We number the input arguments from 0 to filtered_num_inputs-1.
- ** When cur_arg becomes equal to filtered_num_inputs, this means that
- ** we have values for all the tabled input arguments, so we print the
- ** corresponding call table entry. We then initiate backtracking:
- ** we decrement cur_arg to get the next value of the last argument.
- ** We also do this whenever we run out of values in any trie.
- **
- ** We stop when we are about to backtrack out of the outermost loop.
- */
-
- cur_arg = word_count;
- num_tips = 0;
- for (;;) {
- MR_bool no_more;
- MR_bool start_backtrack;
-
- switch (call_table_args[cur_arg].MR_cta_step) {
- case MR_TABLE_STEP_INT:
- no_more = MR_update_int_table_arg_slot(&table_cur,
- &call_table_args[cur_arg]);
- break;
-
- case MR_TABLE_STEP_FLOAT:
- no_more = MR_update_float_table_arg_slot(&table_cur,
- &call_table_args[cur_arg]);
- break;
-
- case MR_TABLE_STEP_STRING:
- no_more = MR_update_string_table_arg_slot(&table_cur,
- &call_table_args[cur_arg]);
- break;
-
- default:
- MR_fatal_error("arg not int, float or string after check");
- }
-
- if (no_more) {
- /*
- ** There aren't any more values in the current trie
- ** of input argument cur_arg.
- */
-
- start_backtrack = MR_TRUE;
- } else {
- /*
- ** There is at least one more value in the current trie
- ** of input argument cur_arg, so go on to the next trie
- ** (if there is one).
- */
-
- cur_arg++;
-
- if (cur_arg >= filtered_num_inputs) {
- MR_trace_cmd_table_print_tip(proc, filtered_num_inputs,
- call_table_args, table_cur);
- num_tips++;
- start_backtrack = MR_TRUE;
- } else {
- start_backtrack = MR_FALSE;
- }
- }
-
- if (start_backtrack) {
- cur_arg--;
- table_cur = call_table_args[cur_arg].MR_cta_start_node;
-
- if (cur_arg < word_count) {
- break;
- }
- }
- }
-
- fprintf(MR_mdb_out, "end of table (%d %s)\n",
- num_tips, (num_tips == 1 ? "entry" : "entries"));
- MR_GC_free(call_table_args);
- return KEEP_INTERACTING;
-}
-
-static MR_bool
-MR_trace_fill_in_int_table_arg_slot(MR_TrieNode *table_cur_ptr,
- int arg_num, MR_ConstString given_arg,
- MR_Call_Table_Arg *call_table_arg_ptr)
-{
- MR_Integer n;
- MR_TrieNode table_next;
-
- if (! MR_trace_is_integer(given_arg, &n)) {
- fprintf(MR_mdb_out, "argument %d is not an integer.\n", arg_num);
- return MR_FALSE;
- }
-
- table_next = MR_int_hash_lookup(*table_cur_ptr, n);
- if (table_next == NULL) {
- fprintf(MR_mdb_out,
- "call table does not contain %" MR_INTEGER_LENGTH_MODIFIER "d"
- " in argument position %d.\n", n, arg_num);
- return MR_FALSE;
- }
-
- call_table_arg_ptr->MR_cta_start_node = *table_cur_ptr;
- call_table_arg_ptr->MR_cta_valid = MR_TRUE;
- call_table_arg_ptr->MR_cta_int_values = NULL;
- call_table_arg_ptr->MR_cta_int_value_next = -1;
- call_table_arg_ptr->MR_cta_int_cur_index = -1;
- call_table_arg_ptr->MR_cta_int_cur_value = n;
- *table_cur_ptr = table_next;
-
- return MR_TRUE;
-}
-
-static MR_bool
-MR_trace_fill_in_float_table_arg_slot(MR_TrieNode *table_cur_ptr,
- int arg_num, MR_ConstString given_arg,
- MR_Call_Table_Arg *call_table_arg_ptr)
-{
- MR_Float f;
- MR_TrieNode table_next;
-
- if (! MR_trace_is_float(given_arg, &f)) {
- fprintf(MR_mdb_out, "argument %d is not a float.\n", arg_num);
- return MR_FALSE;
- }
-
- table_next = MR_float_hash_lookup(*table_cur_ptr, f);
- if (table_next == NULL) {
- fprintf(MR_mdb_out,
- "call table does not contain %f in argument position %d.\n",
- f, arg_num);
- return MR_FALSE;
- }
-
- call_table_arg_ptr->MR_cta_start_node = *table_cur_ptr;
- call_table_arg_ptr->MR_cta_valid = MR_TRUE;
- call_table_arg_ptr->MR_cta_float_values = NULL;
- call_table_arg_ptr->MR_cta_float_value_next = -1;
- call_table_arg_ptr->MR_cta_float_cur_index = -1;
- call_table_arg_ptr->MR_cta_float_cur_value = f;
- *table_cur_ptr = table_next;
-
- return MR_TRUE;
-}
-
-static MR_bool
-MR_trace_fill_in_string_table_arg_slot(MR_TrieNode *table_cur_ptr,
- int arg_num, MR_ConstString given_arg,
- MR_Call_Table_Arg *call_table_arg_ptr)
-{
- MR_ConstString s;
- MR_TrieNode table_next;
-
- s = given_arg;
-
- table_next = MR_string_hash_lookup(*table_cur_ptr, s);
- if (table_next == NULL) {
- fprintf(MR_mdb_out,
- "call table does not contain %s in argument position %d.\n",
- s, arg_num);
- return MR_FALSE;
- }
-
- call_table_arg_ptr->MR_cta_start_node = *table_cur_ptr;
- call_table_arg_ptr->MR_cta_valid = MR_TRUE;
- call_table_arg_ptr->MR_cta_string_values = NULL;
- call_table_arg_ptr->MR_cta_string_value_next = -1;
- call_table_arg_ptr->MR_cta_string_cur_index = -1;
- call_table_arg_ptr->MR_cta_string_cur_value = s;
- *table_cur_ptr = table_next;
-
- return MR_TRUE;
-}
-
-static MR_bool
-MR_update_int_table_arg_slot(MR_TrieNode *table_cur_ptr,
- MR_Call_Table_Arg *call_table_arg_ptr)
-{
- MR_TrieNode table_next;
- MR_Integer *values;
- int value_next;
-
- if (call_table_arg_ptr->MR_cta_valid
- && call_table_arg_ptr->MR_cta_int_values != NULL)
- {
- call_table_arg_ptr->MR_cta_int_cur_index++;
- } else {
- if (! MR_get_int_hash_table_contents(*table_cur_ptr,
- &values, &value_next))
- {
- /* there are no values in this trie node */
- call_table_arg_ptr->MR_cta_valid = MR_FALSE;
- return MR_TRUE;
- }
-
- call_table_arg_ptr->MR_cta_start_node = *table_cur_ptr;
- call_table_arg_ptr->MR_cta_valid = MR_TRUE;
- call_table_arg_ptr->MR_cta_int_values = values;
- call_table_arg_ptr->MR_cta_int_value_next = value_next;
- call_table_arg_ptr->MR_cta_int_cur_index = 0;
- }
-
- if (call_table_arg_ptr->MR_cta_int_cur_index
- >= call_table_arg_ptr->MR_cta_int_value_next)
- {
- /* we have already returned all the values in this trie node */
- call_table_arg_ptr->MR_cta_valid = MR_FALSE;
- return MR_TRUE;
- }
-
- call_table_arg_ptr->MR_cta_int_cur_value =
- call_table_arg_ptr->MR_cta_int_values[
- call_table_arg_ptr->MR_cta_int_cur_index];
-
- table_next = MR_int_hash_lookup(call_table_arg_ptr->MR_cta_start_node,
- call_table_arg_ptr->MR_cta_int_cur_value);
-
- if (table_next == NULL) {
- MR_fatal_error("MR_update_int_table_arg_slot: bad lookup");
- }
-
- *table_cur_ptr = table_next;
- return MR_FALSE;
-}
-
-static MR_bool
-MR_update_float_table_arg_slot(MR_TrieNode *table_cur_ptr,
- MR_Call_Table_Arg *call_table_arg_ptr)
-{
- MR_TrieNode table_next;
- MR_Float *values;
- int value_next;
-
- if (call_table_arg_ptr->MR_cta_valid
- && call_table_arg_ptr->MR_cta_float_values != NULL)
- {
- call_table_arg_ptr->MR_cta_float_cur_index++;
- } else {
- if (! MR_get_float_hash_table_contents(*table_cur_ptr,
- &values, &value_next))
- {
- /* there are no values in this trie node */
- call_table_arg_ptr->MR_cta_valid = MR_FALSE;
- return MR_TRUE;
- }
-
- call_table_arg_ptr->MR_cta_start_node = *table_cur_ptr;
- call_table_arg_ptr->MR_cta_valid = MR_TRUE;
- call_table_arg_ptr->MR_cta_float_values = values;
- call_table_arg_ptr->MR_cta_float_value_next = value_next;
- call_table_arg_ptr->MR_cta_float_cur_index = 0;
- }
-
- if (call_table_arg_ptr->MR_cta_float_cur_index
- >= call_table_arg_ptr->MR_cta_float_value_next)
- {
- /* we have already returned all the values in this trie node */
- call_table_arg_ptr->MR_cta_valid = MR_FALSE;
- return MR_TRUE;
- }
-
- call_table_arg_ptr->MR_cta_float_cur_value =
- call_table_arg_ptr->MR_cta_float_values[
- call_table_arg_ptr->MR_cta_float_cur_index];
-
- table_next = MR_float_hash_lookup(call_table_arg_ptr->MR_cta_start_node,
- call_table_arg_ptr->MR_cta_float_cur_value);
-
- if (table_next == NULL) {
- MR_fatal_error("MR_update_float_table_arg_slot: bad lookup");
- }
-
- *table_cur_ptr = table_next;
- return MR_FALSE;
-}
-
-static MR_bool
-MR_update_string_table_arg_slot(MR_TrieNode *table_cur_ptr,
- MR_Call_Table_Arg *call_table_arg_ptr)
-{
- MR_TrieNode table_next;
- MR_ConstString *values;
- int value_next;
-
- if (call_table_arg_ptr->MR_cta_valid
- && call_table_arg_ptr->MR_cta_string_values != NULL)
- {
- call_table_arg_ptr->MR_cta_string_cur_index++;
- } else {
- if (! MR_get_string_hash_table_contents(*table_cur_ptr,
- &values, &value_next))
- {
- /* there are no values in this trie node */
- call_table_arg_ptr->MR_cta_valid = MR_FALSE;
- return MR_TRUE;
- }
-
- call_table_arg_ptr->MR_cta_start_node = *table_cur_ptr;
- call_table_arg_ptr->MR_cta_valid = MR_TRUE;
- call_table_arg_ptr->MR_cta_string_values = values;
- call_table_arg_ptr->MR_cta_string_value_next = value_next;
- call_table_arg_ptr->MR_cta_string_cur_index = 0;
- }
-
- if (call_table_arg_ptr->MR_cta_string_cur_index
- >= call_table_arg_ptr->MR_cta_string_value_next)
- {
- /* we have already returned all the values in this trie node */
- call_table_arg_ptr->MR_cta_valid = MR_FALSE;
- return MR_TRUE;
- }
-
- call_table_arg_ptr->MR_cta_string_cur_value =
- call_table_arg_ptr->MR_cta_string_values[
- call_table_arg_ptr->MR_cta_string_cur_index];
-
- table_next = MR_string_hash_lookup(
- call_table_arg_ptr->MR_cta_start_node,
- call_table_arg_ptr->MR_cta_string_cur_value);
-
- if (table_next == NULL) {
- MR_fatal_error("MR_update_string_table_arg_slot: bad lookup");
- }
-
- *table_cur_ptr = table_next;
- return MR_FALSE;
-}
-
-static void
-MR_trace_cmd_table_print_tip(const MR_Proc_Layout *proc,
- int num_filtered_inputs, MR_Call_Table_Arg *call_table_args,
- MR_TrieNode table)
-{
- int i;
- MR_EvalMethod eval_method;
-
- fprintf(MR_mdb_out, "<");
- for (i = 0; i < num_filtered_inputs; i++) {
- if (i > 0) {
- fprintf(MR_mdb_out, ", ");
- }
-
- switch (call_table_args[i].MR_cta_step) {
- case MR_TABLE_STEP_INT:
- fprintf(MR_mdb_out, "%" MR_INTEGER_LENGTH_MODIFIER "d",
- call_table_args[i].MR_cta_int_cur_value);
- break;
-
- case MR_TABLE_STEP_FLOAT:
- fprintf(MR_mdb_out, "%f",
- call_table_args[i].MR_cta_float_cur_value);
- break;
-
- case MR_TABLE_STEP_STRING:
- fprintf(MR_mdb_out, "\"%s\"",
- call_table_args[i].MR_cta_string_cur_value);
- break;
-
- default:
- MR_fatal_error("arg not int, float or string after check");
- }
- }
-
- fprintf(MR_mdb_out, ">: ");
-
- eval_method = MR_sle_eval_method(proc);
- switch (eval_method) {
- case MR_EVAL_METHOD_MINIMAL_STACK_COPY:
- {
- MR_Subgoal *subgoal;
- int subgoal_num;
-
- fprintf(MR_mdb_out, "trie node %p\n", table);
- subgoal = table->MR_subgoal;
- if (subgoal == NULL) {
- fprintf(MR_mdb_out, "uninitialized\n");
- } else {
- MR_trace_print_subgoal(proc, subgoal);
- }
- }
- break;
-
- case MR_EVAL_METHOD_MINIMAL_OWN_STACKS:
- {
- MR_GeneratorPtr generator;
-
- fprintf(MR_mdb_out, "trie node %p\n", table);
- generator = table->MR_generator;
- if (generator == NULL) {
- fprintf(MR_mdb_out, "uninitialized\n");
- } else {
- MR_trace_print_generator(proc, generator);
- }
- }
- break;
-
- case MR_EVAL_METHOD_MEMO_STRICT:
- case MR_EVAL_METHOD_MEMO_FAST_LOOSE:
- case MR_EVAL_METHOD_MEMO_SPECIFIED:
- {
- MR_Determinism detism;
-
- detism = proc->MR_sle_detism;
- if (MR_DETISM_DET_STACK(detism)) {
- MR_print_memo_tip(MR_mdb_out, proc, table);
- } else {
- MR_MemoNonRecordPtr record;
-
- record = table->MR_memo_non_record;
- MR_print_memo_non_record(MR_mdb_out, proc, record);
- }
- }
- break;
-
- case MR_EVAL_METHOD_LOOP_CHECK:
- MR_print_loopcheck_tip(MR_mdb_out, proc, table);
- break;
-
- case MR_EVAL_METHOD_NORMAL:
- case MR_EVAL_METHOD_TABLE_IO:
- case MR_EVAL_METHOD_TABLE_IO_DECL:
- case MR_EVAL_METHOD_TABLE_IO_UNITIZE:
- case MR_EVAL_METHOD_TABLE_IO_UNITIZE_DECL:
- MR_fatal_error("MR_trace_cmd_table_print_tip: bad eval method");
- break;
- }
-}
-
-static void
-MR_trace_print_subgoal(const MR_Proc_Layout *proc, MR_Subgoal *subgoal)
-{
-#ifdef MR_USE_MINIMAL_MODEL_STACK_COPY
- MR_print_subgoal(MR_mdb_out, proc, subgoal);
-#else
- fprintf(MR_mdb_out, "minimal model tabling is not enabled\n");
-#endif
-}
-
-static void
-MR_trace_print_subgoal_debug(const MR_Proc_Layout *proc,
- MR_SubgoalDebug *subgoal_debug)
-{
-#ifdef MR_USE_MINIMAL_MODEL_STACK_COPY
- MR_print_subgoal_debug(MR_mdb_out, proc, subgoal_debug);
-#else
- fprintf(MR_mdb_out, "minimal model tabling is not enabled\n");
-#endif
-}
-
-static void
-MR_trace_print_generator(const MR_Proc_Layout *proc, MR_Generator *generator)
-{
-#ifdef MR_USE_MINIMAL_MODEL_OWN_STACKS
- MR_print_generator(MR_mdb_out, proc, generator);
-#else
- fprintf(MR_mdb_out, "minimal model tabling is not enabled\n");
-#endif
-}
-
-static void
-MR_trace_print_generator_debug(const MR_Proc_Layout *proc,
- MR_GenDebug *generator_debug)
-{
-#ifdef MR_USE_MINIMAL_MODEL_OWN_STACKS
- MR_print_gen_debug(MR_mdb_out, proc, generator_debug);
-#else
- fprintf(MR_mdb_out, "minimal model tabling is not enabled\n");
-#endif
-}
-
-static void
-MR_trace_print_consumer(const MR_Proc_Layout *proc, MR_Consumer *consumer)
-{
-#if defined(MR_USE_MINIMAL_MODEL_STACK_COPY) \
- || defined(MR_USE_MINIMAL_MODEL_OWN_STACKS)
- MR_print_consumer(MR_mdb_out, proc, consumer);
-#else
- fprintf(MR_mdb_out, "minimal model tabling is not enabled\n");
-#endif
-}
-
-static void
-MR_trace_print_consumer_debug(const MR_Proc_Layout *proc,
- MR_ConsumerDebug *consumer_debug)
-{
-#if defined(MR_USE_MINIMAL_MODEL_STACK_COPY)
- MR_print_consumer_debug(MR_mdb_out, proc, consumer_debug);
-#elif defined(MR_USE_MINIMAL_MODEL_STACK_COPY)
- MR_print_cons_debug(MR_mdb_out, proc, consumer_debug);
-#else
- fprintf(MR_mdb_out, "minimal model tabling is not enabled\n");
-#endif
-}
-
-static MR_Next
-MR_trace_cmd_type_ctor(char **words, int word_count,
- MR_Trace_Cmd_Info *cmd, MR_Event_Info *event_info, MR_Code **jumpaddr)
-{
- const char *module_name;
- const char *name;
- int arity;
- MR_bool print_rep;
- MR_bool print_functors;
- MR_TypeCtorInfo type_ctor_info;
-
- MR_do_init_modules_type_tables();
-
- print_rep = MR_FALSE;
- print_functors = MR_FALSE;
- if (! MR_trace_options_type_ctor(&print_rep, &print_functors,
- &words, &word_count))
- {
- ; /* the usage message has already been printed */
- } else if (word_count == 4 &&
- MR_trace_is_natural_number(words[3], &arity))
- {
- module_name = words[1];
- name = words[2];
- type_ctor_info = MR_lookup_type_ctor_info(module_name, name, arity);
- if (type_ctor_info != NULL) {
- MR_print_type_ctor_info(MR_mdb_out, type_ctor_info, print_rep,
- print_functors);
- } else {
- fprintf(MR_mdb_out, "there is no such type constructor\n");
- }
- } else {
- MR_trace_usage_cur_cmd();
- }
-
- return KEEP_INTERACTING;
-}
-
-static MR_Next
-MR_trace_cmd_class_decl(char **words, int word_count,
- MR_Trace_Cmd_Info *cmd, MR_Event_Info *event_info, MR_Code **jumpaddr)
-{
- const char *module_name;
- const char *name;
- int arity;
- MR_bool print_methods;
- MR_bool print_instances;
- MR_TypeClassDeclInfo *type_class_decl_info;
-
- MR_do_init_modules_type_tables();
-
- print_methods = MR_FALSE;
- print_instances = MR_FALSE;
- if (! MR_trace_options_class_decl(&print_methods, &print_instances,
- &words, &word_count))
- {
- ; /* the usage message has already been printed */
- } else if (word_count == 4 &&
- MR_trace_is_natural_number(words[3], &arity))
- {
- module_name = words[1];
- name = words[2];
- type_class_decl_info = MR_lookup_type_class_decl_info(module_name,
- name, arity);
- if (type_class_decl_info != NULL) {
- MR_print_class_decl_info(MR_mdb_out, type_class_decl_info,
- print_methods, print_instances);
- } else {
- fprintf(MR_mdb_out, "there is no such type class\n");
- }
- } else {
- MR_trace_usage_cur_cmd();
- }
-
- return KEEP_INTERACTING;
-}
-
-static MR_Next
-MR_trace_cmd_all_type_ctors(char **words, int word_count,
- MR_Trace_Cmd_Info *cmd, MR_Event_Info *event_info, MR_Code **jumpaddr)
-{
- MR_bool print_rep;
- MR_bool print_functors;
- MR_Dlist *list;
- MR_Dlist *element_ptr;
- MR_TypeCtorInfo type_ctor_info;
- const char *module_name;
- int count;
-
- MR_do_init_modules_type_tables();
-
- print_rep = MR_FALSE;
- print_functors = MR_FALSE;
- if (! MR_trace_options_type_ctor(&print_rep, &print_functors,
- &words, &word_count))
- {
- ; /* the usage message has already been printed */
- } else if (word_count == 1 || word_count == 2) {
- if (word_count == 2) {
- module_name = words[1];
- } else {
- module_name = NULL;
- }
-
- list = MR_all_type_ctor_infos(NULL);
- count = 0;
- MR_for_dlist(element_ptr, list) {
- type_ctor_info = (MR_TypeCtorInfo) MR_dlist_data(element_ptr);
- if (module_name != NULL && strcmp(module_name,
- type_ctor_info->MR_type_ctor_module_name) != 0)
- {
- continue;
- }
-
- if (count > 0) {
- fprintf(MR_mdb_out, "\n");
- }
- MR_print_type_ctor_info(MR_mdb_out, type_ctor_info, print_rep,
- print_functors);
- count++;
- }
-
- fprintf(MR_mdb_out, "\nnumber of type constructors ");
- if (module_name == NULL) {
- fprintf(MR_mdb_out, "in the program: %d\n", count);
- } else {
- fprintf(MR_mdb_out, "in module %s: %d\n", module_name, count);
- }
- } else {
- MR_trace_usage_cur_cmd();
- }
-
- return KEEP_INTERACTING;
-}
-
-static MR_Next
-MR_trace_cmd_all_class_decls(char **words, int word_count,
- MR_Trace_Cmd_Info *cmd, MR_Event_Info *event_info, MR_Code **jumpaddr)
-{
- MR_bool print_methods;
- MR_bool print_instances;
- MR_Dlist *list;
- MR_Dlist *element_ptr;
- MR_TypeClassDeclInfo *type_class_decl_info;
- const char *module_name;
- int count;
-
- MR_do_init_modules_type_tables();
-
- print_methods = MR_FALSE;
- print_instances = MR_FALSE;
- if (! MR_trace_options_class_decl(&print_methods, &print_instances,
- &words, &word_count))
- {
- ; /* the usage message has already been printed */
- } else if (word_count == 1 || word_count == 2) {
- if (word_count == 2) {
- module_name = words[1];
- } else {
- module_name = NULL;
- }
- list = MR_all_type_class_decl_infos(NULL);
- count = 0;
- MR_for_dlist(element_ptr, list) {
- type_class_decl_info = (MR_TypeClassDeclInfo *)
- MR_dlist_data(element_ptr);
- if (module_name != NULL && strcmp(module_name,
- type_class_decl_info->MR_tcd_info_decl->
- MR_tc_decl_id->MR_tc_id_module_name) != 0)
- {
- continue;
- }
-
- if (count > 0) {
- fprintf(MR_mdb_out, "\n");
- }
- MR_print_class_decl_info(MR_mdb_out, type_class_decl_info,
- print_methods, print_instances);
- count++;
- }
-
- fprintf(MR_mdb_out, "\nnumber of type classes ");
- if (module_name == NULL) {
- fprintf(MR_mdb_out, "in the program: %d\n", count);
- } else {
- fprintf(MR_mdb_out, "in module %s: %d\n", module_name, count);
- }
- } else {
- MR_trace_usage_cur_cmd();
- }
-
- return KEEP_INTERACTING;
-}
-
-static MR_Next
-MR_trace_cmd_all_procedures(char **words, int word_count,
- MR_Trace_Cmd_Info *cmd, MR_Event_Info *event_info, MR_Code **jumpaddr)
-{
- const char *filename;
- MR_bool separate;
- MR_bool uci;
- FILE *fp;
- char *module;
-
- MR_register_all_modules_and_procs(MR_mdb_out, MR_TRUE);
-
- separate = MR_FALSE;
- uci = MR_FALSE;
- module = NULL;
- if (! MR_trace_options_all_procedures(&separate, &uci, &module,
- &words, &word_count))
- {
- ; /* the usage message has already been printed */
- } else if (word_count == 2) {
- filename = words[1];
- fp = fopen(filename, "w");
- if (fp == NULL) {
- fflush(MR_mdb_out);
- fprintf(MR_mdb_err, "mdb: error opening `%s': %s.\n",
- filename, strerror(errno));
- return KEEP_INTERACTING;
- }
-
- MR_dump_module_tables(fp, separate, uci, module);
- if (fclose(fp) != 0) {
- fprintf(MR_mdb_err, "mdb: error writing to `%s': %s.\n",
- filename, strerror(errno));
- return KEEP_INTERACTING;
- } else {
- fprintf(MR_mdb_out, "mdb: wrote table to `%s'.\n", filename);
- }
- } else {
- MR_trace_usage_cur_cmd();
- }
-
- return KEEP_INTERACTING;
-}
-
-static MR_Next
-MR_trace_cmd_ambiguity(char **words, int word_count,
- MR_Trace_Cmd_Info *cmd, MR_Event_Info *event_info, MR_Code **jumpaddr)
-{
- const char *filename;
- FILE *fp;
- int i;
-
- filename = NULL;
- if (! MR_trace_options_ambiguity(&filename, &words, &word_count)) {
- ; /* the usage message has already been printed */
- } else {
- MR_register_all_modules_and_procs(MR_mdb_out, MR_TRUE);
-
- if (filename == NULL) {
- fp = MR_mdb_out;
- } else {
- fp = fopen(filename, "w");
- if (fp == NULL) {
- fflush(MR_mdb_out);
- fprintf(MR_mdb_err, "mdb: error opening `%s': %s.\n",
- filename, strerror(errno));
- return KEEP_INTERACTING;
- }
- }
-
- /*
- ** The words on the command line after the command name and the already
- ** processed options are a list of modules names. If this list is not
- ** empty, then we consider only the modules named here when looking for
- ** ambiguities.
- */
-
- MR_print_ambiguities(fp, &words[1], word_count - 1);
-
- if (filename != NULL) {
- fprintf(MR_mdb_out, "mdb: wrote report to `%s'.\n", filename);
- fclose(fp);
- }
- }
-
- return KEEP_INTERACTING;
-}
-
-static void
-MR_print_type_ctor_info(FILE *fp, MR_TypeCtorInfo type_ctor_info,
- MR_bool print_rep, MR_bool print_functors)
-{
- MR_TypeCtorRep rep;
- MR_EnumFunctorDesc *enum_functor;
- MR_DuFunctorDesc *du_functor;
- MR_MaybeResAddrFunctorDesc *maybe_res_functor;
- MR_NotagFunctorDesc *notag_functor;
- int num_functors;
- int i;
-
- fprintf(fp, "type constructor %s.%s/%d",
- type_ctor_info->MR_type_ctor_module_name,
- type_ctor_info->MR_type_ctor_name,
- (int) type_ctor_info->MR_type_ctor_arity);
-
- rep = MR_type_ctor_rep(type_ctor_info);
- if (print_rep) {
- fprintf(fp, ": %s\n", MR_ctor_rep_name[MR_GET_ENUM_VALUE(rep)]);
- } else {
- fprintf(fp, "\n");
- }
-
- if (print_functors) {
- num_functors = type_ctor_info->MR_type_ctor_num_functors;
- switch (rep) {
- case MR_TYPECTOR_REP_ENUM:
- case MR_TYPECTOR_REP_ENUM_USEREQ:
- for (i = 0; i < num_functors; i++) {
- enum_functor = type_ctor_info->MR_type_ctor_functors.
- MR_functors_enum[i];
- if (i > 0) {
- fprintf(fp, ", ");
- }
- fprintf(fp, "%s/0", enum_functor->MR_enum_functor_name);
- }
- fprintf(fp, "\n");
- break;
-
- case MR_TYPECTOR_REP_DU:
- case MR_TYPECTOR_REP_DU_USEREQ:
- for (i = 0; i < num_functors; i++) {
- du_functor = type_ctor_info->MR_type_ctor_functors.
- MR_functors_du[i];
- if (i > 0) {
- fprintf(fp, ", ");
- }
- fprintf(fp, "%s/%d", du_functor->MR_du_functor_name,
- du_functor-> MR_du_functor_orig_arity);
- }
- fprintf(fp, "\n");
- break;
-
- case MR_TYPECTOR_REP_RESERVED_ADDR:
- case MR_TYPECTOR_REP_RESERVED_ADDR_USEREQ:
- for (i = 0; i < num_functors; i++) {
- maybe_res_functor = &type_ctor_info->MR_type_ctor_functors.
- MR_functors_res[i];
- if (i > 0) {
- fprintf(fp, ", ");
- }
- fprintf(fp, "%s/%d", maybe_res_functor->MR_maybe_res_name,
- (int) maybe_res_functor-> MR_maybe_res_arity);
- }
- fprintf(fp, "\n");
- break;
-
- case MR_TYPECTOR_REP_NOTAG:
- case MR_TYPECTOR_REP_NOTAG_USEREQ:
- case MR_TYPECTOR_REP_NOTAG_GROUND:
- case MR_TYPECTOR_REP_NOTAG_GROUND_USEREQ:
- notag_functor = type_ctor_info->MR_type_ctor_functors.
- MR_functors_notag;
- fprintf(fp, "%s/1\n", notag_functor->MR_notag_functor_name);
- break;
-
- default:
- break;
- }
- }
-}
-
-static void
-MR_print_class_decl_info(FILE *fp, MR_TypeClassDeclInfo *type_class_decl_info,
- MR_bool print_methods, MR_bool print_instances)
-{
- MR_TypeClassDecl type_class_decl;
- const MR_TypeClassId *type_class_id;
- const MR_TypeClassMethod *method;
- MR_Instance instance;
- MR_Dlist *list;
- MR_Dlist *element_ptr;
- int num_methods;
- int i;
-
- type_class_decl = type_class_decl_info->MR_tcd_info_decl;
- type_class_id = type_class_decl->MR_tc_decl_id;
- fprintf(fp, "type class %s.%s/%d\n",
- type_class_id->MR_tc_id_module_name,
- type_class_id->MR_tc_id_name,
- type_class_id->MR_tc_id_arity);
-
- if (print_methods) {
- num_methods = type_class_id->MR_tc_id_num_methods;
- fprintf(fp, "methods: ");
-
- for (i = 0; i < num_methods; i++) {
- if (i > 0) {
- fprintf(fp, ", ");
- }
-
- method = &type_class_id->MR_tc_id_methods[i];
- if (method->MR_tc_method_pred_func == MR_FUNCTION) {
- fprintf(fp, "func ");
- } else {
- fprintf(fp, "pred ");
- }
-
- fprintf(fp, "%s/%d", method->MR_tc_method_name,
- method->MR_tc_method_arity);
- }
-
- fprintf(fp, "\n");
- }
-
- if (print_instances) {
- list = type_class_decl_info->MR_tcd_info_instances;
- MR_for_dlist (element_ptr, list) {
- instance = (MR_Instance) MR_dlist_data(element_ptr);
-
- if (instance->MR_tc_inst_type_class != type_class_decl) {
- MR_fatal_error("instance/type class mismatch");
- }
-
- fprintf(fp, "instance ");
-
- for (i = 0; i < type_class_id->MR_tc_id_arity; i++) {
- if (i > 0) {
- fprintf(fp, ", ");
- }
-
- MR_print_pseudo_type_info(fp,
- instance->MR_tc_inst_type_args[i]);
- }
-
- fprintf(fp, "\n");
- }
- }
-}
-
-static void
-MR_print_pseudo_type_info(FILE *fp, MR_PseudoTypeInfo pseudo)
-{
- MR_TypeCtorInfo type_ctor_info;
- MR_PseudoTypeInfo *pseudo_args;
- MR_Integer tvar_num;
- int arity;
- int i;
-
- if (MR_PSEUDO_TYPEINFO_IS_VARIABLE(pseudo)) {
- tvar_num = (MR_Integer) pseudo;
- fprintf(fp, "T%d", (int) tvar_num);
- } else {
- type_ctor_info = MR_PSEUDO_TYPEINFO_GET_TYPE_CTOR_INFO(pseudo);
- fprintf(fp, "%s.%s",
- type_ctor_info->MR_type_ctor_module_name,
- type_ctor_info->MR_type_ctor_name);
- if (MR_type_ctor_has_variable_arity(type_ctor_info)) {
- arity = MR_PSEUDO_TYPEINFO_GET_VAR_ARITY_ARITY(pseudo);
- pseudo_args = (MR_PseudoTypeInfo *)
- &pseudo->MR_pti_var_arity_arity;
- } else {
- arity = type_ctor_info->MR_type_ctor_arity;
- pseudo_args = (MR_PseudoTypeInfo *) &pseudo->MR_pti_type_ctor_info;
- }
-
- if (type_ctor_info->MR_type_ctor_arity > 0) {
- fprintf(fp, "(");
- for (i = 1; i <= arity; i++) {
- if (i > 1) {
- fprintf(fp, ", ");
- }
-
- MR_print_pseudo_type_info(fp, pseudo_args[i]);
- }
- fprintf(fp, ")");
- }
- }
-}
-
-static MR_Next
-MR_trace_cmd_source(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
- MR_Event_Info *event_info, MR_Code **jumpaddr)
-{
- MR_bool ignore_errors;
-
- 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) {
- /*
- ** 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);
- } else {
- MR_trace_usage_cur_cmd();
- }
-
- return KEEP_INTERACTING;
-}
-
-static MR_Next
-MR_trace_cmd_save(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
- MR_Event_Info *event_info, MR_Code **jumpaddr)
-{
- if (word_count == 2) {
- FILE *fp;
- MR_bool found_error;
- MR_Word path_list;
-
- fp = fopen(words[1], "w");
- if (fp == NULL) {
- fflush(MR_mdb_out);
- fprintf(MR_mdb_err, "mdb: error opening `%s': %s.\n",
- words[1], strerror(errno));
- return KEEP_INTERACTING;
- }
-
- MR_trace_print_all_aliases(fp, MR_TRUE);
- switch (MR_default_print_level) {
- case MR_PRINT_LEVEL_NONE:
- fprintf(fp, "printlevel none\n");
- break;
-
- case MR_PRINT_LEVEL_SOME:
- fprintf(fp, "printlevel some\n");
- break;
-
- case MR_PRINT_LEVEL_ALL:
- fprintf(fp, "printlevel all\n");
- break;
- }
-
- if (MR_echo_commands) {
- fprintf(fp, "echo on\n");
- } else {
- fprintf(fp, "echo off\n");
- }
-
- if (MR_scroll_control) {
- fprintf(fp, "scroll on\n");
- } else {
- fprintf(fp, "scroll off\n");
- }
-
- fprintf(fp, "scroll %d\n", MR_scroll_limit);
- fprintf(fp, "stack_default_limit %d\n", MR_stack_default_line_limit);
-
- switch (MR_context_position) {
- case MR_CONTEXT_NOWHERE:
- fprintf(fp, "context nowhere\n");
- break;
-
- case MR_CONTEXT_AFTER:
- fprintf(fp, "context after\n");
- break;
-
- case MR_CONTEXT_BEFORE:
- fprintf(fp, "context before\n");
- break;
-
- case MR_CONTEXT_PREVLINE:
- fprintf(fp, "context prevline\n");
- break;
-
- case MR_CONTEXT_NEXTLINE:
- fprintf(fp, "context nextline\n");
- break;
- }
-
- if (MR_print_goal_paths) {
- fprintf(fp, "goal_paths on\n");
- } else {
- fprintf(fp, "goal_paths off\n");
- }
-
- found_error = MR_save_spy_points(fp, MR_mdb_err);
-
- switch (MR_default_breakpoint_scope) {
- case MR_SPY_ALL:
- fprintf(fp, "scope all\n");
- break;
-
- case MR_SPY_INTERFACE:
- fprintf(fp, "scope interface\n");
- break;
-
- case MR_SPY_ENTRY:
- fprintf(fp, "scope entry\n");
- break;
-
- case MR_SPY_LINENO:
- case MR_SPY_SPECIFIC:
- MR_fatal_error("save cmd: invalid default scope");
- }
-
- MR_trace_print_all_browser_params(fp, MR_TRUE);
- MR_decl_print_all_trusted(fp, MR_TRUE);
-
- if (MR_dice_fail_trace_counts_file != NULL) {
- fprintf(fp, "set fail_trace_counts %s\n",
- MR_dice_fail_trace_counts_file);
- }
- if (MR_dice_pass_trace_counts_file != NULL) {
- fprintf(fp, "set pass_trace_counts %s\n",
- MR_dice_pass_trace_counts_file);
- }
-
- fprintf(fp, "set list_context_lines %d\n", MR_num_context_lines);
- MR_TRACE_CALL_MERCURY(
- path_list = ML_LISTING_get_list_path(MR_listing_path);
- if (! MR_list_is_empty(path_list)) {
- fprintf(fp, "set list_path");
- while (! MR_list_is_empty(path_list)) {
- fprintf(fp, " %s", (const char *) MR_list_head(path_list));
- path_list = MR_list_tail(path_list);
- }
- fprintf(fp, "\n");
- }
- );
-
- if (found_error) {
- fflush(MR_mdb_out);
- fprintf(MR_mdb_err, "mdb: could not save debugger state to %s.\n",
- words[1]);
- (void) fclose(fp);
- } else if (fclose(fp) != 0) {
- fflush(MR_mdb_out);
- fprintf(MR_mdb_err, "mdb: error closing `%s': %s.\n",
- words[1], strerror(errno));
- } else {
- fprintf(MR_mdb_out, "Debugger state saved to %s.\n", words[1]);
- }
- } else {
- MR_trace_usage_cur_cmd();
- }
-
- return KEEP_INTERACTING;
-}
-
-static MR_Next
-MR_trace_cmd_quit(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
- MR_Event_Info *event_info, MR_Code **jumpaddr)
-{
- MR_bool confirmed;
-
- confirmed = MR_FALSE;
- if (! MR_trace_options_confirmed(&confirmed, &words, &word_count)) {
- ; /* the usage message has already been printed */
- } else if (word_count == 1) {
- if (! confirmed) {
- char *line2;
-
- line2 = MR_trace_getline("mdb: are you sure you want to quit? ",
- MR_mdb_in, MR_mdb_out);
- if (line2 == NULL) {
- /* This means the user input EOF. */
- confirmed = MR_TRUE;
- } else {
- int i = 0;
- while (line2[i] != '\0' && MR_isspace(line2[i])) {
- i++;
- }
-
- if (line2[i] == 'y' || line2[i] == 'Y') {
- confirmed = MR_TRUE;
- }
-
- MR_free(line2);
- }
- }
-
- if (confirmed) {
- MR_trace_maybe_close_source_window(MR_FALSE);
- exit(EXIT_SUCCESS);
- }
- } else {
- MR_trace_usage_cur_cmd();
- }
-
- return KEEP_INTERACTING;
-}
-
-static MR_Next
-MR_trace_cmd_dd(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
- MR_Event_Info *event_info, MR_Code **jumpaddr)
-{
- MR_Decl_Search_Mode search_mode;
- MR_bool search_mode_was_set = MR_FALSE;
- MR_bool new_session = MR_TRUE;
- MR_bool search_mode_requires_trace_counts = MR_FALSE;
- char *pass_trace_counts_file;
- char *fail_trace_counts_file;
- MR_String problem;
- MR_bool testing = MR_FALSE;
- MR_bool debug = MR_FALSE;
- const char *filename;
- MR_Decl_Mode decl_mode;
-
- MR_trace_decl_assume_all_io_is_tabled = MR_FALSE;
- MR_edt_default_depth_limit = MR_TRACE_DECL_INITIAL_DEPTH;
- search_mode = MR_trace_get_default_search_mode();
- pass_trace_counts_file = MR_dice_pass_trace_counts_file;
- fail_trace_counts_file = MR_dice_fail_trace_counts_file;
- MR_trace_decl_debug_debugger_mode = MR_FALSE;
-
- if (! MR_trace_options_dd(&MR_trace_decl_assume_all_io_is_tabled,
- &MR_edt_default_depth_limit, &MR_edt_desired_nodes_in_subtree,
- &search_mode, &search_mode_was_set,
- &search_mode_requires_trace_counts,
- &pass_trace_counts_file, &fail_trace_counts_file, &new_session,
- &testing, &MR_trace_decl_debug_debugger_mode, &words, &word_count))
- {
- ; /* the usage message has already been printed */
- } else if (word_count <= 2) {
- if (word_count == 2 && MR_trace_decl_debug_debugger_mode) {
- decl_mode = MR_DECL_DUMP;
- filename = (const char *) words[1];
- } else {
- decl_mode = MR_DECL_NODUMP;
- filename = (const char *) NULL;
- }
- if (MR_trace_have_unhid_events) {
- fflush(MR_mdb_out);
- fprintf(MR_mdb_err,
- "mdb: dd doesn't work after `unhide_events on'.\n");
- return KEEP_INTERACTING;
- }
- if (search_mode_requires_trace_counts && (
- pass_trace_counts_file == NULL || fail_trace_counts_file == NULL))
- {
- fflush(MR_mdb_out);
- fprintf(MR_mdb_err,
- "mdb: you need to supply passing and failing trace count "
- "files\nbefore using the specified search mode.\n");
- return KEEP_INTERACTING;
- }
- if (pass_trace_counts_file != NULL && fail_trace_counts_file != NULL) {
- if (! MR_trace_decl_init_suspicion_table(pass_trace_counts_file,
- fail_trace_counts_file, &problem))
- {
- fflush(MR_mdb_out);
- fprintf(MR_mdb_err, "mdb: %s\n", problem);
- return KEEP_INTERACTING;
- }
- }
-
- MR_trace_decl_set_testing_flag(testing);
-
- if (search_mode_was_set || new_session) {
- MR_trace_decl_set_fallback_search_mode(search_mode);
- }
-
- if (MR_trace_start_decl_debug(decl_mode, filename, new_session, cmd,
- event_info, jumpaddr))
- {
- return STOP_INTERACTING;
- }
- } else {
- MR_trace_usage_cur_cmd();
- }
-
- return KEEP_INTERACTING;
-}
-
-static MR_Next
-MR_trace_cmd_trust(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
- MR_Event_Info *event_info, MR_Code **jumpaddr)
-{
- MR_Proc_Spec spec;
- MR_Matches_Info matches;
-
- if (word_count == 2) {
- spec.MR_proc_module = NULL;
- spec.MR_proc_name = NULL;
- spec.MR_proc_arity = -1;
- spec.MR_proc_mode = -1;
- spec.MR_proc_prefix = (MR_Proc_Prefix) -1;
-
- MR_register_all_modules_and_procs(MR_mdb_out, MR_TRUE);
-
- /* First see if the argument is a module name */
- spec.MR_proc_module = words[1];
- matches = MR_search_for_matching_procedures(&spec);
- if (matches.match_proc_next > 0) {
- MR_decl_add_trusted_module(words[1]);
- fprintf(MR_mdb_out, "Trusting module %s\n", words[1]);
- } else if (MR_parse_proc_spec(words[1], &spec)) {
- /* Check to see if the argument is a pred/func */
- matches = MR_search_for_matching_procedures(&spec);
- MR_filter_user_preds(&matches);
- if (matches.match_proc_next == 0) {
- fprintf(MR_mdb_err,
- "mdb: there is no such module, predicate or function.\n");
- } else if (matches.match_proc_next == 1) {
- MR_decl_add_trusted_pred_or_func(matches.match_procs[0]);
- fprintf(MR_mdb_out, "Trusting ");
- MR_print_pred_id_and_nl(MR_mdb_out, matches.match_procs[0]);
- } else {
- int i;
- char buf[80];
- char *line2;
-
- fprintf(MR_mdb_out, "Ambiguous predicate or function"
- " specification. The matches are:\n");
- for (i = 0; i < matches.match_proc_next; i++) {
- fprintf(MR_mdb_out, "%d: ", i);
- MR_print_pred_id_and_nl(MR_mdb_out,
- matches.match_procs[i]);
- }
- sprintf(buf, "\nWhich predicate or function "
- "do you want to trust (0-%d or *)? ",
- matches.match_proc_next - 1);
- line2 = MR_trace_getline(buf, MR_mdb_in, MR_mdb_out);
- if (line2 == NULL) {
- /* This means the user input EOF. */
- fprintf(MR_mdb_out, "none of them\n");
- } else if (MR_streq(line2, "*")) {
- for (i = 0; i < matches.match_proc_next; i++) {
- MR_decl_add_trusted_pred_or_func(
- matches.match_procs[i]);
-
- fprintf(MR_mdb_out, "Trusting ");
- MR_print_pred_id_and_nl(MR_mdb_out,
- matches.match_procs[i]);
- }
- MR_free(line2);
- } else if(MR_trace_is_natural_number(line2, &i)) {
- if (0 <= i && i < matches.match_proc_next) {
- MR_decl_add_trusted_pred_or_func(
- matches.match_procs[i]);
-
- fprintf(MR_mdb_out, "Trusting ");
- MR_print_pred_id_and_nl(MR_mdb_out,
- matches.match_procs[i]);
- } else {
- fprintf(MR_mdb_out, "no such match\n");
- }
- MR_free(line2);
- } else {
- fprintf(MR_mdb_out, "none of them\n");
- MR_free(line2);
- }
- }
- }
- } else if (word_count == 3 &&
- ((MR_streq(words[1], "std") && MR_streq(words[2], "lib"))
- || (MR_streq(words[1], "standard") && MR_streq(words[2], "library"))))
- {
- MR_decl_trust_standard_library();
- fprintf(MR_mdb_out, "Trusting the Mercury standard library\n");
- } else {
- MR_trace_usage_cur_cmd();
- }
-
- return KEEP_INTERACTING;
-}
-
-static MR_Next
-MR_trace_cmd_untrust(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
- MR_Event_Info *event_info, MR_Code **jumpaddr)
-{
- int i;
-
- if (word_count == 2 && MR_trace_is_natural_number(words[1], &i)) {
- if (!MR_decl_remove_trusted(i)) {
- fprintf(MR_mdb_err, "mdb: no such trusted object\n");
- }
- } else {
- MR_trace_usage_cur_cmd();
- }
- return KEEP_INTERACTING;
-}
-
-static MR_Next
-MR_trace_cmd_trusted(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
- MR_Event_Info *event_info, MR_Code **jumpaddr)
-{
- if (word_count == 1) {
- MR_decl_print_all_trusted(MR_mdb_out, MR_FALSE);
- } else {
- MR_trace_usage_cur_cmd();
- }
- return KEEP_INTERACTING;
-}
-
-static MR_Next
-MR_trace_cmd_dice(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
- MR_Event_Info *event_info, MR_Code **jumpaddr)
-{
- char *pass_trace_counts_file;
- char *fail_trace_counts_file;
- char *sort_str;
- char *out_file;
- char *module;
- int number_of_lines;
-
- sort_str = NULL;
- out_file = NULL;
- module = NULL;
- number_of_lines = MR_DEFAULT_DICE_LINES;
-
- pass_trace_counts_file = MR_dice_pass_trace_counts_file;
- fail_trace_counts_file = MR_dice_fail_trace_counts_file;
-
- if (! MR_trace_options_dice(&pass_trace_counts_file,
- &fail_trace_counts_file, &sort_str, &number_of_lines, &out_file,
- &module, &words, &word_count))
- {
- ; /* the usage message has already been printed */
- } else if (word_count == 1) {
- if (pass_trace_counts_file == NULL) {
- fflush(MR_mdb_out);
- fprintf(MR_mdb_err, "mdb: No passing trace counts file specified."
- "\nmdb: Specify one with the -p option or using the `set' "
- "command.\n");
- } else if (fail_trace_counts_file == NULL) {
- fflush(MR_mdb_out);
- fprintf(MR_mdb_err, "mdb: No failing trace counts file specified."
- "\nmdb: Specify one with the -f option or using the `set' "
- "command.\n");
- } else {
- if (sort_str == NULL) {
- sort_str = MR_copy_string("");
- }
-
- if (module == NULL) {
- module = MR_copy_string("");
- }
-
- MR_trace_print_dice(pass_trace_counts_file, fail_trace_counts_file,
- sort_str, number_of_lines, out_file, module);
- }
- } else {
- MR_trace_usage_cur_cmd();
- }
-
- if (out_file != NULL) {
- free(out_file);
- }
-
- if (sort_str != NULL) {
- free(sort_str);
- }
-
- if (module != NULL) {
- free(module);
- }
-
- return KEEP_INTERACTING;
-}
-
-static void
-MR_trace_print_dice(char *pass_trace_counts_file,
- char *fail_trace_count_file, char *sort_str, int number_of_lines,
- char *out_file, char *module)
-{
- MR_String dice;
- MR_String problem;
- MR_String aligned_pass_trace_counts_file;
- MR_String aligned_fail_trace_count_file;
- MR_String aligned_sort_str;
- MR_String aligned_module;
- FILE *fp;
-
- MR_TRACE_USE_HP(
- MR_make_aligned_string(aligned_pass_trace_counts_file,
- (MR_String) pass_trace_counts_file);
- MR_make_aligned_string(aligned_fail_trace_count_file,
- (MR_String) fail_trace_count_file);
- MR_make_aligned_string(aligned_sort_str, (MR_String) sort_str);
- if (module == NULL) {
- MR_make_aligned_string(aligned_module, (MR_String) "");
- } else {
- MR_make_aligned_string(aligned_module, (MR_String) module);
- }
- );
-
- MR_TRACE_CALL_MERCURY(
- MR_MDB_read_dice_to_string(aligned_pass_trace_counts_file,
- aligned_fail_trace_count_file, aligned_sort_str,
- number_of_lines, aligned_module, &dice, &problem);
- );
-
- /* The string in dice is a sequence of complete lines */
- if (MR_streq(problem, "")) {
- if (out_file == NULL) {
- fprintf(MR_mdb_out, "%s", dice);
- } else {
- fp = fopen(out_file, "w");
- if (fp != NULL) {
- fprintf(fp, "%s", dice);
- if (fclose(fp) != 0) {
- fflush(MR_mdb_out);
- fprintf(MR_mdb_err, "mdb: Error closing file `%s': %s\n",
- out_file, strerror(errno));
- }
- } else {
- fflush(MR_mdb_out);
- fprintf(MR_mdb_err, "mdb: Error opening file `%s': %s\n",
- out_file, strerror(errno));
- }
- }
- } else {
- fflush(MR_mdb_out);
- fprintf(MR_mdb_err, "mdb: %s\n", problem);
- }
-}
-
-static void
-MR_maybe_print_spy_point(int slot, const char *problem)
-{
- if (slot < 0) {
- fflush(MR_mdb_out);
- fprintf(MR_mdb_err, "mdb: %s.\n", problem);
- } else {
- MR_print_spy_point(MR_mdb_out, slot, MR_TRUE);
- }
-}
-
-static void
-MR_print_unsigned_var(FILE *fp, const char *var, MR_Unsigned value)
-{
- fprintf(fp, "%s = %" MR_INTEGER_LENGTH_MODIFIER "u\n", var, value);
-}
-
-static MR_bool
-MR_parse_source_locn(char *word, const char **file, int *line)
-{
- char *s;
- const char *t;
-
- if ((s = strrchr(word, ':')) != NULL) {
- for (t = s+1; *t != '\0'; t++) {
- if (! MR_isdigit(*t)) {
- return MR_FALSE;
- }
- }
-
- *s = '\0';
- *file = word;
- *line = atoi(s+1);
- return MR_TRUE;
- }
-
- return MR_FALSE;
-}
-
-/*
-** Implement the `view' command. First, check if there is a server
-** attached. If so, either stop it or abort the command, depending
-** on whether '-f' was given. Then, if a server name was not supplied,
-** start a new server with a unique name (which has been MR_malloc'd),
-** otherwise attach to the server with the supplied name (and make a
-** MR_malloc'd copy of the name).
-*/
-static const char *
-MR_trace_new_source_window(const char *window_cmd, const char *server_cmd,
- const char *server_name, int timeout, MR_bool force,
- MR_bool verbose, MR_bool split)
-{
- const char *msg;
-
- if (MR_trace_source_server.server_name != NULL) {
- /*
- ** We are already attached to a server.
- */
- if (force) {
- MR_trace_maybe_close_source_window(verbose);
- } else {
- return "error: server already open (use '-f' to force)";
- }
- }
-
- MR_trace_source_server.split = split;
- if (server_cmd != NULL) {
- MR_trace_source_server.server_cmd = MR_copy_string(server_cmd);
- } else {
- MR_trace_source_server.server_cmd = NULL;
- }
-
- if (server_name == NULL) {
- msg = MR_trace_source_open_server(&MR_trace_source_server,
- window_cmd, timeout, verbose);
- } else {
- MR_trace_source_server.server_name = MR_copy_string(server_name);
- msg = MR_trace_source_attach(&MR_trace_source_server, timeout,
- verbose);
- if (msg != NULL) {
- /*
- ** Something went wrong, so we should free the
- ** strings we allocated just above.
- */
- MR_free(MR_trace_source_server.server_name);
- MR_trace_source_server.server_name = NULL;
- MR_free(MR_trace_source_server.server_cmd);
- MR_trace_source_server.server_cmd = NULL;
- }
- }
-
- return msg;
-}
-
-/*
-** If we are attached to a source server, then find the appropriate
-** context and ask the server to point to it, otherwise do nothing.
-*/
-static void
-MR_trace_maybe_sync_source_window(MR_Event_Info *event_info, MR_bool verbose)
-{
- const MR_Label_Layout *parent;
- const char *filename;
- int lineno;
- const char *parent_filename;
- int parent_lineno;
- const char *problem; /* not used */
- MR_Word *base_sp, *base_curfr;
- const char *msg;
-
- if (MR_trace_source_server.server_name != NULL) {
- lineno = 0;
- filename = "";
- parent_lineno = 0;
- parent_filename = "";
-
- /*
- ** At interface ports we send both the parent context and
- ** the current context. Otherwise, we just send the current
- ** context.
- */
- if (MR_port_is_interface(event_info->MR_trace_port)) {
- base_sp = MR_saved_sp(event_info->MR_saved_regs);
- base_curfr = MR_saved_curfr(event_info->MR_saved_regs);
- parent = MR_find_nth_ancestor(event_info->MR_event_sll, 1,
- &base_sp, &base_curfr, &problem);
- if (parent != NULL) {
- (void) MR_find_context(parent, &parent_filename,
- &parent_lineno);
- }
- }
-
- if (filename[0] == '\0') {
- (void) MR_find_context(event_info->MR_event_sll,
- &filename, &lineno);
- }
-
- msg = MR_trace_source_sync(&MR_trace_source_server, filename, lineno,
- parent_filename, parent_lineno, verbose);
- if (msg != NULL) {
- fflush(MR_mdb_out);
- fprintf(MR_mdb_err, "mdb: %s.\n", msg);
- }
- }
-}
-
-/*
-** Close a source server, if there is one attached.
-*/
-static void
-MR_trace_maybe_close_source_window(MR_bool verbose)
-{
- const char *msg;
-
- if (MR_trace_source_server.server_name != NULL) {
- msg = MR_trace_source_close(&MR_trace_source_server, verbose);
- if (msg != NULL) {
- fflush(MR_mdb_out);
- fprintf(MR_mdb_err, "mdb: %s.\n", msg);
- }
-
- MR_free(MR_trace_source_server.server_name);
- MR_trace_source_server.server_name = NULL;
- MR_free(MR_trace_source_server.server_cmd);
- MR_trace_source_server.server_cmd = NULL;
- }
-}
-
-static struct MR_option MR_trace_movement_cmd_opts[] =
-{
- { "all", MR_no_argument, NULL, 'a' },
- { "none", MR_no_argument, NULL, 'n' },
- { "some", MR_no_argument, NULL, 's' },
- { "nostrict", MR_no_argument, NULL, 'N' },
- { "strict", MR_no_argument, NULL, 'S' },
-#ifdef MR_TRACE_CHECK_INTEGRITY
- { "integrity", MR_no_argument, NULL, 'i' },
-#endif
- { NULL, MR_no_argument, NULL, 0 }
-};
-
-static MR_bool
-MR_trace_options_movement_cmd(MR_Trace_Cmd_Info *cmd,
- char ***words, int *word_count)
-{
- int c;
-
-#ifdef MR_TRACE_CHECK_INTEGRITY
- #define MR_TRACE_MOVEMENT_OPTS "NSains"
-#else
- #define MR_TRACE_MOVEMENT_OPTS "NSans"
-#endif
-
- MR_optind = 0;
- while ((c = MR_getopt_long(*word_count, *words, MR_TRACE_MOVEMENT_OPTS,
- MR_trace_movement_cmd_opts, NULL)) != EOF)
- {
- switch (c) {
-
- case 'N':
- cmd->MR_trace_strict = MR_FALSE;
- break;
-
- case 'S':
- cmd->MR_trace_strict = MR_TRUE;
- break;
-
- case 'a':
- cmd->MR_trace_print_level = MR_PRINT_LEVEL_ALL;
- break;
-
- case 'n':
- cmd->MR_trace_print_level = MR_PRINT_LEVEL_NONE;
- break;
-
- case 's':
- cmd->MR_trace_print_level = MR_PRINT_LEVEL_SOME;
- break;
-
-#ifdef MR_TRACE_CHECK_INTEGRITY
- case 'i':
- cmd->MR_trace_check_integrity = MR_TRUE;
- break;
-#endif
-
- 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_retry_opts[] =
-{
- { "assume-all-io-is-tabled", MR_no_argument, NULL, 'a' },
- { "force", MR_no_argument, NULL, 'f' },
- { "interactive", MR_no_argument, NULL, 'i' },
- { "only-if-safe", MR_no_argument, NULL, 'o' },
- { NULL, MR_no_argument, NULL, 0 }
-};
-
-static MR_bool
-MR_trace_options_retry(MR_Retry_Across_Io *across_io,
- MR_bool *assume_all_io_is_tabled, char ***words, int *word_count)
-{
- int c;
-
- MR_optind = 0;
- while ((c = MR_getopt_long(*word_count, *words, "afio",
- MR_trace_retry_opts, NULL)) != EOF)
- {
- switch (c) {
-
- case 'a':
- *assume_all_io_is_tabled = MR_TRUE;
- break;
-
- case 'f':
- *across_io = MR_RETRY_IO_FORCE;
- break;
-
- case 'i':
- *across_io = MR_RETRY_IO_INTERACTIVE;
- break;
-
- case 'o':
- *across_io = MR_RETRY_IO_ONLY_IF_SAFE;
- 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_when_action_multi_ignore_opts[] =
-{
- { "all", MR_no_argument, NULL, 'a' },
- { "entry", MR_no_argument, NULL, 'e' },
- { "interface", MR_no_argument, NULL, 'i' },
- { "ignore-entry", MR_required_argument, NULL, 'E' },
- { "ignore-interface", MR_required_argument, NULL, 'I' },
- { "print-list", MR_required_argument, NULL, 'p' },
- { "no-warn", MR_no_argument, NULL, 'n' },
- { "print", MR_no_argument, NULL, 'P' },
- { "stop", MR_no_argument, NULL, 'S' },
- { "select-all", MR_no_argument, NULL, 'A' },
- { "select-one", MR_no_argument, NULL, 'O' },
- { NULL, MR_no_argument, NULL, 0 }
-};
-
-static MR_bool
-MR_trace_options_when_action_multi_ignore(MR_Spy_When *when,
- MR_Spy_Action *action, MR_MultiMatch *multi_match,
- MR_Spy_Ignore_When*ignore_when, int *ignore_count,
- MR_Spy_Print_List *print_list,
- char ***words, int *word_count)
-{
- int c;
- MR_Spy_Print node;
- MR_Spy_Print_List list;
- MR_bool warn;
-
- warn = MR_TRUE;
- MR_optind = 0;
- while ((c = MR_getopt_long(*word_count, *words, "AE:I:OPSaeinp:",
- MR_trace_when_action_multi_ignore_opts, NULL)) != EOF)
- {
- switch (c) {
-
- case 'a':
- *when = MR_SPY_ALL;
- break;
-
- case 'e':
- *when = MR_SPY_ENTRY;
- break;
-
- case 'i':
- *when = MR_SPY_INTERFACE;
- break;
-
- case 'n':
- warn = MR_FALSE;
- break;
-
- case 'p':
- *print_list = MR_add_to_print_list_end(MR_BROWSE_FORMAT_FLAT,
- MR_optarg, warn, *print_list);
- break;
-
- case 'E':
- if (! MR_trace_is_natural_number(MR_optarg, ignore_count)) {
- MR_trace_usage_cur_cmd();
- return MR_FALSE;
- }
- *ignore_when = MR_SPY_IGNORE_ENTRY;
- break;
-
- case 'I':
- if (! MR_trace_is_natural_number(MR_optarg, ignore_count)) {
- MR_trace_usage_cur_cmd();
- return MR_FALSE;
- }
- *ignore_when = MR_SPY_IGNORE_INTERFACE;
- break;
-
- case 'A':
- *multi_match = MR_MULTIMATCH_ALL;
- break;
-
- case 'O':
- *multi_match = MR_MULTIMATCH_ONE;
- break;
-
- case 'P':
- *action = MR_SPY_PRINT;
- break;
-
- case 'S':
- *action = MR_SPY_STOP;
- 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_condition_opts[] =
-{
- { "break-num", MR_required_argument, NULL, 'n' },
- { "dont-require-var", MR_no_argument, NULL, 'v' },
- { "dont-require-path", MR_no_argument, NULL, 'p' },
- { NULL, MR_no_argument, NULL, 0 }
-};
-
-static MR_bool
-MR_trace_options_condition(int *break_num, MR_bool *require_var,
- MR_bool *require_path, char ***words, int *word_count)
-{
- int c;
- int n;
-
- MR_optind = 0;
- while ((c = MR_getopt_long(*word_count, *words, "n:vp",
- MR_trace_condition_opts, NULL)) != EOF)
- {
- switch (c) {
-
- case 'n':
- if (! MR_trace_is_natural_number(MR_optarg, &n)) {
- MR_trace_usage_cur_cmd();
- return MR_FALSE;
- }
- *break_num = n;
- break;
-
- case 'p':
- *require_path = MR_FALSE;
- break;
-
- case 'v':
- /*
- ** If a variable is missing, then the path inside
- ** is missing as well.
- */
-
- *require_path = MR_FALSE;
- *require_var = MR_FALSE;
- 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_ignore_count_opts[] =
-{
- { "ignore-entry", MR_required_argument, NULL, 'E' },
- { "ignore-interface", MR_required_argument, NULL, 'I' },
- { NULL, MR_no_argument, NULL, 0 }
-};
-
-static MR_bool
-MR_trace_options_ignore_count(MR_Spy_Ignore_When *ignore_when,
- int *ignore_count, char ***words, int *word_count)
-{
- int c;
-
- MR_optind = 0;
- while ((c = MR_getopt_long(*word_count, *words, "E:I:",
- MR_trace_ignore_count_opts, NULL)) != EOF)
- {
- switch (c) {
-
- case 'E':
- if (! MR_trace_is_natural_number(MR_optarg, ignore_count)) {
- MR_trace_usage_cur_cmd();
- return MR_FALSE;
- }
- *ignore_when = MR_SPY_IGNORE_ENTRY;
- break;
-
- case 'I':
- if (! MR_trace_is_natural_number(MR_optarg, ignore_count)) {
- MR_trace_usage_cur_cmd();
- return MR_FALSE;
- }
- *ignore_when = MR_SPY_IGNORE_INTERFACE;
- 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_break_print_opts[] =
-{
- { "end", MR_no_argument, NULL, 'e' },
- { "no-warn", MR_no_argument, NULL, 'n' },
- { "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' },
- { NULL, MR_no_argument, NULL, 0 }
-};
-
-static MR_bool
-MR_trace_options_break_print(MR_Browse_Format *format, MR_bool *at_start,
- MR_bool *warn, char ***words, int *word_count)
-{
- int c;
-
- *format = MR_BROWSE_FORMAT_FLAT;
- *at_start = MR_TRUE;
- *warn = MR_TRUE;
- MR_optind = 0;
- while ((c = MR_getopt_long(*word_count, *words, "enfrvp",
- MR_trace_break_print_opts, NULL)) != EOF)
- {
- switch (c) {
-
- case 'e':
- *at_start = MR_FALSE;
- break;
-
- case 'n':
- *warn = MR_FALSE;
- break;
-
- case 'f':
- *format = MR_BROWSE_FORMAT_FLAT;
- break;
-
- case 'r':
- *format = MR_BROWSE_FORMAT_RAW_PRETTY;
- break;
-
- case 'v':
- *format = MR_BROWSE_FORMAT_VERBOSE;
- break;
-
- case 'p':
- *format = MR_BROWSE_FORMAT_PRETTY;
- 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_detailed_opts[] =
-{
- { "detailed", MR_no_argument, NULL, 'd' },
- { NULL, MR_no_argument, NULL, 0 }
-};
-
-static MR_bool
-MR_trace_options_detailed(MR_bool *detailed, char ***words, int *word_count)
-{
- int c;
-
- MR_optind = 0;
- while ((c = MR_getopt_long(*word_count, *words, "d",
- MR_trace_detailed_opts, NULL)) != EOF)
- {
- switch (c) {
-
- case 'd':
- *detailed = MR_TRUE;
- 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 MR_bool
-MR_trace_options_stack_trace(MR_bool *detailed, int *frame_limit,
- char ***words, int *word_count)
-{
- int c;
-
- MR_optind = 0;
- while ((c = MR_getopt_long(*word_count, *words, "df:",
- MR_trace_detailed_opts, NULL)) != EOF)
- {
- switch (c) {
-
- case 'd':
- *detailed = MR_TRUE;
- break;
-
- case 'f':
- if (! MR_trace_is_natural_number(MR_optarg, frame_limit)) {
- MR_trace_usage_cur_cmd();
- return MR_FALSE;
- }
- 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 MR_bool
-MR_trace_options_confirmed(MR_bool *confirmed, char ***words, int *word_count)
-{
- int c;
-
- MR_optind = 0;
- while ((c = MR_getopt(*word_count, *words, "NYny")) != EOF) {
- switch (c) {
-
- case 'n':
- case 'N':
- *confirmed = MR_FALSE;
- break;
-
- case 'y':
- case 'Y':
- *confirmed = MR_TRUE;
- 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_quiet_opts[] =
-{
- { "quiet", MR_no_argument, NULL, 'q' },
- { "verbose", MR_no_argument, NULL, 'v' },
- { NULL, MR_no_argument, NULL, 0 }
-};
-
-static MR_bool
-MR_trace_options_quiet(MR_bool *verbose, char ***words, int *word_count)
-{
- int c;
-
- MR_optind = 0;
- while ((c = MR_getopt_long(*word_count, *words, "qv",
- MR_trace_quiet_opts, NULL)) != EOF)
- {
- switch (c) {
-
- case 'q':
- *verbose = MR_FALSE;
- break;
-
- case 'v':
- *verbose = MR_TRUE;
- 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_ignore_opts[] =
-{
- { "ignore-errors", MR_no_argument, NULL, 'i' },
- { NULL, MR_no_argument, NULL, 0 }
-};
-
-static MR_bool
-MR_trace_options_ignore(MR_bool *ignore_errors, char ***words, int *word_count)
-{
- int c;
-
- MR_optind = 0;
- while ((c = MR_getopt_long(*word_count, *words, "i",
- MR_trace_ignore_opts, NULL)) != EOF)
- {
- switch (c) {
-
- case 'i':
- *ignore_errors = MR_TRUE;
- 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_format_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' },
- { "xml", MR_no_argument, NULL, 'x' },
- { NULL, MR_no_argument, NULL, 0 }
-};
-
-static MR_bool
-MR_trace_options_format(MR_Browse_Format *format, MR_bool *xml, char ***words,
- int *word_count)
-{
- int c;
-
- *format = MR_BROWSE_DEFAULT_FORMAT;
- *xml = MR_FALSE;
- MR_optind = 0;
- while ((c = MR_getopt_long(*word_count, *words, "frvpx",
- MR_trace_format_opts, NULL)) != EOF)
- {
- switch (c) {
-
- case 'f':
- *format = MR_BROWSE_FORMAT_FLAT;
- break;
-
- case 'r':
- *format = MR_BROWSE_FORMAT_RAW_PRETTY;
- break;
-
- case 'v':
- *format = MR_BROWSE_FORMAT_VERBOSE;
- break;
-
- case 'p':
- *format = MR_BROWSE_FORMAT_PRETTY;
- break;
-
- case 'x':
- *xml = MR_TRUE;
- 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_set_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_param_set(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_set_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;
-}
-
-static struct MR_option MR_trace_view_opts[] =
-{
- { "close", MR_no_argument, NULL, 'c' },
- { "window-command", MR_required_argument, NULL, 'w' },
- { "server-command", MR_required_argument, NULL, 's' },
- { "server-name", MR_required_argument, NULL, 'n' },
- { "timeout", MR_required_argument, NULL, 't' },
- { "force", MR_no_argument, NULL, 'f' },
- { "verbose", MR_no_argument, NULL, 'v' },
- { "split-screen", MR_no_argument, NULL, '2' },
- { NULL, MR_no_argument, NULL, 0 }
-};
-
-static MR_bool
-MR_trace_options_view(const char **window_cmd, const char **server_cmd,
- const char **server_name, int *timeout, MR_bool *force,
- MR_bool *verbose, MR_bool *split, MR_bool *close_window,
- char ***words, int *word_count)
-{
- int c;
- MR_bool no_close = MR_FALSE;
-
- MR_optind = 0;
- while ((c = MR_getopt_long(*word_count, *words, "cw:s:n:t:fv2",
- MR_trace_view_opts, NULL)) != EOF)
- {
- /*
- ** Option '-c' is mutually incompatible with '-f', '-t',
- ** '-s', '-n', '-w' and '-2'.
- */
- switch (c) {
-
- case 'c':
- if (no_close) {
- MR_trace_usage_cur_cmd();
- return MR_FALSE;
- }
- *close_window = MR_TRUE;
- break;
-
- case 'w':
- if (*close_window) {
- MR_trace_usage_cur_cmd();
- return MR_FALSE;
- }
- *window_cmd = MR_optarg;
- no_close = MR_TRUE;
- break;
-
- case 's':
- if (*close_window) {
- MR_trace_usage_cur_cmd();
- return MR_FALSE;
- }
- *server_cmd = MR_optarg;
- no_close = MR_TRUE;
- break;
-
- case 'n':
- if (*close_window) {
- MR_trace_usage_cur_cmd();
- return MR_FALSE;
- }
- *server_name = MR_optarg;
- no_close = MR_TRUE;
- break;
-
- case 't':
- if (*close_window ||
- ! MR_trace_is_natural_number(MR_optarg, timeout))
- {
- MR_trace_usage_cur_cmd();
- return MR_FALSE;
- }
- no_close = MR_TRUE;
- break;
-
- case 'f':
- if (*close_window) {
- MR_trace_usage_cur_cmd();
- return MR_FALSE;
- }
- *force = MR_TRUE;
- no_close = MR_TRUE;
- break;
-
- case 'v':
- *verbose = MR_TRUE;
- break;
-
- case '2':
- if (*close_window) {
- MR_trace_usage_cur_cmd();
- return MR_FALSE;
- }
- *split = MR_TRUE;
- no_close = MR_TRUE;
- 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_dd_opts[] =
-{
- { "assume-all-io-is-tabled", MR_no_argument, NULL, 'a' },
- { "debug", MR_no_argument, NULL, 'z' },
- { "depth", MR_required_argument, NULL, 'd' },
- { "nodes", MR_required_argument, NULL, 'n' },
- { "resume", MR_no_argument, NULL, 'r' },
- { "search-mode", MR_required_argument, NULL, 's' },
- { "pass-trace-counts", MR_required_argument, NULL, 'p' },
- { "pass-trace-count", MR_required_argument, NULL, 'p' },
- { "fail-trace-counts", MR_required_argument, NULL, 'f' },
- { "fail-trace-count", MR_required_argument, NULL, 'f' },
- { "resume", MR_no_argument, NULL, 'r' },
- { "test", MR_no_argument, NULL, 't' },
- { NULL, MR_no_argument, NULL, 0 }
-};
-
-static MR_bool
-MR_trace_options_dd(MR_bool *assume_all_io_is_tabled,
- MR_Unsigned *default_depth, MR_Unsigned *num_nodes,
- MR_Decl_Search_Mode *search_mode, MR_bool *search_mode_was_set,
- MR_bool *search_mode_requires_trace_counts,
- char **pass_trace_counts_file, char **fail_trace_counts_file,
- MR_bool *new_session, MR_bool *testing, MR_bool *debug,
- char ***words, int *word_count)
-{
- int c;
-
- MR_optind = 0;
- while ((c = MR_getopt_long(*word_count, *words, "ad:f:n:p:rs:tz",
- MR_trace_dd_opts, NULL)) != EOF)
- {
- switch (c) {
-
- case 'a':
- *assume_all_io_is_tabled = MR_TRUE;
- break;
-
- case 'd':
- if (! MR_trace_is_unsigned(MR_optarg, default_depth)) {
- MR_trace_usage_cur_cmd();
- return MR_FALSE;
- }
- break;
-
- case 'f':
- *fail_trace_counts_file = MR_copy_string(MR_optarg);
- break;
-
- case 'n':
- if (! MR_trace_is_unsigned(MR_optarg, num_nodes)) {
- MR_trace_usage_cur_cmd();
- return MR_FALSE;
- }
- break;
-
- case 'p':
- *pass_trace_counts_file = MR_copy_string(MR_optarg);
- break;
-
- case 'r':
- *new_session = MR_FALSE;
- break;
-
- case 's':
- if (MR_trace_is_valid_search_mode_string(MR_optarg,
- search_mode, search_mode_requires_trace_counts))
- {
- *search_mode_was_set = MR_TRUE;
- } else {
- MR_trace_usage_cur_cmd();
- return MR_FALSE;
- }
- break;
-
- case 't':
- *testing = MR_TRUE;
- break;
-
- case 'z':
- *debug = MR_TRUE;
- 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_dice_opts[] =
-{
- { "pass-trace-counts", MR_required_argument, NULL, 'p' },
- { "pass-trace-count", MR_required_argument, NULL, 'p' },
- { "fail-trace-counts", MR_required_argument, NULL, 'f' },
- { "fail-trace-count", MR_required_argument, NULL, 'f' },
- { "sort", MR_required_argument, NULL, 's' },
- { "top", MR_required_argument, NULL, 'n' },
- { "output-to-file", MR_required_argument, NULL, 'o' },
- { "module", MR_required_argument, NULL, 'm' },
- { NULL, MR_no_argument, NULL, 0 }
-};
-
-static MR_bool
-MR_trace_options_dice(char **pass_trace_counts_file,
- char **fail_trace_counts_file, char **sort_str, int *n, char **out_file,
- char **module, char ***words, int *word_count)
-{
- int c;
-
- MR_optind = 0;
- while ((c = MR_getopt_long(*word_count, *words, "p:f:s:n:o:m:",
- MR_trace_dice_opts, NULL)) != EOF)
- {
- switch (c) {
-
- case 'p':
- /*
- ** Don't free *pass_trace_counts_file even if non-NULL,
- ** since its initial value comes from a global variable,
- ** and thus will still be used after the dice command.
- ** The waste of not freeing of the string allocated by
- ** MR_copy_string if this option is duplicated can be
- ** easily lived with.
- */
-
- *pass_trace_counts_file = MR_copy_string(MR_optarg);
- break;
-
- case 'f':
- /*
- ** Don't free *fail_trace_counts_file even if non-NULL,
- ** since its initial value comes from a global variable,
- ** and thus will still be used after the dice command.
- ** The waste of not freeing of the string allocated by
- ** MR_copy_string if this option is duplicated can be
- ** easily lived with.
- */
-
- *fail_trace_counts_file = MR_copy_string(MR_optarg);
- break;
-
- case 's':
- *sort_str = MR_copy_string(MR_optarg);
- break;
-
- case 'n':
- if (! MR_trace_is_natural_number(MR_optarg, n)) {
- MR_trace_usage_cur_cmd();
- return MR_FALSE;
- }
- break;
-
- case 'o':
- *out_file = MR_copy_string(MR_optarg);
- break;
-
- case 'm':
- *module = MR_copy_string(MR_optarg);
- 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_stats_opts[] =
-{
- { "file", MR_required_argument, NULL, 'f' },
- { NULL, MR_no_argument, NULL, 0 }
-};
-
-static MR_bool
-MR_trace_options_stats(char **filename, char ***words, int *word_count)
-{
- int c;
-
- MR_optind = 0;
- while ((c = MR_getopt_long(*word_count, *words, "f:",
- MR_trace_stats_opts, NULL)) != EOF)
- {
- switch (c) {
-
- case 'f':
- *filename = MR_optarg;
- 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_type_ctor_opts[] =
-{
- { "print-rep", MR_no_argument, NULL, 'r' },
- { "print-functors", MR_no_argument, NULL, 'f' },
- { NULL, MR_no_argument, NULL, 0 }
-};
-
-static MR_bool
-MR_trace_options_type_ctor(MR_bool *print_rep, MR_bool *print_functors,
- char ***words, int *word_count)
-{
- int c;
-
- MR_optind = 0;
- while ((c = MR_getopt_long(*word_count, *words, "rf",
- MR_trace_type_ctor_opts, NULL)) != EOF)
- {
- switch (c) {
-
- case 'f':
- *print_functors = MR_TRUE;
- break;
-
- case 'r':
- *print_rep = MR_TRUE;
- 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_class_decl_opts[] =
-{
- { "print-methods", MR_no_argument, NULL, 'm' },
- { "print-instances", MR_no_argument, NULL, 'i' },
- { NULL, MR_no_argument, NULL, 0 }
-};
-
-static MR_bool
-MR_trace_options_class_decl(MR_bool *print_methods, MR_bool *print_instances,
- char ***words, int *word_count)
-{
- int c;
-
- MR_optind = 0;
- while ((c = MR_getopt_long(*word_count, *words, "mi",
- MR_trace_class_decl_opts, NULL)) != EOF)
- {
- switch (c) {
-
- case 'm':
- *print_methods = MR_TRUE;
- break;
-
- case 'i':
- *print_instances = MR_TRUE;
- 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_all_procedures_opts[] =
-{
- { "separate", MR_no_argument, NULL, 's' },
- { "uci", MR_no_argument, NULL, 'u' },
- { "module", MR_required_argument, NULL, 'm' },
- { NULL, MR_no_argument, NULL, 0 }
-};
-
-static MR_bool
-MR_trace_options_all_procedures(MR_bool *separate, MR_bool *uci, char **module,
- char ***words, int *word_count)
-{
- int c;
-
- MR_optind = 0;
- while ((c = MR_getopt_long(*word_count, *words, "sum:",
- MR_trace_all_procedures_opts, NULL)) != EOF)
- {
- switch (c) {
-
- case 's':
- *separate = MR_TRUE;
- break;
-
- case 'u':
- *uci = MR_TRUE;
- break;
-
- case 'm':
- *module = MR_optarg;
- 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_ambiguity_opts[] =
-{
- { "outputfile", MR_required_argument, NULL, 'o' },
- { NULL, MR_no_argument, NULL, 0 }
-};
-
-static MR_bool
-MR_trace_options_ambiguity(const char **outfile,
- char ***words, int *word_count)
-{
- int c;
-
- MR_optind = 0;
- while ((c = MR_getopt_long(*word_count, *words, "o:",
- MR_trace_ambiguity_opts, NULL)) != EOF)
- {
- switch (c) {
-
- case 'o':
- *outfile = MR_optarg;
- 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_diff_opts[] =
-{
- { "start", MR_required_argument, NULL, 's' },
- { "max", MR_required_argument, NULL, 'm' },
- { NULL, MR_no_argument, NULL, 0 }
-};
-
-static MR_bool
-MR_trace_options_diff(int *start, int *max, char ***words, int *word_count)
-{
- int c;
-
- MR_optind = 0;
- while ((c = MR_getopt_long(*word_count, *words, "m:s:", MR_trace_diff_opts,
- NULL)) != EOF)
- {
- switch (c) {
-
- case 'm':
- if (! MR_trace_is_natural_number(MR_optarg, max)) {
- MR_trace_usage_cur_cmd();
- return MR_FALSE;
- }
- break;
-
- case 's':
- if (! MR_trace_is_natural_number(MR_optarg, start)) {
- MR_trace_usage_cur_cmd();
- return MR_FALSE;
- }
- 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_dump_opts[] =
-{
- { "xml", MR_no_argument, NULL, 'x' },
- { NULL, MR_no_argument, NULL, 0 }
-};
-
-static MR_bool
-MR_trace_options_dump(MR_bool *xml, char ***words, int *word_count)
-{
- int c;
-
- MR_optind = 0;
- while ((c = MR_getopt_long(*word_count, *words, "x",
- MR_trace_dump_opts, NULL)) != EOF)
- {
- switch (c) {
-
- case 'x':
- *xml = MR_TRUE;
- 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 void
-MR_trace_usage_cur_cmd(void)
-{
- /* MR_current_cmd_category is unused now, for but could be used later. */
- fflush(MR_mdb_out);
- fprintf(MR_mdb_err,
- "mdb: %s: usage error -- type `help %s' for help.\n",
- MR_current_cmd_name, MR_current_cmd_name);
-}
-
-/*
-** Read lines until we find one that contains only "end".
-** Return the lines concatenated together.
-** The memory returned is allocated with MR_malloc();
-** it is the caller's responsibility to MR_free() it when appropriate.
-*/
-
-static const char *
-MR_trace_read_help_text(void)
-{
- char *text;
- char *doc_chars = NULL;
- int doc_char_max = 0;
- int next_char_slot;
- int line_len;
- int i;
-
- next_char_slot = 0;
- while ((text = MR_trace_getline("cat> ", MR_mdb_in, MR_mdb_out)) != NULL) {
- if (MR_streq(text, "end")) {
- MR_free(text);
- break;
- }
-
- line_len = strlen(text);
- MR_ensure_big_enough(next_char_slot + line_len + 2, doc_char, char,
- MR_INIT_DOC_CHARS);
- for (i = 0; i < line_len; i++) {
- doc_chars[next_char_slot + i] = text[i];
- }
-
- next_char_slot += line_len;
- doc_chars[next_char_slot] = '\n';
- next_char_slot += 1;
- MR_free(text);
- }
-
- MR_ensure_big_enough(next_char_slot, doc_char, char, MR_INIT_DOC_CHARS);
- doc_chars[next_char_slot] = '\0';
- return doc_chars;
-}
-
-/*
-** Given a text line, break it up into words composed of non-space characters
-** separated by space characters. Make each word a NULL-terminated string,
-** overwriting some spaces in the line array in the process.
-**
-** If the first word is a number but the second is not, swap the two.
-** If the first word has a number prefix, separate it out.
-**
-** On return *words will point to an array of strings, with space for
-** *words_max strings. The number of strings (words) filled in will be
-** given by *word_count.
-**
-** The space for the *words array is allocated with MR_malloc().
-** It is the caller's responsibility to free it when appropriate.
-** The elements of the *words array point to memory from the line array.
-** The lifetime of the elements of the *words array expires when
-** the line array is MR_free()'d or further modified or when
-** MR_trace_parse_line is called again, whichever comes first.
-**
-** The return value is NULL if everything went OK, and an error message
-** otherwise.
-*/
-
-static const char *
-MR_trace_parse_line(char *line, char ***words, int *word_max, int *word_count)
-{
- char **raw_words;
- int raw_word_max;
- int raw_word_count;
- static char count_buf[MR_NUMBER_LEN + 1];
- char *s;
- int i;
- const char *problem;
-
- /*
- ** Handle a possible number prefix on the first word on the line,
- ** separating it out into a word on its own.
- */
-
- problem = MR_trace_break_into_words(line, &raw_words, &raw_word_max,
- &raw_word_count);
- if (problem != NULL) {
- return problem;
- }
+ problem = MR_trace_break_into_words(line, &raw_words, &raw_word_max,
+ &raw_word_count);
+ if (problem != NULL) {
+ return problem;
+ }
if (raw_word_count > 0 && MR_isdigit(*raw_words[0])) {
i = 0;
@@ -7927,99 +1130,6 @@
return NULL;
}
-static void
-MR_trace_expand_aliases(char ***words, int *word_max, int *word_count)
-{
- const char *alias_key;
- char **alias_words;
- int alias_word_count;
- int alias_copy_start;
- int i;
- int n;
-
- if (*word_count == 0) {
- alias_key = "EMPTY";
- alias_copy_start = 0;
- } else if (MR_trace_is_natural_number(*words[0], &n)) {
- alias_key = "NUMBER";
- alias_copy_start = 0;
- } else {
- alias_key = *words[0];
- alias_copy_start = 1;
- }
-
- if (MR_trace_lookup_alias(alias_key, &alias_words, &alias_word_count)) {
- MR_ensure_big_enough(*word_count + alias_word_count, *word, char *,
- MR_INIT_WORD_COUNT);
-
- /* Move the original words (except the alias key) up. */
- for (i = *word_count - 1; i >= alias_copy_start; i--) {
- (*words)[i + alias_word_count - alias_copy_start] = (*words)[i];
- }
-
- /* Move the alias body to the words array. */
- for (i = 0; i < alias_word_count; i++) {
- (*words)[i] = alias_words[i];
- }
-
- *word_count += alias_word_count - alias_copy_start;
- }
-}
-
-static MR_bool
-MR_trace_source(const char *filename, MR_bool ignore_errors)
-{
- FILE *fp;
-
- if ((fp = fopen(filename, "r")) != NULL) {
- MR_trace_source_from_open_file(fp);
- fclose(fp);
- return MR_TRUE;
- } else {
- fflush(MR_mdb_out);
- fprintf(MR_mdb_err, "%s: %s.\n", filename, strerror(errno));
- return MR_FALSE;
- }
-}
-
-static void
-MR_trace_source_from_open_file(FILE *fp)
-{
- char *contents;
- MR_Line *line;
- MR_Line *prev_line;
- MR_Line *old_head;
-
- prev_line = NULL;
- old_head = MR_line_head;
-
- /*
- ** Insert the sourced commands at the front of the command queue,
- ** preserving their order in the sourced file.
- */
- while ((contents = MR_trace_readline_raw(fp)) != NULL) {
- line = MR_NEW(MR_Line);
- line->MR_line_contents = MR_copy_string(contents);
-
- if (prev_line == NULL) {
- MR_line_head = line;
- } else {
- prev_line->MR_line_next = line;
- }
-
- prev_line = line;
- }
-
- if (prev_line != NULL) {
- prev_line->MR_line_next = old_head;
- if (MR_line_tail == NULL) {
- MR_line_tail = prev_line;
- }
- }
-
- MR_trace_internal_interacting = MR_FALSE;
-}
-
/*
** Call MR_trace_getline to get the next line of input, then do some
** further processing. If the input has reached EOF, return the command
@@ -8130,7 +1240,7 @@
** If there are no lines in the queue, this function returns NULL.
*/
-static char *
+char *
MR_trace_getline_queue(void)
{
if (MR_line_head != NULL) {
@@ -8151,7 +1261,7 @@
}
}
-static void
+void
MR_insert_line_at_head(const char *contents)
{
MR_Line *line;
@@ -8166,7 +1276,7 @@
}
}
-static void
+void
MR_insert_line_at_tail(const char *contents)
{
MR_Line *line;
@@ -8301,7 +1411,7 @@
return NULL;
}
-static void
+void
MR_trace_event_print_internal_report(MR_Event_Info *event_info)
{
const MR_Label_Layout *parent;
@@ -8358,90 +1468,6 @@
parent_filename, parent_lineno, indent);
}
-static const char *const MR_trace_movement_cmd_args[] =
- { "-N", "-S", "-a", "-i", "-n", "-s",
- "--none", "--some", "--all", "--integrity",
- "--strict", "--no-strict", NULL };
-
-/*
-** "retry --assume-all-io-is-tabled" is deliberately not documented as
-** it is for developers only.
-*/
-static const char *const MR_trace_retry_cmd_args[] =
- { "--force", "--interactive", "--only-if-safe", NULL };
-
-static const char *const MR_trace_print_cmd_args[] =
- { "-f", "-p", "-v", "--flat", "--pretty", "--verbose",
- "exception", "goal", "*", NULL };
-
-/*
-** It's better to have a single completion where possible,
-** so don't include `-d' here.
-*/
-static const char *const MR_trace_stack_cmd_args[] =
- { "--detailed", NULL };
-
-static const char *const MR_trace_set_cmd_args[] =
- { "-A", "-B", "-P", "-f", "-p", "-v",
- "--print-all", "--print", "--browse",
- "--flat", "--pretty", "--verbose", "xml_tmp_filename",
- "xml_browser_cmd", "format", "depth", "size", "width", "lines", "flat",
- "pretty", "verbose", NULL };
-
-static const char *const MR_trace_view_cmd_args[] =
- { "-c", "-f", "-n", "-s", "-t", "-v", "-w", "-2",
- "--close", "--verbose", "--force", "--split-screen",
- "--window-command", "--server-command", "--server-name",
- "--timeout", NULL };
-
-static const char *const MR_trace_break_cmd_args[] =
- { "-A", "-E", "-I", "-O", "-P", "-S", "-a", "-e", "-i",
- "--all", "--entry", "--ignore-entry", "--ignore-interface",
- "--interface", "--print", "--select-all", "--select-one",
- "--stop", "here", "info", NULL };
-
-static const char *const MR_trace_ignore_cmd_args[] =
- { "-E", "-I", "--ignore-entry", "--ignore-interface", NULL };
-
-static const char *const MR_trace_printlevel_cmd_args[] =
- { "none", "some", "all", NULL };
-
-static const char *const MR_trace_on_off_args[] =
- { "on", "off", NULL };
-
-static const char *const MR_trace_context_cmd_args[] =
- { "none", "before", "after", "prevline", "nextline", NULL };
-
-static const char *const MR_trace_scope_cmd_args[] =
- { "all", "interface", "entry", NULL };
-
-static const char *const MR_trace_dd_cmd_args[] =
- { "-s", "-a", "-d", "-n", "--search-mode",
- "--assume-all-io-is-tabled", "--depth", "--nodes",
- "td", "top_down", "dq" "divide_and_query", "sdq",
- "suspicion_divide_and_query", NULL };
-
-/*
-** "table_io allow" is deliberately not documented as it is developer only
-** "table_io begin" and "table_io end" are deliberately not documented in an
-** effort to encourage consistent use of start/stop.
-*/
-static const char *const MR_trace_table_io_cmd_args[] =
- { "stats", "start", "stop", NULL };
-
-/*
-** It's better to have a single completion where possible,
-** so don't include `-i' here.
-*/
-static const char *const MR_trace_source_cmd_args[] =
- { "--ignore-errors", NULL };
-
-static const char *const MR_trace_quit_cmd_args[] =
- { "-y", NULL };
-
-static const char *const MR_trace_stats_cmd_args[] =
- { "procs", "labels", "var_names", "io_tabling", NULL };
-
static const MR_Trace_Command_Info MR_trace_command_infos[] =
{
/*
@@ -8501,10 +1527,6 @@
NULL, MR_trace_var_completer },
{ "browsing", "list", MR_trace_cmd_list,
NULL, MR_trace_null_completer },
- { "browsing", "push_list_dir", MR_trace_cmd_push_list_dir,
- NULL, MR_trace_null_completer },
- { "browsing", "pop_list_dir", MR_trace_cmd_pop_list_dir,
- NULL, MR_trace_null_completer },
{ "breakpoint", "break", MR_trace_cmd_break,
MR_trace_break_cmd_args, MR_trace_proc_spec_completer },
@@ -8541,22 +1563,44 @@
{ "table_io", "table_io", MR_trace_cmd_table_io,
MR_trace_table_io_cmd_args, MR_trace_null_completer },
- { "parameter", "printlevel", MR_trace_cmd_printlevel,
- MR_trace_printlevel_cmd_args, MR_trace_null_completer },
{ "parameter", "mmc_options", MR_trace_cmd_mmc_options,
NULL, MR_trace_null_completer },
+ { "parameter", "printlevel", MR_trace_cmd_printlevel,
+ MR_trace_printlevel_cmd_args, MR_trace_null_completer },
{ "parameter", "scroll", MR_trace_cmd_scroll,
MR_trace_on_off_args, MR_trace_null_completer },
{ "parameter", "stack_default_limit", MR_trace_cmd_stack_default_limit,
NULL, MR_trace_null_completer },
- { "parameter", "context", MR_trace_cmd_context,
- MR_trace_context_cmd_args, MR_trace_null_completer },
{ "parameter", "goal_paths", MR_trace_cmd_goal_paths,
MR_trace_on_off_args, MR_trace_null_completer },
{ "parameter", "scope", MR_trace_cmd_scope,
MR_trace_scope_cmd_args, MR_trace_null_completer },
{ "parameter", "echo", MR_trace_cmd_echo,
MR_trace_on_off_args, MR_trace_null_completer },
+ { "parameter", "context", MR_trace_cmd_context,
+ MR_trace_context_cmd_args, MR_trace_null_completer },
+ { "parameter", "list_context_lines", MR_trace_cmd_list_context_lines,
+ NULL, MR_trace_null_completer },
+ { "parameter", "list_path", MR_trace_cmd_list_path,
+ NULL, MR_trace_null_completer },
+ { "parameter", "push_list_dir", MR_trace_cmd_push_list_dir,
+ NULL, MR_trace_null_completer },
+ { "parameter", "pop_list_dir", MR_trace_cmd_pop_list_dir,
+ NULL, MR_trace_null_completer },
+ { "parameter", "fail_trace_counts", MR_trace_cmd_fail_trace_counts,
+ NULL, MR_trace_filename_completer },
+ { "parameter", "pass_trace_counts", MR_trace_cmd_pass_trace_counts,
+ NULL, MR_trace_filename_completer },
+ { "parameter", "max_io_actions", MR_trace_cmd_max_io_actions,
+ NULL, MR_trace_null_completer },
+ { "parameter", "xml_browser_cmd", MR_trace_cmd_xml_browser_cmd,
+ NULL, MR_trace_null_completer },
+ { "parameter", "xml_tmp_filename", MR_trace_cmd_xml_tmp_filename,
+ NULL, MR_trace_null_completer },
+ { "parameter", "format", MR_trace_cmd_format,
+ MR_trace_format_cmd_args, MR_trace_null_completer },
+ { "parameter", "format_param", MR_trace_cmd_format_param,
+ MR_trace_format_param_cmd_args, MR_trace_null_completer },
{ "parameter", "alias", MR_trace_cmd_alias,
NULL, MR_trace_command_completer },
{ "parameter", "unalias", MR_trace_cmd_unalias,
@@ -8575,11 +1619,9 @@
NULL, MR_trace_proc_spec_completer },
{ "dd", "untrust", MR_trace_cmd_untrust,
NULL, MR_trace_null_completer },
- { "dd", "trusted", MR_trace_cmd_trusted, NULL,
- MR_trace_null_completer },
+ { "dd", "trusted", MR_trace_cmd_trusted,
+ NULL, MR_trace_null_completer },
- { "misc", "set", MR_trace_cmd_set,
- MR_trace_set_cmd_args, MR_trace_null_completer },
{ "misc", "source", MR_trace_cmd_source,
MR_trace_source_cmd_args, MR_trace_filename_completer },
{ "misc", "save", MR_trace_cmd_save,
@@ -8615,7 +1657,7 @@
{ "developer", "mm_stacks", MR_trace_cmd_mm_stacks,
NULL, MR_trace_null_completer },
{ "developer", "nondet_stack", MR_trace_cmd_nondet_stack,
- MR_trace_stack_cmd_args, MR_trace_null_completer },
+ MR_trace_nondet_stack_cmd_args, MR_trace_null_completer },
{ "developer", "stack_regs", MR_trace_cmd_stack_regs,
NULL, MR_trace_null_completer },
{ "developer", "all_regs", MR_trace_cmd_all_regs,
@@ -8668,7 +1710,7 @@
}
}
-static const MR_Trace_Command_Info *
+const MR_Trace_Command_Info *
MR_trace_valid_command(const char *word)
{
int i;
Index: trace/mercury_trace_internal.h
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/trace/mercury_trace_internal.h,v
retrieving revision 1.20
diff -u -b -r1.20 mercury_trace_internal.h
--- trace/mercury_trace_internal.h 12 Aug 2005 02:01:28 -0000 1.20
+++ trace/mercury_trace_internal.h 3 Apr 2006 12:28:15 -0000
@@ -1,4 +1,7 @@
/*
+** vim: ts=4 sw=4 expandtab
+*/
+/*
** Copyright (C) 1998-2002, 2005 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.
@@ -8,10 +11,14 @@
#define MERCURY_TRACE_INTERNAL_H
#include "mercury_types.h" /* for MR_Code */
+#include "mercury_trace_base.h" /* for MR_SavedDebugState */
+
#include "mercury_trace.h" /* for MR_Event_Info, etc. */
#include "mercury_std.h" /* for MR_bool */
+#include "mercury_trace_cmds.h" /* for MR_Spy_Print_List */
#include "mercury_trace_completion.h" /* for MR_Make_Completer */
#include "mercury_trace_spy.h" /* for MR_Spy_Print_List */
+#include "mercury_trace_source.h" /* for MR_Trace_Source_Server */
#include <stdio.h> /* for FILE */
@@ -19,6 +26,10 @@
MR_bool interactive, MR_Spy_Print_List print_list,
MR_Event_Info *event_info);
+extern void MR_trace_event_print_internal_report(
+ MR_Event_Info *event_info);
+
+
/*
** Debugger I/O streams.
** Replacements for stdin/stdout/stderr respectively.
@@ -34,6 +45,78 @@
extern FILE *MR_mdb_err;
/*
+** We print confirmation of commands (e.g. new aliases) if this is MR_TRUE.
+*/
+
+MR_bool MR_trace_internal_interacting;
+
+/*
+** The structure of the input queue, and the operations that work on it.
+*/
+
+typedef struct MR_Line_Struct {
+ char *MR_line_contents;
+ struct MR_Line_Struct *MR_line_next;
+} MR_Line;
+
+extern void MR_insert_line_at_head(const char *contents);
+extern void MR_insert_line_at_tail(const char *contents);
+
+/*
+** If there any lines waiting in the queue, return the first of these.
+** The memory for the line will have been allocated with MR_malloc(),
+** and it is the caller's resposibility to MR_free() it when appropriate.
+** If there are no lines in the queue, this function returns NULL.
+*/
+
+extern char *MR_trace_getline_queue(void);
+
+/*
+** The details of the source server, if any.
+*/
+
+extern MR_Trace_Source_Server MR_trace_source_server;
+
+/*
+** Source commands from the given file. Print an error message if the file
+** cannot be read, unless ignore_errors is true.
+*/
+
+extern MR_bool MR_trace_source(const char *filename,
+ MR_bool ignore_errors);
+
+/*
+** Source commands from the given file.
+*/
+
+extern void MR_trace_source_from_open_file(FILE *fp);
+
+/*
+** Print a usage message for the currently executing command.
+*/
+
+extern void MR_trace_usage_cur_cmd(void);
+
+/*
+** Print a message about this command being a no-op from this port.
+*/
+
+extern void MR_trace_do_noop(void);
+
+/*
+** If the given word is the name of a valid command, return its info.
+*/
+
+extern const MR_Trace_Command_Info
+ *MR_trace_valid_command(const char *word);
+
+/*
+** Close a source server, if there is one attached.
+*/
+
+extern void MR_trace_maybe_close_source_window(MR_bool verbose);
+
+/*
** This just prints to MR_mdb_out a message telling the user
** that the debugger caught an interrupt.
*/
@@ -45,6 +128,9 @@
extern char *MR_trace_get_command(const char *prompt, FILE *mdb_in,
FILE *mdb_out);
+extern MR_SavedDebugState
+ MR_saved_debug_state;
+
/*
** If word is a valid command, return information about the
** completer for the command.
@@ -58,7 +144,7 @@
** A Readline completer for command names.
*/
-extern MR_Completer_List *MR_trace_command_completer(const char *word,
- size_t word_len);
+extern MR_Completer_List
+ *MR_trace_command_completer(const char *word, size_t word_len);
#endif /* MERCURY_TRACE_INTERNAL_H */
Index: trace/mercury_trace_tables.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/trace/mercury_trace_tables.c,v
retrieving revision 1.41
diff -u -b -r1.41 mercury_trace_tables.c
--- trace/mercury_trace_tables.c 1 Mar 2006 22:58:51 -0000 1.41
+++ trace/mercury_trace_tables.c 2 Apr 2006 05:56:15 -0000
@@ -775,9 +775,10 @@
** Search backwards for the end of the final module qualifier.
** There must be at least one character before the qualifier.
*/
+
while (end > str) {
- if (*end == ':' || *end == '.' || (*end == '_' && *(end + 1) == '_')) {
- if (*end == ':' || *end == '.') {
+ if (*end == '.' || (*end == '_' && *(end + 1) == '_')) {
+ if (*end == '.') {
spec->MR_proc_name = end + 1;
} else {
spec->MR_proc_name = end + 2;
@@ -812,6 +813,7 @@
/*
** Convert all occurrences of `__' to `.'.
*/
+
static void
MR_translate_double_underscores(char *start)
{
@@ -1078,6 +1080,11 @@
data->MR_complete_pf = MR_FUNCTION;
word += 5;
} else {
+ /*
+ ** We don't complete on the names of special (unify, index compare,
+ ** or init) predicates.
+ */
+
data->MR_complete_pf = -1;
}
@@ -1091,21 +1098,19 @@
data->MR_complete_current_proc= -1;
/*
- ** Handle the case where the word matches the first part of
- ** a module name. If the word unambiguously determines the
- ** module name we want to return module qualified completions
- ** for all the procedures in that module. Otherwise, we just
- ** complete on the names of all of the matching modules and
- ** unqualified procedure names.
+ ** Handle the case where the word matches the first part of a module name.
+ ** If the word unambiguously determines the module name we want to return
+ ** module qualified completions for all the procedures in that module.
+ ** Otherwise, we just complete on the names of all of the matching modules
+ ** and unqualified procedure names.
**
- ** For example, given word to complete `f' and modules `foo'
- ** and `bar', we want to return all the procedures in module
- ** `foo' as completions, as well as all procedures whose
- ** unqualified names begin with `f'.
- ** Given word to complete `foo.' and modules `foo' and `foo.bar'
- ** we want to return `foo.bar.' and all the procedures in
- ** module `foo' as completions.
+ ** For example, given word to complete `f' and modules `foo' and `bar',
+ ** we want to return all the procedures in module `foo' as completions,
+ ** as well as all procedures whose unqualified names begin with `f'.
+ ** Given word to complete `foo.' and modules `foo' and `foo.bar' we want to
+ ** return `foo.bar.' and all the procedures in module `foo' as completions.
*/
+
MR_bsearch(MR_module_info_next, slot, found,
strncmp(MR_module_infos[slot]->MR_ml_name,
data->MR_complete_name, data->MR_complete_name_len));
@@ -1157,6 +1162,7 @@
/*
** Move on to the next module.
*/
+
data->MR_complete_current_module++;
if (data->MR_complete_current_module >= MR_module_info_next) {
return NULL;
@@ -1167,6 +1173,7 @@
** Complete on the module name if we aren't finding
** qualified completions in this module.
*/
+
module_name = MR_module_infos[data->MR_complete_current_module]
->MR_ml_name;
if (data->MR_complete_word_matches_module == 0 &&
@@ -1194,6 +1201,7 @@
/*
** Set up the completer data for processing a module.
*/
+
static void
MR_trace_proc_spec_completer_init_module(MR_Proc_Completer_Data *data)
{
@@ -1213,6 +1221,7 @@
** Work out whether we should find qualified completions
** for procedures in this module.
*/
+
if (MR_strneq(module_name, name, module_name_len)
&& name_len > module_name_len
&& name[module_name_len] == '.'
@@ -1223,6 +1232,7 @@
** When searching for qualified completions skip past
** the module name and the trailing '.'.
*/
+
data->MR_complete_word_matches_module = module_name_len + 1;
} else if (data->MR_complete_current_module ==
data->MR_unambiguous_matching_module)
@@ -1233,6 +1243,7 @@
** matching all procedures, use the empty string as the
** name to match against.
*/
+
data->MR_complete_word_matches_module = name_len;
} else {
data->MR_complete_word_matches_module = 0;
@@ -1255,6 +1266,7 @@
** Check whether the current procedure matches the word to be completed.
** To do: complete on arity and mode number.
*/
+
static char *
MR_trace_complete_proc(MR_Proc_Completer_Data *data)
{
@@ -1298,6 +1310,7 @@
/*
** Move on to the next procedure in the current module.
*/
+
data->MR_complete_current_proc++;
if (data->MR_complete_word_matches_module != 0
Index: trace/mercury_trace_util.h
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/trace/mercury_trace_util.h,v
retrieving revision 1.14
diff -u -b -r1.14 mercury_trace_util.h
--- trace/mercury_trace_util.h 8 Feb 2006 21:54:34 -0000 1.14
+++ trace/mercury_trace_util.h 3 Apr 2006 11:29:41 -0000
@@ -74,6 +74,7 @@
** and false otherwise. Because builtin_catch creates a stack frame, but no
** events, it must be handled specially by some parts of the debugger.
*/
+
extern MR_bool MR_trace_proc_layout_is_builtin_catch(
const MR_Proc_Layout *layout);
cvs diff: Diffing util
cvs diff: Diffing vim
cvs diff: Diffing vim/after
cvs diff: Diffing vim/ftplugin
cvs diff: Diffing vim/syntax
--------------------------------------------------------------------------
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