This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

'eval' command with printf-like args, take 2


On Fri, Feb 22, 2008 at 12:50 AM, Michael Snyder <msnyder@specifix.com> wrote:
>  If you factored out the grow/append functionality, could you
>  do it with more minimal changes to printf_command (or to, say,
 >  printf_command_core()?)
>
>  Aside, is there any reason to put the new command in source.c?
>  Why not keep the code close together by putting it in printcmd.c?
>  Doesn't seem like it's directly related to source files...

This is second version of 'val "printf-like format", args,...'.
It touches only printcmd.c. This version is smaller and simpler.
I hope I made the cleanup code right.

There is one additional thing I'd like to improve, but that would make
the patch bigger.

It is to treat \n in the eval'd string as command separator.
Then multi-command sequences can be properly evaluated as expected, for example:
             eval "while $x\n...\nend"
Right now, \n in the eval'd string is not treated command separator.
This is not right.
 It would be another 50-100 lines of code to correct this.
Shall I add it ?

Yakov

--- printcmd.c.000    2008-02-20 14:37:39.000000000 +0200
+++ printcmd.c    2008-02-24 17:03:08.000000000 +0200
@@ -1714,7 +1714,9 @@
  }

 static void
-printf_command (char *arg, int from_tty)
+printf_command_core(char *arg,
+            void (*printf_func)(void *file, const char *format, ...),
+            void *file)
 {
   char *f = NULL;
    char *s = arg;
@@ -2078,20 +2080,20 @@
         read_memory (tem, str, j);
           str[j] = 0;

-          printf_filtered (current_substring, (char *) str);
+          printf_func (file, current_substring, (char *) str);
          }
         break;
       case double_arg:
         {
           double val = value_as_double (val_args[i]);
-          printf_filtered (current_substring, val);
+          printf_func (file, current_substring, val);
            break;
         }
       case long_double_arg:
 #ifdef HAVE_LONG_DOUBLE
         {
           long double val = value_as_double (val_args[i]);
-          printf_filtered (current_substring, val);
 +           printf_func (file, current_substring, val);
           break;
         }
 #else
@@ -2101,7 +2103,7 @@
 #if defined (CC_HAS_LONG_LONG) && defined (PRINTF_HAS_LONG_LONG)
         {
           long long val = value_as_long (val_args[i]);
 -          printf_filtered (current_substring, val);
+          printf_func (file, current_substring, val);
           break;
         }
 #else
@@ -2110,13 +2112,13 @@
       case int_arg:
         {
            int val = value_as_long (val_args[i]);
-          printf_filtered (current_substring, val);
+          printf_func (file, current_substring, val);
           break;
         }
       case long_arg:
          {
           long val = value_as_long (val_args[i]);
-          printf_filtered (current_substring, val);
+          printf_func (file, current_substring, val);
           break;
         }

 @@ -2127,7 +2129,7 @@
 #if defined (PRINTF_HAS_DECFLOAT)
           /* If we have native support for Decimal floating
          printing, handle it here.  */
-          printf_filtered (current_substring, param_ptr);
 +          printf_func (file, current_substring, param_ptr);
 #else

           /* As a workaround until vasprintf has native support for DFP
@@ -2213,7 +2215,7 @@
           decimal_to_string (dfp_ptr, dfp_len, decstr);

           /* Print the DFP value.  */
-          printf_filtered (current_substring, decstr);
+          printf_func (file, current_substring, decstr);

           break;
 #endif
@@ -2267,13 +2269,13 @@
            *fmt_p++ = 'l';
           *fmt_p++ = 'x';
           *fmt_p++ = '\0';
-          printf_filtered (fmt, val);
+          printf_func (file, fmt, val);
         }
           else
          {
           *fmt_p++ = 's';
           *fmt_p++ = '\0';
-          printf_filtered (fmt, "(nil)");
+          printf_func (file, fmt, "(nil)");
         }

            break;
@@ -2286,8 +2288,61 @@
     current_substring += strlen (current_substring) + 1;
       }
     /* Print the portion of the format string after the last argument.  */
-    puts_filtered (last_arg);
 +    printf_func (file, "%s", last_arg);
   }
+
+  do_cleanups (old_cleanups);
+}
+
+static void
+printf_for_printf_command(void *unused, const char *format, ...)
+{
+  va_list args;
 +
+  va_start (args, format);
+  vprintf_filtered (format, args);
+  va_end (args);
+}
+
+static void
+printf_command (char *arg, int from_tty)
+{
+  printf_command_core (arg, printf_for_printf_command, NULL);
 +}
+
+static void
+printf_for_eval_command (void *stream, const char *format, ...)
+{
+  char *ret;
+  va_list args;
+
+  va_start (args, format);
+  ret = xstrvprintf (format, args);
+  va_end (args);
 +
+  ui_file_write (stream, ret, strlen(ret));
+}
+
+static void
+eval_command (char *arg, int from_tty)
+{
+  struct ui_file *memfile = NULL;
+  char *cmd;
+  long cmd_length;
+  struct cleanup *old_cleanups;
 +
+  memfile = mem_fileopen ();
+  old_cleanups = make_cleanup_ui_file_delete (memfile);
+
+  printf_command_core (arg, printf_for_eval_command, memfile );
+
+  cmd = ui_file_xstrdup (memfile, &cmd_length );
 +  do_cleanups (old_cleanups);                 /* closes memfile */
+
+  old_cleanups = make_cleanup (free_current_contents, &cmd);
+
+  execute_command ( cmd, from_tty );
+
   do_cleanups (old_cleanups);
  }

@@ -2463,4 +2518,10 @@
   examine_w_type = init_type (TYPE_CODE_INT, 4, 0, "examine_w_type", NULL);
   examine_g_type = init_type (TYPE_CODE_INT, 8, 0, "examine_g_type", NULL);

 +  add_cmd ("eval", class_support, eval_command, _("\
+eval \"printf-like format string\", arg1, arg2, arg3, ..., argn\n\
+Execute gdb command from a string generated by printf-like format and\n\
 +arguments."),
+           &cmdlist);
+
 }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]