mirror of
https://github.com/Mercury-Language/mercury.git
synced 2025-12-14 13:23:53 +00:00
Estimated hours taken: 3 Branches: main Make the commands that update the browser parameters within the browser itself affect the parameter settings only for the current browser caller type (print, print all, or browse). browser/browse_info.m: Add the current call type to the browser state. Add a more convenient mechanism for setting the parameters only for a specified caller type. Make some existing code look nicer. browser/browse.m: When setting parameters, set them only for the current caller type. tests/debugger/browse_pretty.exp: Update the expected output of this test case.
524 lines
17 KiB
Mathematica
524 lines
17 KiB
Mathematica
%---------------------------------------------------------------------------%
|
|
% Copyright (C) 2000-2002 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.
|
|
%---------------------------------------------------------------------------%
|
|
%
|
|
% File: browser_info.m
|
|
% Main author: Mark Brown
|
|
%
|
|
% Basic data structures used by the browser.
|
|
%
|
|
|
|
:- module mdb__browser_info.
|
|
|
|
:- interface.
|
|
:- import_module bool, list, std_util.
|
|
|
|
:- type browser_term
|
|
---> plain_term(
|
|
univ % We are browsing a plain term.
|
|
)
|
|
; synthetic_term(
|
|
string, % We are browsing a synthetic term,
|
|
% such as a predicate name applied to
|
|
% a list of arguments. The string says
|
|
% what we should print as the functor.
|
|
list(univ), % The arguments.
|
|
maybe(univ) % If yes, the synthetic term represents
|
|
% a function call, and the argument
|
|
% inside the yes() is the return value.
|
|
).
|
|
|
|
% The non-persistent browser information. A new one of these is
|
|
% created every time the browser is called, based on the contents
|
|
% of the persistent state, and lasts for the duration of the call.
|
|
%
|
|
:- type browser_info
|
|
---> browser_info(
|
|
term :: browser_term,
|
|
% Term to browse.
|
|
dirs :: list(dir),
|
|
% The list of directories to take,
|
|
% starting from the root, to reach
|
|
% the current subterm.
|
|
caller_type :: browse_caller_type,
|
|
% What command called the browser?
|
|
format :: maybe(portray_format),
|
|
% Format specified as an option to the
|
|
% mdb command.
|
|
state :: browser_persistent_state,
|
|
% Persistent settings.
|
|
maybe_mark :: maybe(list(dir))
|
|
% Location of the marked term
|
|
% relative to the root, or `no'
|
|
% if there is no mark.
|
|
).
|
|
|
|
:- type dir
|
|
---> parent
|
|
; child_num(int)
|
|
; child_name(string).
|
|
|
|
% The browser is required to behave differently for different
|
|
% caller circumstances. The following type enumerates the
|
|
% various possibilities.
|
|
%
|
|
:- type browse_caller_type
|
|
---> print % Non-interactively called via mdb's `print'
|
|
% command, to print a single value.
|
|
; browse % Interactively called via mdb's `browse'
|
|
% command.
|
|
; print_all. % Non-interactively called via mdb's `print *'
|
|
% command, to print one of a sequence of
|
|
% values.
|
|
|
|
% The various ways of representing terms by the browser.
|
|
%
|
|
:- type portray_format
|
|
---> flat
|
|
; raw_pretty % calls pprint module directly, without first
|
|
% attempting to manipulate the term in any way.
|
|
; verbose
|
|
; pretty. % It allows the user to specify the maximum
|
|
% number of lines which the term has to be
|
|
% printed within.
|
|
|
|
:- type format_params
|
|
---> format_params(
|
|
depth :: int,
|
|
size :: int,
|
|
width :: int,
|
|
lines :: int
|
|
).
|
|
|
|
:- type setting
|
|
---> depth(int)
|
|
; size(int)
|
|
; format(portray_format)
|
|
; width(int)
|
|
; lines(int).
|
|
|
|
% Initialise a new browser_info. The optional portray_format
|
|
% overrides the default format.
|
|
%
|
|
:- func browser_info__init(browser_term, browse_caller_type,
|
|
maybe(portray_format), browser_persistent_state) = browser_info.
|
|
|
|
% Get the format to use for the given caller type. The optional
|
|
% portray_format overrides the current default.
|
|
%
|
|
:- pred browser_info__get_format(browser_info, browse_caller_type,
|
|
maybe(portray_format), portray_format).
|
|
:- mode browser_info__get_format(in, in, in, out) is det.
|
|
|
|
% Get the format parameters for the given caller type and format.
|
|
%
|
|
:- pred browser_info__get_format_params(browser_info, browse_caller_type,
|
|
portray_format, format_params).
|
|
:- mode browser_info__get_format_params(in, in, in, out) is det.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
% An abstract data type that holds persistent browser settings.
|
|
% This state must be saved by the caller of the browse module
|
|
% between calls.
|
|
%
|
|
:- type browser_persistent_state.
|
|
|
|
% Initialize the persistent browser state with default values.
|
|
%
|
|
:- pred browser_info__init_persistent_state(browser_persistent_state).
|
|
:- mode browser_info__init_persistent_state(out) is det.
|
|
|
|
% Update a setting in the browser state. The first seven arguments
|
|
% indicate the presence of the `set' options -P, -B, -A, -f, -r, -v
|
|
% and -p, in that order.
|
|
%
|
|
:- pred browser_info__set_param(bool::in, bool::in, bool::in, bool::in,
|
|
bool::in, bool::in, bool::in, setting::in,
|
|
browser_persistent_state::in, browser_persistent_state::out) is det.
|
|
|
|
% Update a setting in the browser state. The first argument
|
|
% indicates the presence of at most one of the options -P, -B, -A,
|
|
% while the next four indicate the presence of -f, -r, -v and -p,
|
|
% in that order.
|
|
%
|
|
:- pred browser_info__set_param(maybe(browse_caller_type)::in, bool::in,
|
|
bool::in, bool::in, bool::in, setting::in,
|
|
browser_persistent_state::in, browser_persistent_state::out) is det.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
% These three predicates are like the deconstruct, limited_deconstruct
|
|
% and functor procedures in deconstruct, except they implicitly specify
|
|
% include_details_cc and they work on browser_terms instead of plain terms.
|
|
% The latter difference requires them to have an extra argument (the last).
|
|
% For deconstruct and limited_deconstruct, this returns the return value
|
|
% if the browser term represents a function call. For functor, it says
|
|
% whether the browser term represents a function call.
|
|
|
|
:- pred deconstruct_browser_term_cc(browser_term::in,
|
|
string::out, int::out, list(univ)::out, maybe(univ)::out) is cc_multi.
|
|
|
|
:- pred limited_deconstruct_browser_term_cc(browser_term::in, int::in,
|
|
string::out, int::out, list(univ)::out, maybe(univ)::out) is cc_nondet.
|
|
|
|
:- pred functor_browser_term_cc(browser_term::in, string::out, int::out,
|
|
bool::out) is cc_multi.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- implementation.
|
|
:- import_module deconstruct, require.
|
|
|
|
:- pragma export(browser_info__init_persistent_state(out),
|
|
"ML_BROWSE_init_persistent_state").
|
|
|
|
%
|
|
% The following exported predicates are a convenient way to
|
|
% call browser_info__set_param from C code.
|
|
%
|
|
|
|
:- pred set_param_depth(bool::in, bool::in, bool::in, bool::in, bool::in,
|
|
bool::in, bool::in, int::in, browser_persistent_state::in,
|
|
browser_persistent_state::out) is det.
|
|
:- pragma export(set_param_depth(in, in, in, in, in, in, in, in, in, out),
|
|
"ML_BROWSE_set_param_depth").
|
|
|
|
set_param_depth(P, B, A, F, Pr, V, NPr, Depth) -->
|
|
browser_info__set_param(P, B, A, F, Pr, V, NPr, depth(Depth)).
|
|
|
|
:- pred set_param_size(bool::in, bool::in, bool::in, bool::in, bool::in,
|
|
bool::in, bool::in, int::in, browser_persistent_state::in,
|
|
browser_persistent_state::out) is det.
|
|
:- pragma export(set_param_size(in, in, in, in, in, in, in, in, in, out),
|
|
"ML_BROWSE_set_param_size").
|
|
|
|
set_param_size(P, B, A, F, Pr, NPr, V, Size) -->
|
|
browser_info__set_param(P, B, A, F, Pr, V, NPr, size(Size)).
|
|
|
|
:- pred set_param_width(bool::in, bool::in, bool::in, bool::in, bool::in,
|
|
bool::in, bool::in, int::in, browser_persistent_state::in,
|
|
browser_persistent_state::out) is det.
|
|
:- pragma export(set_param_width(in, in, in, in, in, in, in, in, in, out),
|
|
"ML_BROWSE_set_param_width").
|
|
|
|
set_param_width(P, B, A, F, Pr, V, NPr, Width) -->
|
|
browser_info__set_param(P, B, A, F, Pr, V, NPr, width(Width)).
|
|
|
|
:- pred set_param_lines(bool::in, bool::in, bool::in, bool::in, bool::in,
|
|
bool::in, bool::in, int::in, browser_persistent_state::in,
|
|
browser_persistent_state::out) is det.
|
|
:- pragma export(set_param_lines(in, in, in, in, in, in, in, in, in, out),
|
|
"ML_BROWSE_set_param_lines").
|
|
|
|
set_param_lines(P, B, A, F, Pr, V, NPr, Lines) -->
|
|
browser_info__set_param(P, B, A, F, Pr, V, NPr, lines(Lines)).
|
|
|
|
:- pred set_param_format(bool::in, bool::in, bool::in, portray_format::in,
|
|
browser_persistent_state::in, browser_persistent_state::out)
|
|
is det.
|
|
:- pragma export(set_param_format(in, in, in, in, in, out),
|
|
"ML_BROWSE_set_param_format").
|
|
|
|
set_param_format(P, B, A, Format) -->
|
|
%
|
|
% Any format flags are ignored for this parameter.
|
|
%
|
|
browser_info__set_param(P, B, A, no, no, no, no, format(Format)).
|
|
|
|
%
|
|
% The following exported functions allow C code to create
|
|
% Mercury values of type bool.
|
|
%
|
|
|
|
:- func mercury_bool_yes = bool.
|
|
:- pragma export(mercury_bool_yes = out, "ML_BROWSE_mercury_bool_yes").
|
|
mercury_bool_yes = yes.
|
|
|
|
:- func mercury_bool_no = bool.
|
|
:- pragma export(mercury_bool_no = out, "ML_BROWSE_mercury_bool_no").
|
|
mercury_bool_no = no.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
browser_info__init(BrowserTerm, CallerType, MaybeFormat, State) =
|
|
browser_info(BrowserTerm, [], CallerType, MaybeFormat, State, no).
|
|
|
|
browser_info__get_format(Info, Caller, MaybeFormat, Format) :-
|
|
(
|
|
MaybeFormat = yes(Format)
|
|
;
|
|
MaybeFormat = no,
|
|
MdbFormatOption = Info ^ format,
|
|
(
|
|
MdbFormatOption = yes(Format)
|
|
;
|
|
MdbFormatOption = no,
|
|
get_caller_params(Info ^ state, Caller, Params),
|
|
Format = Params ^ default_format
|
|
)
|
|
).
|
|
|
|
browser_info__get_format_params(Info, Caller, Format, Params) :-
|
|
get_caller_params(Info ^ state, Caller, CallerParams),
|
|
get_caller_format_params(CallerParams, Format, Params).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- type browser_persistent_state
|
|
---> browser_persistent_state(
|
|
print_params :: caller_params,
|
|
browse_params :: caller_params,
|
|
print_all_params :: caller_params
|
|
).
|
|
|
|
:- type caller_params
|
|
---> caller_params(
|
|
default_format :: portray_format,
|
|
flat_params :: format_params,
|
|
raw_pretty_params :: format_params,
|
|
verbose_params :: format_params,
|
|
pretty_params :: format_params
|
|
).
|
|
|
|
% Initialise the persistent settings with default values. The
|
|
% rationale for the default values is:
|
|
% Depth and Size:
|
|
% For non-interactive display, these are 3 and 10 resp.,
|
|
% so that terms will generally fit on one line. For
|
|
% interactive browsing these values are increased.
|
|
%
|
|
% Width:
|
|
% Defaults to 80 characters in any situation.
|
|
%
|
|
% Lines:
|
|
% If one term is printed then it is limited to 25 lines.
|
|
% If there can be more than one term (i.e., with
|
|
% `print *') then a much lower limit is imposed. For
|
|
% verbose format, there is not much point setting this to
|
|
% less than about 5 since otherwise very little of the
|
|
% term will be shown.
|
|
%
|
|
browser_info__init_persistent_state(State) :-
|
|
caller_type_print_defaults(Print),
|
|
caller_type_browse_defaults(Browse),
|
|
caller_type_print_all_defaults(PrintAll),
|
|
State = browser_persistent_state(Print, Browse, PrintAll).
|
|
|
|
:- pred caller_type_print_defaults(caller_params).
|
|
:- mode caller_type_print_defaults(out) is det.
|
|
|
|
caller_type_print_defaults(Params) :-
|
|
DefaultFormat = flat,
|
|
Flat = format_params(3, 10, 80, 25),
|
|
RawPretty = format_params(3, 10, 80, 25),
|
|
Verbose = format_params(3, 10, 80, 25),
|
|
Pretty = format_params(3, 10, 80, 25),
|
|
Params = caller_params(DefaultFormat, Flat, RawPretty, Verbose, Pretty).
|
|
|
|
:- pred caller_type_browse_defaults(caller_params).
|
|
:- mode caller_type_browse_defaults(out) is det.
|
|
|
|
caller_type_browse_defaults(Params) :-
|
|
DefaultFormat = verbose,
|
|
Flat = format_params(10, 30, 80, 25),
|
|
RawPretty = format_params(10, 30, 80, 25),
|
|
Verbose = format_params(10, 30, 80, 25),
|
|
Pretty = format_params(10, 30, 80, 25),
|
|
Params = caller_params(DefaultFormat, Flat, RawPretty, Verbose, Pretty).
|
|
|
|
:- pred caller_type_print_all_defaults(caller_params).
|
|
:- mode caller_type_print_all_defaults(out) is det.
|
|
|
|
caller_type_print_all_defaults(Params) :-
|
|
DefaultFormat = flat,
|
|
Flat = format_params(3, 10, 80, 2),
|
|
RawPretty = format_params(3, 10, 80, 2),
|
|
Verbose = format_params(3, 10, 80, 5),
|
|
Pretty = format_params(3, 10, 80, 2),
|
|
Params = caller_params(DefaultFormat, Flat, RawPretty, Verbose, Pretty).
|
|
|
|
browser_info__set_param(MaybeCallerType, F0, Pr0, V0, NPr0, Setting, State0,
|
|
State) :-
|
|
affected_caller_types(MaybeCallerType, P, B, A),
|
|
browser_info__set_param(P, B, A, F0, Pr0, V0, NPr0, Setting, State0,
|
|
State).
|
|
|
|
browser_info__set_param(P0, B0, A0, F0, Pr0, V0, NPr0, Setting, State0,
|
|
State) :-
|
|
default_all_yes(P0, B0, A0, P, B, A),
|
|
default_all_yes(F0, Pr0, V0, NPr0, F, Pr, V, NPr),
|
|
PParams0 = State0 ^ print_params,
|
|
BParams0 = State0 ^ browse_params,
|
|
AParams0 = State0 ^ print_all_params,
|
|
maybe_set_param(P, F, Pr, V, NPr, Setting, PParams0, PParams),
|
|
maybe_set_param(B, F, Pr, V, NPr, Setting, BParams0, BParams),
|
|
maybe_set_param(A, F, Pr, V, NPr, Setting, AParams0, AParams),
|
|
State = browser_persistent_state(PParams, BParams, AParams).
|
|
|
|
:- pred affected_caller_types(maybe(browse_caller_type)::in,
|
|
bool::out, bool::out, bool::out) is det.
|
|
|
|
%
|
|
% If no caller type is specified, the command by default
|
|
% applies to _all_ caller types.
|
|
%
|
|
affected_caller_types(no, yes, yes, yes).
|
|
affected_caller_types(yes(print), yes, no, no).
|
|
affected_caller_types(yes(browse), no, yes, no).
|
|
affected_caller_types(yes(print_all), no, no, yes).
|
|
|
|
:- pred default_all_yes(bool, bool, bool, bool, bool, bool).
|
|
:- mode default_all_yes(in, in, in, out, out, out) is det.
|
|
|
|
default_all_yes(A0, B0, C0, A, B, C) :-
|
|
%
|
|
% If none of the flags are set, the command by default
|
|
% applies to _all_ caller types/formats.
|
|
%
|
|
(
|
|
A0 = no,
|
|
B0 = no,
|
|
C0 = no
|
|
->
|
|
A = yes,
|
|
B = yes,
|
|
C = yes
|
|
;
|
|
A = A0,
|
|
B = B0,
|
|
C = C0
|
|
).
|
|
|
|
:- pred default_all_yes(bool, bool, bool, bool, bool, bool, bool, bool).
|
|
:- mode default_all_yes(in, in, in, in, out, out, out, out) is det.
|
|
|
|
default_all_yes(A0, B0, C0, D0, A, B, C, D) :-
|
|
%
|
|
% If none of the format flags are set, the command by default
|
|
% applies to _all_ formats.
|
|
%
|
|
(
|
|
A0 = no,
|
|
B0 = no,
|
|
C0 = no,
|
|
D0 = no
|
|
->
|
|
A = yes,
|
|
B = yes,
|
|
C = yes,
|
|
D = yes
|
|
;
|
|
A = A0,
|
|
B = B0,
|
|
C = C0,
|
|
D = D0
|
|
).
|
|
|
|
:- pred maybe_set_param(bool, bool, bool, bool, bool, setting, caller_params,
|
|
caller_params).
|
|
:- mode maybe_set_param(in, in, in, in, in, in, in, out) is det.
|
|
|
|
maybe_set_param(no, _, _, _, _, _, Params, Params).
|
|
maybe_set_param(yes, F, Pr, V, NPr, Setting, Params0, Params) :-
|
|
(
|
|
Setting = format(NewFormat)
|
|
->
|
|
Params = Params0 ^ default_format := NewFormat
|
|
;
|
|
Format0 = Params0 ^ default_format,
|
|
FParams0 = Params0 ^ flat_params,
|
|
PrParams0 = Params0 ^ raw_pretty_params,
|
|
VParams0 = Params0 ^ verbose_params,
|
|
NPrParams0 = Params0 ^ pretty_params,
|
|
maybe_set_param_2(F, Setting, FParams0, FParams),
|
|
maybe_set_param_2(Pr, Setting, PrParams0, PrParams),
|
|
maybe_set_param_2(V, Setting, VParams0, VParams),
|
|
maybe_set_param_2(NPr, Setting, NPrParams0, NPrParams),
|
|
Params = caller_params(Format0,
|
|
FParams, PrParams, VParams, NPrParams)
|
|
).
|
|
|
|
:- pred maybe_set_param_2(bool, setting, format_params, format_params).
|
|
:- mode maybe_set_param_2(in, in, in, out) is det.
|
|
|
|
maybe_set_param_2(no, _, Params, Params).
|
|
maybe_set_param_2(yes, depth(D), Params, Params ^ depth := D).
|
|
maybe_set_param_2(yes, size(S), Params, Params ^ size := S).
|
|
maybe_set_param_2(yes, format(_), _, _) :-
|
|
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).
|
|
|
|
:- pred get_caller_params(browser_persistent_state, browse_caller_type,
|
|
caller_params).
|
|
:- mode get_caller_params(in, in, out) is det.
|
|
|
|
get_caller_params(State, print, State ^ print_params).
|
|
get_caller_params(State, browse, State ^ browse_params).
|
|
get_caller_params(State, print_all, State ^ print_all_params).
|
|
|
|
:- pred get_caller_format_params(caller_params, portray_format, format_params).
|
|
:- mode get_caller_format_params(in, in, out) is det.
|
|
|
|
get_caller_format_params(Params, flat, Params ^ flat_params).
|
|
get_caller_format_params(Params, raw_pretty, Params ^ raw_pretty_params).
|
|
get_caller_format_params(Params, verbose, Params ^ verbose_params).
|
|
get_caller_format_params(Params, pretty, Params ^ pretty_params).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- pred browser_persistent_state_type(type_info).
|
|
:- mode browser_persistent_state_type(out) is det.
|
|
:- pragma export(browser_persistent_state_type(out),
|
|
"ML_BROWSE_browser_persistent_state_type").
|
|
|
|
browser_persistent_state_type(type_of(State)) :-
|
|
browser_info__init_persistent_state(State).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
deconstruct_browser_term_cc(BrowserTerm, Functor, Arity, Args, MaybeReturn) :-
|
|
(
|
|
BrowserTerm = plain_term(Univ),
|
|
deconstruct(univ_value(Univ), include_details_cc,
|
|
Functor, Arity, Args),
|
|
MaybeReturn = no
|
|
;
|
|
BrowserTerm = synthetic_term(Functor, Args, MaybeReturn),
|
|
list__length(Args, Arity)
|
|
).
|
|
|
|
limited_deconstruct_browser_term_cc(BrowserTerm, Limit, Functor, Arity, Args,
|
|
MaybeReturn) :-
|
|
(
|
|
BrowserTerm = plain_term(Univ),
|
|
limited_deconstruct(univ_value(Univ), include_details_cc,
|
|
Limit, Functor, Arity, Args),
|
|
MaybeReturn = no
|
|
;
|
|
BrowserTerm = synthetic_term(Functor, Args, MaybeReturn),
|
|
list__length(Args, Arity)
|
|
).
|
|
|
|
functor_browser_term_cc(BrowserTerm, Functor, Arity, IsFunc) :-
|
|
(
|
|
BrowserTerm = plain_term(Univ),
|
|
functor(univ_value(Univ), include_details_cc, Functor, Arity),
|
|
IsFunc = no
|
|
;
|
|
BrowserTerm = synthetic_term(Functor, Args, MaybeReturn),
|
|
list__length(Args, Arity),
|
|
(
|
|
MaybeReturn = yes(_),
|
|
IsFunc = yes
|
|
;
|
|
MaybeReturn = no,
|
|
IsFunc = no
|
|
)
|
|
).
|
|
|
|
%---------------------------------------------------------------------------%
|