/* C preprocessor macro expansion commands for GDB.
   Copyright (C) 2002-2020 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 "defs.h"
#include "macrotab.h"
#include "macroexp.h"
#include "macroscope.h"
#include "cli/cli-style.h"
#include "cli/cli-utils.h"
#include "command.h"
#include "gdbcmd.h"
#include "linespec.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)
{
  puts_filtered ("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."));

  gdb::unique_xmalloc_ptr<macro_scope> ms = default_macro_scope ();

  if (ms != nullptr)
    {
      gdb::unique_xmalloc_ptr<char> expanded = macro_expand (exp, *ms);

      fputs_filtered ("expands to: ", gdb_stdout);
      fputs_filtered (expanded.get (), gdb_stdout);
      fputs_filtered ("\n", gdb_stdout);
    }
  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."));

  gdb::unique_xmalloc_ptr<macro_scope> ms = default_macro_scope ();

  if (ms != nullptr)
    {
      gdb::unique_xmalloc_ptr<char> expanded = macro_expand_once (exp, *ms);

      fputs_filtered ("expands to: ", gdb_stdout);
      fputs_filtered (expanded.get (), gdb_stdout);
      fputs_filtered ("\n", gdb_stdout);
    }
  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);
  fprintf_filtered (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);
      fputs_filtered (_("  included at "), stream);
      fputs_styled (fullname.c_str (), file_name_style.style (), stream);
      fprintf_filtered (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)
{
  fprintf_filtered (gdb_stdout, "Defined at ");
  show_pp_source_pos (gdb_stdout, file, line);

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

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

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

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

/* The implementation of the `info macro' command.  */
static void
info_macro_command (const char *args, int from_tty)
{
  gdb::unique_xmalloc_ptr<struct macro_scope> ms;
  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."));

  ms = default_macro_scope ();

  if (! ms)
    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
        {
          fprintf_filtered (gdb_stdout,
                            "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)
{
  gdb::unique_xmalloc_ptr<struct 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 || ! ms->file || ! ms->file->table)
    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, returns a newly allocated string; otherwise returns NULL.
   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 gdb::unique_xmalloc_ptr<char>
extract_identifier (const char **expp, int is_parameter)
{
  char *result;
  const char *p = *expp;
  unsigned int len;

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

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

  len = p - *expp;
  result = (char *) xmalloc (len + 1);
  memcpy (result, *expp, len);
  result[len] = '\0';
  *expp += len;
  return gdb::unique_xmalloc_ptr<char> (result);
}

struct temporary_macro_definition : public macro_definition
{
  temporary_macro_definition ()
  {
    table = nullptr;
    kind = macro_object_like;
    argc = 0;
    argv = nullptr;
    replacement = nullptr;
  }

  ~temporary_macro_definition ()
  {
    int i;

    for (i = 0; i < argc; ++i)
      xfree ((char *) argv[i]);
    xfree ((char *) argv);
    /* Note that the 'replacement' field is not allocated.  */
  }
};

static void
macro_define_command (const char *exp, int from_tty)
{
  temporary_macro_definition new_macro;

  if (!exp)
    error (_("usage: macro define NAME[(ARGUMENT-LIST)] [REPLACEMENT-LIST]"));

  skip_ws (&exp);
  gdb::unique_xmalloc_ptr<char> name = extract_identifier (&exp, 0);
  if (name == NULL)
    error (_("Invalid macro name."));
  if (*exp == '(')
    {
      /* Function-like macro.  */
      int alloced = 5;
      char **argv = XNEWVEC (char *, alloced);

      new_macro.kind = macro_function_like;
      new_macro.argc = 0;
      new_macro.argv = (const char * const *) argv;

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

      while (*exp != ')')
	{
	  int i;

	  if (new_macro.argc == alloced)
	    {
	      alloced *= 2;
	      argv = (char **) xrealloc (argv, alloced * sizeof (char *));
	      /* Must update new_macro as well...  */
	      new_macro.argv = (const char * const *) argv;
	    }
	  argv[new_macro.argc] = extract_identifier (&exp, 1).release ();
	  if (! argv[new_macro.argc])
	    error (_("Macro is missing an argument."));
	  ++new_macro.argc;

	  for (i = new_macro.argc - 2; i >= 0; --i)
	    {
	      if (! strcmp (argv[i], argv[new_macro.argc - 1]))
		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.get (),
			     new_macro.argc, (const char **) new_macro.argv,
			     exp);
    }
  else
    {
      skip_ws (&exp);
      macro_define_object (macro_main (macro_user_macros), -1, name.get (),
			   exp);
    }
}


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

  skip_ws (&exp);
  gdb::unique_xmalloc_ptr<char> name = extract_identifier (&exp, 0);
  if (name == nullptr)
    error (_("Invalid macro name."));
  macro_undef (macro_main (macro_user_macros), -1, name.get ());
}


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

      fprintf_filtered (gdb_stdout, "(");
      for (i = 0; i < macro->argc; ++i)
	fprintf_filtered (gdb_stdout, "%s%s", (i > 0) ? ", " : "",
			  macro->argv[i]);
      fprintf_filtered (gdb_stdout, ")");
    }
  fprintf_filtered (gdb_stdout, " %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.  */

void _initialize_macrocmd ();
void
_initialize_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, "macro ", 0, &cmdlist);

  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", "expand", no_class, 1, &macrolist);
  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", "expand-once", 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);
}
