Index: gdb/ChangeLog =================================================================== RCS file: /cvs/src/src/gdb/ChangeLog,v retrieving revision 1.11324 diff -u -r1.11324 ChangeLog --- gdb/ChangeLog 4 Feb 2010 12:45:49 -0000 1.11324 +++ gdb/ChangeLog 6 Feb 2010 13:20:42 -0000 @@ -1,3 +1,9 @@ +Thu Feb 4 11:47:53 2010 Chris Moller + + PR gdb/11067 + * c-valprint.c (c_val_print _initialize_c_valprint):Provided + user-definable formatting for enum printing. + 2010-02-04 Tristan Gingold * machoread.c (macho_add_oso): Renamed to macho_register_oso. Index: gdb/c-valprint.c =================================================================== RCS file: /cvs/src/src/gdb/c-valprint.c,v retrieving revision 1.67 diff -u -r1.67 c-valprint.c --- gdb/c-valprint.c 2 Feb 2010 16:45:16 -0000 1.67 +++ gdb/c-valprint.c 6 Feb 2010 13:20:43 -0000 @@ -30,8 +30,15 @@ #include "c-lang.h" #include "cp-abi.h" #include "target.h" +#include "command.h" +#include "cli/cli-cmds.h" +void _initialize_c_valprint (void); + +/* Enum format string. */ +char *enum_format; + /* Print function pointer with inferior address ADDRESS onto stdio stream STREAM. */ @@ -413,7 +420,96 @@ } if (i < len) { - fputs_filtered (TYPE_FIELD_NAME (type, i), stream); + if (enum_format && *enum_format) + { + struct cleanup *cleanups; + char *enum_name; + char *fmt_ptr; + char *fmt = NULL; + int fmt_max = 0; + int fmt_idx = 0; +#define FMT_LEN_INCR 256 + + void chk_alloc (int amt) + { + if (fmt_max <= fmt_idx + amt) + { + fmt_max += amt + FMT_LEN_INCR; + fmt = xrealloc (fmt, fmt_max); + } + } + + void fmt_cat_char (char c) + { + chk_alloc (1); + fmt[fmt_idx++] = c; + fmt[fmt_idx] = 0; + } + + void fmt_cat_str (char *s) + { + chk_alloc (strlen (s)); + memcpy (fmt + fmt_idx, s, strlen (s)); + fmt_idx += strlen (s); + fmt[fmt_idx] = 0; + } + + int fprintf_enum (void *stream, const char *format, ...) + { + va_list args; + va_start (args, format); + vfprintf_filtered (stream, format, args); + va_end (args); + return 0; + } + + fmt_max = FMT_LEN_INCR + strlen (enum_format); + fmt_idx = 0; + fmt = xmalloc (fmt_max); + cleanups = make_cleanup (xfree, fmt); + + for (fmt_ptr = enum_format; *fmt_ptr; fmt_ptr++) + { + if (*fmt_ptr == '%' && *(fmt_ptr+1)) + { + switch (*++fmt_ptr) + { + case 'v': + fmt_cat_str ("%1$lld"); + break; + case 's': + fmt_cat_str ("%2$s"); + break; + case 't': + fmt_cat_str ("%3$s"); + break; + default: + fmt_cat_char (*fmt_ptr); + break; + } + } + else + { + fmt_cat_char (*fmt_ptr); + } + } + + if (TYPE_NAME (type)) enum_name = TYPE_NAME (type); + else if (TYPE_TAG_NAME(type)) enum_name = TYPE_TAG_NAME(type); + else enum_name = ""; + + fprintf_enum (stream, + fmt, + val, + TYPE_FIELD_NAME (type, i), + enum_name); + + do_cleanups (cleanups); + } + else + { + fputs_filtered (TYPE_FIELD_NAME (type, i), stream); + } } else { @@ -715,3 +811,26 @@ value_address (val), stream, 0, &opts, current_language); } + +void +_initialize_c_valprint (void) +{ + + enum_format = NULL; + add_setshow_string_cmd ("enum-fmt", no_class, + &enum_format, + _("Set enum display format."), + _("Show enum display format."), + _("\ +Allows a printf-style format string to be specified to control the display\n\ +of enum values. The string will be printed verbatim when enum values are\n\ +displayed except that:\n\ + %v directives will be expanded to the numeric value of the enum,\n\ + %s directives will be expanded to the symbolic value of the enum, and\n\ + %t directives will be expanded to the enum tag.\n\ +The default format is equivalent to \"%s\" and the default will be used if\n\ +no argument is provided to the set operation."), + NULL, + NULL, + &setlist, &showlist); +} Index: gdb/testsuite/ChangeLog =================================================================== RCS file: /cvs/src/src/gdb/testsuite/ChangeLog,v retrieving revision 1.2120 diff -u -r1.2120 ChangeLog --- gdb/testsuite/ChangeLog 2 Feb 2010 23:40:28 -0000 1.2120 +++ gdb/testsuite/ChangeLog 6 Feb 2010 13:21:02 -0000 @@ -1,3 +1,10 @@ +2010-02-03 Chris Moller + + PR gdb/11067 + * gdb.base/pr11067.exp: New. + * gdb.base/pr11067.c: New. + * gdb.base/Makefile.in (EXECUTABLES): Added new testcase. + 2010-02-02 Tom Tromey * gdb.cp/virtbase.exp: Add regression tests. Index: gdb/testsuite/gdb.base/Makefile.in =================================================================== RCS file: /cvs/src/src/gdb/testsuite/gdb.base/Makefile.in,v retrieving revision 1.5 diff -u -r1.5 Makefile.in --- gdb/testsuite/gdb.base/Makefile.in 15 Sep 2009 03:30:08 -0000 1.5 +++ gdb/testsuite/gdb.base/Makefile.in 6 Feb 2010 13:21:02 -0000 @@ -12,7 +12,8 @@ scope section_command setshow setvar shmain sigall signals \ solib solib_sl so-impl-ld so-indr-cl \ step-line step-test structs structs2 \ - twice-tmp varargs vforked-prog watchpoint whatis catch-syscall + twice-tmp varargs vforked-prog watchpoint whatis catch-syscall \ + pr11067 MISCELLANEOUS = coremmap.data ../foobar.baz \ shr1.sl shr2.sl solib_sl.sl solib1.sl solib2.sl Index: gdb/testsuite/gdb.base/pr11067.c =================================================================== RCS file: gdb/testsuite/gdb.base/pr11067.c diff -N gdb/testsuite/gdb.base/pr11067.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ gdb/testsuite/gdb.base/pr11067.c 6 Feb 2010 13:21:02 -0000 @@ -0,0 +1,27 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2010 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +enum E { + Val1 = 56, + Val2 +}; + +int main() { + enum E e = Val1; + return e; //marker 1 +} + Index: gdb/testsuite/gdb.base/pr11067.exp =================================================================== RCS file: gdb/testsuite/gdb.base/pr11067.exp diff -N gdb/testsuite/gdb.base/pr11067.exp --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ gdb/testsuite/gdb.base/pr11067.exp 6 Feb 2010 13:21:02 -0000 @@ -0,0 +1,58 @@ +# Copyright 2010 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +if { [skip_cplus_tests] } { continue } + +load_lib "cp-support.exp" + +set testfile "pr11067" +set srcfile ${testfile}.c +set binfile ${objdir}/${subdir}/${testfile} + +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {c++ debug}] != "" } { + untested pr11067.exp + return -1 +} + +gdb_exit +gdb_start +gdb_reinitialize_dir $srcdir/$subdir +gdb_load ${binfile} + +if ![runto_main] then { + perror "couldn't run to breakpoint" + continue +} + +# set a breakpoint at the return stmt + +gdb_breakpoint [gdb_get_line_number "marker 1"] +gdb_continue_to_breakpoint "marker 1" + +gdb_test "print e" "Val1" + +gdb_test "set enum-fmt %s=(enum %t)%v" "" +gdb_test "print e" "Val1=\\(enum E\\)56" + +gdb_test "set enum-fmt %s = (enum %t)%v" "" +gdb_test "print Val2" "Val2 = \\(enum E\\)57" + +gdb_test "show enum-fmt" "%s.* = \\(enum %t\\)%v.*" + +gdb_test "set enum-fmt" "" +gdb_test "print e" "Val1" + +gdb_exit +return 0