Files
mercury/browser/parse.m
Zoltan Somogyi eeb69f14ba Use explicit streams in browser/*.m.
browser/browse.m:
browser/browser_info.m:
browser/collect_lib.m:
browser/declarative_debugger.m:
browser/declarative_oracle.m:
browser/declarative_user.m:
browser/diff.m:
browser/help.m:
browser/interactive_query.m:
browser/parse.m:
browser/util.m:
    Replace implicit streams with explicit streams.

    Shorten lines longer than 79 chars.

    In some places, simplify some code, often using constructs such as
    string.format that either did not exist or were too expensive to use
    when the original code was written.

    In some places, change predicate names that were not meaningful
    without module qualification by *including* the module qualification
    in the name (e.g. init -> browser_info_init).

    In some places, add XXXs.

    In browser_info.m, make the output stream *part* of the debugger type,
    because without this, having the debugger type belong to the stream
    typeclass does NOT make sense. (The typeclass instance for debugger
    used to always write to the current output stream, which this diff
    is replacing with the use of explicitly specified streams.)

    In browse.m, consistently put stream arguments before other arguments.

    In browse.m, when exporting Mercury predicates to C, export them
    under names with the standard ML_BROWSE_ prefix, NOT under the name
    of a *different* predicate with that prefix.

    In diff.m, eliminate an unnecessary difference between what we print
    when the difference between two terms is at the root, vs what we print
    when the difference between two terms is lower down.

    In interactive_query.m, when trying to write a program out to a file,
    do NOT write the program to the current output stream if we cannot open
    the file, since that would accomplish nothing useful.

    Also in interactive_query.m, cleanup .dylib instead of .so on MacOS.

    In util.m, delete some unused predicates.

    In collect_lib.m, document why some code is not worth updating.

    In declarative_oracle.m, rename predicates with previously-ambiguous
    names.

browser/MDBFLAGS.in:
    Specify --warn-implicit-stream-calls for all Mercury modules
    in the browser directory from now.

trace/mercury_trace_browse.c:
trace/mercury_trace_cmd_browsing.c:
ssdb/ssdb.m:
    Conform to the changes in browser/*.m.

tests/debugger/queens.{exp,exp2}:
    Expect the extra output from browser/diff.m.
2021-03-05 22:54:28 +11:00

878 lines
26 KiB
Mathematica

%---------------------------------------------------------------------------%
% vim: ft=mercury ts=4 sw=4 et
%---------------------------------------------------------------------------%
% Copyright (C) 1998-2007, 2009 The University of Melbourne.
% Copyright (C) 2015-2016, 2018 The Mercury team.
% This file is distributed under the terms specified in COPYING.LIB.
%---------------------------------------------------------------------------%
%
% File: parse.m.
% Author: aet.
%
% This file contains the parser for the term browser command language.
% If the term browser is called from mdb, it parses the stuff you type
% at the "browser> " prompt after typing "browse" from the mdb prompt.
% If it is called from the external debugger, then it parses the stuff
% contained in a term `external_request(<string to parse>)' send by the
% external debugger.
%
%---------------------------------------------------------------------------%
%---------------------------------------------------------------------------%
% The Command Language
%
% commandline:
% "?" // SICStus help
% "^" [path] // SICStus cd
% "d" // SICStus display
% "w" // SICStus write
% "<" // SICStus set depth
% "help"
% "h" // short for help
% "cd" [path]
% "pwd"
% "ls" [formatoptions] [path]
% "print" [formatoptions] [path]
% "p" [formatoptions] [path] // short for print
% "display"
% "write"
% "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]
% "m" [--accurate] [path]
% "mode" [path]
% "quit"
%
% formatoptions:
% /* empty */
% formatoption formatoptions
%
% formatoption:
% -f
% -r
% -v
% -p
% --flat
% --raw-pretty
% --verbose
% --pretty
%
% formatcmdoptions:
% /* empty */
% formatcmdoption formatcmdoptions
%
% formatcmdoption:
% -P
% -B
% -A
% --print
% --browse
% --print-all
%
% formatparamcmdoptions:
% /* empty */
% formatparamcmdoption formatparamcmdoptions
%
% formatparamcmdoption:
% -P
% -B
% -A
% -f
% -r
% -v
% -p
% --print
% --browse
% --print-all
% --flat
% --raw-pretty
% --verbose
% --pretty
%
% fmt:
% "flat"
% "raw_pretty"
% "verbose"
% "pretty"
%
% path:
% ["/"] [dirs]
%
% dirs:
% dir ["/" dirs]
%
% dir:
% num
% ".."
%
%---------------------------------------------------------------------------%
%---------------------------------------------------------------------------%
:- module mdb.parse.
:- interface.
:- import_module mdb.browser_info.
:- import_module getopt.
:- import_module io.
:- import_module list.
:- import_module maybe.
%---------------------------------------------------------------------------%
:- type command
---> cmd_print(maybe(maybe_option_table(format_option)), maybe(path))
; cmd_display
; cmd_write
; cmd_memory_addr(maybe(path))
; cmd_cd_path(path)
; cmd_cd_no_path
; cmd_pwd
; cmd_track(how_track_subterm, should_assert_invalid, maybe(path))
; cmd_mode_query(path)
; cmd_mode_query_no_path
; cmd_param(param_cmd)
; cmd_help
; cmd_quit
; cmd_empty
; cmd_unknown.
:- type format_param_cmd
---> param_depth
; param_size
; param_width
; param_lines.
:- type path
---> root_rel(list(up_down_dir))
; dot_rel(list(up_down_dir)).
:- type format_option
---> flat
; raw_pretty
; verbose
; pretty.
:- type setting_option
---> 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
% external_request.
%
:- type external_request
---> external_request(string).
:- pred read_command(io.text_input_stream::in, io.text_output_stream::in,
string::in, command::out, io::di, io::uo) is det.
:- pred read_command_external(io.text_input_stream::in, command::out,
io::di, io::uo) is det.
% parse(Words, Command):
%
% Command is the command give by the list of strings Words.
%
:- pred parse(list(string)::in, command::out) is semidet.
%---------------------------------------------------------------------------%
%---------------------------------------------------------------------------%
:- implementation.
:- import_module mdb.util.
:- import_module bool.
:- import_module char.
:- import_module int.
:- import_module string.
:- type token
---> token_dot
; token_dot_dot
; token_slash
; token_question
; token_up
; token_lessthan
; token_num(int)
; token_name(string)
; token_arg(string)
; token_unknown(char).
read_command(MdbIn, MdbOut, Prompt, Command, !IO) :-
util.trace_get_command(MdbIn, MdbOut, Prompt, Line, !IO),
string.words_separator(char.is_whitespace, Line) = Words,
( if parse(Words, CommandPrime) then
Command = CommandPrime
else
Command = cmd_unknown
).
read_command_external(InputStream, Command, !IO) :-
io.read(InputStream, Result, !IO),
(
Result = ok(external_request(StringToParse)),
string.words_separator(char.is_whitespace, StringToParse) = Words,
( if parse(Words, CommandPrime) then
Command = CommandPrime
else
Command = cmd_unknown
)
;
Result = eof,
Command = cmd_quit
;
Result = error(_, _),
Command = cmd_unknown
).
:- pred lexer_words(list(string)::in, list(token)::out) is det.
lexer_words([], []).
lexer_words([Word | Words], Tokens) :-
lexer_word(Word, WordTokens),
lexer_words(Words, WordsTokens),
list.append(WordTokens, WordsTokens, Tokens).
:- pred lexer_word(string::in, list(token)::out) is det.
lexer_word(Word, Tokens) :-
string.to_char_list(Word, Chars),
lexer_word_chars(Chars, Tokens).
:- pred lexer_word_chars(list(char)::in, list(token)::out) is det.
lexer_word_chars([], []).
lexer_word_chars([C | Cs], Toks) :-
( if C = ('.') then
lexer_dots(Cs, Toks)
else if C = ('/') then
Toks = [token_slash | Toks2],
lexer_word_chars(Cs, Toks2)
else if C = ('?') then
Toks = [token_question | Toks2],
lexer_word_chars(Cs, Toks2)
else if C = ('^') then
Toks = [token_up | Toks2],
lexer_word_chars(Cs, Toks2)
else if C = ('<') then
Toks = [token_lessthan | Toks2],
lexer_word_chars(Cs, Toks2)
else if C = ('-'), Cs = [H | T] then
lexer_arg([H | T], Toks)
else if char.is_digit(C) then
dig_to_int(C, N),
lexer_num(N, Cs, Toks)
else if char.is_alpha_or_underscore(C) then
lexer_name(C, Cs, Toks)
else if char.is_whitespace(C) then
lexer_word_chars(Cs, Toks)
else
Toks = [token_unknown(C) | Toks2],
lexer_word_chars(Cs, Toks2)
).
:- pred lexer_dots(list(char)::in, list(token)::out) is det.
lexer_dots([], []).
lexer_dots([C | Cs], Toks) :-
( if C = ('.') then
lexer_word_chars(Cs, Toks2),
Toks = [token_dot_dot | Toks2]
else
lexer_word_chars([C | Cs], Toks2),
Toks = [token_dot | Toks2]
).
:- pred dig_to_int(char::in, int::out) is det.
dig_to_int(C, N) :-
char.to_int('0', Zero),
char.to_int(C, CN),
N = CN - Zero.
:- pred lexer_arg(list(char)::in(non_empty_list), list(token)::out) is det.
lexer_arg([Head | Tail], Toks) :-
( if Head = ('-') then
string.from_char_list(Tail, ArgName)
else
string.from_char_list([Head | Tail], ArgName)
),
Toks = [token_arg(ArgName)].
:- pred lexer_num(int::in, list(char)::in, list(token)::out) is det.
lexer_num(N, Cs, Toks) :-
list.take_while(char.is_digit, Cs, Digits, Rest),
digits_to_int_acc(N, Digits, Num),
Toks = [token_num(Num) | Toks2],
lexer_word_chars(Rest, Toks2).
:- pred digits_to_int_acc(int::in, list(char)::in, int::out) is det.
digits_to_int_acc(Acc, [], Acc).
digits_to_int_acc(Acc, [C | Cs], Num) :-
dig_to_int(C, D),
Acc2 = 10 * Acc + D,
digits_to_int_acc(Acc2, Cs, Num).
:- pred lexer_name(char::in, list(char)::in, list(token)::out) is det.
lexer_name(C, Cs, Toks) :-
list.take_while(char.is_alnum_or_underscore, Cs, Letters, Rest),
string.from_char_list([C | Letters], Name),
lexer_word_chars(Rest, Toks2),
Toks = [token_name(Name) | Toks2].
%---------------------------------------------------------------------------%
parse(Words, Command) :-
(
Words = [],
Command = cmd_empty
;
Words = [CmdWord | ArgWords],
lexer_word(CmdWord, CmdTokens),
lexer_words(ArgWords, ArgTokens),
( if CmdTokens = [_] then
% If the initial word is one token, then it can make sense
% to parse the command line as words.
MaybeArgWords = yes(ArgWords)
else
% If the initial word is more than one token, then it doesn't
% make sense to parse the command line as words.
MaybeArgWords = no
),
list.append(CmdTokens, ArgTokens, AllTokens),
(
AllTokens = [],
Command = cmd_empty
;
AllTokens = [FirstToken | LaterTokens],
parse_cmd(FirstToken, LaterTokens, MaybeArgWords, Command)
)
).
:- pred parse_cmd(token::in, list(token)::in, maybe(list(string))::in,
command::out) is semidet.
parse_cmd(CmdToken, ArgTokens, MaybeArgWords, Command) :-
% Please keep the code recognizing commands in the same order
% as the definition of the command type.
% If you add more commands, please update the documentation printed
% by the help predicate in browse.m.
( if
( CmdToken = token_name("print")
; CmdToken = token_name("p")
; CmdToken = token_name("ls")
)
then
(
MaybeArgWords = no,
MaybeMaybeOptionTable = no,
RemainingTokens = ArgTokens
;
MaybeArgWords = yes(ArgWords),
OptionOps = option_ops_multi(short_format_option,
long_format_option, format_option_defaults),
getopt.process_options(OptionOps, ArgWords,
RemainingWords, MaybeOptionTable0),
MaybeOptionTable =
convert_to_maybe_option_table(MaybeOptionTable0),
MaybeMaybeOptionTable = yes(MaybeOptionTable),
lexer_words(RemainingWords, RemainingTokens)
),
(
RemainingTokens = [],
MaybePath = no
;
RemainingTokens = [_ | _],
parse_path(RemainingTokens, Path),
MaybePath = yes(Path)
),
Command = cmd_print(MaybeMaybeOptionTable, MaybePath)
else if
( CmdToken = token_name("display")
; CmdToken = token_name("d")
)
then
ArgTokens = [],
Command = cmd_display
else if
( CmdToken = token_name("write")
; CmdToken = token_name("w")
)
then
ArgTokens = [],
Command = cmd_write
else if
( CmdToken = token_name("memory_addr")
; CmdToken = token_name("addr") % "m" and "a" are both taken.
)
then
(
ArgTokens = [],
MaybePath = no
;
ArgTokens = [_ | _],
parse_path(ArgTokens, Path),
MaybePath = yes(Path)
),
Command = cmd_memory_addr(MaybePath)
else if
CmdToken = token_name("cdr")
then
ArgTokens = [token_num(Repetitions) | TokenPath],
list.duplicate(Repetitions, TokenPath, DupTokenPath),
list.condense(DupTokenPath, RepeatedTokenPath),
parse_path(RepeatedTokenPath, RepeatedPath),
Command = cmd_cd_path(RepeatedPath)
else if
( CmdToken = token_name("cd")
; CmdToken = token_up
)
then
(
ArgTokens = [_ | _],
parse_path(ArgTokens, Path),
Command = cmd_cd_path(Path)
;
ArgTokens = [],
Command = cmd_cd_no_path
)
else if
CmdToken = token_name("pwd")
then
ArgTokens = [],
Command = cmd_pwd
else if
(
CmdToken = token_name("track"),
AssertInvalid = no_assert_invalid
;
CmdToken = token_name("t"),
AssertInvalid = no_assert_invalid
;
CmdToken = token_name("mark"),
AssertInvalid = assert_invalid
;
CmdToken = token_name("m"),
AssertInvalid = assert_invalid
)
then
(
ArgTokens = [],
HowTrack = track_fast,
MaybePath = no
;
ArgTokens = [HeadArgToken | TailArgTokens],
( if
( HeadArgToken = token_arg("accurate")
; HeadArgToken = token_arg("a")
)
then
HowTrack = track_accurate,
(
TailArgTokens = [],
MaybePath = no
;
TailArgTokens = [_ | _],
parse_path(TailArgTokens, Path),
MaybePath = yes(Path)
)
else
HowTrack = track_fast,
parse_path(ArgTokens, Path),
MaybePath = yes(Path)
)
),
Command = cmd_track(HowTrack, AssertInvalid, MaybePath)
else if
CmdToken = token_name("mode")
then
(
ArgTokens = [_ | _],
parse_path(ArgTokens, Path),
Command = cmd_mode_query(Path)
;
ArgTokens = [],
Command = cmd_mode_query_no_path
)
else if
CmdToken = token_name("format")
then
(
ArgTokens = [],
FormatCmd = 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, MaybeOptionTable0),
MaybeOptionTable =
convert_to_maybe_option_table(MaybeOptionTable0),
lexer_words(RemainingWords, RemainingTokens),
parse_format(RemainingTokens, Setting),
FormatCmd = format(MaybeOptionTable, Setting)
),
Command = cmd_param(FormatCmd)
else if
(
CmdToken = token_name("depth"),
ParamCmd = param_depth
;
CmdToken = token_name("size"),
ParamCmd = param_size
;
CmdToken = token_name("width"),
ParamCmd = param_width
;
CmdToken = token_name("lines"),
ParamCmd = param_lines
)
then
(
ArgTokens = [],
FormatCmd = print_params
;
ArgTokens = [_ | _],
MaybeArgWords = yes(ArgWords),
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, MaybeOptionTable0),
MaybeOptionTable =
convert_to_maybe_option_table(MaybeOptionTable0),
lexer_words(RemainingWords, RemainingTokens),
RemainingTokens = [token_num(N)],
param_cmd_to_setting(ParamCmd, N, Setting),
FormatCmd = format_param(MaybeOptionTable, Setting)
),
Command = cmd_param(FormatCmd)
else if
CmdToken = token_lessthan
then
ArgTokens = [token_num(Depth)],
OptionOps = option_ops_multi(short_format_param_cmd_option,
long_format_param_cmd_option, format_param_cmd_option_defaults),
getopt.process_options(OptionOps, [], _, MaybeOptionTable0),
MaybeOptionTable = convert_to_maybe_option_table(MaybeOptionTable0),
FormatCmd = format_param(MaybeOptionTable, setting_depth(Depth)),
Command = cmd_param(FormatCmd)
else if
CmdToken = token_name("num_io_actions")
then
ArgTokens = [token_num(N)],
Command = cmd_param(num_io_actions(N))
else if
CmdToken = token_name("params")
then
Command = cmd_param(print_params)
else if
( CmdToken = token_name("help")
; CmdToken = token_name("h")
; CmdToken = token_question
)
then
ArgTokens = [],
Command = cmd_help
else if
CmdToken = token_name("quit")
then
ArgTokens = [],
Command = cmd_quit
else
fail
).
:- pred param_cmd_to_setting(format_param_cmd::in, int::in, setting::out)
is det.
param_cmd_to_setting(param_depth, N, setting_depth(N)).
param_cmd_to_setting(param_size, N, setting_size(N)).
param_cmd_to_setting(param_width, N, setting_width(N)).
param_cmd_to_setting(param_lines, N, setting_lines(N)).
% SICStus is forgiving in the syntax of paths, hence so are we.
% XXX: Be less forgiving?
%
:- pred parse_path(list(token)::in, path::out) is semidet.
parse_path([Token | Tokens], Path) :-
( if Token = token_slash then
Path = root_rel(Dirs),
parse_up_down_dirs(Tokens, Dirs)
else
Path = dot_rel(Dirs),
parse_up_down_dirs([Token | Tokens], Dirs)
).
:- pred parse_up_down_dirs(list(token)::in, list(up_down_dir)::out) is semidet.
parse_up_down_dirs([], []).
parse_up_down_dirs([Token | Tokens], Dirs) :-
(
Token = token_num(Subdir),
Dirs = [updown_child_num(Subdir) | RestDirs],
parse_up_down_dirs(Tokens, RestDirs)
;
Token = token_name(NamedSubdir),
Dirs = [updown_child_name(NamedSubdir) | RestDirs],
parse_up_down_dirs(Tokens, RestDirs)
;
Token = token_dot_dot,
Dirs = [updown_parent | RestDirs],
parse_up_down_dirs(Tokens, RestDirs)
;
% We can effectively ignore slashes (for Unix-style pathnames)
% and carets (for SICStus-style pathnames),
% but anything else is not allowed.
Token = token_slash,
parse_up_down_dirs(Tokens, Dirs)
;
Token = token_up,
parse_up_down_dirs(Tokens, Dirs)
).
:- pred parse_format(list(token)::in, setting::out) is semidet.
parse_format([Token], Setting) :-
Token = token_name(TokenName),
( if TokenName = "flat" then
Setting = setting_format(flat)
else if TokenName = "raw_pretty" then
Setting = setting_format(raw_pretty)
else if TokenName = "verbose" then
Setting = setting_format(verbose)
else if TokenName = "pretty" then
Setting = setting_format(pretty)
else
fail
).
:- pred parse_format_param(list(token)::in, setting::out) is semidet.
parse_format_param([Token | Tokens], Setting) :-
Token = token_name(TokenName),
( if TokenName = "depth" then
Tokens = [token_num(Depth)],
Setting = setting_depth(Depth)
else if TokenName = "size" then
Tokens = [token_num(Size)],
Setting = setting_size(Size)
else if TokenName = "width" then
Tokens = [token_num(X)],
Setting = setting_width(X)
else if TokenName = "lines" then
Tokens = [token_num(Y)],
Setting = setting_lines(Y)
else
fail
).
%---------------------------------------------------------------------------%
:- pred short_format_option(char::in, format_option::out) is semidet.
short_format_option('f', flat).
short_format_option('r', raw_pretty).
short_format_option('v', verbose).
short_format_option('p', pretty).
:- pred long_format_option(string::in, format_option::out) is semidet.
long_format_option("flat", flat).
long_format_option("raw-pretty", raw_pretty).
long_format_option("verbose", verbose).
long_format_option("pretty", pretty).
:- pred format_option_defaults(format_option::out, option_data::out) is multi.
format_option_defaults(flat, bool(no)).
format_option_defaults(raw_pretty, bool(no)).
format_option_defaults(verbose, bool(no)).
format_option_defaults(pretty, bool(no)).
%---------------------------------------------------------------------------%
:- 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).
:- pred long_format_cmd_option(string::in, setting_option::out) is semidet.
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.
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)).
%---------------------------------------------------------------------------%
% The commented out code is not currently used.
% :- pred show_command(command::in, io::di, io::uo) is det.
%
% show_command(ls(Path)) -->
% io.write_string("ls "),
% show_path(Path),
% io.nl.
% show_command(ls) -->
% io.write_string("ls\n").
% show_command(cd_path(Path)) -->
% io.write_string("cd "),
% show_path(Path),
% io.nl.
% show_command(cd_no_path) -->
% io.write_string("cd\n").
% show_command(track(Path)) -->
% io.write_string("track "),
% show_path(Path),
% io.nl.
% show_command(track) -->
% io.write_string("track\n").
% show_command(pwd) -->
% io.write_string("pwd\n").
% show_command(help) -->
% io.write_string("help\n").
% show_command(quit) -->
% io.write_string("quit\n").
% show_command(print) -->
% io.write_string("print\n").
% show_command(display) -->
% io.write_string("display\n").
% show_command(write) -->
% io.write_string("write\n").
% show_command(empty) -->
% io.write_string("empty\n").
% show_command(unknown) -->
% io.write_string("unknown\n").
%
% :- pred show_path(path::in, io::di, io::uo) is det.
%
% show_path(root_rel(Dirs)) -->
% io.write_string("/"),
% show_dirs(Dirs).
% show_path(dot_rel(Dirs)) -->
% show_dirs(Dirs).
%
% :- pred show_dirs(list(dir)::in, io::di, io::uo) is det.
%
% show_dirs([]) -->
% io.nl.
% show_dirs([child_num(Num) | Dirs]) -->
% io.write_int(Num),
% io.write_string("/"),
% show_dirs(Dirs).
% show_dirs([child_name(Name) | Dirs]) -->
% io.write_string(Name),
% io.write_string("/"),
% show_dirs(Dirs).
% show_dirs([parent | Dirs]) -->
% io.write_string("../"),
% show_dirs(Dirs).
%
% :- pred show_setting(setting::in, io::di, io::uo) is det.
%
% show_setting(depth(Depth)) -->
% io.write_string("depth "),
% io.write_int(Depth),
% io.nl.
% show_setting(size(Size)) -->
% io.write_string("size "),
% io.write_int(Size),
% io.nl.
% show_setting(width(X)) -->
% io.write_string("width "),
% io.write_int(X),
% io.nl.
% show_setting(lines(Y)) -->
% io.write_string("lines "),
% io.write_int(Y),
% io.nl.
% show_setting(format(Fmt)) -->
% io.write_string("format "),
% show_format(Fmt),
% io.nl.
% show_setting(num_io_actions(N)) -->
% io.write_string("num_io_actions "),
% io.write_int(N),
% io.nl.
%
% :- pred show_format(portray_format::in, io::di, io::uo) is det.
%
% show_format(flat) -->
% io.write_string("flat").
% show_format(raw_pretty) -->
% io.write_string("raw_pretty").
% show_format(verbose) -->
% io.write_string("verbose").
% show_format(pretty) -->
% io.write_string("pretty").
%---------------------------------------------------------------------------%