// vim: ts=4 sw=4 expandtab ft=c // Copyright (C) 1998-2000,2002-2006 The University of Melbourne. // Copyright (C) 2014, 2016, 2018 The Mercury team. // This file is distributed under the terms specified in COPYING.LIB. // mercury_trace_help.c // // Main author: Zoltan Somogyi. // // Help system for the internal debugger. // Most of the implementation is in browser/help.m; // this is only the interface. // 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_layout_util.h" #include "mercury_array_macros.h" #include "mercury_deep_copy.h" #include "mercury_trace_help.h" #include "mercury_trace_internal.h" #include "mercury_trace_util.h" #include "type_desc.mh" #include "io.mh" #include "mdb.help.mh" #include MR_Word MR_trace_help_system; static MR_TypeInfo MR_trace_help_system_type; static const char *MR_trace_help_add_node(MR_Word path, const char *name, int slot, const char *text); static void MR_trace_help_ensure_init(void); // Used for completion of arguments of the `help' command. static char **MR_help_words = NULL; static int MR_help_word_max = 0; static int MR_help_word_next = 0; static void MR_trace_add_help_word(const char *word); static char *MR_trace_get_help_word(int slot); const char * MR_trace_add_cat(const char *category, int slot, const char *text) { MR_Word path; MR_trace_help_ensure_init(); MR_trace_add_help_word(category); MR_TRACE_USE_HP( path = MR_list_empty(); ); return MR_trace_help_add_node(path, category, slot, text); } const char * MR_trace_add_item(const char *category, const char *item, int slot, const char *text) { MR_Word path; char *category_on_heap; MR_trace_help_ensure_init(); MR_trace_add_help_word(item); MR_TRACE_USE_HP( MR_make_aligned_string_copy(category_on_heap, category); path = MR_list_empty(); path = MR_string_list_cons((MR_Word) category_on_heap, path); ); return MR_trace_help_add_node(path, item, slot, text); } static const char * MR_trace_help_add_node(MR_Word path, const char *name, int slot, const char *text) { MR_Word result; char *msg; char *name_on_heap; char *text_on_heap; MR_bool error; MR_TRACE_USE_HP( MR_make_aligned_string_copy(name_on_heap, name); MR_make_aligned_string_copy(text_on_heap, text); ); MR_TRACE_CALL_MERCURY( 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); ); MR_trace_help_system = MR_make_permanent(MR_trace_help_system, MR_trace_help_system_type); return (error ? msg : NULL); } void MR_trace_help(void) { MercuryFile mdb_out; MR_trace_help_ensure_init(); MR_c_file_to_mercury_file(MR_mdb_out, &mdb_out); MR_TRACE_CALL_MERCURY( ML_HELP_print_top_level_help_nodes(MR_wrap_output_stream(&mdb_out), MR_trace_help_system); ); } void MR_trace_help_word(const char *word) { char *word_on_heap; MercuryFile mdb_out; MR_trace_help_ensure_init(); MR_TRACE_USE_HP( MR_make_aligned_string_copy(word_on_heap, word); ); MR_c_file_to_mercury_file(MR_mdb_out, &mdb_out); MR_TRACE_CALL_MERCURY( ML_HELP_print_help_for_name(MR_wrap_output_stream(&mdb_out), MR_trace_help_system, word_on_heap); ); } void MR_trace_help_cat_item(const char *category, const char *item) { MR_Word path; MR_Word result; char *msg; char *category_on_heap; char *item_on_heap; MR_bool error; MercuryFile mdb_out; MR_trace_help_ensure_init(); MR_TRACE_USE_HP( MR_make_aligned_string_copy(category_on_heap, category); MR_make_aligned_string_copy(item_on_heap, item); path = MR_list_empty(); path = MR_string_list_cons((MR_Word) item_on_heap, path); path = MR_string_list_cons((MR_Word) category_on_heap, path); ); MR_c_file_to_mercury_file(MR_mdb_out, &mdb_out); MR_TRACE_CALL_MERCURY( 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); ); if (error) { printf("error in the trace help system: %s\n", msg); } } static void MR_trace_help_ensure_init(void) { static MR_bool done = MR_FALSE; MR_Word typeinfo_type; MR_Word MR_trace_help_system_type_word; if (! done) { MR_TRACE_CALL_MERCURY( typeinfo_type = ML_get_type_info_for_type_info(); ML_HELP_help_system_type(&MR_trace_help_system_type_word); MR_trace_help_system_type = (MR_TypeInfo) MR_trace_help_system_type_word; ML_HELP_init(&MR_trace_help_system); ); MR_trace_help_system_type = (MR_TypeInfo) MR_make_permanent( (MR_Word) MR_trace_help_system_type, (MR_TypeInfo) typeinfo_type); MR_trace_help_system = MR_make_permanent(MR_trace_help_system, MR_trace_help_system_type); done = MR_TRUE; } } // Add the help categories and items to a sorted array for use in completion. static void MR_trace_add_help_word(const char *word) { MR_bool found; int slot; MR_bsearch(MR_help_word_next, slot, found, strcmp(MR_help_words[slot], word)); if (!found) { MR_ensure_room_for_next(MR_help_word, char *, 100); MR_prepare_insert_into_sorted(MR_help_words, MR_help_word_next, slot, strcmp(MR_help_words[slot], word)); MR_help_words[slot] = MR_copy_string(word); } } MR_CompleterList * MR_trace_help_completer(const char *word, size_t word_len) { return MR_trace_sorted_array_completer(word, word_len, MR_help_word_next, MR_trace_get_help_word); } static char * MR_trace_get_help_word(int slot) { return MR_help_words[slot]; }