From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 1343 invoked by alias); 24 Feb 2008 15:39:21 -0000 Received: (qmail 1331 invoked by uid 22791); 24 Feb 2008 15:39:19 -0000 X-Spam-Check-By: sourceware.org Received: from el-out-1112.google.com (HELO el-out-1112.google.com) (209.85.162.183) by sourceware.org (qpsmtpd/0.31) with ESMTP; Sun, 24 Feb 2008 15:38:58 +0000 Received: by el-out-1112.google.com with SMTP id s27so1031595ele.12 for ; Sun, 24 Feb 2008 07:38:56 -0800 (PST) Received: by 10.142.83.4 with SMTP id g4mr1239323wfb.103.1203867535448; Sun, 24 Feb 2008 07:38:55 -0800 (PST) Received: by 10.143.125.5 with HTTP; Sun, 24 Feb 2008 07:38:55 -0800 (PST) Message-ID: Date: Sun, 24 Feb 2008 19:54:00 -0000 From: "Yakov Lerner" To: gdb-patches@sourceware.org Subject: 'eval' command with printf-like args, take 2 In-Reply-To: MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Content-Disposition: inline References: X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2008-02/txt/msg00368.txt.bz2 On Fri, Feb 22, 2008 at 12:50 AM, Michael Snyder 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); + }