This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
Re: 'eval' command with printf-like args, take 2
- From: Michael Snyder <msnyder at specifix dot com>
- To: Yakov Lerner <iler dot ml at gmail dot com>
- Cc: gdb-patches at sourceware dot org
- Date: Fri, 29 Feb 2008 11:50:26 -0800
- Subject: Re: 'eval' command with printf-like args, take 2
- References: <f36b08ee0802240736y2ec3b356m23ec55d59ead50c2@mail.gmail.com> <f36b08ee0802240738p70696235ue9324d3c13acaf70@mail.gmail.com>
Yakov, just giving you an 'ack' on this.
Been a little busy, haven't had a chance to look at it yet,
will try to get to it soon.
Michael
On Sun, 2008-02-24 at 17:38 +0200, Yakov Lerner wrote:
> 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);
> +
> }