Save plain text in the source cache
[deliverable/binutils-gdb.git] / gdb / source-cache.c
index f0cb6b80059e58ad4240f192e2e64aff016c03e9..0cc2076258cf60efebda3a199886cb56dbb53597 100644 (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;
 
-#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
This page took 0.025386 seconds and 4 git commands to generate.