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>
/* 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));
if (first_line < 1 || last_line < 1 || first_line > last_line)
return false;
-#ifdef HAVE_SOURCE_HIGHLIGHT
- if (source_styling && gdb_stdout->can_emit_style_escape ())
- {
- const char *fullname = symtab_to_fullname (s);
+ std::string fullname = symtab_to_fullname (s);
- for (const auto &item : m_source_map)
+ for (const auto &item : m_source_map)
+ {
+ if (item.fullname == fullname)
{
- if (item.fullname == fullname)
- {
- *lines = extract_lines (item.contents, first_line, last_line);
- return true;
- }
+ *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 *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