This is the mail archive of the gdb-cvs@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]

[binutils-gdb] Fix sorting of enum values in FlagEnumerationPrinter


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=5f5dfff63f31511db45278f97dc22059325ec4d6

commit 5f5dfff63f31511db45278f97dc22059325ec4d6
Author: Simon Marchi <simon.marchi@polymtl.ca>
Date:   Wed Jan 20 13:42:53 2016 -0500

    Fix sorting of enum values in FlagEnumerationPrinter
    
    The lambda function used to sort the enumerator list does not work
    properly.  This list consists of tuples, (enum label, enum value).  The
    key function returns x.enumval.  enumval not being defined for a tuple,
    we see this exception in the test log:
    
      Python Exception <class 'AttributeError'> 'tuple' object has no attribute 'enumval'
    
    The function should return the second item of the tuple, which is the
    enumval.
    
    The pretty-printer still worked mostly correctly, except that the
    enumeration values were not sorted.  The test still passed because the
    enumeration values are already sorted where they are defined.  The test
    also passed despite the exception being printed, because the right output
    was printed after the exception:
    
      print (enum flag_enum) (FLAG_1)
      Python Exception <type 'exceptions.AttributeError'> 'tuple' objecthas no attribute 'enumval':M
      $7 = 0x1 [FLAG_1]
      (gdb) PASS: gdb.python/py-pp-maint.exp: print FLAG_1
    
    New in v2:
    
    - Improved test case, I stole Pedro's example directly.  It verifies
      that the sorting of enumerators by value works, by checking that
      printing FOO_MASK appears as FOO_1 | FOO_2 | FOO_3.
    
      I noticed that I could change the regexps to almost anything and the
      tests would still pass.  I think it was because of the | in there.  I
      made them more robust by using string_to_regexp.  I used curly braces
      { } instead of quoting marks " " for strings, so that I could use
      square brackets [ ] in them without having to escape them all.  I also
      removed the "message" part of the tests, since they are redundant with
      the command, and it's just more maintenance to have to update them.
    
      Tested with Python 2.7 and 3.5.
    
    gdb/ChangeLog:
    
    	* python/lib/gdb/printing.py (FlagEnumerationPrinter.__call__):
    	Fix enumerators sort key function.
    
    gdb/testsuite/ChangeLog:
    
    	* gdb.python/py-pp-maint.exp: Change/add enum flag tests.
    	* gdb.python/py-pp-maint.c (enum flag_enum): Use more complex
    	enum flag values.

Diff:
---
 gdb/ChangeLog                            |  5 +++++
 gdb/python/lib/gdb/printing.py           |  2 +-
 gdb/testsuite/ChangeLog                  |  6 ++++++
 gdb/testsuite/gdb.python/py-pp-maint.c   | 16 ++++++++++++----
 gdb/testsuite/gdb.python/py-pp-maint.exp | 27 ++++++++++++++++++---------
 5 files changed, 42 insertions(+), 14 deletions(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 937f8ac..705c2e1 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,8 @@
+2016-01-20  Simon Marchi  <simon.marchi@polymtl.ca>
+
+	* python/lib/gdb/printing.py (FlagEnumerationPrinter.__call__):
+	Fix enumerators sort key function.
+
 2016-01-20  Joel Brobecker  <brobecker@adacore.com>
 
 	* printcmd.c (print_scalar_formatted): Move binary operator from
diff --git a/gdb/python/lib/gdb/printing.py b/gdb/python/lib/gdb/printing.py
index 5160581..63c3aeb 100644
--- a/gdb/python/lib/gdb/printing.py
+++ b/gdb/python/lib/gdb/printing.py
@@ -263,7 +263,7 @@ class FlagEnumerationPrinter(PrettyPrinter):
                 self.enumerators.append((field.name, field.enumval))
             # Sorting the enumerators by value usually does the right
             # thing.
-            self.enumerators.sort(key = lambda x: x.enumval)
+            self.enumerators.sort(key = lambda x: x[1])
 
         if self.enabled:
             return _EnumInstance(self.enumerators, val)
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index 3485cfe..7e6da03 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2016-01-20  Simon Marchi  <simon.marchi@polymtl.ca>
+
+	* gdb.python/py-pp-maint.exp: Change/add enum flag tests.
+	* gdb.python/py-pp-maint.c (enum flag_enum): Use more complex
+	enum flag values.
+
 2016-01-20  Andreas Arnez  <arnez@linux.vnet.ibm.com>
 
 	* gdb.base/gnu_vector.exp: Re-establish handling for should_kfail
diff --git a/gdb/testsuite/gdb.python/py-pp-maint.c b/gdb/testsuite/gdb.python/py-pp-maint.c
index 657dfd7..d750496 100644
--- a/gdb/testsuite/gdb.python/py-pp-maint.c
+++ b/gdb/testsuite/gdb.python/py-pp-maint.c
@@ -17,12 +17,20 @@
 
 #include <string.h>
 
+
 enum flag_enum
   {
-    FLAG_1 = 1,
-    FLAG_2 = 2,
-    FLAG_3 = 4,
-    ALL = FLAG_1 | FLAG_2 | FLAG_3
+    /* Define the enumeration values in an unsorted manner to verify that we
+       effectively sort them by value.  */
+    FOO_MASK = 0x07,
+    FOO_1    = 0x01,
+    FOO_2    = 0x02,
+    FOO_3    = 0x04,
+
+    BAR_MASK = 0x70,
+    BAR_1    = 0x10,
+    BAR_2    = 0x20,
+    BAR_3    = 0x40,
   };
 
 enum flag_enum fval;
diff --git a/gdb/testsuite/gdb.python/py-pp-maint.exp b/gdb/testsuite/gdb.python/py-pp-maint.exp
index db0768f..a424931 100644
--- a/gdb/testsuite/gdb.python/py-pp-maint.exp
+++ b/gdb/testsuite/gdb.python/py-pp-maint.exp
@@ -119,14 +119,23 @@ gdb_test "print flt" " = x=<42> y=<43>" \
 gdb_test "print ss" " = a=<a=<1> b=<$hex>> b=<a=<2> b=<$hex>>" \
     "print ss re-enabled"
 
-gdb_test "print (enum flag_enum) (FLAG_1)" \
-    " = 0x1 .FLAG_1." \
-    "print FLAG_1"
+gdb_test_exact "print (enum flag_enum) (FOO_1)" \
+    { = 0x1 [FOO_1]}
 
-gdb_test "print (enum flag_enum) (FLAG_1 | FLAG_3)" \
-    " = 0x5 .FLAG_1 | FLAG_3." \
-    "print FLAG_1 | FLAG_3"
+gdb_test_exact "print (enum flag_enum) (BAR_3)" \
+    { = 0x40 [BAR_3]}
 
-gdb_test "print (enum flag_enum) (4 + 8)" \
-    " = 0xc .FLAG_1 | <unknown: 0x8>." \
-    "print FLAG_1 | 8"
+gdb_test_exact "print (enum flag_enum) (BAR_2 | FOO_2)" \
+    { = 0x22 [FOO_2 | BAR_2]}
+
+gdb_test_exact "print (enum flag_enum) (FOO_1 | FOO_2 | FOO_3)" \
+    { = 0x7 [FOO_1 | FOO_2 | FOO_3]}
+
+gdb_test_exact "print (enum flag_enum) (FOO_MASK)" \
+    { = 0x7 [FOO_1 | FOO_2 | FOO_3]}
+
+gdb_test_exact "print (enum flag_enum) (FOO_MASK | (BAR_MASK & ~BAR_2))" \
+    { = 0x57 [FOO_1 | FOO_2 | FOO_3 | BAR_1 | BAR_3]}
+
+gdb_test_exact "print (enum flag_enum) (0x4 + 0x8)" \
+    { = 0xc [FOO_3 | <unknown: 0x8>]}


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