Simplify macro_define_command

Message ID 20240422154923.1601231-1-tromey@adacore.com
State New
Headers
Series Simplify macro_define_command |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_gdb_build--master-aarch64 success Testing passed
linaro-tcwg-bot/tcwg_gdb_build--master-arm success Testing passed
linaro-tcwg-bot/tcwg_gdb_check--master-arm success Testing passed
linaro-tcwg-bot/tcwg_gdb_check--master-aarch64 success Testing passed

Commit Message

Tom Tromey April 22, 2024, 3:49 p.m. UTC
  This simplifies macro_define_command, using std::vector to remove some
manual memory management.  temporary_macro_definition is also
simplified -- much of the code there was simply unnecessary.

Regression tested on x86-64 Fedora 38.
---
 gdb/macrocmd.c | 55 +++++++++++++++-----------------------------------
 1 file changed, 16 insertions(+), 39 deletions(-)
  

Comments

Simon Marchi April 22, 2024, 4:46 p.m. UTC | #1
On 4/22/24 11:49 AM, Tom Tromey wrote:
> This simplifies macro_define_command, using std::vector to remove some
> manual memory management.  temporary_macro_definition is also
> simplified -- much of the code there was simply unnecessary.
> 
> Regression tested on x86-64 Fedora 38.
> ---
>  gdb/macrocmd.c | 55 +++++++++++++++-----------------------------------
>  1 file changed, 16 insertions(+), 39 deletions(-)
> 
> diff --git a/gdb/macrocmd.c b/gdb/macrocmd.c
> index ddabfede0f5..0d0db5d1b90 100644
> --- a/gdb/macrocmd.c
> +++ b/gdb/macrocmd.c
> @@ -308,33 +308,24 @@ extract_identifier (const char **expp, int is_parameter)
>    return gdb::unique_xmalloc_ptr<char> (result);
>  }
>  
> -struct temporary_macro_definition : public macro_definition
> +struct temporary_macro_definition
>  {
> -  temporary_macro_definition ()
> +  ~temporary_macro_definition ()
>    {
> -    table = nullptr;
> -    kind = macro_object_like;
> -    argc = 0;
> -    argv = nullptr;
> -    replacement = nullptr;
> +    free_vector_argv (argv);
>    }

Since this structure has a destructor, perhaps make it
non-copyable/assignable/etc (rule of 3/5)?

It could be a subsequent cleanup, but that class could have a more
general name and live in gdbsupport/common-utils.h.  It could then be
used by other current users of free_vector_argv.

> @@ -358,26 +343,18 @@ macro_define_command (const char *exp, int from_tty)
>  
>        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])
> +	  auto arg = extract_identifier (&exp, 1);
> +	  if (! arg)

arg == nullptr

>  	    error (_("Macro is missing an argument."));
> -	  ++new_macro.argc;
>  
> -	  for (i = new_macro.argc - 2; i >= 0; --i)
> +	  for (const char *existing : new_macro.argv)
>  	    {
> -	      if (! strcmp (argv[i], argv[new_macro.argc - 1]))
> +	      if (! strcmp (existing, arg.get ()))
>  		error (_("Two macro arguments with identical names."));
>  	    }

You could remove the braces while at it.

Simon
  

Patch

diff --git a/gdb/macrocmd.c b/gdb/macrocmd.c
index ddabfede0f5..0d0db5d1b90 100644
--- a/gdb/macrocmd.c
+++ b/gdb/macrocmd.c
@@ -308,33 +308,24 @@  extract_identifier (const char **expp, int is_parameter)
   return gdb::unique_xmalloc_ptr<char> (result);
 }
 
-struct temporary_macro_definition : public macro_definition
+struct temporary_macro_definition
 {
-  temporary_macro_definition ()
+  ~temporary_macro_definition ()
   {
-    table = nullptr;
-    kind = macro_object_like;
-    argc = 0;
-    argv = nullptr;
-    replacement = nullptr;
+    free_vector_argv (argv);
   }
 
-  ~temporary_macro_definition ()
+  void add_argument (gdb::unique_xmalloc_ptr<char> &&value)
   {
-    int i;
-
-    for (i = 0; i < argc; ++i)
-      xfree ((char *) argv[i]);
-    xfree ((char *) argv);
-    /* Note that the 'replacement' field is not allocated.  */
+    argv.push_back (value.release ());
   }
+
+  std::vector<char *> argv;
 };
 
 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]"));
 
@@ -344,13 +335,7 @@  macro_define_command (const char *exp, int from_tty)
     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;
+      temporary_macro_definition new_macro;
 
       /* Skip the '(' and whitespace.  */
       ++exp;
@@ -358,26 +343,18 @@  macro_define_command (const char *exp, int from_tty)
 
       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])
+	  auto arg = extract_identifier (&exp, 1);
+	  if (! arg)
 	    error (_("Macro is missing an argument."));
-	  ++new_macro.argc;
 
-	  for (i = new_macro.argc - 2; i >= 0; --i)
+	  for (const char *existing : new_macro.argv)
 	    {
-	      if (! strcmp (argv[i], argv[new_macro.argc - 1]))
+	      if (! strcmp (existing, arg.get ()))
 		error (_("Two macro arguments with identical names."));
 	    }
 
+	  new_macro.add_argument (std::move (arg));
+
 	  skip_ws (&exp);
 	  if (*exp == ',')
 	    {
@@ -392,8 +369,8 @@  macro_define_command (const char *exp, int from_tty)
       skip_ws (&exp);
 
       macro_define_function (macro_main (macro_user_macros), -1, name.get (),
-			     new_macro.argc, (const char **) new_macro.argv,
-			     exp);
+			     new_macro.argv.size (),
+			     (const char **) new_macro.argv.data (), exp);
     }
   else
     {