/* MI Command Set - symbol commands.
   Copyright (C) 2003-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 "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, const char *const *argv,
			  int argc)
{
  struct gdbarch *gdbarch;
  const 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.  */

  struct objfile *objfile = s->compunit ()->objfile ();
  gdbarch = objfile->arch ();

  ui_out_emit_list list_emitter (uiout, "lines");
  if (s->linetable () != NULL && s->linetable ()->nitems > 0)
    for (i = 0; i < s->linetable ()->nitems; i++)
      {
	ui_out_emit_tuple tuple_emitter (uiout, NULL);
	uiout->field_core_addr ("pc", gdbarch,
				s->linetable ()->item[i].pc (objfile));
	uiout->field_signed ("line", s->linetable ()->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 (sym->line () != 0)
    uiout->field_unsigned ("line", sym->line ());
  uiout->field_string ("name", sym->print_name ());

  if (kind == FUNCTIONS_DOMAIN || kind == VARIABLES_DOMAIN)
    {
      string_file tmp_stream;
      type_print (sym->type (), "", &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 = msymbol.objfile->arch ();
  ui_out_emit_tuple tuple_emitter (uiout, NULL);

  uiout->field_core_addr ("address", gdbarch,
			  msymbol.value_address ());
  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 = symbols[i].symbol->symtab ();
	  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
		  && symbols[i].symbol->symtab () == 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 (const char *arg)
{
  char *ptr;
  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,
				const char *const *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;
  const 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 = first_result_symbol->symtab ();

  /* 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 == iter->second.symbol->symtab ());
       ++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,
					const char *const *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;
  const 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, const char *const *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,
				     const char *const *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,
				     const char *const *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, const char *const *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;
  const 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, const char *const *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;
  const 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, const char *const *argv,
			      int argc)
{
  mi_info_functions_or_variables (VARIABLES_DOMAIN, argv, argc);
}
