/* C preprocessor macro expansion commands for GDB.
   Copyright (C) 2002-2025 Free Software Foundation, Inc.
   Contributed by Red Hat, 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 "macrotab.h"
#include "macroexp.h"
#include "macroscope.h"
#include "cli/cli-style.h"
#include "cli/cli-utils.h"
#include "command.h"
#include "cli/cli-cmds.h"
#include "linespec.h"
#include "ui-out.h"


/* The `macro' prefix command.  */

static struct cmd_list_element *macrolist;


/* Macro expansion commands.  */


/* Prints an informational message regarding the lack of macro information.  */
static void
macro_inform_no_debuginfo (void)
{
  gdb_puts ("GDB has no preprocessor macro information for that code.\n");
}

static void
macro_expand_command (const char *exp, int from_tty)
{
  /* You know, when the user doesn't specify any expression, it would be
     really cool if this defaulted to the last expression evaluated.
     Then it would be easy to ask, "Hey, what did I just evaluate?"  But
     at the moment, the `print' commands don't save the last expression
     evaluated, just its value.  */
  if (! exp || ! *exp)
    error (_("You must follow the `macro expand' command with the"
	   " expression you\n"
	   "want to expand."));

  macro_scope ms = default_macro_scope ();

  if (ms.is_valid ())
    {
      gdb::unique_xmalloc_ptr<char> expanded = macro_expand (exp, ms);

      gdb_puts ("expands to: ");
      gdb_puts (expanded.get ());
      gdb_puts ("\n");
    }
  else
    macro_inform_no_debuginfo ();
}


static void
macro_expand_once_command (const char *exp, int from_tty)
{
  /* You know, when the user doesn't specify any expression, it would be
     really cool if this defaulted to the last expression evaluated.
     And it should set the once-expanded text as the new `last
     expression'.  That way, you could just hit return over and over and
     see the expression expanded one level at a time.  */
  if (! exp || ! *exp)
    error (_("You must follow the `macro expand-once' command with"
	   " the expression\n"
	   "you want to expand."));

  macro_scope ms = default_macro_scope ();

  if (ms.is_valid ())
    {
      gdb::unique_xmalloc_ptr<char> expanded = macro_expand_once (exp, ms);

      gdb_puts ("expands to: ");
      gdb_puts (expanded.get ());
      gdb_puts ("\n");
    }
  else
    macro_inform_no_debuginfo ();
}

/*  Outputs the include path of a macro starting at FILE and LINE to STREAM.

    Care should be taken that this function does not cause any lookups into
    the splay tree so that it can be safely used while iterating.  */
static void
show_pp_source_pos (struct ui_file *stream,
		    struct macro_source_file *file,
		    int line)
{
  std::string fullname = macro_source_fullname (file);
  gdb_printf (stream, "%ps:%d\n",
	      styled_string (file_name_style.style (),
			     fullname.c_str ()),
	      line);

  while (file->included_by)
    {
      fullname = macro_source_fullname (file->included_by);
      gdb_puts (_("  included at "), stream);
      fputs_styled (fullname.c_str (), file_name_style.style (), stream);
      gdb_printf (stream, ":%d\n", file->included_at_line);
      file = file->included_by;
    }
}

/* Outputs a macro for human consumption, detailing the include path
   and macro definition.  NAME is the name of the macro.
   D the definition.  FILE the start of the include path, and LINE the
   line number in FILE.

   Care should be taken that this function does not cause any lookups into
   the splay tree so that it can be safely used while iterating.  */
static void
print_macro_definition (const char *name,
			const struct macro_definition *d,
			struct macro_source_file *file,
			int line)
{
  gdb_printf ("Defined at ");
  show_pp_source_pos (gdb_stdout, file, line);

  if (line != 0)
    gdb_printf ("#define %s", name);
  else
    gdb_printf ("-D%s", name);

  if (d->kind == macro_function_like)
    {
      int i;

      gdb_puts ("(");
      for (i = 0; i < d->argc; i++)
	{
	  gdb_puts (d->argv[i]);
	  if (i + 1 < d->argc)
	    gdb_puts (", ");
	}
      gdb_puts (")");
    }

  if (line != 0)
    gdb_printf (" %s\n", d->replacement);
  else
    gdb_printf ("=%s\n", d->replacement);
}

/* The implementation of the `info macro' command.  */
static void
info_macro_command (const char *args, int from_tty)
{
  const char *name;
  int show_all_macros_named = 0;
  const char *arg_start = args;
  int processing_args = 1;

  while (processing_args
	 && arg_start && *arg_start == '-' && *arg_start != '\0')
    {
      const char *p = skip_to_space (arg_start);

      if (strncmp (arg_start, "-a", p - arg_start) == 0
	  || strncmp (arg_start, "-all", p - arg_start) == 0)
	show_all_macros_named = 1;
      else if (strncmp (arg_start, "--", p - arg_start) == 0)
	  /* Our macro support seems rather C specific but this would
	     seem necessary for languages allowing - in macro names.
	     e.g. Scheme's (defmacro ->foo () "bar\n")  */
	processing_args = 0;
      else
	report_unrecognized_option_error ("info macro", arg_start);

      arg_start = skip_spaces (p);
    }

  name = arg_start;

  if (! name || ! *name)
    error (_("You must follow the `info macro' command with the name"
	     " of the macro\n"
	     "whose definition you want to see."));

  macro_scope ms = default_macro_scope ();

  if (!ms.is_valid ())
    macro_inform_no_debuginfo ();
  else if (show_all_macros_named)
    macro_for_each (ms.file->table, [&] (const char *macro_name,
					 const macro_definition *macro,
					 macro_source_file *source,
					 int line)
      {
	if (strcmp (name, macro_name) == 0)
	  print_macro_definition (name, macro, source, line);
      });
  else
    {
      struct macro_definition *d;

      d = macro_lookup_definition (ms.file, ms.line, name);
      if (d)
	{
	  int line;
	  struct macro_source_file *file
	    = macro_definition_location (ms.file, ms.line, name, &line);

	  print_macro_definition (name, d, file, line);
	}
      else
	{
	  gdb_printf ("The symbol `%s' has no definition as a C/C++"
		      " preprocessor macro\n"
		      "at ", name);
	  show_pp_source_pos (gdb_stdout, ms.file, ms.line);
	}
    }
}

/* Implementation of the "info macros" command. */
static void
info_macros_command (const char *args, int from_tty)
{
  macro_scope ms;

  if (args == NULL)
    ms = default_macro_scope ();
  else
    {
      std::vector<symtab_and_line> sals
	= decode_line_with_current_source (args, 0);

      if (!sals.empty ())
	ms = sal_macro_scope (sals[0]);
    }

  if (!ms.is_valid () || ms.file->table == nullptr)
    macro_inform_no_debuginfo ();
  else
    macro_for_each_in_scope (ms.file, ms.line, print_macro_definition);
}


/* User-defined macros.  */

static void
skip_ws (const char **expp)
{
  while (macro_is_whitespace (**expp))
    ++*expp;
}

/* Try to find the bounds of an identifier.  If an identifier is
   found, return it; otherwise return an empty string.

   EXPP is a pointer to an input string; it is updated to point to the
   text following the identifier.  If IS_PARAMETER is true, this
   function will also allow "..." forms as used in varargs macro
   parameters.  */

static std::string
extract_identifier (const char **expp, int is_parameter)
{
  const char *p = *expp;

  if (is_parameter && startswith (p, "..."))
    {
      /* Ok.  */
    }
  else
    {
      if (! *p || ! macro_is_identifier_nondigit (*p))
	return {};

      for (++p;
	   *p && (macro_is_identifier_nondigit (*p) || macro_is_digit (*p));
	   ++p)
	;
    }

  if (is_parameter && startswith (p, "..."))
    p += 3;

  std::string result (*expp, p);
  *expp = p;

  return result;
}

static void
macro_define_command (const char *exp, int from_tty)
{
  if (!exp)
    error (_("usage: macro define NAME[(ARGUMENT-LIST)] [REPLACEMENT-LIST]"));

  skip_ws (&exp);

  std::string name = extract_identifier (&exp, 0);
  if (name.empty ())
    error (_("Invalid macro name."));

  if (*exp == '(')
    {
      /* Function-like macro.  */
      std::vector<std::string> argv;

      /* Skip the '(' and whitespace.  */
      ++exp;
      skip_ws (&exp);

      while (*exp != ')')
	{
	  argv.emplace_back (extract_identifier (&exp, 1));
	  if (argv.back ().empty ())
	    error (_("Macro is missing an argument."));

	  for (const auto &other_arg : argv)
	    {
	      if (&other_arg != &argv.back () && other_arg == argv.back ())
		error (_("Two macro arguments with identical names."));
	    }

	  skip_ws (&exp);
	  if (*exp == ',')
	    {
	      ++exp;
	      skip_ws (&exp);
	    }
	  else if (*exp != ')')
	    error (_("',' or ')' expected at end of macro arguments."));
	}

      /* Skip the closing paren.  */
      ++exp;
      skip_ws (&exp);

      macro_define_function (macro_main (macro_user_macros), -1, name.c_str (),
			     argv, exp);
    }
  else
    {
      skip_ws (&exp);
      macro_define_object (macro_main (macro_user_macros), -1, name.c_str (),
			   exp);
    }
}


static void
macro_undef_command (const char *exp, int from_tty)
{
  if (!exp)
    error (_("usage: macro undef NAME"));

  skip_ws (&exp);

  std::string name = extract_identifier (&exp, 0);
  if (name.empty ())
    error (_("Invalid macro name."));

  macro_undef (macro_main (macro_user_macros), -1, name.c_str ());
}


static void
print_one_macro (const char *name, const struct macro_definition *macro,
		 struct macro_source_file *source, int line)
{
  gdb_printf ("macro define %s", name);
  if (macro->kind == macro_function_like)
    {
      int i;

      gdb_printf ("(");
      for (i = 0; i < macro->argc; ++i)
	gdb_printf ("%s%s", (i > 0) ? ", " : "",
			 macro->argv[i]);
      gdb_printf (")");
    }
  gdb_printf (" %s\n", macro->replacement);
}


static void
macro_list_command (const char *exp, int from_tty)
{
  macro_for_each (macro_user_macros, print_one_macro);
}

/* Initializing the `macrocmd' module.  */

INIT_GDB_FILE (macrocmd)
{
  /* We introduce a new command prefix, `macro', under which we'll put
     the various commands for working with preprocessor macros.  */
  add_basic_prefix_cmd ("macro", class_info,
			_("Prefix for commands dealing with C preprocessor macros."),
			&macrolist, 0, &cmdlist);

  cmd_list_element *macro_expand_cmd
    = add_cmd ("expand", no_class, macro_expand_command, _("\
Fully expand any C/C++ preprocessor macro invocations in EXPRESSION.\n\
Show the expanded expression."),
	       &macrolist);
  add_alias_cmd ("exp", macro_expand_cmd, no_class, 1, &macrolist);

  cmd_list_element *macro_expand_once_cmd
    = add_cmd ("expand-once", no_class, macro_expand_once_command, _("\
Expand C/C++ preprocessor macro invocations appearing directly in EXPRESSION.\n\
Show the expanded expression.\n\
\n\
This command differs from `macro expand' in that it only expands macro\n\
invocations that appear directly in EXPRESSION; if expanding a macro\n\
introduces further macro invocations, those are left unexpanded.\n\
\n\
`macro expand-once' helps you see how a particular macro expands,\n\
whereas `macro expand' shows you how all the macros involved in an\n\
expression work together to yield a pre-processed expression."),
	       &macrolist);
  add_alias_cmd ("exp1", macro_expand_once_cmd, no_class, 1, &macrolist);

  add_info ("macro", info_macro_command,
	    _("Show the definition of MACRO, and it's source location.\n\
Usage: info macro [-a|-all] [--] MACRO\n\
Options:\n\
  -a, --all    Output all definitions of MACRO in the current compilation\
 unit.\n\
  --           Specify the end of arguments and the beginning of the MACRO."));

  add_info ("macros", info_macros_command,
	    _("Show the definitions of all macros at LINESPEC, or the current \
source location.\n\
Usage: info macros [LINESPEC]"));

  add_cmd ("define", no_class, macro_define_command, _("\
Define a new C/C++ preprocessor macro.\n\
The GDB command `macro define DEFINITION' is equivalent to placing a\n\
preprocessor directive of the form `#define DEFINITION' such that the\n\
definition is visible in all the inferior's source files.\n\
For example:\n\
  (gdb) macro define PI (3.1415926)\n\
  (gdb) macro define MIN(x,y) ((x) < (y) ? (x) : (y))"),
	   &macrolist);

  add_cmd ("undef", no_class, macro_undef_command, _("\
Remove the definition of the C/C++ preprocessor macro with the given name."),
	   &macrolist);

  add_cmd ("list", no_class, macro_list_command,
	   _("List all the macros defined using the `macro define' command."),
	   &macrolist);
}
