/* MI Command Set - symbol commands.
   Copyright (C) 2003-2020 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 "mi-cmds.h"
#include "symtab.h"
#include "objfiles.h"
#include "ui-out.h"
#include "source.h"
#include "mi-getopt.h"

/* Print the list of all pc addresses and lines of code for the
   provided (full or base) source file name.  The entries are sorted
   in ascending PC order.  */

void
mi_cmd_symbol_list_lines (const char *command, char **argv, int argc)
{
  struct gdbarch *gdbarch;
  char *filename;
  struct symtab *s;
  int i;
  struct ui_out *uiout = current_uiout;

  if (argc != 1)
    error (_("-symbol-list-lines: Usage: SOURCE_FILENAME"));

  filename = argv[0];
  s = lookup_symtab (filename);

  if (s == NULL)
    error (_("-symbol-list-lines: Unknown source file name."));

  /* Now, dump the associated line table.  The pc addresses are
     already sorted by increasing values in the symbol table, so no
     need to perform any other sorting.  */

  gdbarch = get_objfile_arch (SYMTAB_OBJFILE (s));

  ui_out_emit_list list_emitter (uiout, "lines");
  if (SYMTAB_LINETABLE (s) != NULL && SYMTAB_LINETABLE (s)->nitems > 0)
    for (i = 0; i < SYMTAB_LINETABLE (s)->nitems; i++)
    {
      ui_out_emit_tuple tuple_emitter (uiout, NULL);
      uiout->field_core_addr ("pc", gdbarch, SYMTAB_LINETABLE (s)->item[i].pc);
      uiout->field_signed ("line", SYMTAB_LINETABLE (s)->item[i].line);
    }
}

/* Used by the -symbol-info-* and -symbol-info-module-* commands to print
   information about the symbol SYM in a block of index BLOCK (either
   GLOBAL_BLOCK or STATIC_BLOCK).  KIND is the kind of symbol we searched
   for in order to find SYM, which impact which fields are displayed in the
   results.  */

static void
output_debug_symbol (ui_out *uiout, enum search_domain kind,
		     struct symbol *sym, int block)
{
  ui_out_emit_tuple tuple_emitter (uiout, NULL);

  if (SYMBOL_LINE (sym) != 0)
    uiout->field_unsigned ("line", SYMBOL_LINE (sym));
  uiout->field_string ("name", sym->print_name ());

  if (kind == FUNCTIONS_DOMAIN || kind == VARIABLES_DOMAIN)
    {
      string_file tmp_stream;
      type_print (SYMBOL_TYPE (sym), "", &tmp_stream, -1);
      uiout->field_string ("type", tmp_stream.string ());

      std::string str = symbol_to_info_string (sym, block, kind);
      uiout->field_string ("description", str);
    }
}

/* Actually output one nondebug symbol, puts a tuple emitter in place
   and then outputs the fields for this msymbol.  */

static void
output_nondebug_symbol (ui_out *uiout,
			const struct bound_minimal_symbol &msymbol)
{
  struct gdbarch *gdbarch = get_objfile_arch (msymbol.objfile);
  ui_out_emit_tuple tuple_emitter (uiout, NULL);

  uiout->field_core_addr ("address", gdbarch,
			  BMSYMBOL_VALUE_ADDRESS (msymbol));
  uiout->field_string ("name", msymbol.minsym->print_name ());
}

/* This is the guts of the commands '-symbol-info-functions',
   '-symbol-info-variables', and '-symbol-info-types'.  It searches for
   symbols matching KING, NAME_REGEXP, TYPE_REGEXP, and EXCLUDE_MINSYMS,
   and then prints the matching [m]symbols in an MI structured format.  */

static void
mi_symbol_info (enum search_domain kind, const char *name_regexp,
		const char *type_regexp, bool exclude_minsyms,
		size_t max_results)
{
  global_symbol_searcher sym_search (kind, name_regexp);
  sym_search.set_symbol_type_regexp (type_regexp);
  sym_search.set_exclude_minsyms (exclude_minsyms);
  sym_search.set_max_search_results (max_results);
  std::vector<symbol_search> symbols = sym_search.search ();
  ui_out *uiout = current_uiout;
  int i = 0;

  ui_out_emit_tuple outer_symbols_emitter (uiout, "symbols");

  /* Debug symbols are placed first. */
  if (i < symbols.size () && symbols[i].msymbol.minsym == nullptr)
    {
      ui_out_emit_list debug_symbols_list_emitter (uiout, "debug");

      /* As long as we have debug symbols...  */
      while (i < symbols.size () && symbols[i].msymbol.minsym == nullptr)
	{
	  symtab *symtab = symbol_symtab (symbols[i].symbol);
	  ui_out_emit_tuple symtab_tuple_emitter (uiout, nullptr);

	  uiout->field_string ("filename",
			       symtab_to_filename_for_display (symtab));
	  uiout->field_string ("fullname", symtab_to_fullname (symtab));

	  ui_out_emit_list symbols_list_emitter (uiout, "symbols");

	  /* As long as we have debug symbols from this symtab...  */
	  for (; (i < symbols.size ()
		  && symbols[i].msymbol.minsym == nullptr
		  && symbol_symtab (symbols[i].symbol) == symtab);
	       ++i)
	    {
	      symbol_search &s = symbols[i];

	      output_debug_symbol (uiout, kind, s.symbol, s.block);
	    }
	}
    }

  /* Non-debug symbols are placed after.  */
  if (i < symbols.size ())
    {
      ui_out_emit_list nondebug_symbols_list_emitter (uiout, "nondebug");

      /* As long as we have nondebug symbols...  */
      for (; i < symbols.size (); i++)
	{
	  gdb_assert (symbols[i].msymbol.minsym != nullptr);
	  output_nondebug_symbol (uiout, symbols[i].msymbol);
	}
    }
}

/* Helper to parse the option text from an -max-results argument and return
   the parsed value.  If the text can't be parsed then an error is thrown.  */

static size_t
parse_max_results_option (char *arg)
{
  char *ptr = arg;
  long long val = strtoll (arg, &ptr, 10);
  if (arg == ptr || *ptr != '\0' || val > SIZE_MAX || val < 0)
    error (_("invalid value for --max-results argument"));
  size_t max_results = (size_t) val;

  return max_results;
}

/* Helper for mi_cmd_symbol_info_{functions,variables} - depending on KIND.
   Processes command line options from ARGV and ARGC.  */

static void
mi_info_functions_or_variables (enum search_domain kind, char **argv, int argc)
{
  size_t max_results = SIZE_MAX;
  const char *regexp = nullptr;
  const char *t_regexp = nullptr;
  bool exclude_minsyms = true;

  enum opt
    {
     INCLUDE_NONDEBUG_OPT, TYPE_REGEXP_OPT, NAME_REGEXP_OPT, MAX_RESULTS_OPT
    };
  static const struct mi_opt opts[] =
  {
    {"-include-nondebug" , INCLUDE_NONDEBUG_OPT, 0},
    {"-type", TYPE_REGEXP_OPT, 1},
    {"-name", NAME_REGEXP_OPT, 1},
    {"-max-results", MAX_RESULTS_OPT, 1},
    { 0, 0, 0 }
  };

  int oind = 0;
  char *oarg = nullptr;

  while (1)
    {
      const char *cmd_string
	= ((kind == FUNCTIONS_DOMAIN)
	   ? "-symbol-info-functions" : "-symbol-info-variables");
      int opt = mi_getopt (cmd_string, argc, argv, opts, &oind, &oarg);
      if (opt < 0)
	break;
      switch ((enum opt) opt)
	{
	case INCLUDE_NONDEBUG_OPT:
	  exclude_minsyms = false;
	  break;
	case TYPE_REGEXP_OPT:
	  t_regexp = oarg;
	  break;
	case NAME_REGEXP_OPT:
	  regexp = oarg;
	  break;
	case MAX_RESULTS_OPT:
	  max_results = parse_max_results_option (oarg);
	  break;
	}
    }

  mi_symbol_info (kind, regexp, t_regexp, exclude_minsyms, max_results);
}

/* Type for an iterator over a vector of module_symbol_search results.  */
typedef std::vector<module_symbol_search>::const_iterator
	module_symbol_search_iterator;

/* Helper for mi_info_module_functions_or_variables.  Display the results
   from ITER up to END or until we find a symbol that is in a different
   module, or in a different symtab than the first symbol we print.  Update
   and return the new value for ITER.  */
static module_symbol_search_iterator
output_module_symbols_in_single_module_and_file
	(struct ui_out *uiout, module_symbol_search_iterator iter,
	 const module_symbol_search_iterator end, enum search_domain kind)
{
  /* The symbol for the module in which the first result resides.  */
  const symbol *first_module_symbol = iter->first.symbol;

  /* The symbol for the first result, and the symtab in which it resides.  */
  const symbol *first_result_symbol = iter->second.symbol;
  symtab *first_symbtab = symbol_symtab (first_result_symbol);

  /* Formatted output.  */
  ui_out_emit_tuple current_file (uiout, nullptr);
  uiout->field_string ("filename",
		       symtab_to_filename_for_display (first_symbtab));
  uiout->field_string ("fullname", symtab_to_fullname (first_symbtab));
  ui_out_emit_list item_list (uiout, "symbols");

  /* Repeatedly output result symbols until either we run out of symbols,
     we change module, or we change symtab.  */
  for (; (iter != end
	  && first_module_symbol == iter->first.symbol
	  && first_symbtab == symbol_symtab (iter->second.symbol));
       ++iter)
    output_debug_symbol (uiout, kind, iter->second.symbol,
			 iter->second.block);

  return iter;
}

/* Helper for mi_info_module_functions_or_variables.  Display the results
   from ITER up to END or until we find a symbol that is in a different
   module than the first symbol we print.  Update and return the new value
   for ITER.  */
static module_symbol_search_iterator
output_module_symbols_in_single_module
	(struct ui_out *uiout, module_symbol_search_iterator iter,
	 const module_symbol_search_iterator end, enum search_domain kind)
{
  gdb_assert (iter->first.symbol != nullptr);
  gdb_assert (iter->second.symbol != nullptr);

  /* The symbol for the module in which the first result resides.  */
  const symbol *first_module_symbol = iter->first.symbol;

  /* Create output formatting.  */
  ui_out_emit_tuple module_tuple (uiout, nullptr);
  uiout->field_string ("module", first_module_symbol->print_name ());
  ui_out_emit_list files_list (uiout, "files");

  /* The results are sorted so that symbols within the same file are next
     to each other in the list.  Calling the output function once will
     print all results within a single file.  We keep calling the output
     function until we change module.  */
  while (iter != end && first_module_symbol == iter->first.symbol)
    iter = output_module_symbols_in_single_module_and_file (uiout, iter,
							    end, kind);
  return iter;
}

/* Core of -symbol-info-module-functions and -symbol-info-module-variables.
   KIND indicates what we are searching for, and ARGV and ARGC are the
   command line options passed to the MI command.  */

static void
mi_info_module_functions_or_variables (enum search_domain kind,
					char **argv, int argc)
{
  const char *module_regexp = nullptr;
  const char *regexp = nullptr;
  const char *type_regexp = nullptr;

  /* Process the command line options.  */

  enum opt
    {
     MODULE_REGEXP_OPT, TYPE_REGEXP_OPT, NAME_REGEXP_OPT
    };
  static const struct mi_opt opts[] =
  {
    {"-module", MODULE_REGEXP_OPT, 1},
    {"-type", TYPE_REGEXP_OPT, 1},
    {"-name", NAME_REGEXP_OPT, 1},
    { 0, 0, 0 }
  };

  int oind = 0;
  char *oarg = nullptr;

  while (1)
    {
      const char *cmd_string
	= ((kind == FUNCTIONS_DOMAIN)
	   ? "-symbol-info-module-functions"
	   : "-symbol-info-module-variables");
      int opt = mi_getopt (cmd_string, argc, argv, opts, &oind, &oarg);
      if (opt < 0)
	break;
      switch ((enum opt) opt)
	{
	case MODULE_REGEXP_OPT:
	  module_regexp = oarg;
	  break;
	case TYPE_REGEXP_OPT:
	  type_regexp = oarg;
	  break;
	case NAME_REGEXP_OPT:
	  regexp = oarg;
	  break;
	}
    }

  std::vector<module_symbol_search> module_symbols
    = search_module_symbols (module_regexp, regexp, type_regexp, kind);

  struct ui_out *uiout = current_uiout;
  ui_out_emit_list all_matching_symbols (uiout, "symbols");

  /* The results in the module_symbols list are ordered so symbols in the
     same module are next to each other.  Repeatedly call the output
     function to print sequences of symbols that are in the same module
     until we have no symbols left to print.  */
  module_symbol_search_iterator iter = module_symbols.begin ();
  const module_symbol_search_iterator end = module_symbols.end ();
  while (iter != end)
    iter = output_module_symbols_in_single_module (uiout, iter, end, kind);
}

/* Implement -symbol-info-functions command.  */

void
mi_cmd_symbol_info_functions (const char *command, char **argv, int argc)
{
  mi_info_functions_or_variables (FUNCTIONS_DOMAIN, argv, argc);
}

/* Implement -symbol-info-module-functions command.  */

void
mi_cmd_symbol_info_module_functions (const char *command, char **argv,
				     int argc)
{
  mi_info_module_functions_or_variables (FUNCTIONS_DOMAIN, argv, argc);
}

/* Implement -symbol-info-module-variables command.  */

void
mi_cmd_symbol_info_module_variables (const char *command, char **argv,
				     int argc)
{
  mi_info_module_functions_or_variables (VARIABLES_DOMAIN, argv, argc);
}

/* Implement -symbol-inf-modules command.  */

void
mi_cmd_symbol_info_modules (const char *command, char **argv, int argc)
{
  size_t max_results = SIZE_MAX;
  const char *regexp = nullptr;

  enum opt
    {
     NAME_REGEXP_OPT, MAX_RESULTS_OPT
    };
  static const struct mi_opt opts[] =
  {
    {"-name", NAME_REGEXP_OPT, 1},
    {"-max-results", MAX_RESULTS_OPT, 1},
    { 0, 0, 0 }
  };

  int oind = 0;
  char *oarg = nullptr;

  while (1)
    {
      int opt = mi_getopt ("-symbol-info-modules", argc, argv, opts,
			   &oind, &oarg);
      if (opt < 0)
	break;
      switch ((enum opt) opt)
	{
	case NAME_REGEXP_OPT:
	  regexp = oarg;
	  break;
	case MAX_RESULTS_OPT:
	  max_results = parse_max_results_option (oarg);
	  break;
	}
    }

  mi_symbol_info (MODULES_DOMAIN, regexp, nullptr, true, max_results);
}

/* Implement -symbol-info-types command.  */

void
mi_cmd_symbol_info_types (const char *command, char **argv, int argc)
{
  size_t max_results = SIZE_MAX;
  const char *regexp = nullptr;

  enum opt
    {
     NAME_REGEXP_OPT, MAX_RESULTS_OPT
    };
  static const struct mi_opt opts[] =
  {
    {"-name", NAME_REGEXP_OPT, 1},
    {"-max-results", MAX_RESULTS_OPT, 1},
    { 0, 0, 0 }
  };

  int oind = 0;
  char *oarg = nullptr;

  while (true)
    {
      int opt = mi_getopt ("-symbol-info-types", argc, argv, opts,
			   &oind, &oarg);
      if (opt < 0)
	break;
      switch ((enum opt) opt)
	{
	case NAME_REGEXP_OPT:
	  regexp = oarg;
	  break;
	case MAX_RESULTS_OPT:
	  max_results = parse_max_results_option (oarg);
	  break;
	}
    }

  mi_symbol_info (TYPES_DOMAIN, regexp, nullptr, true, max_results);
}

/* Implement -symbol-info-variables command.  */

void
mi_cmd_symbol_info_variables (const char *command, char **argv, int argc)
{
  mi_info_functions_or_variables (VARIABLES_DOMAIN, argv, argc);
}
