--- /dev/null
+/* C preprocessor macro expansion commands for GDB.
+ Copyright 2002 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 2 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, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+
+#include "defs.h"
+#include "macrotab.h"
+#include "macroexp.h"
+#include "macroscope.h"
+#include "command.h"
+#include "gdbcmd.h"
+
+\f
+/* The `macro' prefix command. */
+
+static struct cmd_list_element *macrolist;
+
+static void
+macro_command (char *arg, int from_tty)
+{
+ printf_unfiltered
+ ("\"macro\" must be followed by the name of a macro command.\n");
+ help_list (macrolist, "macro ", -1, gdb_stdout);
+}
+
+
+\f
+/* Macro expansion commands. */
+
+
+static void
+macro_expand_command (char *exp, int from_tty)
+{
+ struct macro_scope *ms = NULL;
+ char *expanded = NULL;
+ struct cleanup *cleanup_chain = make_cleanup (free_current_contents, &ms);
+ make_cleanup (free_current_contents, &expanded);
+
+ /* 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.");
+
+ ms = default_macro_scope ();
+ if (ms)
+ {
+ expanded = macro_expand (exp, standard_macro_lookup, ms);
+ fputs_filtered ("expands to: ", gdb_stdout);
+ fputs_filtered (expanded, gdb_stdout);
+ fputs_filtered ("\n", gdb_stdout);
+ }
+ else
+ fputs_filtered ("GDB has no preprocessor macro information for "
+ "that code.\n",
+ gdb_stdout);
+
+ do_cleanups (cleanup_chain);
+ return;
+}
+
+
+static void
+macro_expand_once_command (char *exp, int from_tty)
+{
+ struct macro_scope *ms = NULL;
+ char *expanded = NULL;
+ struct cleanup *cleanup_chain = make_cleanup (free_current_contents, &ms);
+ make_cleanup (free_current_contents, &expanded);
+
+ /* 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.");
+
+ ms = default_macro_scope ();
+ if (ms)
+ {
+ expanded = macro_expand_once (exp, standard_macro_lookup, ms);
+ fputs_filtered ("expands to: ", gdb_stdout);
+ fputs_filtered (expanded, gdb_stdout);
+ fputs_filtered ("\n", gdb_stdout);
+ }
+ else
+ fputs_filtered ("GDB has no preprocessor macro information for "
+ "that code.\n",
+ gdb_stdout);
+
+ do_cleanups (cleanup_chain);
+ return;
+}
+
+
+static void
+show_pp_source_pos (struct ui_file *stream,
+ struct macro_source_file *file,
+ int line)
+{
+ fprintf_filtered (stream, "%s:%d\n", file->filename, line);
+
+ while (file->included_by)
+ {
+ fprintf_filtered (gdb_stdout, " included at %s:%d\n",
+ file->included_by->filename,
+ file->included_at_line);
+ file = file->included_by;
+ }
+}
+
+
+static void
+show_macro_command (char *name, int from_tty)
+{
+ struct macro_scope *ms = NULL;
+ struct cleanup *cleanup_chain = make_cleanup (free_current_contents, &ms);
+ struct macro_definition *d;
+
+ if (! name || ! *name)
+ error ("You must follow the `show macro' command with the name"
+ " of the macro\n"
+ "whose definition you want to see.");
+
+ ms = default_macro_scope ();
+ if (! ms)
+ error ("GDB has no preprocessor macro information for that code.\n");
+
+ 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);
+
+ fprintf_filtered (gdb_stdout, "Defined at ");
+ show_pp_source_pos (gdb_stdout, file, line);
+ fprintf_filtered (gdb_stdout, "#define %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);
+ }
+ fprintf_filtered (gdb_stdout, " %s\n", d->replacement);
+ }
+ 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);
+ }
+
+ do_cleanups (cleanup_chain);
+}
+
+
+\f
+/* User-defined macros. */
+
+/* A table of user-defined macros. Unlike the macro tables used for
+ symtabs, this one uses xmalloc for all its allocation, not an
+ obstack, and it doesn't bcache anything; it just xmallocs things. So
+ it's perfectly possible to remove things from this, or redefine
+ things. */
+static struct macro_table *user_macros;
+
+static void
+macro_define_command (char *exp, int from_tty)
+{
+ error ("Command not implemented yet.");
+}
+
+
+static void
+macro_undef_command (char *exp, int from_tty)
+{
+ error ("Command not implemented yet.");
+}
+
+
+static void
+macro_list_command (char *exp, int from_tty)
+{
+ error ("Command not implemented yet.");
+}
+
+
+\f
+/* Initializing the `macrocmd' module. */
+
+void
+_initialize_macrocmd (void)
+{
+ struct cmd_list_element *c;
+
+ /* We introduce a new command prefix, `macro', under which we'll put
+ the various commands for working with preprocessor macros. */
+ add_prefix_cmd
+ ("macro", class_info, macro_command,
+ "Prefix for commands dealing with C preprocessor macros.",
+ ¯olist, "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.",
+ ¯olist);
+ add_alias_cmd ("exp", "expand", no_class, 1, ¯olist);
+ 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.",
+ ¯olist);
+ add_alias_cmd ("exp1", "expand-once", no_class, 1, ¯olist);
+
+ add_cmd
+ ("macro", no_class, show_macro_command,
+ "Show the definition of MACRO, and its source location.",
+ &showlist);
+
+ 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))",
+ ¯olist);
+
+ add_cmd
+ ("undef", no_class, macro_undef_command,
+ "Remove the definition of the C/C++ preprocessor macro with the"
+ " given name.",
+ ¯olist);
+
+ add_cmd
+ ("list", no_class, macro_list_command,
+ "List all the macros defined using the `macro define' command.",
+ ¯olist);
+
+ user_macros = new_macro_table (0, 0);
+}
--- /dev/null
+/* Functions for deciding which macros are currently in scope.
+ Copyright 2002 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 2 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, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include "defs.h"
+
+#include "macroscope.h"
+#include "symtab.h"
+#include "target.h"
+#include "frame.h"
+#include "inferior.h"
+
+
+struct macro_scope *
+sal_macro_scope (struct symtab_and_line sal)
+{
+ struct macro_source_file *main;
+ struct macro_scope *ms;
+
+ if (! sal.symtab
+ || ! sal.symtab->macro_table)
+ return 0;
+
+ ms = (struct macro_scope *) xmalloc (sizeof (*ms));
+
+ main = macro_main (sal.symtab->macro_table);
+ ms->file = macro_lookup_inclusion (main, sal.symtab->filename);
+
+ if (! ms->file)
+ internal_error
+ (__FILE__, __LINE__,
+ "\n"
+ "the symtab `%s' refers to a preprocessor macro table which doesn't\n"
+ "have any record of processing a file by that name.\n",
+ sal.symtab->filename);
+
+ ms->line = sal.line;
+
+ return ms;
+}
+
+
+struct macro_scope *
+default_macro_scope ()
+{
+ struct symtab_and_line sal;
+ struct macro_source_file *main;
+ struct macro_scope *ms;
+
+ /* If there's a selected frame, use its PC. */
+ if (selected_frame)
+ sal = find_pc_line (selected_frame->pc, 0);
+
+ /* If the target has any registers at all, then use its PC. Why we
+ would have registers but no stack, I'm not sure. */
+ else if (target_has_registers)
+ sal = find_pc_line (read_pc (), 0);
+
+ /* If all else fails, fall back to the current listing position. */
+ else
+ {
+ /* Don't call select_source_symtab here. That can raise an
+ error if symbols aren't loaded, but GDB calls the expression
+ evaluator in all sorts of contexts.
+
+ For example, commands like `set width' call the expression
+ evaluator to evaluate their numeric arguments. If the
+ current language is C, then that may call this function to
+ choose a scope for macro expansion. If you don't have any
+ symbol files loaded, then select_source_symtab will raise an
+ error. But `set width' shouldn't raise an error just because
+ it can't decide which scope to macro-expand its argument in. */
+ sal.symtab = current_source_symtab;
+ sal.line = current_source_line;
+ }
+
+ return sal_macro_scope (sal);
+}
+
+
+/* Look up the definition of the macro named NAME in scope at the source
+ location given by BATON, which must be a pointer to a `struct
+ macro_scope' structure. */
+struct macro_definition *
+standard_macro_lookup (const char *name, void *baton)
+{
+ struct macro_scope *ms = (struct macro_scope *) baton;
+
+ return macro_lookup_definition (ms->file, ms->line, name);
+}
--- /dev/null
+/* Interface to functions for deciding which macros are currently in scope.
+ Copyright 2002 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 2 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, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#ifndef MACROSCOPE_H
+#define MACROSCOPE_H
+
+#include "macrotab.h"
+#include "symtab.h"
+
+
+/* All the information we need to decide which macro definitions are
+ in scope: a source file (either a main source file or an
+ #inclusion), and a line number in that file. */
+struct macro_scope {
+ struct macro_source_file *file;
+ int line;
+};
+
+
+/* Return a `struct macro_scope' object corresponding to the symtab
+ and line given in SAL. If we have no macro information for that
+ location, or if SAL's pc is zero, return zero. */
+struct macro_scope *sal_macro_scope (struct symtab_and_line sal);
+
+
+/* Return a `struct macro_scope' object describing the scope the `macro
+ expand' and `macro expand-once' commands should use for looking up
+ macros. If we have a selected frame, this is the source location of
+ its PC; otherwise, this is the last listing position.
+
+ If we have no macro information for the current location, return zero.
+
+ The object returned is allocated using xmalloc; the caller is
+ responsible for freeing it. */
+struct macro_scope *default_macro_scope (void);
+
+
+/* Look up the definition of the macro named NAME in scope at the source
+ location given by BATON, which must be a pointer to a `struct
+ macro_scope' structure. This function is suitable for use as
+ a macro_lookup_ftype function. */
+struct macro_definition *standard_macro_lookup (const char *name, void *baton);
+
+
+#endif /* MACROSCOPE_H */