/* Cache of styled source file text
   Copyright (C) 2018-2023 Free Software Foundation, Inc.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#include "defs.h"
#include "source-cache.h"
#include "gdbsupport/scoped_fd.h"
#include "source.h"
#include "cli/cli-style.h"
#include "symtab.h"
#include "gdbsupport/selftest.h"
#include "objfiles.h"
#include "exec.h"
#include "cli/cli-cmds.h"

#ifdef HAVE_SOURCE_HIGHLIGHT
/* If Gnulib redirects 'open' and 'close' to its replacements
   'rpl_open' and 'rpl_close' via cpp macros, including <fstream>
   below with those macros in effect will cause unresolved externals
   when GDB is linked.  Happens, e.g., in the MinGW build.  */
#undef open
#undef close
#include <sstream>
#include <srchilite/sourcehighlight.h>
#include <srchilite/langmap.h>
#endif

/* The number of source files we'll cache.  */

#define MAX_ENTRIES 5

/* See source-cache.h.  */

source_cache g_source_cache;

/* When this is true we will use the GNU Source Highlight to add styling to
   source code (assuming the library is available).  This is initialized to
   true (if appropriate) in _initialize_source_cache below.  */

static bool use_gnu_source_highlight;

/* The "maint show gnu-source-highlight enabled" command. */

static void
show_use_gnu_source_highlight_enabled (struct ui_file *file, int from_tty,
				       struct cmd_list_element *c,
				       const char *value)
{
  gdb_printf (file, _ ("Use of GNU Source Highlight library is \"%s\".\n"),
	      value);
}

/* The "maint set gnu-source-highlight enabled" command.  */

static void
set_use_gnu_source_highlight_enabled (const char *ignore_args, int from_tty,
				      struct cmd_list_element *c)
{
#ifndef HAVE_SOURCE_HIGHLIGHT
  /* If the library is not available and the user tried to enable use of
     the library, then disable use of the library, and give an error.  */
  if (use_gnu_source_highlight)
    {
      use_gnu_source_highlight = false;
      error (_ ("the GNU Source Highlight library is not available"));
    }
#else
  /* We (might) have just changed how we style source code, discard any
     previously cached contents.  */
  forget_cached_source_info ();
#endif
}

/* See source-cache.h.  */

std::string
source_cache::get_plain_source_lines (struct symtab *s,
				      const std::string &fullname)
{
  scoped_fd desc (open_source_file (s));
  if (desc.get () < 0)
    perror_with_name (symtab_to_filename_for_display (s));

  struct stat st;
  if (fstat (desc.get (), &st) < 0)
    perror_with_name (symtab_to_filename_for_display (s));

  std::string lines;
  lines.resize (st.st_size);
  if (myread (desc.get (), &lines[0], lines.size ()) < 0)
    perror_with_name (symtab_to_filename_for_display (s));

  time_t mtime = 0;
  if (s->compunit ()->objfile () != NULL
      && s->compunit ()->objfile ()->obfd != NULL)
    mtime = s->compunit ()->objfile ()->mtime;
  else if (current_program_space->exec_bfd ())
    mtime = current_program_space->ebfd_mtime;

  if (mtime && mtime < st.st_mtime)
    warning (_ ("Source file is more recent than executable."));

  std::vector<off_t> offsets;
  offsets.push_back (0);
  for (size_t offset = lines.find ('\n'); offset != std::string::npos;
       offset = lines.find ('\n', offset))
    {
      ++offset;
      /* A newline at the end does not start a new line.  It would
	 seem simpler to just strip the newline in this function, but
	 then "list" won't print the final newline.  */
      if (offset != lines.size ())
	offsets.push_back (offset);
    }

  offsets.shrink_to_fit ();
  m_offset_cache.emplace (fullname, std::move (offsets));

  return lines;
}

#ifdef HAVE_SOURCE_HIGHLIGHT

/* Return the Source Highlight language name, given a gdb language
   LANG.  Returns NULL if the language is not known.  */

static const char *
get_language_name (enum language lang)
{
  switch (lang)
    {
    case language_c:
    case language_objc:
      return "c.lang";

    case language_cplus:
      return "cpp.lang";

    case language_d:
      return "d.lang";

    case language_go:
      return "go.lang";

    case language_fortran:
      return "fortran.lang";

    case language_m2:
      /* Not handled by Source Highlight.  */
      break;

    case language_asm:
      return "asm.lang";

    case language_pascal:
      return "pascal.lang";

    case language_opencl:
      /* Not handled by Source Highlight.  */
      break;

    case language_rust:
      return "rust.lang";

    case language_ada:
      return "ada.lang";

    default:
      break;
    }

  return nullptr;
}

#endif /* HAVE_SOURCE_HIGHLIGHT */

/* See source-cache.h.  */

bool
source_cache::ensure (struct symtab *s)
{
  std::string fullname = symtab_to_fullname (s);

  size_t size = m_source_map.size ();
  for (int i = 0; i < size; ++i)
    {
      if (m_source_map[i].fullname == fullname)
	{
	  /* This should always hold, because we create the file offsets
	     when reading the file.  */
	  gdb_assert (m_offset_cache.find (fullname) != m_offset_cache.end ());
	  /* Not strictly LRU, but at least ensure that the most
	     recently used entry is always the last candidate for
	     deletion.  Note that this property is relied upon by at
	     least one caller.  */
	  if (i != size - 1)
	    std::swap (m_source_map[i], m_source_map[size - 1]);
	  return true;
	}
    }

  std::string contents;
  try
    {
      contents = get_plain_source_lines (s, fullname);
    }
  catch (const gdb_exception_error &e)
    {
      /* If 's' is not found, an exception is thrown.  */
      return false;
    }

  if (source_styling && gdb_stdout->can_emit_style_escape ())
    {
#ifdef HAVE_SOURCE_HIGHLIGHT
      bool already_styled = false;
      const char *lang_name = get_language_name (s->language ());
      if (lang_name != nullptr && use_gnu_source_highlight)
	{
	  /* 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;

	  try
	    {
	      if (highlighter == nullptr)
		{
		  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 ();
	      already_styled = true;
	    }
	  catch (...)
	    {
	      /* Source Highlight will throw an exception if
		 highlighting fails.  One possible reason it can fail
		 is if the language is unknown -- which matters to gdb
		 because Rust support wasn't added until after 3.1.8.
		 Ignore exceptions here and fall back to
		 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));

  if (m_source_map.size () > MAX_ENTRIES)
    {
      auto iter = m_source_map.begin ();
      m_offset_cache.erase (iter->fullname);
      m_source_map.erase (iter);
    }

  return true;
}

/* See source-cache.h.  */

bool
source_cache::get_line_charpos (struct symtab *s,
				const std::vector<off_t> **offsets)
{
  std::string fullname = symtab_to_fullname (s);

  auto iter = m_offset_cache.find (fullname);
  if (iter == m_offset_cache.end ())
    {
      if (!ensure (s))
	return false;
      iter = m_offset_cache.find (fullname);
      /* cache_source_text ensured this was entered.  */
      gdb_assert (iter != m_offset_cache.end ());
    }

  *offsets = &iter->second;
  return true;
}

/* A helper function that extracts the desired source lines from TEXT,
   putting them into LINES_OUT.  The arguments are as for
   get_source_lines.  Returns true on success, false if the line
   numbers are invalid.  */

static bool
extract_lines (const std::string &text, int first_line, int last_line,
	       std::string *lines_out)
{
  int lineno = 1;
  std::string::size_type pos = 0;
  std::string::size_type first_pos = std::string::npos;

  while (pos != std::string::npos && lineno <= last_line)
    {
      std::string::size_type new_pos = text.find ('\n', pos);

      if (lineno == first_line)
	first_pos = pos;

      pos = new_pos;
      if (lineno == last_line || pos == std::string::npos)
	{
	  /* A newline at the end does not start a new line.  */
	  if (first_pos == std::string::npos || first_pos == text.size ())
	    return false;
	  if (pos == std::string::npos)
	    pos = text.size ();
	  else
	    ++pos;
	  *lines_out = text.substr (first_pos, pos - first_pos);
	  return true;
	}
      ++lineno;
      ++pos;
    }

  return false;
}

/* See source-cache.h.  */

bool
source_cache::get_source_lines (struct symtab *s, int first_line,
				int last_line, std::string *lines)
{
  if (first_line < 1 || last_line < 1 || first_line > last_line)
    return false;

  if (!ensure (s))
    return false;

  return extract_lines (m_source_map.back ().contents, first_line, last_line,
			lines);
}

/* Implement 'maint flush source-cache' command.  */

static void
source_cache_flush_command (const char *command, int from_tty)
{
  forget_cached_source_info ();
  gdb_printf (_ ("Source cache flushed.\n"));
}

#if GDB_SELF_TEST
namespace selftests
{
static void
extract_lines_test ()
{
  std::string input_text = "abc\ndef\nghi\njkl\n";
  std::string result;

  SELF_CHECK (extract_lines (input_text, 1, 1, &result) && result == "abc\n");
  SELF_CHECK (!extract_lines (input_text, 2, 1, &result));
  SELF_CHECK (extract_lines (input_text, 1, 2, &result)
	      && result == "abc\ndef\n");
  SELF_CHECK (extract_lines ("abc", 1, 1, &result) && result == "abc");
}
} // namespace selftests
#endif

void _initialize_source_cache ();

void
_initialize_source_cache ()
{
  add_cmd ("source-cache", class_maintenance, source_cache_flush_command,
	   _ ("Force gdb to flush its source code cache."),
	   &maintenanceflushlist);

  /* All the 'maint set|show gnu-source-highlight' sub-commands.  */
  static struct cmd_list_element *maint_set_gnu_source_highlight_cmdlist;
  static struct cmd_list_element *maint_show_gnu_source_highlight_cmdlist;

  /* Adds 'maint set|show gnu-source-highlight'.  */
  add_setshow_prefix_cmd ("gnu-source-highlight", class_maintenance,
			  _ ("Set gnu-source-highlight specific variables."),
			  _ ("Show gnu-source-highlight specific variables."),
			  &maint_set_gnu_source_highlight_cmdlist,
			  &maint_show_gnu_source_highlight_cmdlist,
			  &maintenance_set_cmdlist, &maintenance_show_cmdlist);

  /* Adds 'maint set|show gnu-source-highlight enabled'.  */
  add_setshow_boolean_cmd ("enabled", class_maintenance,
			   &use_gnu_source_highlight, _ ("\
Set whether the GNU Source Highlight library should be used."),
			   _ ("\
Show whether the GNU Source Highlight library is being used."),
			   _ ("\
When enabled, GDB will use the GNU Source Highlight library to apply\n\
styling to source code lines that are shown."),
			   set_use_gnu_source_highlight_enabled,
			   show_use_gnu_source_highlight_enabled,
			   &maint_set_gnu_source_highlight_cmdlist,
			   &maint_show_gnu_source_highlight_cmdlist);

  /* Enable use of GNU Source Highlight library, if we have it.  */
#ifdef HAVE_SOURCE_HIGHLIGHT
  use_gnu_source_highlight = true;
#endif

#if GDB_SELF_TEST
  selftests::register_test ("source-cache", selftests::extract_lines_test);
#endif
}
