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]

simlpe patch implements eval command (with printf-like format and args)


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 @@
 }
 

+/* 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);
+}
+
 
 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: eval-patch
Description: Binary data


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