Files
mercury/trace/mercury_trace_browse.c
Zoltan Somogyi 31ad9a21e1 Allow terms to be dumped as docs in mdb.
The usual mdb "dump" command puts every function symbol on its own line.
This guarantees that we generate any line that is too long to be displayed
on terminals, but it also generates output that is too stretched out
vertically for its structure to be readily apparent. Dumping the term
as a doc allows pretty_printer.m to put as many function symbols on a line
as would fit, without exceeding the maximum line length.

browser/browse.m:
    Add save_term_to_file_doc, a way to save a (possibly synthetic)
    browser term in a file, using an interface that works the same way
    the predicate that saves browser terms as XML.

    Inline a predicate at its only call site. Improve variable names.

trace/mercury_trace_browse.[ch]:
    Add MR_trace_save_term_as_doc, as an interface function between
    save_term_to_file_doc and the code of mercury_trace_cmd_browsing.c.

trace/mercury_trace_cmd_browsing.c:
    Add support for a new -p/--prettyprint flag to the mdb "dump" command,
    which asks for the given term to be dumped as a pretty_printer doc.

doc/user_guide.texi:
NEWS:
    Document the new option.

library/pretty_printer.m:
NEWS:
    Rename write_as_doc to write_doc_formatted, and fix its argument type.

tests/debugger/browser_test.inp:
    Dump a term that we already dumped with "dump" with "dump -x" and
    "dump -p" as well.

tests/debugger/browser_test.m:
    Put the code to remove the files we are going to dump to
    and then later to print the files we have dumped to into separate
    predicates. This keeps most (but not all) line numbers unchanged
    even though we now dump to more files.

tests/debugger/browser_test.exp3:
    Update this file to account both for the extra output from the just-added
    dump commands, and for the changes in line numbers.
2022-08-25 16:39:50 +10:00

438 lines
12 KiB
C

// vim: ts=4 sw=4 expandtab ft=c
// Copyright (C) 1998-2006 The University of Melbourne.
// Copyright (C) 2017-2018 The Mercury team.
// This file is distributed under the terms specified in COPYING.LIB.
// mercury_trace_browse.c
//
// Main author: fjh
//
// This file provides the C interface to browser/browse.m
// and browser/interactive_query.m.
// Some header files refer to files automatically generated by the Mercury
// compiler for modules in the browser and library directories.
//
// XXX Figure out how to prevent these names from encroaching on the user's
// name space.
#include "mercury_imp.h"
#include "mercury_deep_copy.h"
#include "mercury_trace_browse.h"
#include "mercury_trace_util.h"
#include "mercury_trace_internal.h"
#include "mercury_trace_external.h"
#include "mdb.browse.mh"
#include "mdb.browser_info.mh"
#include "mdb.browser_term.mh"
#include "mdb.interactive_query.mh"
#include "type_desc.mh"
#include <stdio.h>
MR_TypeInfo MR_trace_browser_persistent_state_type;
MR_Word MR_trace_browser_persistent_state;
MR_Word
MR_type_value_to_browser_term(MR_TypeInfo type_info, MR_Word value)
{
MR_Word browser_term;
MR_TRACE_CALL_MERCURY(
browser_term = ML_BROWSE_plain_term_to_browser_term(
(MR_Word) type_info, value);
);
return browser_term;
}
MR_Word
MR_univ_to_browser_term(MR_Word univ)
{
MR_Word browser_term;
MR_TRACE_CALL_MERCURY(
browser_term = ML_BROWSE_univ_to_browser_term(univ);
);
return browser_term;
}
MR_Word
MR_synthetic_to_browser_term(const char *functor, MR_Word arg_list,
MR_bool is_func)
{
MR_Word browser_term;
MR_TRACE_CALL_MERCURY(
browser_term = ML_BROWSE_synthetic_term_to_browser_term(
(MR_String) (MR_Integer) functor, arg_list, is_func);
);
return browser_term;
}
void
MR_trace_save_term(const char *filename, MR_Word browser_term)
{
MercuryFile mdb_out;
MR_String mercury_filename;
MR_String mercury_format;
MR_trace_browse_ensure_init();
// cast away const
mercury_filename = (MR_String) (MR_Integer) filename;
mercury_format = (MR_String) (MR_Integer) "default";
MR_c_file_to_mercury_file(MR_mdb_out, &mdb_out);
MR_TRACE_CALL_MERCURY(
ML_BROWSE_save_term_to_file(MR_wrap_output_stream(&mdb_out),
mercury_filename, mercury_format, browser_term);
);
}
void
MR_trace_save_term_xml(const char *filename, MR_Word browser_term)
{
MercuryFile mdb_out;
MR_String mercury_filename;
// cast away const
mercury_filename = (MR_String) (MR_Integer) filename;
MR_c_file_to_mercury_file(MR_mdb_out, &mdb_out);
MR_TRACE_CALL_MERCURY(
ML_BROWSE_save_term_to_file_xml(MR_wrap_output_stream(&mdb_out),
mercury_filename, browser_term);
);
}
void
MR_trace_save_term_doc(const char *filename, MR_Word browser_term)
{
MercuryFile mdb_out;
MR_String mercury_filename;
MR_trace_browse_ensure_init();
// cast away const
mercury_filename = (MR_String) (MR_Integer) filename;
MR_c_file_to_mercury_file(MR_mdb_out, &mdb_out);
MR_TRACE_CALL_MERCURY(
ML_BROWSE_save_term_to_file_doc(MR_wrap_output_stream(&mdb_out),
mercury_filename, browser_term);
);
}
void
MR_trace_save_and_invoke_web_browser(MR_Word browser_term)
{
MercuryFile mdb_out;
MercuryFile mdb_err;
MR_c_file_to_mercury_file(MR_mdb_out, &mdb_out);
MR_c_file_to_mercury_file(MR_mdb_err, &mdb_err);
MR_TRACE_CALL_MERCURY(
ML_BROWSE_save_and_browse_browser_term_web(
MR_wrap_output_stream(&mdb_out),
MR_wrap_output_stream(&mdb_err),
browser_term, MR_trace_browser_persistent_state);
);
}
MR_bool
MR_trace_is_portray_format(const char *str, MR_BrowseFormat *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_BrowseFormat format)
{
MercuryFile mdb_in;
MercuryFile mdb_out;
MR_Word maybe_mark;
MR_Word browser_term;
MR_trace_browse_ensure_init();
MR_c_file_to_mercury_file(MR_mdb_in, &mdb_in);
MR_c_file_to_mercury_file(MR_mdb_out, &mdb_out);
browser_term = MR_type_value_to_browser_term((MR_TypeInfo) type_info,
value);
if (format != MR_BROWSE_DEFAULT_FORMAT) {
MR_TRACE_CALL_MERCURY(
ML_BROWSE_browse_browser_term_format_no_modes(
MR_wrap_input_stream(&mdb_in),
MR_wrap_output_stream(&mdb_out),
(MR_Word) format, browser_term,
MR_trace_browser_persistent_state,
&MR_trace_browser_persistent_state);
);
} else {
MR_TRACE_CALL_MERCURY(
ML_BROWSE_browse_browser_term_no_modes(
MR_wrap_input_stream(&mdb_in),
MR_wrap_output_stream(&mdb_out),
browser_term, &maybe_mark,
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);
}
void
MR_trace_browse_goal(MR_ConstString name, MR_Word arg_list, MR_Word is_func,
MR_BrowseFormat format)
{
MercuryFile mdb_in;
MercuryFile mdb_out;
MR_Word maybe_mark;
MR_Word browser_term;
MR_trace_browse_ensure_init();
MR_c_file_to_mercury_file(MR_mdb_in, &mdb_in);
MR_c_file_to_mercury_file(MR_mdb_out, &mdb_out);
browser_term = MR_synthetic_to_browser_term(name, arg_list, is_func);
if (format != MR_BROWSE_DEFAULT_FORMAT) {
MR_TRACE_CALL_MERCURY(
ML_BROWSE_browse_browser_term_format_no_modes(
MR_wrap_input_stream(&mdb_in),
MR_wrap_output_stream(&mdb_out),
(MR_Word) format, browser_term,
MR_trace_browser_persistent_state,
&MR_trace_browser_persistent_state);
);
} else {
MR_TRACE_CALL_MERCURY(
ML_BROWSE_browse_browser_term_no_modes(
MR_wrap_input_stream(&mdb_in),
MR_wrap_output_stream(&mdb_out),
browser_term, &maybe_mark,
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);
}
// MR_trace_browse_external() is the same as MR_trace_browse() except it
// uses debugger_socket_in and debugger_socket_out to read program-readable
// terms, whereas MR_trace_browse() uses mdb_in and mdb_out to read
// human-readable strings.
#ifdef MR_USE_EXTERNAL_DEBUGGER
void
MR_trace_browse_external(MR_Word type_info, MR_Word value,
MR_BrowseCallerType caller, MR_BrowseFormat format)
{
MR_trace_browse_ensure_init();
MR_TRACE_CALL_MERCURY(
ML_BROWSE_browse_external_no_modes(type_info,
MR_wrap_input_stream(&MR_debugger_socket_in),
MR_wrap_output_stream(&MR_debugger_socket_out),
value,
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);
}
#endif
void
MR_trace_print(MR_Word type_info, MR_Word value,
MR_BrowseCallerType caller_type, MR_BrowseFormat format)
{
MercuryFile mdb_out;
MR_Word browser_term;
MR_trace_browse_ensure_init();
MR_c_file_to_mercury_file(MR_mdb_out, &mdb_out);
browser_term =
MR_type_value_to_browser_term((MR_TypeInfo) type_info, value);
if (format != MR_BROWSE_DEFAULT_FORMAT) {
MR_TRACE_CALL_MERCURY(
ML_BROWSE_print_browser_term_format(
MR_wrap_output_stream(&mdb_out),
(MR_Word) caller_type, (MR_Word) format, browser_term,
MR_trace_browser_persistent_state);
);
} else {
MR_TRACE_CALL_MERCURY(
ML_BROWSE_print_browser_term(
MR_wrap_output_stream(&mdb_out),
(MR_Word) caller_type, browser_term,
MR_trace_browser_persistent_state);
);
}
}
void
MR_trace_print_goal(MR_ConstString name, MR_Word arg_list, MR_Word is_func,
MR_BrowseCallerType caller, MR_BrowseFormat format)
{
MercuryFile mdb_out;
MR_Word browser_term;
MR_trace_browse_ensure_init();
MR_c_file_to_mercury_file(MR_mdb_out, &mdb_out);
browser_term = MR_synthetic_to_browser_term(name, arg_list, is_func);
if (format != MR_BROWSE_DEFAULT_FORMAT) {
MR_TRACE_CALL_MERCURY(
ML_BROWSE_print_browser_term_format(
MR_wrap_output_stream(&mdb_out),
(MR_Word) caller, (MR_Word) format, browser_term,
MR_trace_browser_persistent_state);
);
} else {
MR_TRACE_CALL_MERCURY(
ML_BROWSE_print_browser_term(
MR_wrap_output_stream(&mdb_out),
(MR_Word) caller, browser_term,
MR_trace_browser_persistent_state);
);
}
}
void
MR_trace_print_all_browser_params(FILE *fp)
{
MR_String param_string;
MR_trace_browse_ensure_init();
MR_TRACE_CALL_MERCURY(
ML_BROWSE_browser_params_to_string(MR_trace_browser_persistent_state,
&param_string);
);
fputs(param_string, fp);
}
void
MR_trace_browse_ensure_init(void)
{
static MR_bool done = MR_FALSE;
MR_Word typeinfo_type_word;
MR_Word MR_trace_browser_persistent_state_type_word;
if (! done) {
MR_TRACE_CALL_MERCURY(
typeinfo_type_word = ML_get_type_info_for_type_info();
ML_BROWSE_browser_persistent_state_type(
&MR_trace_browser_persistent_state_type_word);
ML_BROWSE_init_persistent_state(
&MR_trace_browser_persistent_state);
);
MR_trace_browser_persistent_state_type =
(MR_TypeInfo) MR_make_permanent(
MR_trace_browser_persistent_state_type_word,
(MR_TypeInfo) typeinfo_type_word);
MR_trace_browser_persistent_state = MR_make_permanent(
MR_trace_browser_persistent_state,
MR_trace_browser_persistent_state_type);
done = MR_TRUE;
}
}
void
MR_trace_query(MR_QueryType type, const char *options, int num_imports,
char *imports[])
{
MR_ConstString options_on_heap;
MR_Word imports_list;
MR_Word names_list;
MR_Word values_list;
MercuryFile mdb_in;
MercuryFile mdb_out;
int i;
MR_c_file_to_mercury_file(MR_mdb_in, &mdb_in);
MR_c_file_to_mercury_file(MR_mdb_out, &mdb_out);
if (options == NULL) {
options = "";
}
MR_TRACE_USE_HP(
MR_make_aligned_string(options_on_heap, options);
imports_list = MR_list_empty();
for (i = num_imports; i > 0; i--) {
MR_ConstString this_import;
MR_make_aligned_string(this_import, imports[i - 1]);
imports_list = MR_string_list_cons((MR_Word) this_import,
imports_list);
}
);
MR_trace_return_bindings(&names_list, &values_list);
MR_TRACE_CALL_MERCURY(
ML_query(type, imports_list, (MR_String) options_on_heap,
names_list, values_list, MR_wrap_input_stream(&mdb_in),
MR_wrap_output_stream(&mdb_out));
);
}
#ifdef MR_USE_EXTERNAL_DEBUGGER
void
MR_trace_query_external(MR_QueryType type, MR_String options, int num_imports,
MR_Word imports_list)
{
MR_Word names_list;
MR_Word values_list;
MR_trace_return_bindings(&names_list, &values_list);
MR_TRACE_CALL_MERCURY(
ML_query_external(type, imports_list, options, names_list, values_list,
MR_wrap_input_stream(&MR_debugger_socket_in),
MR_wrap_output_stream(&MR_debugger_socket_out));
);
}
#endif