From: "Yakov Lerner" <iler.ml@gmail.com>
To: gdb-patches@sourceware.org
Subject: simlpe patch implements eval command (with printf-like format and args)
Date: Thu, 21 Feb 2008 17:33:00 -0000 [thread overview]
Message-ID: <f36b08ee0802210120t9646eewf1ae66469883e6f0@mail.gmail.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 8248 bytes --]
This simple patch implements eval command with printf-like syntax:
eval "printf-like-format", comma-separated args
The patch is against cvs-checkedout source. Suggestions are welcome.
Implementation is very simple.
I am unsure about naming of new variables and functions. Suggestions
are welcome.
Especially about "grow_xasprints_append" name. Sorry, can't think of
better name at the moment.
Long repeating calls to this functions can be shortened by packing 3
first args into
if we declare 3-member struct dyna_str_t { char *buf; size_t len;
size_t *size; }. Shall I do it ?
I am attaching both inline AND as attachment; I am not sure
about tabs mangling inline.
Yakov Lerner
--- defs.h.000 2008-02-21 10:00:40.000000000 +0200
+++ defs.h 2008-02-21 11:47:13.000000000 +0200
@@ -849,6 +849,12 @@
extern void xvasprintf (char **ret, const char *format, va_list ap)
ATTR_FORMAT (printf, 2, 0);
+/* Grow allocated buffer and appens to it, without causing quadratic
slowdown */
+extern int grow_xvasprintf_append (char **to, size_t *filled_len,
size_t *allocated_size, const char *format, va_list args)
+ ATTR_FORMAT (printf, 4, 0);
+int grow_xasprintf_append (char **to, size_t *filled_len, size_t
*allocated_size, const char *format, ...)
+ ATTR_FORMAT (printf, 4, 5);
+
/* Like asprintf and vasprintf, but return the string, throw an error
if no memory. */
extern char *xstrprintf (const char *format, ...) ATTR_FORMAT (printf, 1, 2);
@@ -905,6 +911,8 @@
extern void vwarning (const char *, va_list args) ATTR_FORMAT (printf, 1, 0);
+char *gdb_own_xasprintf (char *arg);
+
/* List of known OS ABIs. If you change this, make sure to update the
table in osabi.c. */
enum gdb_osabi
--- utils.c.000 2008-02-21 09:47:38.000000000 +0200
+++ utils.c 2008-02-21 11:48:27.000000000 +0200
@@ -991,6 +991,46 @@
}
\f
+/* Grow allocated buffer and appens to it, without causing quadratic
slowdown */
+
+int
+grow_xvasprintf_append (char **to, size_t *filled_len, size_t
*allocated_size, const char *format, va_list args)
+{
+ int len_add;
+
+ if (*to == NULL || *allocated_size == 0)
+ to = xmalloc (*allocated_size = 32);
+
+ gdb_assert (*filled_len < *allocated_size);
+
+ len_add = vsnprintf (*to + *filled_len, *allocated_size -
*filled_len, format, args);
+ if (len_add >= *allocated_size - *filled_len)
+ {
+ *allocated_size = max (*allocated_size * 2, *filled_len + len_add + 1);
+ *to = xrealloc (*to, *allocated_size);
+
+ len_add = vsnprintf (*to + *filled_len, *allocated_size -
*filled_len, format, args);
+ gdb_assert( len_add < *allocated_size - *filled_len );
+ }
+ *filled_len += len_add;
+
+ return *filled_len;
+}
+
+int
+grow_xasprintf_append (char **to, size_t *filled_len, size_t
*allocated_size, const char *format, ...)
+{
+ va_list args;
+ int ret;
+
+ va_start (args, format);
+ ret = grow_xvasprintf_append (to, filled_len, allocated_size, format, args);
+ va_end (args);
+
+ return ret;
+}
+
+
/* Like asprintf/vasprintf but get an internal_error if the call
fails. */
--- source.c.000 2008-02-21 11:33:17.000000000 +0200
+++ source.c 2008-02-21 11:52:18.000000000 +0200
@@ -1928,6 +1928,17 @@
add_substitute_path_rule (argv[0], argv[1]);
}
+static void
+eval_command (char *arg, int from_tty)
+{
+ struct cleanup *old_cleanups;
+ char *str = gdb_own_xasprintf (arg);
+
+ old_cleanups = make_cleanup (free_current_contents, &str);
+ execute_command (str, from_tty);
+ do_cleanups (old_chain);
+}
+
\f
void
_initialize_source (void)
@@ -2030,4 +2041,10 @@
Print the rule for substituting FROM in source file names. If FROM\n\
is not specified, print all substitution rules."),
&showlist);
+
+ 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);
}
--- printcmd.c.000 2008-02-20 14:37:39.000000000 +0200
+++ printcmd.c 2008-02-21 11:48:14.000000000 +0200
@@ -1716,6 +1716,15 @@
static void
printf_command (char *arg, int from_tty)
{
+ char *str = gdb_own_xasprintf (arg);
+
+ puts_filtered( str );
+ xfree (str);
+}
+
+char *
+gdb_own_xasprintf(char *arg)
+{
char *f = NULL;
char *s = arg;
char *string = NULL;
@@ -1725,10 +1734,16 @@
int nargs = 0;
int allocated_args = 20;
struct cleanup *old_cleanups;
-
+ size_t result_alloc = 16;
+ char *result;
+ size_t result_len = 0;
+
val_args = xmalloc (allocated_args * sizeof (struct value *));
old_cleanups = make_cleanup (free_current_contents, &val_args);
+ result = xmalloc(result_alloc);
+ make_cleanup (free_current_contents, &result);
+
if (s == 0)
error_no_arg (_("format-control string and values to print"));
@@ -2078,20 +2093,23 @@
read_memory (tem, str, j);
str[j] = 0;
- printf_filtered (current_substring, (char *) str);
+ grow_xasprintf_append (&result, &result_len, &result_alloc,
+ current_substring, (char *) str );
}
break;
case double_arg:
{
double val = value_as_double (val_args[i]);
- printf_filtered (current_substring, val);
+ grow_xasprintf_append (&result, &result_len, &result_alloc,
+ 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);
+ grow_xasprintf_append (&result, &result_len, &result_alloc,
+ current_substring, val);
break;
}
#else
@@ -2101,7 +2119,8 @@
#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);
+ grow_xasprintf_append (&result, &result_len, &result_alloc,
+ current_substring, val);
break;
}
#else
@@ -2110,13 +2129,15 @@
case int_arg:
{
int val = value_as_long (val_args[i]);
- printf_filtered (current_substring, val);
+ grow_xasprintf_append (&result, &result_len, &result_alloc,
+ current_substring, val);
break;
}
case long_arg:
{
long val = value_as_long (val_args[i]);
- printf_filtered (current_substring, val);
+ grow_xasprintf_append (&result, &result_len, &result_alloc,
+ current_substring, val);
break;
}
@@ -2127,7 +2148,8 @@
#if defined (PRINTF_HAS_DECFLOAT)
/* If we have native support for Decimal floating
printing, handle it here. */
- printf_filtered (current_substring, param_ptr);
+ grow_xasprintf_append (&result, &result_len, &result_alloc,
+ current_substring, param_ptr);
#else
/* As a workaround until vasprintf has native support for DFP
@@ -2213,7 +2235,8 @@
decimal_to_string (dfp_ptr, dfp_len, decstr);
/* Print the DFP value. */
- printf_filtered (current_substring, decstr);
+ grow_xasprintf_append (&result, &result_len, &result_alloc,
+ current_substring, decstr);
break;
#endif
@@ -2267,13 +2290,15 @@
*fmt_p++ = 'l';
*fmt_p++ = 'x';
*fmt_p++ = '\0';
- printf_filtered (fmt, val);
+ grow_xasprintf_append (&result, &result_len, &result_alloc,
+ fmt, val);
}
else
{
*fmt_p++ = 's';
*fmt_p++ = '\0';
- printf_filtered (fmt, "(nil)");
+ grow_xasprintf_append (&result, &result_len, &result_alloc,
+ fmt, "(nil)");
}
break;
@@ -2286,9 +2311,14 @@
current_substring += strlen (current_substring) + 1;
}
/* Print the portion of the format string after the last argument. */
- puts_filtered (last_arg);
+ grow_xasprintf_append (&result, &result_len, &result_alloc,
+ "%s", last_arg);
}
- do_cleanups (old_cleanups);
+
+ xfree (val_args);
+ discard_cleanups (old_cleanups);
+
+ return result;
}
void
[-- Attachment #2: eval-patch --]
[-- Type: application/octet-stream, Size: 7292 bytes --]
--- defs.h.000 2008-02-21 10:00:40.000000000 +0200
+++ defs.h 2008-02-21 11:47:13.000000000 +0200
@@ -849,6 +849,12 @@
extern void xvasprintf (char **ret, const char *format, va_list ap)
ATTR_FORMAT (printf, 2, 0);
+/* Grow allocated buffer and appens to it, without causing quadratic slowdown */
+extern int grow_xvasprintf_append (char **to, size_t *filled_len, size_t *allocated_size, const char *format, va_list args)
+ ATTR_FORMAT (printf, 4, 0);
+int grow_xasprintf_append (char **to, size_t *filled_len, size_t *allocated_size, const char *format, ...)
+ ATTR_FORMAT (printf, 4, 5);
+
/* Like asprintf and vasprintf, but return the string, throw an error
if no memory. */
extern char *xstrprintf (const char *format, ...) ATTR_FORMAT (printf, 1, 2);
@@ -905,6 +911,8 @@
extern void vwarning (const char *, va_list args) ATTR_FORMAT (printf, 1, 0);
+char *gdb_own_xasprintf (char *arg);
+
/* List of known OS ABIs. If you change this, make sure to update the
table in osabi.c. */
enum gdb_osabi
--- utils.c.000 2008-02-21 09:47:38.000000000 +0200
+++ utils.c 2008-02-21 11:48:27.000000000 +0200
@@ -991,6 +991,46 @@
}
\f
+/* Grow allocated buffer and appens to it, without causing quadratic slowdown */
+
+int
+grow_xvasprintf_append (char **to, size_t *filled_len, size_t *allocated_size, const char *format, va_list args)
+{
+ int len_add;
+
+ if (*to == NULL || *allocated_size == 0)
+ to = xmalloc (*allocated_size = 32);
+
+ gdb_assert (*filled_len < *allocated_size);
+
+ len_add = vsnprintf (*to + *filled_len, *allocated_size - *filled_len, format, args);
+ if (len_add >= *allocated_size - *filled_len)
+ {
+ *allocated_size = max (*allocated_size * 2, *filled_len + len_add + 1);
+ *to = xrealloc (*to, *allocated_size);
+
+ len_add = vsnprintf (*to + *filled_len, *allocated_size - *filled_len, format, args);
+ gdb_assert( len_add < *allocated_size - *filled_len );
+ }
+ *filled_len += len_add;
+
+ return *filled_len;
+}
+
+int
+grow_xasprintf_append (char **to, size_t *filled_len, size_t *allocated_size, const char *format, ...)
+{
+ va_list args;
+ int ret;
+
+ va_start (args, format);
+ ret = grow_xvasprintf_append (to, filled_len, allocated_size, format, args);
+ va_end (args);
+
+ return ret;
+}
+
+
/* Like asprintf/vasprintf but get an internal_error if the call
fails. */
--- source.c.000 2008-02-21 11:33:17.000000000 +0200
+++ source.c 2008-02-21 11:52:18.000000000 +0200
@@ -1928,6 +1928,17 @@
add_substitute_path_rule (argv[0], argv[1]);
}
+static void
+eval_command (char *arg, int from_tty)
+{
+ struct cleanup *old_cleanups;
+ char *str = gdb_own_xasprintf (arg);
+
+ old_cleanups = make_cleanup (free_current_contents, &str);
+ execute_command (str, from_tty);
+ do_cleanups (old_chain);
+}
+
\f
void
_initialize_source (void)
@@ -2030,4 +2041,10 @@
Print the rule for substituting FROM in source file names. If FROM\n\
is not specified, print all substitution rules."),
&showlist);
+
+ 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);
}
--- printcmd.c.000 2008-02-20 14:37:39.000000000 +0200
+++ printcmd.c 2008-02-21 11:48:14.000000000 +0200
@@ -1716,6 +1716,15 @@
static void
printf_command (char *arg, int from_tty)
{
+ char *str = gdb_own_xasprintf (arg);
+
+ puts_filtered( str );
+ xfree (str);
+}
+
+char *
+gdb_own_xasprintf(char *arg)
+{
char *f = NULL;
char *s = arg;
char *string = NULL;
@@ -1725,10 +1734,16 @@
int nargs = 0;
int allocated_args = 20;
struct cleanup *old_cleanups;
-
+ size_t result_alloc = 16;
+ char *result;
+ size_t result_len = 0;
+
val_args = xmalloc (allocated_args * sizeof (struct value *));
old_cleanups = make_cleanup (free_current_contents, &val_args);
+ result = xmalloc(result_alloc);
+ make_cleanup (free_current_contents, &result);
+
if (s == 0)
error_no_arg (_("format-control string and values to print"));
@@ -2078,20 +2093,23 @@
read_memory (tem, str, j);
str[j] = 0;
- printf_filtered (current_substring, (char *) str);
+ grow_xasprintf_append (&result, &result_len, &result_alloc,
+ current_substring, (char *) str );
}
break;
case double_arg:
{
double val = value_as_double (val_args[i]);
- printf_filtered (current_substring, val);
+ grow_xasprintf_append (&result, &result_len, &result_alloc,
+ 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);
+ grow_xasprintf_append (&result, &result_len, &result_alloc,
+ current_substring, val);
break;
}
#else
@@ -2101,7 +2119,8 @@
#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);
+ grow_xasprintf_append (&result, &result_len, &result_alloc,
+ current_substring, val);
break;
}
#else
@@ -2110,13 +2129,15 @@
case int_arg:
{
int val = value_as_long (val_args[i]);
- printf_filtered (current_substring, val);
+ grow_xasprintf_append (&result, &result_len, &result_alloc,
+ current_substring, val);
break;
}
case long_arg:
{
long val = value_as_long (val_args[i]);
- printf_filtered (current_substring, val);
+ grow_xasprintf_append (&result, &result_len, &result_alloc,
+ current_substring, val);
break;
}
@@ -2127,7 +2148,8 @@
#if defined (PRINTF_HAS_DECFLOAT)
/* If we have native support for Decimal floating
printing, handle it here. */
- printf_filtered (current_substring, param_ptr);
+ grow_xasprintf_append (&result, &result_len, &result_alloc,
+ current_substring, param_ptr);
#else
/* As a workaround until vasprintf has native support for DFP
@@ -2213,7 +2235,8 @@
decimal_to_string (dfp_ptr, dfp_len, decstr);
/* Print the DFP value. */
- printf_filtered (current_substring, decstr);
+ grow_xasprintf_append (&result, &result_len, &result_alloc,
+ current_substring, decstr);
break;
#endif
@@ -2267,13 +2290,15 @@
*fmt_p++ = 'l';
*fmt_p++ = 'x';
*fmt_p++ = '\0';
- printf_filtered (fmt, val);
+ grow_xasprintf_append (&result, &result_len, &result_alloc,
+ fmt, val);
}
else
{
*fmt_p++ = 's';
*fmt_p++ = '\0';
- printf_filtered (fmt, "(nil)");
+ grow_xasprintf_append (&result, &result_len, &result_alloc,
+ fmt, "(nil)");
}
break;
@@ -2286,9 +2311,14 @@
current_substring += strlen (current_substring) + 1;
}
/* Print the portion of the format string after the last argument. */
- puts_filtered (last_arg);
+ grow_xasprintf_append (&result, &result_len, &result_alloc,
+ "%s", last_arg);
}
- do_cleanups (old_cleanups);
+
+ xfree (val_args);
+ discard_cleanups (old_cleanups);
+
+ return result;
}
void
next reply other threads:[~2008-02-21 9:20 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-02-21 17:33 Yakov Lerner [this message]
2008-02-21 22:37 ` Michael Snyder
2008-02-21 22:50 ` Yakov Lerner
2008-02-21 22:56 ` Michael Snyder
2008-02-22 9:59 ` Daniel Jacobowitz
2008-02-22 11:17 ` Yakov Lerner
2008-02-22 17:12 ` Eli Zaretskii
2008-02-24 15:39 ` Yakov Lerner
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=f36b08ee0802210120t9646eewf1ae66469883e6f0@mail.gmail.com \
--to=iler.ml@gmail.com \
--cc=gdb-patches@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox