This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
'eval' command with printf-like args, take 2
- From: "Yakov Lerner" <iler dot ml at gmail dot com>
- To: gdb-patches at sourceware dot org
- Date: Sun, 24 Feb 2008 17:38:55 +0200
- Subject: 'eval' command with printf-like args, take 2
- References: <f36b08ee0802240736y2ec3b356m23ec55d59ead50c2@mail.gmail.com>
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);
+
}