[Patch] Try2: -var-evaluate-expression [-f FORMAT] NAME

Marc Khouzam
2008-04-01T14:28:02Z

Hi,

now that I have my Copyright Assignment and sourceforge account, I'm re-sending this patch.
It adds a -f FORMAT option to -var-evaluate-expression, to avoid having to change the default
display format of a varObj every time. The real usefulness, is that to have -var-update
notify of a change in -any- format, I must always keep the varObj in natural format.
It is a simple change that passes a format parameter down the chain of calls.

Please refer to the tail end of the last attempt:
http://sourceware.org/ml/gdb-patches/2008-02/msg00103.html

I tested, ran regression and built the doc.

Thanks

--
Marc Khouzam

gdb/ChangeLog
2008-04-01 Marc Khouzam <marc.khouzam@ericsson.com>

* mi/mi-cmd-var.c: Include "mi-getopt.h".
(mi_parse_format): New. Factored out from mi_cmd_var_set_format.
(mi_cmd_var_set_format): Use new mi_parse_format.
(mi_cmd_var_evaluate_expression): Support for -f option to specify
format.
* Makefile.in (mi-cmd-var.o): Update dependencies.

* varobj.h (varobj_get_formatted_value): Declare.
* varobj.c (my_value_of_variable): Added format parameter.
(cplus_value_of_variable): Likewise.
(java_value_of_variable): Likewise.
(*(value_of_variable)): Likewise.
(c_value_of_variable): Likewise. Evaluate expression based
on format parameter.
(varobj_get_formatted_value): New.
(varobj_get_value): Added format parameter to method call.

gdb/doc/ChangeLog
2008-04-01 Marc Khouzam <marc.khouzam@ericsson.com>

* gdb.texinfo (GDB/MI Variable Objects): Add anchor to
-var-set-format. Add -f option to -var-evaluate-expression.

gdb/testsuite/ChangeLog
2008-04-01 Marc Khouzam <marc.khouzam@ericsson.com>

* gdb.mi/mi2-var-display.exp: Added tests for the new -f
option of -var-evaluate-expression.
* gdb.mi/mi2-var-display.exp: Likewise.

Index: gdb/testsuite/gdb.mi/mi-var-display.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.mi/mi-var-display.exp,v
retrieving revision 1.23
diff -u -r1.23 mi-var-display.exp
--- gdb/testsuite/gdb.mi/mi-var-display.exp 26 Mar 2008 13:36:51 -0000 1.23
+++ gdb/testsuite/gdb.mi/mi-var-display.exp 1 Apr 2008 14:01:36 -0000
@@ -168,6 +168,50 @@
"\\^done,value=\"3\"" \
"eval variable foo"

+
+# Test: c_variable-6.19
+# Desc: check optional format parameter of var-evaluate-expression
+# and check that current format is not changed
+mi_gdb_test "-var-evaluate-expression -f hex foo" \
+ "\\^done,value=\"0x3\"" \
+ "eval variable foo in hex"
+
+mi_gdb_test "-var-show-format foo" \
+ "\\^done,format=\"decimal\"" \
+ "show format variable foo after eval in hex"
+
+mi_gdb_test "-var-evaluate-expression -f octal foo" \
+ "\\^done,value=\"03\"" \
+ "eval variable foo in octal"
+
+mi_gdb_test "-var-show-format foo" \
+ "\\^done,format=\"decimal\"" \
+ "show format variable foo after eval in octal"
+
+mi_gdb_test "-var-evaluate-expression -f decimal foo" \
+ "\\^done,value=\"3\"" \
+ "eval variable foo in decimal"
+
+mi_gdb_test "-var-show-format foo" \
+ "\\^done,format=\"decimal\"" \
+ "show format variable foo after eval in decimal"
+
+mi_gdb_test "-var-evaluate-expression -f nat foo" \
+ "\\^done,value=\"0x3\"" \
+ "eval variable foo in natural"
+
+mi_gdb_test "-var-show-format foo" \
+ "\\^done,format=\"decimal\"" \
+ "show format variable foo after eval in natural"
+
+mi_gdb_test "-var-evaluate-expression -f bin foo" \
+ "\\^done,value=\"11\"" \
+ "eval variable foo in binary"
+
+mi_gdb_test "-var-show-format foo" \
+ "\\^done,format=\"decimal\"" \
+ "show format variable foo after eval in binary"
+
mi_gdb_test "-var-delete foo" \
"\\^done,ndeleted=\"1\"" \
"delete var foo"
Index: gdb/testsuite/gdb.mi/mi2-var-display.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.mi/mi2-var-display.exp,v
retrieving revision 1.16
diff -u -r1.16 mi2-var-display.exp
--- gdb/testsuite/gdb.mi/mi2-var-display.exp 26 Mar 2008 13:36:51 -0000 1.16
+++ gdb/testsuite/gdb.mi/mi2-var-display.exp 1 Apr 2008 14:01:36 -0000
@@ -168,6 +168,49 @@
"\\^done,value=\"3\"" \
"eval variable foo"

+# Test: c_variable-6.19
+# Desc: check optional format parameter of var-evaluate-expression
+# and check that current format is not changed
+mi_gdb_test "-var-evaluate-expression -f hex foo" \
+ "\\^done,value=\"0x3\"" \
+ "eval variable foo in hex"
+
+mi_gdb_test "-var-show-format foo" \
+ "\\^done,format=\"decimal\"" \
+ "show format variable foo after eval in hex"
+
+mi_gdb_test "-var-evaluate-expression -f octal foo" \
+ "\\^done,value=\"03\"" \
+ "eval variable foo in octal"
+
+mi_gdb_test "-var-show-format foo" \
+ "\\^done,format=\"decimal\"" \
+ "show format variable foo after eval in octal"
+
+mi_gdb_test "-var-evaluate-expression -f decimal foo" \
+ "\\^done,value=\"3\"" \
+ "eval variable foo in decimal"
+
+mi_gdb_test "-var-show-format foo" \
+ "\\^done,format=\"decimal\"" \
+ "show format variable foo after eval in decimal"
+
+mi_gdb_test "-var-evaluate-expression -f nat foo" \
+ "\\^done,value=\"0x3\"" \
+ "eval variable foo in natural"
+
+mi_gdb_test "-var-show-format foo" \
+ "\\^done,format=\"decimal\"" \
+ "show format variable foo after eval in natural"
+
+mi_gdb_test "-var-evaluate-expression -f bin foo" \
+ "\\^done,value=\"11\"" \
+ "eval variable foo in binary"
+
+mi_gdb_test "-var-show-format foo" \
+ "\\^done,format=\"decimal\"" \
+ "show format variable foo after eval in binary"
+
mi_gdb_test "-var-delete foo" \
"\\^done,ndeleted=\"1\"" \
"delete var foo"
Index: gdb/varobj.h
===================================================================
RCS file: /cvs/src/src/gdb/varobj.h,v
retrieving revision 1.17
diff -u -r1.17 varobj.h
--- gdb/varobj.h 26 Mar 2008 14:51:28 -0000 1.17
+++ gdb/varobj.h 1 Apr 2008 14:01:32 -0000
@@ -111,6 +111,9 @@

extern int varobj_get_attributes (struct varobj *var);

+extern char *varobj_get_formatted_value (struct varobj *var,
+ enum varobj_display_formats format);
+
extern char *varobj_get_value (struct varobj *var);

extern int varobj_set_value (struct varobj *var, char *expression);
Index: gdb/varobj.c
===================================================================
RCS file: /cvs/src/src/gdb/varobj.c,v
retrieving revision 1.108
diff -u -r1.108 varobj.c
--- gdb/varobj.c 26 Mar 2008 14:51:28 -0000 1.108
+++ gdb/varobj.c 1 Apr 2008 14:01:32 -0000
@@ -228,7 +228,8 @@

static struct value *value_of_child (struct varobj *parent, int index);

-static char *my_value_of_variable (struct varobj *var);
+static char *my_value_of_variable (struct varobj *var,
+ enum varobj_display_formats format);

static char *value_get_print_value (struct value *value,
enum varobj_display_formats format);
@@ -253,7 +254,8 @@

static struct type *c_type_of_child (struct varobj *parent, int index);

-static char *c_value_of_variable (struct varobj *var);
+static char *c_value_of_variable (struct varobj *var,
+ enum varobj_display_formats format);

/* C++ implementation */

@@ -273,7 +275,8 @@

static struct type *cplus_type_of_child (struct varobj *parent, int index);

-static char *cplus_value_of_variable (struct varobj *var);
+static char *cplus_value_of_variable (struct varobj *var,
+ enum varobj_display_formats format);

/* Java implementation */

@@ -291,7 +294,8 @@

static struct type *java_type_of_child (struct varobj *parent, int index);

-static char *java_value_of_variable (struct varobj *var);
+static char *java_value_of_variable (struct varobj *var,
+ enum varobj_display_formats format);

/* The language specific vector */

@@ -324,7 +328,8 @@
struct type *(*type_of_child) (struct varobj * parent, int index);

/* The current value of VAR. */
- char *(*value_of_variable) (struct varobj * var);
+ char *(*value_of_variable) (struct varobj * var,
+ enum varobj_display_formats format);
};

/* Array of known source language routines. */
@@ -858,9 +863,16 @@
}

char *
+varobj_get_formatted_value (struct varobj *var,
+ enum varobj_display_formats format)
+{
+ return my_value_of_variable (var, format);
+}
+
+char *
varobj_get_value (struct varobj *var)
{
- return my_value_of_variable (var);
+ return my_value_of_variable (var, var->format);
}

/* Set the value of an object variable (if it is editable) to the
@@ -1777,10 +1789,10 @@

/* GDB already has a command called "value_of_variable". Sigh. */
static char *
-my_value_of_variable (struct varobj *var)
+my_value_of_variable (struct varobj *var, enum varobj_display_formats format)
{
if (var->root->is_valid)
- return (*var->root->lang->value_of_variable) (var);
+ return (*var->root->lang->value_of_variable) (var, format);
else
return NULL;
}
@@ -2253,7 +2265,7 @@
}

static char *
-c_value_of_variable (struct varobj *var)
+c_value_of_variable (struct varobj *var, enum varobj_display_formats format)
{
/* BOGUS: if val_print sees a struct/class, or a reference to one,
it will print out its children instead of "{...}". So we need to
@@ -2298,7 +2310,13 @@

gdb_assert (varobj_value_is_changeable_p (var));
gdb_assert (!value_lazy (var->value));
- return xstrdup (var->print_value);
+
+ /* If the specified format is the current one,
+ we can reuse print_value */
+ if (format == var->format)
+ return xstrdup (var->print_value);
+ else
+ return value_get_print_value (var->value, format);
}
}
}
@@ -2624,7 +2642,7 @@
}

static char *
-cplus_value_of_variable (struct varobj *var)
+cplus_value_of_variable (struct varobj *var, enum varobj_display_formats format)
{

/* If we have one of our special types, don't print out
@@ -2632,7 +2650,7 @@
if (CPLUS_FAKE_CHILD (var))
return xstrdup ("");

- return c_value_of_variable (var);
+ return c_value_of_variable (var, format);
}

/* Java */
@@ -2707,9 +2725,9 @@
}

static char *
-java_value_of_variable (struct varobj *var)
+java_value_of_variable (struct varobj *var, enum varobj_display_formats format)
{
- return cplus_value_of_variable (var);
+ return cplus_value_of_variable (var, format);
}

extern void _initialize_varobj (void);
Index: gdb/Makefile.in
===================================================================
RCS file: /cvs/src/src/gdb/Makefile.in,v
retrieving revision 1.996
diff -u -r1.996 Makefile.in
--- gdb/Makefile.in 26 Mar 2008 14:53:28 -0000 1.996
+++ gdb/Makefile.in 1 Apr 2008 14:01:31 -0000
@@ -3219,7 +3219,7 @@
$(mi_getopt_h) $(remote_h)
$(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/mi/mi-cmd-target.c
mi-cmd-var.o: $(srcdir)/mi/mi-cmd-var.c $(defs_h) $(mi_cmds_h) $(ui_out_h) \
- $(mi_out_h) $(varobj_h) $(value_h) $(gdb_string_h)
+ $(mi_out_h) $(varobj_h) $(value_h) $(gdb_string_h) $(mi_getopt_h)
$(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/mi/mi-cmd-var.c
mi-console.o: $(srcdir)/mi/mi-console.c $(defs_h) $(mi_console_h) \
$(gdb_string_h)
Index: gdb/doc/gdb.texinfo
===================================================================
RCS file: /cvs/src/src/gdb/doc/gdb.texinfo,v
retrieving revision 1.478
diff -u -r1.478 gdb.texinfo
--- gdb/doc/gdb.texinfo 26 Mar 2008 18:37:47 -0000 1.478
+++ gdb/doc/gdb.texinfo 1 Apr 2008 14:01:36 -0000
@@ -19996,6 +19996,7 @@
Sets the output format for the value of the object @var{name} to be
@var{format-spec}.

+@anchor{-var-set-format}
The syntax for the @var{format-spec} is as follows:

@smallexample
@@ -20172,12 +20173,16 @@
@subsubheading Synopsis

@smallexample
- -var-evaluate-expression @var{name}
+ -var-evaluate-expression [-f @var{format-spec}] @var{name}
@end smallexample

Evaluates the expression that is represented by the specified variable
-object and returns its value as a string. The format of the
-string can be changed using the @code{-var-set-format} command.
+object and returns its value as a string. The format of the string
+can be specified with the @samp{-f} option. The possible values of
+this option are the same as for @code{-var-set-format}
+(@pxref{-var-set-format}). If the @samp{-f} option is not specified,
+the current display format will be used. The current display format
+can be changed using the @code{-var-set-format} command.

@smallexample
value=@var{value}
@@ -20230,7 +20235,7 @@
object names, all existing variable objects are updated, except
for frozen ones (@pxref{-var-set-frozen}). The option
@var{print-values} determines whether both names and values, or just
-names are printed. The possible values of this options are the same
+names are printed. The possible values of this option are the same
as for @code{-var-list-children} (@pxref{-var-list-children}). It is
recommended to use the @samp{--all-values} option, to reduce the
number of MI commands needed on each program stop.
Index: gdb/mi/mi-cmd-var.c
===================================================================
RCS file: /cvs/src/src/gdb/mi/mi-cmd-var.c,v
retrieving revision 1.47
diff -u -r1.47 mi-cmd-var.c
--- gdb/mi/mi-cmd-var.c 26 Mar 2008 14:51:28 -0000 1.47
+++ gdb/mi/mi-cmd-var.c 1 Apr 2008 14:01:36 -0000
@@ -28,6 +28,7 @@
#include "value.h"
#include <ctype.h>
#include "gdb_string.h"
+#include "mi-getopt.h"

const char mi_no_values[] = "--no-values";
const char mi_simple_values[] = "--simple-values";
@@ -195,11 +196,33 @@
return MI_CMD_DONE;
}

+/* Parse a string argument into a format value. */
+
+static enum varobj_display_formats
+mi_parse_format (const char *arg)
+{
+ int len;
+
+ len = strlen (arg);
+
+ if (strncmp (arg, "natural", len) == 0)
+ return FORMAT_NATURAL;
+ else if (strncmp (arg, "binary", len) == 0)
+ return FORMAT_BINARY;
+ else if (strncmp (arg, "decimal", len) == 0)
+ return FORMAT_DECIMAL;
+ else if (strncmp (arg, "hexadecimal", len) == 0)
+ return FORMAT_HEXADECIMAL;
+ else if (strncmp (arg, "octal", len) == 0)
+ return FORMAT_OCTAL;
+ else
+ error (_("Unknown display format: must be: \"natural\", \"binary\", \"decimal\", \"hexadecimal\", or \"octal\""));
+}
+
enum mi_cmd_result
mi_cmd_var_set_format (char *command, char **argv, int argc)
{
enum varobj_display_formats format;
- int len;
struct varobj *var;
char *formspec;

@@ -216,21 +239,8 @@
if (formspec == NULL)
error (_("mi_cmd_var_set_format: Must specify the format as: \"natural\", \"binary\", \"decimal\", \"hexadecimal\", or \"octal\""));

- len = strlen (formspec);
-
- if (strncmp (formspec, "natural", len) == 0)
- format = FORMAT_NATURAL;
- else if (strncmp (formspec, "binary", len) == 0)
- format = FORMAT_BINARY;
- else if (strncmp (formspec, "decimal", len) == 0)
- format = FORMAT_DECIMAL;
- else if (strncmp (formspec, "hexadecimal", len) == 0)
- format = FORMAT_HEXADECIMAL;
- else if (strncmp (formspec, "octal", len) == 0)
- format = FORMAT_OCTAL;
- else
- error (_("mi_cmd_var_set_format: Unknown display format: must be: \"natural\", \"binary\", \"decimal\", \"hexadecimal\", or \"octal\""));
-
+ format = mi_parse_format (formspec);
+
/* Set the format of VAR to given format */
varobj_set_display_format (var, format);

@@ -493,15 +503,58 @@
{
struct varobj *var;

- if (argc != 1)
- error (_("mi_cmd_var_evaluate_expression: Usage: NAME."));
+ enum varobj_display_formats format;
+ int formatFound;
+ int optind;
+ char *optarg;
+
+ enum opt
+ {
+ OP_FORMAT
+ };
+ static struct mi_opt opts[] =
+ {
+ {"f", OP_FORMAT, 1},
+ { 0, 0, 0 }
+ };
+
+ /* Parse arguments */
+ format = FORMAT_NATURAL;
+ formatFound = 0;
+ optind = 0;
+ while (1)
+ {
+ int opt = mi_getopt ("mi_cmd_var_evaluate_expression", argc, argv, opts, &optind, &optarg);
+ if (opt < 0)
+ break;
+ switch ((enum opt) opt)
+ {
+ case OP_FORMAT:
+ if (formatFound)
+ error (_("mi_cmd_var_evaluate_expression: cannot specify format more than once"));
+
+ format = mi_parse_format (optarg);
+ formatFound = 1;
+ break;
+ }
+ }

- /* Get varobj handle, if a valid var obj name was specified */
- var = varobj_get_handle (argv[0]);
+ if (optind >= argc)
+ error (_("mi_cmd_var_evaluate_expression: Usage: [-f FORMAT] NAME"));
+
+ if (optind < argc - 1)
+ error (_("mi_cmd_var_evaluate_expression: Garbage at end of command"));
+
+ /* Get varobj handle, if a valid var obj name was specified */
+ var = varobj_get_handle (argv[optind]);
if (var == NULL)
error (_("mi_cmd_var_evaluate_expression: Variable object not found"));
+
+ if (formatFound)
+ ui_out_field_string (uiout, "value", varobj_get_formatted_value (var, format));
+ else
+ ui_out_field_string (uiout, "value", varobj_get_value (var));

- ui_out_field_string (uiout, "value", varobj_get_value (var));
return MI_CMD_DONE;
}