xref: /netbsd-src/external/gpl3/gdb.old/dist/gdb/macrocmd.c (revision 8b657b0747480f8989760d71343d6dd33f8d4cf9)
1 /* C preprocessor macro expansion commands for GDB.
2    Copyright (C) 2002-2023 Free Software Foundation, Inc.
3    Contributed by Red Hat, Inc.
4 
5    This file is part of GDB.
6 
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11 
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16 
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19 
20 
21 #include "defs.h"
22 #include "macrotab.h"
23 #include "macroexp.h"
24 #include "macroscope.h"
25 #include "cli/cli-style.h"
26 #include "cli/cli-utils.h"
27 #include "command.h"
28 #include "gdbcmd.h"
29 #include "linespec.h"
30 
31 
32 /* The `macro' prefix command.  */
33 
34 static struct cmd_list_element *macrolist;
35 
36 
37 /* Macro expansion commands.  */
38 
39 
40 /* Prints an informational message regarding the lack of macro information.  */
41 static void
42 macro_inform_no_debuginfo (void)
43 {
44   gdb_puts ("GDB has no preprocessor macro information for that code.\n");
45 }
46 
47 static void
48 macro_expand_command (const char *exp, int from_tty)
49 {
50   /* You know, when the user doesn't specify any expression, it would be
51      really cool if this defaulted to the last expression evaluated.
52      Then it would be easy to ask, "Hey, what did I just evaluate?"  But
53      at the moment, the `print' commands don't save the last expression
54      evaluated, just its value.  */
55   if (! exp || ! *exp)
56     error (_("You must follow the `macro expand' command with the"
57 	   " expression you\n"
58 	   "want to expand."));
59 
60   gdb::unique_xmalloc_ptr<macro_scope> ms = default_macro_scope ();
61 
62   if (ms != nullptr)
63     {
64       gdb::unique_xmalloc_ptr<char> expanded = macro_expand (exp, *ms);
65 
66       gdb_puts ("expands to: ");
67       gdb_puts (expanded.get ());
68       gdb_puts ("\n");
69     }
70   else
71     macro_inform_no_debuginfo ();
72 }
73 
74 
75 static void
76 macro_expand_once_command (const char *exp, int from_tty)
77 {
78   /* You know, when the user doesn't specify any expression, it would be
79      really cool if this defaulted to the last expression evaluated.
80      And it should set the once-expanded text as the new `last
81      expression'.  That way, you could just hit return over and over and
82      see the expression expanded one level at a time.  */
83   if (! exp || ! *exp)
84     error (_("You must follow the `macro expand-once' command with"
85 	   " the expression\n"
86 	   "you want to expand."));
87 
88   gdb::unique_xmalloc_ptr<macro_scope> ms = default_macro_scope ();
89 
90   if (ms != nullptr)
91     {
92       gdb::unique_xmalloc_ptr<char> expanded = macro_expand_once (exp, *ms);
93 
94       gdb_puts ("expands to: ");
95       gdb_puts (expanded.get ());
96       gdb_puts ("\n");
97     }
98   else
99     macro_inform_no_debuginfo ();
100 }
101 
102 /*  Outputs the include path of a macro starting at FILE and LINE to STREAM.
103 
104     Care should be taken that this function does not cause any lookups into
105     the splay tree so that it can be safely used while iterating.  */
106 static void
107 show_pp_source_pos (struct ui_file *stream,
108 		    struct macro_source_file *file,
109 		    int line)
110 {
111   std::string fullname = macro_source_fullname (file);
112   gdb_printf (stream, "%ps:%d\n",
113 	      styled_string (file_name_style.style (),
114 			     fullname.c_str ()),
115 	      line);
116 
117   while (file->included_by)
118     {
119       fullname = macro_source_fullname (file->included_by);
120       gdb_puts (_("  included at "), stream);
121       fputs_styled (fullname.c_str (), file_name_style.style (), stream);
122       gdb_printf (stream, ":%d\n", file->included_at_line);
123       file = file->included_by;
124     }
125 }
126 
127 /* Outputs a macro for human consumption, detailing the include path
128    and macro definition.  NAME is the name of the macro.
129    D the definition.  FILE the start of the include path, and LINE the
130    line number in FILE.
131 
132    Care should be taken that this function does not cause any lookups into
133    the splay tree so that it can be safely used while iterating.  */
134 static void
135 print_macro_definition (const char *name,
136 			const struct macro_definition *d,
137 			struct macro_source_file *file,
138 			int line)
139 {
140   gdb_printf ("Defined at ");
141   show_pp_source_pos (gdb_stdout, file, line);
142 
143   if (line != 0)
144     gdb_printf ("#define %s", name);
145   else
146     gdb_printf ("-D%s", name);
147 
148   if (d->kind == macro_function_like)
149     {
150       int i;
151 
152       gdb_puts ("(");
153       for (i = 0; i < d->argc; i++)
154 	{
155 	  gdb_puts (d->argv[i]);
156 	  if (i + 1 < d->argc)
157 	    gdb_puts (", ");
158 	}
159       gdb_puts (")");
160     }
161 
162   if (line != 0)
163     gdb_printf (" %s\n", d->replacement);
164   else
165     gdb_printf ("=%s\n", d->replacement);
166 }
167 
168 /* The implementation of the `info macro' command.  */
169 static void
170 info_macro_command (const char *args, int from_tty)
171 {
172   gdb::unique_xmalloc_ptr<struct macro_scope> ms;
173   const char *name;
174   int show_all_macros_named = 0;
175   const char *arg_start = args;
176   int processing_args = 1;
177 
178   while (processing_args
179 	 && arg_start && *arg_start == '-' && *arg_start != '\0')
180     {
181       const char *p = skip_to_space (arg_start);
182 
183       if (strncmp (arg_start, "-a", p - arg_start) == 0
184 	  || strncmp (arg_start, "-all", p - arg_start) == 0)
185 	show_all_macros_named = 1;
186       else if (strncmp (arg_start, "--", p - arg_start) == 0)
187 	  /* Our macro support seems rather C specific but this would
188 	     seem necessary for languages allowing - in macro names.
189 	     e.g. Scheme's (defmacro ->foo () "bar\n")  */
190 	processing_args = 0;
191       else
192 	report_unrecognized_option_error ("info macro", arg_start);
193 
194       arg_start = skip_spaces (p);
195     }
196 
197   name = arg_start;
198 
199   if (! name || ! *name)
200     error (_("You must follow the `info macro' command with the name"
201 	     " of the macro\n"
202 	     "whose definition you want to see."));
203 
204   ms = default_macro_scope ();
205 
206   if (! ms)
207     macro_inform_no_debuginfo ();
208   else if (show_all_macros_named)
209     macro_for_each (ms->file->table, [&] (const char *macro_name,
210 					  const macro_definition *macro,
211 					  macro_source_file *source,
212 					  int line)
213       {
214 	if (strcmp (name, macro_name) == 0)
215 	  print_macro_definition (name, macro, source, line);
216       });
217   else
218     {
219       struct macro_definition *d;
220 
221       d = macro_lookup_definition (ms->file, ms->line, name);
222       if (d)
223 	{
224 	  int line;
225 	  struct macro_source_file *file
226 	    = macro_definition_location (ms->file, ms->line, name, &line);
227 
228 	  print_macro_definition (name, d, file, line);
229 	}
230       else
231 	{
232 	  gdb_printf ("The symbol `%s' has no definition as a C/C++"
233 		      " preprocessor macro\n"
234 		      "at ", name);
235 	  show_pp_source_pos (gdb_stdout, ms->file, ms->line);
236 	}
237     }
238 }
239 
240 /* Implementation of the "info macros" command. */
241 static void
242 info_macros_command (const char *args, int from_tty)
243 {
244   gdb::unique_xmalloc_ptr<struct macro_scope> ms;
245 
246   if (args == NULL)
247     ms = default_macro_scope ();
248   else
249     {
250       std::vector<symtab_and_line> sals
251 	= decode_line_with_current_source (args, 0);
252 
253       if (!sals.empty ())
254 	ms = sal_macro_scope (sals[0]);
255     }
256 
257   if (! ms || ! ms->file || ! ms->file->table)
258     macro_inform_no_debuginfo ();
259   else
260     macro_for_each_in_scope (ms->file, ms->line, print_macro_definition);
261 }
262 
263 
264 /* User-defined macros.  */
265 
266 static void
267 skip_ws (const char **expp)
268 {
269   while (macro_is_whitespace (**expp))
270     ++*expp;
271 }
272 
273 /* Try to find the bounds of an identifier.  If an identifier is
274    found, returns a newly allocated string; otherwise returns NULL.
275    EXPP is a pointer to an input string; it is updated to point to the
276    text following the identifier.  If IS_PARAMETER is true, this
277    function will also allow "..." forms as used in varargs macro
278    parameters.  */
279 
280 static gdb::unique_xmalloc_ptr<char>
281 extract_identifier (const char **expp, int is_parameter)
282 {
283   char *result;
284   const char *p = *expp;
285   unsigned int len;
286 
287   if (is_parameter && startswith (p, "..."))
288     {
289       /* Ok.  */
290     }
291   else
292     {
293       if (! *p || ! macro_is_identifier_nondigit (*p))
294 	return NULL;
295       for (++p;
296 	   *p && (macro_is_identifier_nondigit (*p) || macro_is_digit (*p));
297 	   ++p)
298 	;
299     }
300 
301   if (is_parameter && startswith (p, "..."))
302     p += 3;
303 
304   len = p - *expp;
305   result = (char *) xmalloc (len + 1);
306   memcpy (result, *expp, len);
307   result[len] = '\0';
308   *expp += len;
309   return gdb::unique_xmalloc_ptr<char> (result);
310 }
311 
312 struct temporary_macro_definition : public macro_definition
313 {
314   temporary_macro_definition ()
315   {
316     table = nullptr;
317     kind = macro_object_like;
318     argc = 0;
319     argv = nullptr;
320     replacement = nullptr;
321   }
322 
323   ~temporary_macro_definition ()
324   {
325     int i;
326 
327     for (i = 0; i < argc; ++i)
328       xfree ((char *) argv[i]);
329     xfree ((char *) argv);
330     /* Note that the 'replacement' field is not allocated.  */
331   }
332 };
333 
334 static void
335 macro_define_command (const char *exp, int from_tty)
336 {
337   temporary_macro_definition new_macro;
338 
339   if (!exp)
340     error (_("usage: macro define NAME[(ARGUMENT-LIST)] [REPLACEMENT-LIST]"));
341 
342   skip_ws (&exp);
343   gdb::unique_xmalloc_ptr<char> name = extract_identifier (&exp, 0);
344   if (name == NULL)
345     error (_("Invalid macro name."));
346   if (*exp == '(')
347     {
348       /* Function-like macro.  */
349       int alloced = 5;
350       char **argv = XNEWVEC (char *, alloced);
351 
352       new_macro.kind = macro_function_like;
353       new_macro.argc = 0;
354       new_macro.argv = (const char * const *) argv;
355 
356       /* Skip the '(' and whitespace.  */
357       ++exp;
358       skip_ws (&exp);
359 
360       while (*exp != ')')
361 	{
362 	  int i;
363 
364 	  if (new_macro.argc == alloced)
365 	    {
366 	      alloced *= 2;
367 	      argv = (char **) xrealloc (argv, alloced * sizeof (char *));
368 	      /* Must update new_macro as well...  */
369 	      new_macro.argv = (const char * const *) argv;
370 	    }
371 	  argv[new_macro.argc] = extract_identifier (&exp, 1).release ();
372 	  if (! argv[new_macro.argc])
373 	    error (_("Macro is missing an argument."));
374 	  ++new_macro.argc;
375 
376 	  for (i = new_macro.argc - 2; i >= 0; --i)
377 	    {
378 	      if (! strcmp (argv[i], argv[new_macro.argc - 1]))
379 		error (_("Two macro arguments with identical names."));
380 	    }
381 
382 	  skip_ws (&exp);
383 	  if (*exp == ',')
384 	    {
385 	      ++exp;
386 	      skip_ws (&exp);
387 	    }
388 	  else if (*exp != ')')
389 	    error (_("',' or ')' expected at end of macro arguments."));
390 	}
391       /* Skip the closing paren.  */
392       ++exp;
393       skip_ws (&exp);
394 
395       macro_define_function (macro_main (macro_user_macros), -1, name.get (),
396 			     new_macro.argc, (const char **) new_macro.argv,
397 			     exp);
398     }
399   else
400     {
401       skip_ws (&exp);
402       macro_define_object (macro_main (macro_user_macros), -1, name.get (),
403 			   exp);
404     }
405 }
406 
407 
408 static void
409 macro_undef_command (const char *exp, int from_tty)
410 {
411   if (!exp)
412     error (_("usage: macro undef NAME"));
413 
414   skip_ws (&exp);
415   gdb::unique_xmalloc_ptr<char> name = extract_identifier (&exp, 0);
416   if (name == nullptr)
417     error (_("Invalid macro name."));
418   macro_undef (macro_main (macro_user_macros), -1, name.get ());
419 }
420 
421 
422 static void
423 print_one_macro (const char *name, const struct macro_definition *macro,
424 		 struct macro_source_file *source, int line)
425 {
426   gdb_printf ("macro define %s", name);
427   if (macro->kind == macro_function_like)
428     {
429       int i;
430 
431       gdb_printf ("(");
432       for (i = 0; i < macro->argc; ++i)
433 	gdb_printf ("%s%s", (i > 0) ? ", " : "",
434 			 macro->argv[i]);
435       gdb_printf (")");
436     }
437   gdb_printf (" %s\n", macro->replacement);
438 }
439 
440 
441 static void
442 macro_list_command (const char *exp, int from_tty)
443 {
444   macro_for_each (macro_user_macros, print_one_macro);
445 }
446 
447 /* Initializing the `macrocmd' module.  */
448 
449 void _initialize_macrocmd ();
450 void
451 _initialize_macrocmd ()
452 {
453   /* We introduce a new command prefix, `macro', under which we'll put
454      the various commands for working with preprocessor macros.  */
455   add_basic_prefix_cmd ("macro", class_info,
456 			_("Prefix for commands dealing with C preprocessor macros."),
457 			&macrolist, 0, &cmdlist);
458 
459   cmd_list_element *macro_expand_cmd
460     = add_cmd ("expand", no_class, macro_expand_command, _("\
461 Fully expand any C/C++ preprocessor macro invocations in EXPRESSION.\n\
462 Show the expanded expression."),
463 	       &macrolist);
464   add_alias_cmd ("exp", macro_expand_cmd, no_class, 1, &macrolist);
465 
466   cmd_list_element *macro_expand_once_cmd
467     = add_cmd ("expand-once", no_class, macro_expand_once_command, _("\
468 Expand C/C++ preprocessor macro invocations appearing directly in EXPRESSION.\n\
469 Show the expanded expression.\n\
470 \n\
471 This command differs from `macro expand' in that it only expands macro\n\
472 invocations that appear directly in EXPRESSION; if expanding a macro\n\
473 introduces further macro invocations, those are left unexpanded.\n\
474 \n\
475 `macro expand-once' helps you see how a particular macro expands,\n\
476 whereas `macro expand' shows you how all the macros involved in an\n\
477 expression work together to yield a pre-processed expression."),
478 	       &macrolist);
479   add_alias_cmd ("exp1", macro_expand_once_cmd, no_class, 1, &macrolist);
480 
481   add_info ("macro", info_macro_command,
482 	    _("Show the definition of MACRO, and it's source location.\n\
483 Usage: info macro [-a|-all] [--] MACRO\n\
484 Options: \n\
485   -a, --all    Output all definitions of MACRO in the current compilation\
486  unit.\n\
487   --           Specify the end of arguments and the beginning of the MACRO."));
488 
489   add_info ("macros", info_macros_command,
490 	    _("Show the definitions of all macros at LINESPEC, or the current \
491 source location.\n\
492 Usage: info macros [LINESPEC]"));
493 
494   add_cmd ("define", no_class, macro_define_command, _("\
495 Define a new C/C++ preprocessor macro.\n\
496 The GDB command `macro define DEFINITION' is equivalent to placing a\n\
497 preprocessor directive of the form `#define DEFINITION' such that the\n\
498 definition is visible in all the inferior's source files.\n\
499 For example:\n\
500   (gdb) macro define PI (3.1415926)\n\
501   (gdb) macro define MIN(x,y) ((x) < (y) ? (x) : (y))"),
502 	   &macrolist);
503 
504   add_cmd ("undef", no_class, macro_undef_command, _("\
505 Remove the definition of the C/C++ preprocessor macro with the given name."),
506 	   &macrolist);
507 
508   add_cmd ("list", no_class, macro_list_command,
509 	   _("List all the macros defined using the `macro define' command."),
510 	   &macrolist);
511 }
512