mirror of
https://github.com/Mercury-Language/mercury.git
synced 2026-04-15 01:13:30 +00:00
Simplify the code of the mdb help system.
browser/help.m:
Simplify the data types representing the nested structure
of help information. Simplify the code of the predicates
that work on that structure.
Simplify some of the predicates, e.g. by having a search predicate
do *just* search.
Give types and predicates more meaningful names. Make argument order
more suitable for state-variables. Move a predicate next to its
only call site.
browser/declarative_user.m:
Conform to the change in help.m.
Replace two bools with values of bespoke types.
browser/declarative_debugger.m:
browser/declarative_oracle.m:
Conform to the changes in help.m and declarative_user.m.
doc/generate_mdb_doc:
Fix the vim modeline.
trace/mercury_trace_declarative.c:
trace/mercury_trace_help.c:
Conform to the changes in the browser directory.
util/info_to_mdb.c:
Switch from /**/ to // for comments.
Give a macro a meaningful name.
Fix indentation.
This commit is contained in:
@@ -298,7 +298,7 @@
|
||||
%
|
||||
:- pred diagnoser_state_init(io.input_stream::in, io.output_stream::in,
|
||||
browser_info.browser_persistent_state::in,
|
||||
help.system::in, diagnoser_state(R)::out) is det.
|
||||
help_system::in, diagnoser_state(R)::out) is det.
|
||||
|
||||
:- pred diagnosis(S::in, analysis_type(edt_node(R))::in,
|
||||
diagnoser_response(R)::out,
|
||||
@@ -331,6 +331,7 @@
|
||||
|
||||
:- import_module mdb.declarative_edt.
|
||||
:- import_module mdb.declarative_oracle.
|
||||
:- import_module mdb.declarative_user.
|
||||
:- import_module mdb.util.
|
||||
:- import_module mdbcomp.rtti_access.
|
||||
:- import_module mdbcomp.sym_name.
|
||||
@@ -660,7 +661,7 @@ overrule_bug(Store, Response, Diagnoser0, Diagnoser, !IO) :-
|
||||
% make it easier to call from C code.
|
||||
%
|
||||
:- pred diagnoser_state_init_store(io.input_stream::in, io.output_stream::in,
|
||||
browser_info.browser_persistent_state::in, help.system::in,
|
||||
browser_info.browser_persistent_state::in, help_system::in,
|
||||
diagnoser_state(trace_node_id)::out) is det.
|
||||
|
||||
:- pragma foreign_export("C", diagnoser_state_init_store(in, in, in, in, out),
|
||||
@@ -684,16 +685,30 @@ diagnoser_session_init(!Diagnoser) :-
|
||||
|
||||
% Set the testing flag of the user_state in the given diagnoser.
|
||||
%
|
||||
:- pred set_diagnoser_testing_flag(bool::in,
|
||||
:- pred set_diagnoser_to_testing(
|
||||
diagnoser_state(trace_node_id)::in,
|
||||
diagnoser_state(trace_node_id)::out) is det.
|
||||
|
||||
:- pragma foreign_export("C", set_diagnoser_testing_flag(in, in, out),
|
||||
"MR_DD_decl_set_diagnoser_testing_flag").
|
||||
:- pragma foreign_export("C", set_diagnoser_to_testing(in, out),
|
||||
"MR_DD_decl_set_diagnoser_to_testing").
|
||||
|
||||
set_diagnoser_testing_flag(Testing, !Diagnoser) :-
|
||||
set_diagnoser_to_testing(!Diagnoser) :-
|
||||
Oracle0 = !.Diagnoser ^ oracle_state,
|
||||
set_oracle_testing_flag(Testing, Oracle0, Oracle),
|
||||
set_oracle_testing_flag(we_are_testing, Oracle0, Oracle),
|
||||
!Diagnoser ^ oracle_state := Oracle.
|
||||
|
||||
% Set the testing flag of the user_state in the given diagnoser.
|
||||
%
|
||||
:- pred set_diagnoser_to_not_testing(
|
||||
diagnoser_state(trace_node_id)::in,
|
||||
diagnoser_state(trace_node_id)::out) is det.
|
||||
|
||||
:- pragma foreign_export("C", set_diagnoser_to_not_testing(in, out),
|
||||
"MR_DD_decl_set_diagnoser_to_not_testing").
|
||||
|
||||
set_diagnoser_to_not_testing(!Diagnoser) :-
|
||||
Oracle0 = !.Diagnoser ^ oracle_state,
|
||||
set_oracle_testing_flag(we_are_not_testing, Oracle0, Oracle),
|
||||
!Diagnoser ^ oracle_state := Oracle.
|
||||
|
||||
:- pred set_fallback_search_mode(trace_node_store::in,
|
||||
|
||||
@@ -67,7 +67,7 @@
|
||||
% Produce a new oracle state.
|
||||
%
|
||||
:- pred oracle_state_init(io.input_stream::in, io.output_stream::in,
|
||||
browser_info.browser_persistent_state::in, help.system::in,
|
||||
browser_info.browser_persistent_state::in, help_system::in,
|
||||
oracle_state::out) is det.
|
||||
|
||||
% Add a module to the set of modules trusted by the oracle
|
||||
@@ -161,8 +161,8 @@
|
||||
|
||||
% Set the testing flag of the user_state in the given oracle.
|
||||
%
|
||||
:- pred set_oracle_testing_flag(bool::in, oracle_state::in, oracle_state::out)
|
||||
is det.
|
||||
:- pred set_oracle_testing_flag(are_we_testing::in,
|
||||
oracle_state::in, oracle_state::out) is det.
|
||||
|
||||
% Reset the oracle's knowledge base.
|
||||
%
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
:- import_module mdb.declarative_debugger.
|
||||
:- import_module mdb.help.
|
||||
|
||||
:- import_module bool.
|
||||
:- import_module io.
|
||||
|
||||
%---------------------------------------------------------------------------%
|
||||
@@ -61,7 +60,7 @@
|
||||
:- type user_state.
|
||||
|
||||
:- pred user_state_init(io.input_stream::in, io.output_stream::in,
|
||||
browser_info.browser_persistent_state::in, help.system::in,
|
||||
browser_info.browser_persistent_state::in, help_system::in,
|
||||
user_state::out) is det.
|
||||
|
||||
% This predicate handles the interactive part of the declarative
|
||||
@@ -94,10 +93,14 @@
|
||||
%
|
||||
:- func get_user_input_stream(user_state) = io.input_stream.
|
||||
|
||||
:- type are_we_testing
|
||||
---> we_are_not_testing
|
||||
; we_are_testing.
|
||||
|
||||
% Set the testing flag of the user_state.
|
||||
%
|
||||
:- pred set_user_testing_flag(bool::in, user_state::in, user_state::out)
|
||||
is det.
|
||||
:- pred set_user_testing_flag(are_we_testing::in,
|
||||
user_state::in, user_state::out) is det.
|
||||
|
||||
%---------------------------------------------------------------------------%
|
||||
%---------------------------------------------------------------------------%
|
||||
@@ -118,6 +121,7 @@
|
||||
:- import_module mdbcomp.rtti_access.
|
||||
:- import_module mdbcomp.sym_name.
|
||||
|
||||
:- import_module bool.
|
||||
:- import_module char.
|
||||
:- import_module deconstruct.
|
||||
:- import_module exception.
|
||||
@@ -197,53 +201,59 @@
|
||||
; user_cmd_illegal.
|
||||
% None of the above.
|
||||
|
||||
:- type maybe_display_question
|
||||
---> do_not_display_question
|
||||
; display_question.
|
||||
|
||||
:- type user_state
|
||||
---> user_state(
|
||||
instr :: io.input_stream,
|
||||
outstr :: io.output_stream,
|
||||
browser :: browser_persistent_state,
|
||||
|
||||
% Yes if the question should be displayed when querying
|
||||
% the user. This is used to suppress the displaying of the
|
||||
% question after the user issues a command which does not
|
||||
% answer the question (such as an `info' command).
|
||||
display_question :: bool,
|
||||
% Control whether the question should be displayed
|
||||
% when querying the user. This is used to suppress
|
||||
% the displaying of the question after the user issues
|
||||
% a command which does not answer the question (such as
|
||||
% an `info' command).
|
||||
display_question :: maybe_display_question,
|
||||
|
||||
% If this following flag is set to, yes then user responses
|
||||
% If this is set we_are_testing, then user responses
|
||||
% will be simulated and will always be `no', except when
|
||||
% confirming a bug in which case the response will be `yes'.
|
||||
testing :: bool,
|
||||
% confirming a bug in which case, the response will be `yes'.
|
||||
testing :: are_we_testing,
|
||||
|
||||
help_system :: help.system
|
||||
help_system :: help_system
|
||||
).
|
||||
|
||||
user_state_init(InStr, OutStr, Browser, HelpSystem, State) :-
|
||||
State = user_state(InStr, OutStr, Browser, yes, no, HelpSystem).
|
||||
State = user_state(InStr, OutStr, Browser, display_question,
|
||||
we_are_not_testing, HelpSystem).
|
||||
|
||||
%---------------------------------------------------------------------------%
|
||||
|
||||
query_user(UserQuestion, Response, !User, !IO) :-
|
||||
Question = get_decl_question(UserQuestion),
|
||||
(
|
||||
!.User ^ testing = yes,
|
||||
!.User ^ testing = we_are_testing,
|
||||
Node = get_decl_question_node(Question),
|
||||
Response = user_response_answer(Question,
|
||||
truth_value(Node, truth_erroneous))
|
||||
;
|
||||
!.User ^ testing = no,
|
||||
!.User ^ testing = we_are_not_testing,
|
||||
(
|
||||
!.User ^ display_question = yes,
|
||||
!.User ^ display_question = display_question,
|
||||
write_decl_question(Question, !.User, !IO),
|
||||
user_question_prompt(UserQuestion, Prompt),
|
||||
!User ^ display_question := no
|
||||
!User ^ display_question := do_not_display_question
|
||||
;
|
||||
!.User ^ display_question = no,
|
||||
!.User ^ display_question = do_not_display_question,
|
||||
Prompt = "dd> "
|
||||
),
|
||||
get_command(Prompt, Command, !User, !IO),
|
||||
handle_command(Command, UserQuestion, Response, !User, !IO),
|
||||
( if Response \= user_response_show_info(_) then
|
||||
!User ^ display_question := yes
|
||||
!User ^ display_question := display_question
|
||||
else
|
||||
true
|
||||
)
|
||||
@@ -380,7 +390,7 @@ handle_command(Cmd, UserQuestion, Response, !User, !IO) :-
|
||||
Response = user_response_change_search(Mode)
|
||||
;
|
||||
Cmd = user_cmd_ask,
|
||||
!User ^ display_question := yes,
|
||||
!User ^ display_question := display_question,
|
||||
query_user(UserQuestion, Response, !User, !IO)
|
||||
;
|
||||
Cmd = user_cmd_pd,
|
||||
@@ -399,7 +409,8 @@ handle_command(Cmd, UserQuestion, Response, !User, !IO) :-
|
||||
MaybeCmd = no,
|
||||
Path = ["concepts", "decl_debug"]
|
||||
),
|
||||
help.path(!.User ^ help_system, Path, !.User ^ outstr, Res, !IO),
|
||||
help.print_help_node_at_path(!.User ^ outstr, !.User ^ help_system,
|
||||
Path, Res, !IO),
|
||||
(
|
||||
Res = help_ok
|
||||
;
|
||||
@@ -1064,10 +1075,10 @@ is_dash('-').
|
||||
|
||||
user_confirm_bug(Bug, Response, !User, !IO) :-
|
||||
(
|
||||
!.User ^ testing = yes,
|
||||
!.User ^ testing = we_are_testing,
|
||||
Response = confirm_bug
|
||||
;
|
||||
!.User ^ testing = no,
|
||||
!.User ^ testing = we_are_not_testing,
|
||||
write_decl_bug(Bug, !.User, !IO),
|
||||
get_command("Is this a bug? ", Command, !User, !IO),
|
||||
(
|
||||
|
||||
234
browser/help.m
234
browser/help.m
@@ -30,9 +30,9 @@
|
||||
:- import_module list.
|
||||
:- import_module type_desc.
|
||||
|
||||
:- type system.
|
||||
:- type help_system.
|
||||
|
||||
:- type path == list(string).
|
||||
:- type path == list(string).
|
||||
|
||||
:- type help_res
|
||||
---> help_ok
|
||||
@@ -42,31 +42,32 @@
|
||||
|
||||
% Initialize an empty help system.
|
||||
%
|
||||
:- pred init(system::out) is det.
|
||||
:- pred init(help_system::out) is det.
|
||||
|
||||
% Add a node to the given help system, at the given path, and with
|
||||
% the given name and index. If successful, return help_ok and the
|
||||
% updated help system; if not, return an error message and the
|
||||
% original help system.
|
||||
%
|
||||
:- pred add_help_node(system::in, path::in, int::in,
|
||||
string::in, string::in, help_res::out, system::out) is det.
|
||||
:- pred add_help_node(path::in, int::in, string::in, string::in,
|
||||
help_res::out, help_system::in, help_system::out) is det.
|
||||
|
||||
% Print the top-level help nodes. This should give an overview
|
||||
% of the main topics for which help is available.
|
||||
%
|
||||
:- pred help(system::in, io.output_stream::in, io::di, io::uo) is det.
|
||||
:- pred print_top_level_help_nodes(io.output_stream::in, help_system::in,
|
||||
io::di, io::uo) is det.
|
||||
|
||||
% Print the help node at the given path. If there is none,
|
||||
% print the top-level nodes.
|
||||
%
|
||||
:- pred path(system::in, path::in, io.output_stream::in,
|
||||
help_res::out, io::di, io::uo) is det.
|
||||
:- pred print_help_node_at_path(io.output_stream::in, help_system::in,
|
||||
path::in, help_res::out, io::di, io::uo) is det.
|
||||
|
||||
% Print all help nodes with the given name. If there are none,
|
||||
% print the top-level nodes.
|
||||
%
|
||||
:- pred name(system::in, string::in, io.output_stream::in,
|
||||
:- pred print_help_for_name(io.output_stream::in, help_system::in, string::in,
|
||||
io::di, io::uo) is det.
|
||||
|
||||
%---------------------------------------------------------------------------%
|
||||
@@ -88,38 +89,39 @@
|
||||
:- import_module require.
|
||||
:- import_module string.
|
||||
|
||||
:- type system == list(entry).
|
||||
:- type help_system == list(help_node).
|
||||
|
||||
:- type node
|
||||
---> node(
|
||||
text,
|
||||
list(entry)
|
||||
).
|
||||
:- type help_node
|
||||
---> help_node(
|
||||
% The index of the node, which determines the position
|
||||
% of the node in the node list of its parent (if any) or
|
||||
% or in the system node list (if it has no parent).
|
||||
% Every node list is always sorted on this field.
|
||||
helpnode_index :: int,
|
||||
|
||||
:- type text == string. % Should be one or more complete lines.
|
||||
% The name of the node, which should be one word or phrase.
|
||||
% It must be unique within the list of nodes containing it,
|
||||
% but need not be unique globally.
|
||||
helpnode_name :: string,
|
||||
|
||||
:- type entry
|
||||
---> entry(
|
||||
int, % This integer determines the position
|
||||
% of the node in the node list. A node
|
||||
% list is always sorted on this field.
|
||||
% The actual help text in the node. Should be one or more
|
||||
% complete lines.
|
||||
helpnode_text :: string,
|
||||
|
||||
string, % The name of the node, which should
|
||||
% be one word or phrase. It must be
|
||||
% unique within the node list, but
|
||||
% need not be unique globally.
|
||||
|
||||
node
|
||||
helpnode_children :: list(help_node)
|
||||
).
|
||||
|
||||
%---------------------------------------------------------------------------%
|
||||
|
||||
:- pragma foreign_export("C", init(out), "ML_HELP_init").
|
||||
:- pragma foreign_export("C", add_help_node(in, in, in, in, in, out, out),
|
||||
:- pragma foreign_export("C", add_help_node(in, in, in, in, out, in, out),
|
||||
"ML_HELP_add_help_node").
|
||||
:- pragma foreign_export("C", help(in, in, di, uo), "ML_HELP_help").
|
||||
:- pragma foreign_export("C", path(in, in, in, out, di, uo), "ML_HELP_path").
|
||||
:- pragma foreign_export("C", name(in, in, in, di, uo), "ML_HELP_name").
|
||||
:- pragma foreign_export("C", print_top_level_help_nodes(in, in, di, uo),
|
||||
"ML_HELP_print_top_level_help_nodes").
|
||||
:- pragma foreign_export("C", print_help_node_at_path(in, in, in, out, di, uo),
|
||||
"ML_HELP_print_help_node_at_path").
|
||||
:- pragma foreign_export("C", print_help_for_name(in, in, in, di, uo),
|
||||
"ML_HELP_print_help_for_name").
|
||||
:- pragma foreign_export("C", help_system_type(out),
|
||||
"ML_HELP_help_system_type").
|
||||
:- pragma foreign_export("C", result_is_error(in, out),
|
||||
@@ -129,78 +131,88 @@
|
||||
|
||||
init([]).
|
||||
|
||||
add_help_node(Sys0, Path, Index, Name, Text, Res, Sys) :-
|
||||
Node = node(Text, []),
|
||||
add_node(Sys0, Path, Index, Name, Node, Res, Sys).
|
||||
add_help_node(Path, Index, Name, Text, Res, !Sys) :-
|
||||
Node = help_node(Index, Name, Text, []),
|
||||
add_node(Path, Node, Res, !Sys).
|
||||
|
||||
:- pred add_node(system::in, path::in, int::in,
|
||||
string::in, node::in, help_res::out, system::out) is det.
|
||||
:- pred add_node(path::in, help_node::in, help_res::out,
|
||||
list(help_node)::in, list(help_node)::out) is det.
|
||||
|
||||
add_node(Nodes0, [Step | Steps], Index, Name, NewNode, Res, Nodes) :-
|
||||
( if one_path_step(Nodes0, Step, Entry0) then
|
||||
Entry0 = entry(EntryIndex, EntryName, EntryNode0),
|
||||
EntryNode0 = node(Text, SubNodes0),
|
||||
add_node(SubNodes0, Steps, Index, Name, NewNode, Res, SubNodes),
|
||||
EntryNode = node(Text, SubNodes),
|
||||
Entry = entry(EntryIndex, EntryName, EntryNode),
|
||||
replace_entry(Nodes0, Entry, Nodes)
|
||||
add_node([Step | Steps], NewNode, Res, Nodes0, Nodes) :-
|
||||
( if one_path_step(Nodes0, Step, Node0) then
|
||||
Node0 = help_node(NodeIndex, NodeName, Text, SubNodes0),
|
||||
add_node(Steps, NewNode, Res, SubNodes0, SubNodes),
|
||||
Node = help_node(NodeIndex, NodeName, Text, SubNodes),
|
||||
replace_node_at_index(Node, Nodes0, Nodes)
|
||||
else
|
||||
string.append("invalid path component ", Step, Msg),
|
||||
Msg = "invalid path component " ++ Step,
|
||||
Res = help_error(Msg),
|
||||
Nodes = Nodes0
|
||||
).
|
||||
add_node(Nodes0, [], Index, Name, Node, Res, Nodes) :-
|
||||
add_node([], NewNode, Res, Nodes0, Nodes) :-
|
||||
( if
|
||||
list.member(Entry1, Nodes0),
|
||||
Entry1 = entry(Index, _, _)
|
||||
some [MemberNode] (
|
||||
list.member(MemberNode, Nodes0),
|
||||
MemberNode ^ helpnode_index = NewNode ^ helpnode_index
|
||||
)
|
||||
then
|
||||
Res = help_error("entry with given index already exists"),
|
||||
Nodes = Nodes0
|
||||
else if
|
||||
list.member(Entry1, Nodes0),
|
||||
Entry1 = entry(_, Name, _)
|
||||
some [MemberNode] (
|
||||
list.member(MemberNode, Nodes0),
|
||||
MemberNode ^ helpnode_name = NewNode ^ helpnode_name
|
||||
)
|
||||
then
|
||||
Res = help_error("entry with given name already exists"),
|
||||
Nodes = Nodes0
|
||||
else
|
||||
Res = help_ok,
|
||||
insert_into_entry_list(Nodes0, Index, Name, Node, Nodes)
|
||||
insert_into_node_list(NewNode, Nodes0, Nodes)
|
||||
).
|
||||
|
||||
:- pred insert_into_entry_list(list(entry)::in, int::in, string::in, node::in,
|
||||
list(entry)::out) is det.
|
||||
:- pred replace_node_at_index(help_node::in,
|
||||
list(help_node)::in, list(help_node)::out) is det.
|
||||
|
||||
insert_into_entry_list([], Index, Name, Node, [Entry]) :-
|
||||
Entry = entry(Index, Name, Node).
|
||||
insert_into_entry_list([Head | Tail], Index, Name, Node, List) :-
|
||||
Head = entry(HeadIndex, _, _),
|
||||
( if HeadIndex < Index then
|
||||
insert_into_entry_list(Tail, Index, Name, Node, NewTail),
|
||||
replace_node_at_index(_, [], _) :-
|
||||
unexpected($pred, "node to be replaced not found").
|
||||
replace_node_at_index(Node, [Head | Tail], List) :-
|
||||
( if Head ^ helpnode_index = Node ^ helpnode_index then
|
||||
List = [Node | Tail]
|
||||
else
|
||||
replace_node_at_index(Node, Tail, NewTail),
|
||||
List = [Head | NewTail]
|
||||
).
|
||||
|
||||
:- pred insert_into_node_list(help_node::in,
|
||||
list(help_node)::in, list(help_node)::out) is det.
|
||||
|
||||
insert_into_node_list(Node, [], [Node]).
|
||||
insert_into_node_list(Node, [Head | Tail], List) :-
|
||||
( if Head ^ helpnode_index < Node ^ helpnode_index then
|
||||
insert_into_node_list(Node, Tail, NewTail),
|
||||
List = [Head | NewTail]
|
||||
else
|
||||
Entry = entry(Index, Name, Node),
|
||||
List = [Entry, Head | Tail]
|
||||
List = [Node, Head | Tail]
|
||||
).
|
||||
|
||||
%---------------------------------------------------------------------------%
|
||||
|
||||
help(Sys, Stream, !IO) :-
|
||||
print_entry_list(Sys, Stream, !IO).
|
||||
print_top_level_help_nodes(Stream, Sys, !IO) :-
|
||||
print_node_list(Stream, Sys, !IO).
|
||||
|
||||
path(Entries, Path, Stream, Result, !IO) :-
|
||||
print_help_node_at_path(Stream, Nodes, Path, Result, !IO) :-
|
||||
(
|
||||
Path = [Step | Tail],
|
||||
( if one_path_step(Entries, Step, Entry) then
|
||||
Entry = entry(_, _, EntryNode),
|
||||
( if one_path_step(Nodes, Step, Node) then
|
||||
(
|
||||
Tail = [],
|
||||
EntryNode = node(Text, _),
|
||||
io.write_string(Stream, Text, !IO),
|
||||
print_node(Stream, Node, !IO),
|
||||
Result = help_ok
|
||||
;
|
||||
Tail = [_ | _],
|
||||
EntryNode = node(_, SubEntries),
|
||||
path(SubEntries, Tail, Stream, Result, !IO)
|
||||
SubNodes = Node ^ helpnode_children,
|
||||
print_help_node_at_path(Stream, SubNodes, Tail, Result, !IO)
|
||||
)
|
||||
else
|
||||
Msg = "error at path component """ ++ Step ++ """",
|
||||
@@ -211,76 +223,56 @@ path(Entries, Path, Stream, Result, !IO) :-
|
||||
Result = help_error("the path does not go that deep")
|
||||
).
|
||||
|
||||
name(Sys, Name, Stream, !IO) :-
|
||||
search_entry_list(Sys, Name, 0, Count, Stream, !IO),
|
||||
( if Count = 0 then
|
||||
print_help_for_name(Stream, Sys, Name, !IO) :-
|
||||
search_node_list(Sys, Name, [], RevMatchedNodes),
|
||||
(
|
||||
RevMatchedNodes = [],
|
||||
io.write_string("There is no such help topic.\n", !IO),
|
||||
help(Sys, Stream, !IO)
|
||||
else
|
||||
true
|
||||
print_top_level_help_nodes(Stream, Sys, !IO)
|
||||
;
|
||||
RevMatchedNodes = [_ | _],
|
||||
list.reverse(RevMatchedNodes, MatchedNodes),
|
||||
print_node_list(Stream, MatchedNodes, !IO)
|
||||
).
|
||||
|
||||
:- pred search_entry_list(list(entry)::in, string::in, int::in, int::out,
|
||||
io.output_stream::in, io::di, io::uo) is det.
|
||||
:- pred search_node_list(list(help_node)::in, string::in,
|
||||
list(help_node)::in, list(help_node)::out) is det.
|
||||
|
||||
search_entry_list([], _, !C, _, !IO).
|
||||
search_entry_list([Entry | Tail], Name, !C, Stream, !IO) :-
|
||||
Entry = entry(_, EntryName, Node),
|
||||
( if Name = EntryName then
|
||||
% We print this node, but don't search its children.
|
||||
print_node(Node, Stream, !IO),
|
||||
!:C = !.C + 1
|
||||
search_node_list([], _, !RevMatchedNodes).
|
||||
search_node_list([Node | Nodes], Name, !RevMatchedNodes) :-
|
||||
( if Name = Node ^ helpnode_name then
|
||||
!:RevMatchedNodes = [Node | !.RevMatchedNodes]
|
||||
else
|
||||
search_node(Node, Name, !C, Stream, !IO),
|
||||
search_entry_list(Tail, Name, !C, Stream, !IO)
|
||||
search_node_list(Node ^ helpnode_children, Name, !RevMatchedNodes),
|
||||
search_node_list(Nodes, Name, !RevMatchedNodes)
|
||||
).
|
||||
|
||||
:- pred search_node(node::in, string::in, int::in, int::out,
|
||||
io.output_stream::in, io::di, io::uo) is det.
|
||||
|
||||
search_node(node(_, SubNodes), Name, !C, Stream, !IO) :-
|
||||
search_entry_list(SubNodes, Name, !C, Stream, !IO).
|
||||
|
||||
%---------------------------------------------------------------------------%
|
||||
|
||||
:- pred print_entry_list(list(entry)::in, io.output_stream::in,
|
||||
:- pred print_node_list(io.output_stream::in, list(help_node)::in,
|
||||
io::di, io::uo) is det.
|
||||
|
||||
print_entry_list([], _, !IO).
|
||||
print_entry_list([entry(_, _, Node) | Nodes], Stream, !IO) :-
|
||||
print_node(Node, Stream, !IO),
|
||||
print_entry_list(Nodes, Stream, !IO).
|
||||
print_node_list(_, [], !IO).
|
||||
print_node_list(Stream, [Node | Nodes], !IO) :-
|
||||
print_node(Stream, Node, !IO),
|
||||
print_node_list(Stream, Nodes, !IO).
|
||||
|
||||
:- pred print_node(node::in, io.output_stream::in, io::di, io::uo) is det.
|
||||
:- pred print_node(io.output_stream::in, help_node::in, io::di, io::uo) is det.
|
||||
|
||||
print_node(node(Text, _Nodes), Stream, !IO) :-
|
||||
print_node(Stream, Node, !IO) :-
|
||||
Node = help_node(_, _, Text, _),
|
||||
io.write_string(Stream, Text, !IO).
|
||||
% XXX print_entry_list(Nodes, Stream, !IO).
|
||||
|
||||
%---------------------------------------------------------------------------%
|
||||
|
||||
:- pred one_path_step(list(entry)::in, string::in, entry::out) is semidet.
|
||||
:- pred one_path_step(list(help_node)::in, string::in, help_node::out)
|
||||
is semidet.
|
||||
|
||||
one_path_step([Head | Tail], Name, Entry) :-
|
||||
Head = entry(_, HeadName, _),
|
||||
( if HeadName = Name then
|
||||
Entry = Head
|
||||
one_path_step([Head | Tail], Name, Node) :-
|
||||
( if Head ^ helpnode_name = Name then
|
||||
Node = Head
|
||||
else
|
||||
one_path_step(Tail, Name, Entry)
|
||||
).
|
||||
|
||||
:- pred replace_entry(list(entry)::in, entry::in, list(entry)::out) is det.
|
||||
|
||||
replace_entry([], _, _) :-
|
||||
error("replace_entry: entry to be replaced not found").
|
||||
replace_entry([Head | Tail], Entry, List) :-
|
||||
Head = entry(HeadIndex, _, _),
|
||||
Entry = entry(EntryIndex, _, _),
|
||||
( if HeadIndex = EntryIndex then
|
||||
List = [Entry | Tail]
|
||||
else
|
||||
replace_entry(Tail, Entry, NewTail),
|
||||
List = [Head | NewTail]
|
||||
one_path_step(Tail, Name, Node)
|
||||
).
|
||||
|
||||
%---------------------------------------------------------------------------%
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
#!/bin/sh
|
||||
# vim: sw=4 ts=8 et
|
||||
# vim: sw=4 ts=4 et
|
||||
#---------------------------------------------------------------------------#
|
||||
# Copyright (C) 1998-1999,2002, 2004-2006 The University of Melbourne.
|
||||
# This file may only be copied under the terms of the GNU General
|
||||
# Public License - see the file COPYING in the Mercury distribution.
|
||||
#---------------------------------------------------------------------------#
|
||||
|
||||
# the info menu items that get us to the chapter on debugger commands
|
||||
# The info menu items that get us to the chapter on debugger commands.
|
||||
cat mdb_categories > mdb_doc
|
||||
|
||||
tmp="mdb_doc_tmp.$$"
|
||||
|
||||
@@ -1426,10 +1426,17 @@ void
|
||||
MR_trace_decl_set_testing_flag(MR_bool testing)
|
||||
{
|
||||
MR_trace_decl_ensure_init();
|
||||
MR_TRACE_CALL_MERCURY(
|
||||
MR_DD_decl_set_diagnoser_testing_flag(testing,
|
||||
MR_trace_front_end_state, &MR_trace_front_end_state);
|
||||
);
|
||||
if (testing) {
|
||||
MR_TRACE_CALL_MERCURY(
|
||||
MR_DD_decl_set_diagnoser_to_testing(
|
||||
MR_trace_front_end_state, &MR_trace_front_end_state);
|
||||
);
|
||||
} else {
|
||||
MR_TRACE_CALL_MERCURY(
|
||||
MR_DD_decl_set_diagnoser_to_not_testing(
|
||||
MR_trace_front_end_state, &MR_trace_front_end_state);
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
MR_bool
|
||||
|
||||
@@ -98,8 +98,8 @@ MR_trace_help_add_node(MR_Word path, const char *name, int slot,
|
||||
);
|
||||
|
||||
MR_TRACE_CALL_MERCURY(
|
||||
ML_HELP_add_help_node(MR_trace_help_system, path, slot, name_on_heap,
|
||||
text_on_heap, &result, &MR_trace_help_system);
|
||||
ML_HELP_add_help_node(path, slot, name_on_heap, text_on_heap,
|
||||
&result, MR_trace_help_system, &MR_trace_help_system);
|
||||
error = ML_HELP_result_is_error(result, &msg);
|
||||
);
|
||||
|
||||
@@ -119,7 +119,7 @@ MR_trace_help(void)
|
||||
MR_c_file_to_mercury_file(MR_mdb_out, &mdb_out);
|
||||
|
||||
MR_TRACE_CALL_MERCURY(
|
||||
ML_HELP_help(MR_trace_help_system,
|
||||
ML_HELP_print_top_level_help_nodes(MR_trace_help_system,
|
||||
MR_wrap_output_stream(&mdb_out));
|
||||
);
|
||||
}
|
||||
@@ -138,8 +138,8 @@ MR_trace_help_word(const char *word)
|
||||
|
||||
MR_c_file_to_mercury_file(MR_mdb_out, &mdb_out);
|
||||
MR_TRACE_CALL_MERCURY(
|
||||
ML_HELP_name(MR_trace_help_system, word_on_heap,
|
||||
MR_wrap_output_stream(&mdb_out));
|
||||
ML_HELP_print_help_for_name(MR_wrap_output_stream(&mdb_out),
|
||||
MR_trace_help_system, word_on_heap);
|
||||
);
|
||||
}
|
||||
|
||||
@@ -166,8 +166,8 @@ MR_trace_help_cat_item(const char *category, const char *item)
|
||||
|
||||
MR_c_file_to_mercury_file(MR_mdb_out, &mdb_out);
|
||||
MR_TRACE_CALL_MERCURY(
|
||||
ML_HELP_path(MR_trace_help_system, path,
|
||||
MR_wrap_output_stream(&mdb_out), &result);
|
||||
ML_HELP_print_help_node_at_path(MR_wrap_output_stream(&mdb_out),
|
||||
MR_trace_help_system, path, &result);
|
||||
error = ML_HELP_result_is_error(result, &msg);
|
||||
);
|
||||
|
||||
|
||||
@@ -1,21 +1,16 @@
|
||||
/*
|
||||
** vim: ts=4 sw=4 expandtab
|
||||
*/
|
||||
/*
|
||||
** Copyright (C) 1998-1999 The University of Melbourne.
|
||||
** This file may only be copied under the terms of the GNU General
|
||||
** Public License - see the file COPYING in the Mercury distribution.
|
||||
*/
|
||||
// vim: ts=4 sw=4 expandtab
|
||||
|
||||
/*
|
||||
** File: info_to_mdb.c
|
||||
** Author: zs
|
||||
**
|
||||
** This tool takes as its input a dump (via the `info' program) of the
|
||||
** nodes in the Mercury user's guide that describe debugging commands,
|
||||
** and generates from them the mdb commands that register with mdb
|
||||
** the online documentation of those commands.
|
||||
*/
|
||||
// Copyright (C) 1998-1999 The University of Melbourne.
|
||||
// This file may only be copied under the terms of the GNU General
|
||||
// Public License - see the file COPYING in the Mercury distribution.
|
||||
|
||||
// File: info_to_mdb.c
|
||||
// Author: zs
|
||||
//
|
||||
// This tool takes as its input a dump (via the `info' program) of the
|
||||
// nodes in the Mercury user's guide that describe debugging commands,
|
||||
// and generates from them the mdb commands that register with mdb
|
||||
// the online documentation of those commands.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@@ -34,19 +29,19 @@ static void print_command_line(const char *line, MR_bool is_concept);
|
||||
static char *get_next_line(FILE *infp);
|
||||
static void put_line_back(char *line);
|
||||
|
||||
#define concept_char(c) (MR_isspace(c) ? '_' : (c))
|
||||
#define space_to_underscore(c) (MR_isspace(c) ? '_' : (c))
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
char *filename;
|
||||
char *category; /* mdb help category */
|
||||
char *category; // mdb help category
|
||||
FILE *infp;
|
||||
char *line;
|
||||
int num_lines;
|
||||
int num_lines;
|
||||
char command[MAXLINELEN];
|
||||
char next_command[MAXLINELEN];
|
||||
int slot = 0;
|
||||
int slot;
|
||||
MR_bool is_concept;
|
||||
MR_bool next_concept;
|
||||
|
||||
@@ -63,8 +58,8 @@ main(int argc, char **argv)
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* skip the top part of the node, up to and including */
|
||||
/* the underlined heading */
|
||||
// Skip the top part of the node, up to and including
|
||||
// the underlined heading.
|
||||
|
||||
while ((line = get_next_line(infp)) != NULL) {
|
||||
if (is_all_same_char(line, '-') || is_all_same_char(line, '=')) {
|
||||
@@ -72,6 +67,7 @@ main(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
slot = 0;
|
||||
while (MR_TRUE) {
|
||||
line = get_next_line(infp);
|
||||
while (line != NULL && is_empty(line)) {
|
||||
@@ -91,7 +87,7 @@ main(int argc, char **argv)
|
||||
if (is_concept) {
|
||||
int i;
|
||||
for (i = 0; line[i + 2] != '\n'; i++) {
|
||||
command[i] = concept_char(line[i + 1]);
|
||||
command[i] = space_to_underscore(line[i + 1]);
|
||||
}
|
||||
command[i] = '\0';
|
||||
} else {
|
||||
@@ -106,18 +102,17 @@ main(int argc, char **argv)
|
||||
if (is_command(line, &next_concept)) {
|
||||
get_command(line, next_command);
|
||||
if (strcmp(command, next_command) != 0) {
|
||||
/*
|
||||
** Sometimes several commands are documented together, e.g.
|
||||
**
|
||||
** cmd1 args...
|
||||
** cmd2 args...
|
||||
** cmd3 args...
|
||||
** description...
|
||||
**
|
||||
** It is difficult for us to handle that case properly
|
||||
** here, so we just insert cross references
|
||||
** ("cmd1: see cmd2", "cmd2: see cmd3", etc.)
|
||||
*/
|
||||
// Sometimes several commands are documented together, e.g.
|
||||
//
|
||||
// cmd1 args...
|
||||
// cmd2 args...
|
||||
// cmd3 args...
|
||||
// description...
|
||||
//
|
||||
// It is difficult for us to handle that case properly
|
||||
// here, so we just insert cross references
|
||||
// ("cmd1: see cmd2", "cmd2: see cmd3", etc.)
|
||||
|
||||
if (num_lines == 0) {
|
||||
printf(" See help for `%s'.\n", next_command);
|
||||
}
|
||||
@@ -204,7 +199,7 @@ print_command_line(const char *line, MR_bool is_concept)
|
||||
|
||||
len = strlen(line);
|
||||
for (i = 1; i < len - 2; i++) {
|
||||
putchar(is_concept ? concept_char(line[i]) : line[i]);
|
||||
putchar(is_concept ? space_to_underscore(line[i]) : line[i]);
|
||||
}
|
||||
putchar('\n');
|
||||
}
|
||||
@@ -225,7 +220,7 @@ get_next_line(FILE *infp)
|
||||
if (fgets(line_buf, MAXLINELEN, infp) == NULL) {
|
||||
return NULL;
|
||||
} else {
|
||||
/* printf("read %s", line_buf); */
|
||||
// printf("read %s", line_buf);
|
||||
return line_buf;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user