21#include "gdbsupport/scoped_fd.h"
25#include "gdbsupport/selftest.h"
30#ifdef HAVE_SOURCE_HIGHLIGHT
38#include <srchilite/sourcehighlight.h>
39#include <srchilite/langmap.h>
64 _(
"Use of GNU Source Highlight library is \"%s\".\n"),
75#ifndef HAVE_SOURCE_HIGHLIGHT
81 error (_(
"the GNU Source Highlight library is not available"));
94 const std::string &fullname)
101 if (fstat (desc.get (), &st) < 0)
105 lines.resize (st.st_size);
106 if (
myread (desc.get (), &lines[0], lines.size ()) < 0)
116 if (mtime && mtime < st.st_mtime)
117 warning (_(
"Source file is more recent than executable."));
119 std::vector<off_t> offsets;
120 offsets.push_back (0);
121 for (
size_t offset = lines.find (
'\n');
122 offset != std::string::npos;
123 offset = lines.find (
'\n', offset))
129 if (offset != lines.size ())
130 offsets.push_back (offset);
133 offsets.shrink_to_fit ();
139#ifdef HAVE_SOURCE_HIGHLIGHT
145get_language_name (
enum language lang)
163 return "fortran.lang";
173 return "pascal.lang";
202 for (
int i = 0; i <
size; ++i)
220 std::string contents;
225 catch (
const gdb_exception_error &e)
233#ifdef HAVE_SOURCE_HIGHLIGHT
234 bool already_styled =
false;
235 const char *lang_name = get_language_name (s->
language ());
242 static srchilite::SourceHighlight *highlighter;
246 if (highlighter ==
nullptr)
248 highlighter =
new srchilite::SourceHighlight (
"esc.outlang");
249 highlighter->setStyleFile (
"esc.style");
252 std::istringstream input (contents);
253 std::ostringstream output;
254 highlighter->highlight (input, output, lang_name, fullname);
255 contents = output.str ();
256 already_styled =
true;
272 gdb::optional<std::string> ext_contents;
274 if (ext_contents.has_value ())
275 contents = std::move (*ext_contents);
279 source_text result = { std::move (fullname), std::move (contents) };
296 const std::vector<off_t> **offsets)
310 *offsets = &iter->second;
321 std::string *lines_out)
324 std::string::size_type pos = 0;
325 std::string::size_type first_pos = std::string::npos;
327 while (pos != std::string::npos && lineno <= last_line)
329 std::string::size_type new_pos = text.find (
'\n', pos);
331 if (lineno == first_line)
335 if (lineno == last_line || pos == std::string::npos)
338 if (first_pos == std::string::npos
339 || first_pos == text.size ())
341 if (pos == std::string::npos)
345 *lines_out = text.substr (first_pos, pos - first_pos);
359 int last_line, std::string *lines)
361 if (first_line < 1 || last_line < 1 || first_line > last_line)
368 first_line, last_line, lines);
383static void extract_lines_test ()
385 std::string input_text =
"abc\ndef\nghi\njkl\n";
389 && result ==
"abc\n");
392 && result ==
"abc\ndef\n");
404 _(
"Force gdb to flush its source code cache."),
413 _(
"Set gnu-source-highlight specific variables."),
414 _(
"Show gnu-source-highlight specific variables."),
415 &maint_set_gnu_source_highlight_cmdlist,
416 &maint_show_gnu_source_highlight_cmdlist,
423Set whether the GNU Source Highlight library should be used."), _(
"\
424Show whether the GNU Source Highlight library is being used."),_(
"\
425When enabled, GDB will use the GNU Source Highlight library to apply\n\
426styling to source code lines that are shown."),
429 &maint_set_gnu_source_highlight_cmdlist,
430 &maint_show_gnu_source_highlight_cmdlist);
433#ifdef HAVE_SOURCE_HIGHLIGHT
438 selftests::register_test (
"source-cache", selftests::extract_lines_test);
bool get_source_lines(struct symtab *s, int first_line, int last_line, std::string *lines_out)
std::vector< source_text > m_source_map
bool ensure(struct symtab *s)
bool get_line_charpos(struct symtab *s, const std::vector< off_t > **offsets)
std::string get_plain_source_lines(struct symtab *s, const std::string &fullname)
std::unordered_map< std::string, std::vector< off_t > > m_offset_cache
struct cmd_list_element * maintenanceflushlist
struct cmd_list_element * maintenance_show_cmdlist
struct cmd_list_element * maintenance_set_cmdlist
struct cmd_list_element * add_cmd(const char *name, enum command_class theclass, const char *doc, struct cmd_list_element **list)
set_show_commands add_setshow_prefix_cmd(const char *name, command_class theclass, const char *set_doc, const char *show_doc, cmd_list_element **set_subcommands_list, cmd_list_element **show_subcommands_list, cmd_list_element **set_list, cmd_list_element **show_list)
set_show_commands add_setshow_boolean_cmd(const char *name, enum command_class theclass, bool *var, const char *set_doc, const char *show_doc, const char *help_doc, cmd_func_ftype *set_func, show_value_ftype *show_func, struct cmd_list_element **set_list, struct cmd_list_element **show_list)
gdb::optional< std::string > ext_lang_colorize(const std::string &filename, const std::string &contents)
struct program_space * current_program_space
static void set_use_gnu_source_highlight_enabled(const char *ignore_args, int from_tty, struct cmd_list_element *c)
static bool use_gnu_source_highlight
source_cache g_source_cache
void _initialize_source_cache()
static void source_cache_flush_command(const char *command, int from_tty)
static bool extract_lines(const std::string &text, int first_line, int last_line, std::string *lines_out)
static void show_use_gnu_source_highlight_enabled(struct ui_file *file, int from_tty, struct cmd_list_element *c, const char *value)
const char * symtab_to_fullname(struct symtab *s)
const char * symtab_to_filename_for_display(struct symtab *symtab)
void forget_cached_source_info(void)
scoped_fd open_source_file(struct symtab *s)
struct objfile * objfile() const
enum language language() const
struct compunit_symtab * compunit() const
void gdb_printf(struct ui_file *stream, const char *format,...)
int myread(int desc, char *addr, int len)