diff options
-rw-r--r-- | gdb/ChangeLog | 12 | ||||
-rw-r--r-- | gdb/cli/cli-style.c | 5 | ||||
-rw-r--r-- | gdb/extension-priv.h | 7 | ||||
-rw-r--r-- | gdb/extension.c | 21 | ||||
-rw-r--r-- | gdb/extension.h | 9 | ||||
-rw-r--r-- | gdb/python/lib/gdb/__init__.py | 14 | ||||
-rw-r--r-- | gdb/python/python.c | 72 | ||||
-rw-r--r-- | gdb/source-cache.c | 14 |
8 files changed, 150 insertions, 4 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 0161fbf..798fe5b 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,15 @@ +2020-01-21 Tom Tromey <tromey@adacore.com> + + * source-cache.c (source_cache::ensure): Call ext_lang_colorize. + * python/python.c (python_extension_ops): Update. + (gdbpy_colorize): New function. + * python/lib/gdb/__init__.py (colorize): New function. + * extension.h (ext_lang_colorize): Declare. + * extension.c (ext_lang_colorize): New function. + * extension-priv.h (struct extension_language_ops) <colorize>: New + member. + * cli/cli-style.c (_initialize_cli_style): Update help text. + 2020-01-21 Luis Machado <luis.machado@linaro.org> * aarch64-tdep.c (struct aarch64_displaced_step_closure) diff --git a/gdb/cli/cli-style.c b/gdb/cli/cli-style.c index 917a7f6..d2d9928 100644 --- a/gdb/cli/cli-style.c +++ b/gdb/cli/cli-style.c @@ -341,8 +341,9 @@ If enabled, source code is styled.\n" "Note that source styling only works if styling in general is enabled,\n\ see \"show style enabled\"." #else -"Source highlighting is disabled in this installation of gdb, because\n\ -it was not linked against GNU Source Highlight." +"Source highlighting may be disabled in this installation of gdb, because\n\ +it was not linked against GNU Source Highlight. However, it might still be\n\ +available if the appropriate extension is available at runtime." #endif ), set_style_enabled, show_style_sources, &style_set_list, &style_show_list); diff --git a/gdb/extension-priv.h b/gdb/extension-priv.h index 2af2ded..c356710 100644 --- a/gdb/extension-priv.h +++ b/gdb/extension-priv.h @@ -254,6 +254,13 @@ struct extension_language_ops struct type *obj_type, const char *method_name, std::vector<xmethod_worker_up> *dm_vec); + + /* Colorize a source file. NAME is the source file's name, and + CONTENTS is the contents of the file. This should either return + colorized (using ANSI terminal escapes) version of the contents, + or an empty option. */ + gdb::optional<std::string> (*colorize) (const std::string &name, + const std::string &contents); }; /* State necessary to restore a signal handler to its previous value. */ diff --git a/gdb/extension.c b/gdb/extension.c index 947e440..e2efe0b 100644 --- a/gdb/extension.c +++ b/gdb/extension.c @@ -903,6 +903,27 @@ xmethod_worker::get_result_type (value *object, gdb::array_view<value *> args) return result_type; } +/* See extension.h. */ + +gdb::optional<std::string> +ext_lang_colorize (const std::string &filename, const std::string &contents) +{ + int i; + const struct extension_language_defn *extlang; + gdb::optional<std::string> result; + + ALL_ENABLED_EXTENSION_LANGUAGES (i, extlang) + { + if (extlang->ops->colorize == nullptr) + continue; + result = extlang->ops->colorize (filename, contents); + if (result.has_value ()) + return result; + } + + return result; +} + /* Called via an observer before gdb prints its prompt. Iterate over the extension languages giving them a chance to change the prompt. The first one to change the prompt wins, diff --git a/gdb/extension.h b/gdb/extension.h index 5da0602..ca3fc14 100644 --- a/gdb/extension.h +++ b/gdb/extension.h @@ -22,6 +22,7 @@ #include "mi/mi-cmds.h" /* For PRINT_NO_VALUES, etc. */ #include "gdbsupport/array-view.h" +#include "gdbsupport/gdb_optional.h" struct breakpoint; struct command_line; @@ -309,4 +310,12 @@ extern void get_matching_xmethod_workers (struct type *type, const char *method_name, std::vector<xmethod_worker_up> *workers); +/* Try to colorize some source code. FILENAME is the name of the file + holding the code. CONTENTS is the source code itself. This will + either a colorized (using ANSI terminal escapes) version of the + source code, or an empty value if colorizing could not be done. */ + +extern gdb::optional<std::string> ext_lang_colorize + (const std::string &filename, const std::string &contents); + #endif /* EXTENSION_H */ diff --git a/gdb/python/lib/gdb/__init__.py b/gdb/python/lib/gdb/__init__.py index 09d43b2..a1aac00 100644 --- a/gdb/python/lib/gdb/__init__.py +++ b/gdb/python/lib/gdb/__init__.py @@ -210,3 +210,17 @@ def find_pc_line(pc): """find_pc_line (pc) -> Symtab_and_line. Return the gdb.Symtab_and_line object corresponding to the pc value.""" return current_progspace().find_pc_line(pc) + +try: + from pygments import formatters, lexers, highlight + def colorize(filename, contents): + # Don't want any errors. + try: + lexer = lexers.get_lexer_for_filename(filename) + formatter = formatters.TerminalFormatter() + return highlight(contents, lexer, formatter) + except: + return None +except: + def colorize(filename, contents): + return None diff --git a/gdb/python/python.c b/gdb/python/python.c index d6f7f99..f75c7b1 100644 --- a/gdb/python/python.c +++ b/gdb/python/python.c @@ -149,6 +149,8 @@ static void gdbpy_set_quit_flag (const struct extension_language_defn *); static int gdbpy_check_quit_flag (const struct extension_language_defn *); static enum ext_lang_rc gdbpy_before_prompt_hook (const struct extension_language_defn *, const char *current_gdb_prompt); +static gdb::optional<std::string> gdbpy_colorize + (const std::string &filename, const std::string &contents); /* The interface between gdb proper and loading of python scripts. */ @@ -188,6 +190,8 @@ const struct extension_language_ops python_extension_ops = gdbpy_before_prompt_hook, gdbpy_get_matching_xmethod_workers, + + gdbpy_colorize, }; /* Architecture and language to be used in callbacks from @@ -1104,6 +1108,74 @@ gdbpy_before_prompt_hook (const struct extension_language_defn *extlang, return EXT_LANG_RC_NOP; } +/* This is the extension_language_ops.colorize "method". */ + +static gdb::optional<std::string> +gdbpy_colorize (const std::string &filename, const std::string &contents) +{ + if (!gdb_python_initialized) + return {}; + + gdbpy_enter enter_py (get_current_arch (), current_language); + + if (gdb_python_module == nullptr + || !PyObject_HasAttrString (gdb_python_module, "colorize")) + return {}; + + gdbpy_ref<> hook (PyObject_GetAttrString (gdb_python_module, "colorize")); + if (hook == nullptr) + { + gdbpy_print_stack (); + return {}; + } + + if (!PyCallable_Check (hook.get ())) + return {}; + + gdbpy_ref<> fname_arg (PyString_FromString (filename.c_str ())); + if (fname_arg == nullptr) + { + gdbpy_print_stack (); + return {}; + } + gdbpy_ref<> contents_arg (PyString_FromString (contents.c_str ())); + if (contents_arg == nullptr) + { + gdbpy_print_stack (); + return {}; + } + + gdbpy_ref<> result (PyObject_CallFunctionObjArgs (hook.get (), + fname_arg.get (), + contents_arg.get (), + nullptr)); + if (result == nullptr) + { + gdbpy_print_stack (); + return {}; + } + + if (!gdbpy_is_string (result.get ())) + return {}; + + gdbpy_ref<> unic = python_string_to_unicode (result.get ()); + if (unic == nullptr) + { + gdbpy_print_stack (); + return {}; + } + gdbpy_ref<> host_str (PyUnicode_AsEncodedString (unic.get (), + host_charset (), + nullptr)); + if (host_str == nullptr) + { + gdbpy_print_stack (); + return {}; + } + + return std::string (PyBytes_AsString (host_str.get ())); +} + /* Printing. */ diff --git a/gdb/source-cache.c b/gdb/source-cache.c index d546ae5..71277ec 100644 --- a/gdb/source-cache.c +++ b/gdb/source-cache.c @@ -178,9 +178,10 @@ source_cache::ensure (struct symtab *s) std::string contents = get_plain_source_lines (s, fullname); -#ifdef HAVE_SOURCE_HIGHLIGHT if (source_styling && gdb_stdout->can_emit_style_escape ()) { +#ifdef HAVE_SOURCE_HIGHLIGHT + bool already_styled = false; const char *lang_name = get_language_name (SYMTAB_LANGUAGE (s)); if (lang_name != nullptr) { @@ -202,6 +203,7 @@ source_cache::ensure (struct symtab *s) std::ostringstream output; highlighter->highlight (input, output, lang_name, fullname); contents = output.str (); + already_styled = true; } catch (...) { @@ -213,8 +215,16 @@ source_cache::ensure (struct symtab *s) un-highlighted text. */ } } - } + + if (!already_styled) #endif /* HAVE_SOURCE_HIGHLIGHT */ + { + gdb::optional<std::string> ext_contents; + ext_contents = ext_lang_colorize (fullname, contents); + if (ext_contents.has_value ()) + contents = std::move (*ext_contents); + } + } source_text result = { std::move (fullname), std::move (contents) }; m_source_map.push_back (std::move (result)); |