Save plain text in the source cache

Currently the source cache will only store highlighted text.  However,
there's no reason it could not also store plain text, when styling is
turned off.

This patch makes this change.  This also simplifies the source cache
code somewhat.

gdb/ChangeLog
2019-08-06  Tom Tromey  <tromey@adacore.com>

	* source-cache.c (source_cache::get_plain_source_lines):
	Remove "first_line" and "last_line" parameters.
	(source_cache::get_source_lines): Cache plain text.
	* source-cache.h (class source_cache)
	<get_plain_source_lines>: Update.
This commit is contained in:
Tom Tromey 2019-07-22 12:41:23 -06:00
parent 269249d940
commit 872dceaaff
3 changed files with 56 additions and 77 deletions

View File

@ -1,3 +1,11 @@
2019-08-06 Tom Tromey <tromey@adacore.com>
* source-cache.c (source_cache::get_plain_source_lines):
Remove "first_line" and "last_line" parameters.
(source_cache::get_source_lines): Cache plain text.
* source-cache.h (class source_cache)
<get_plain_source_lines>: Update.
2019-08-06 Tom Tromey <tromey@adacore.com>
* source-cache.c (extract_lines): No longer a method.

View File

@ -31,7 +31,6 @@
when GDB is linked. Happens, e.g., in the MinGW build. */
#undef open
#undef close
#include <fstream>
#include <sstream>
#include <srchilite/sourcehighlight.h>
#include <srchilite/langmap.h>
@ -48,33 +47,19 @@ source_cache g_source_cache;
/* See source-cache.h. */
bool
source_cache::get_plain_source_lines (struct symtab *s, int first_line,
int last_line, std::string *lines)
source_cache::get_plain_source_lines (struct symtab *s, std::string *lines)
{
scoped_fd desc (open_source_file_with_line_charpos (s));
if (desc.get () < 0)
return false;
if (first_line < 1 || first_line > s->nlines || last_line < 1)
return false;
struct stat st;
if (lseek (desc.get (), s->line_charpos[first_line - 1], SEEK_SET) < 0)
if (fstat (desc.get (), &st) < 0)
perror_with_name (symtab_to_filename_for_display (s));
int last_charpos;
if (last_line >= s->nlines)
{
struct stat st;
if (fstat (desc.get (), &st) < 0)
perror_with_name (symtab_to_filename_for_display (s));
/* We could cache this in line_charpos... */
last_charpos = st.st_size;
}
else
last_charpos = s->line_charpos[last_line];
lines->resize (last_charpos - s->line_charpos[first_line - 1]);
/* We could cache this in line_charpos... */
lines->resize (st.st_size);
if (myread (desc.get (), &(*lines)[0], lines->size ()) < 0)
perror_with_name (symtab_to_filename_for_display (s));
@ -182,70 +167,57 @@ source_cache::get_source_lines (struct symtab *s, int first_line,
if (first_line < 1 || last_line < 1 || first_line > last_line)
return false;
std::string fullname = symtab_to_fullname (s);
for (const auto &item : m_source_map)
{
if (item.fullname == fullname)
{
*lines = extract_lines (item.contents, first_line, last_line);
return true;
}
}
std::string contents;
if (!get_plain_source_lines (s, &contents))
return false;
#ifdef HAVE_SOURCE_HIGHLIGHT
if (source_styling && gdb_stdout->can_emit_style_escape ())
{
const char *fullname = symtab_to_fullname (s);
for (const auto &item : m_source_map)
{
if (item.fullname == fullname)
{
*lines = extract_lines (item.contents, first_line, last_line);
return true;
}
}
const char *lang_name = get_language_name (SYMTAB_LANGUAGE (s));
if (lang_name != nullptr)
{
std::ifstream input (fullname);
if (input.is_open ())
/* The global source highlight object, or null if one was
never constructed. This is stored here rather than in
the class so that we don't need to include anything or do
conditional compilation in source-cache.h. */
static srchilite::SourceHighlight *highlighter;
if (highlighter == nullptr)
{
/* The global source highlight object, or null if one
was never constructed. This is stored here rather
than in the class so that we don't need to include
anything or do conditional compilation in
source-cache.h. */
static srchilite::SourceHighlight *highlighter;
if (s->line_charpos == 0)
{
scoped_fd desc (open_source_file_with_line_charpos (s));
if (desc.get () < 0)
return false;
/* FULLNAME points to a value owned by the symtab
(symtab::fullname). Calling open_source_file reallocates
that value, so we must refresh FULLNAME to avoid a
use-after-free. */
fullname = symtab_to_fullname (s);
}
if (highlighter == nullptr)
{
highlighter = new srchilite::SourceHighlight ("esc.outlang");
highlighter->setStyleFile ("esc.style");
}
std::ostringstream output;
highlighter->highlight (input, output, lang_name, fullname);
source_text result = { fullname, output.str () };
m_source_map.push_back (std::move (result));
if (m_source_map.size () > MAX_ENTRIES)
m_source_map.erase (m_source_map.begin ());
*lines = extract_lines (m_source_map.back ().contents,
first_line, last_line);
return true;
highlighter = new srchilite::SourceHighlight ("esc.outlang");
highlighter->setStyleFile ("esc.style");
}
std::istringstream input (contents);
std::ostringstream output;
highlighter->highlight (input, output, lang_name, fullname);
contents = output.str ();
}
}
#endif /* HAVE_SOURCE_HIGHLIGHT */
return get_plain_source_lines (s, first_line, last_line, lines);
source_text result = { std::move (fullname), std::move (contents) };
m_source_map.push_back (std::move (result));
if (m_source_map.size () > MAX_ENTRIES)
m_source_map.erase (m_source_map.begin ());
*lines = extract_lines (m_source_map.back ().contents,
first_line, last_line);
return true;
}
#if GDB_SELF_TEST

View File

@ -58,11 +58,10 @@ private:
std::string contents;
};
/* A helper function for get_source_lines that is used when the
source lines are not highlighted. The arguments and return value
are as for get_source_lines. */
bool get_plain_source_lines (struct symtab *s, int first_line,
int last_line, std::string *lines_out);
/* A helper function for get_source_lines reads a source file.
Returns false on error. If no error, the contents of the file
are put into *LINES_OUT, and returns true. */
bool get_plain_source_lines (struct symtab *s, std::string *lines_out);
/* The contents of the cache. */
std::vector<source_text> m_source_map;