Handle var_zuinteger and var_zuinteger_unlimited from Python
authorTom Tromey <tom@tromey.com>
Thu, 26 Apr 2018 22:18:07 +0000 (16:18 -0600)
committerTom Tromey <tom@tromey.com>
Wed, 2 May 2018 16:31:55 +0000 (10:31 -0600)
PR python/20084 points out that the Python API doesn't handle the
var_zuinteger and var_zuinteger_unlimited parameter types.

This patch adds support for these types.

Regression tested on x86-64 Fedora 26.

ChangeLog
2018-05-02  Tom Tromey  <tom@tromey.com>

PR python/20084:
* python/python.c (gdbpy_parameter_value): Handle var_zuinteger
and var_zuinteger_unlimited.
* python/py-param.c (struct parm_constant): Add PARAM_ZUINTEGER
and PARAM_ZUINTEGER_UNLIMITED.
(set_parameter_value): Handle var_zuinteger and
var_zuinteger_unlimited.
(add_setshow_generic): Likewise.
(parmpy_init): Likewise.

doc/ChangeLog
2018-05-02  Tom Tromey  <tom@tromey.com>

PR python/20084:
* python.texi (Parameters In Python): Document PARAM_ZUINTEGER and
PARAM_ZUINTEGER_UNLIMITED.

testsuite/ChangeLog
2018-05-02  Tom Tromey  <tom@tromey.com>

PR python/20084:
* gdb.python/py-parameter.exp: Add PARAM_ZUINTEGER and
PARAM_ZUINTEGER_UNLIMITED tests.

gdb/ChangeLog
gdb/doc/ChangeLog
gdb/doc/python.texi
gdb/python/py-param.c
gdb/python/python.c
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.python/py-parameter.exp

index 85f7525a3ea1a1824ac008973087ca4fac5e4690..f326c8e2d35642342bd979ed812dcd9142f9fd98 100644 (file)
@@ -1,3 +1,15 @@
+2018-05-02  Tom Tromey  <tom@tromey.com>
+
+       PR python/20084:
+       * python/python.c (gdbpy_parameter_value): Handle var_zuinteger
+       and var_zuinteger_unlimited.
+       * python/py-param.c (struct parm_constant): Add PARAM_ZUINTEGER
+       and PARAM_ZUINTEGER_UNLIMITED.
+       (set_parameter_value): Handle var_zuinteger and
+       var_zuinteger_unlimited.
+       (add_setshow_generic): Likewise.
+       (parmpy_init): Likewise.
+
 2018-04-28  Dan Robertson  <danlrobertson89@gmail.com>
 
        PR rust/23124
index 2da4984ff9bd65bc9f18140ae4ad7207983e9389..9f5063f99dc4631fe6e42815b003b4ac2d48ba79 100644 (file)
@@ -1,3 +1,9 @@
+2018-05-02  Tom Tromey  <tom@tromey.com>
+
+       PR python/20084:
+       * python.texi (Parameters In Python): Document PARAM_ZUINTEGER and
+       PARAM_ZUINTEGER_UNLIMITED.
+
 2018-04-30  Tom Tromey  <tom@tromey.com>
 
        * python.texi (Types In Python): Document Type.align.
index 05703fbde6cb8fe1436851ab3abab0b9a0593a73..c471e57d5d736528b8b0f11c7948af9b7b320a6c 100644 (file)
@@ -3807,6 +3807,19 @@ The value is a filename.  This is just like
 The value is an integer.  This is like @code{PARAM_INTEGER}, except 0
 is interpreted as itself.
 
+@findex PARAM_ZUINTEGER
+@findex gdb.PARAM_ZUINTEGER
+@item gdb.PARAM_ZUINTEGER
+The value is an unsigned integer.  This is like @code{PARAM_INTEGER},
+except 0 is interpreted as itself, and the value cannot be negative.
+
+@findex PARAM_ZUINTEGER_UNLIMITED
+@findex gdb.PARAM_ZUINTEGER_UNLIMITED
+@item gdb.PARAM_ZUINTEGER_UNLIMITED
+The value is a signed integer.  This is like @code{PARAM_ZUINTEGER},
+except the special value -1 should be interpreted to mean
+``unlimited''.  Other negative values are not allowed.
+
 @findex PARAM_ENUM
 @findex gdb.PARAM_ENUM
 @item gdb.PARAM_ENUM
index 0f8d9b6b4221bddeb4fc76084710b7c2c95b7800..22b26b26da20b2a916541d0218ce40cd28a30afe 100644 (file)
@@ -47,6 +47,8 @@ struct parm_constant parm_constants[] =
   { "PARAM_OPTIONAL_FILENAME", var_optional_filename },
   { "PARAM_FILENAME", var_filename },
   { "PARAM_ZINTEGER", var_zinteger },
+  { "PARAM_ZUINTEGER", var_zuinteger },
+  { "PARAM_ZUINTEGER_UNLIMITED", var_zuinteger_unlimited },
   { "PARAM_ENUM", var_enum },
   { NULL, 0 }
 };
@@ -225,6 +227,8 @@ set_parameter_value (parmpy_object *self, PyObject *value)
     case var_integer:
     case var_zinteger:
     case var_uinteger:
+    case var_zuinteger:
+    case var_zuinteger_unlimited:
       {
        long l;
        int ok;
@@ -239,20 +243,33 @@ set_parameter_value (parmpy_object *self, PyObject *value)
        if (! gdb_py_int_as_long (value, &l))
          return -1;
 
-       if (self->type == var_uinteger)
+       switch (self->type)
          {
-           ok = (l >= 0 && l <= UINT_MAX);
+         case var_uinteger:
            if (l == 0)
              l = UINT_MAX;
-         }
-       else if (self->type == var_integer)
-         {
+           /* Fall through.  */
+         case var_zuinteger:
+           ok = (l >= 0 && l <= UINT_MAX);
+           break;
+
+         case var_zuinteger_unlimited:
+           ok = (l >= -1 && l <= INT_MAX);
+           break;
+
+         case var_integer:
            ok = (l >= INT_MIN && l <= INT_MAX);
            if (l == 0)
              l = INT_MAX;
+           break;
+
+         case var_zinteger:
+           ok = (l >= INT_MIN && l <= INT_MAX);
+           break;
+
+         default:
+           gdb_assert_not_reached ("unknown var_ constant");
          }
-       else
-         ok = (l >= INT_MIN && l <= INT_MAX);
 
        if (! ok)
          {
@@ -261,7 +278,10 @@ set_parameter_value (parmpy_object *self, PyObject *value)
            return -1;
          }
 
-       self->value.intval = (int) l;
+       if (self->type == var_uinteger || self->type == var_zuinteger)
+         self->value.uintval = (unsigned) l;
+       else
+         self->value.intval = (int) l;
        break;
       }
 
@@ -526,6 +546,21 @@ add_setshow_generic (int parmclass, enum command_class cmdclass,
                                set_list, show_list);
       break;
 
+    case var_zuinteger:
+      add_setshow_zuinteger_cmd (cmd_name, cmdclass,
+                               &self->value.uintval, set_doc, show_doc,
+                               help_doc, get_set_value, get_show_value,
+                               set_list, show_list);
+      break;
+
+    case var_zuinteger_unlimited:
+      add_setshow_zuinteger_unlimited_cmd (cmd_name, cmdclass,
+                                          &self->value.intval, set_doc,
+                                          show_doc, help_doc, get_set_value,
+                                          get_show_value,
+                                          set_list, show_list);
+      break;
+
     case var_enum:
       add_setshow_enum_cmd (cmd_name, cmdclass, self->enumeration,
                            &self->value.cstringval, set_doc, show_doc,
@@ -658,7 +693,8 @@ parmpy_init (PyObject *self, PyObject *args, PyObject *kwds)
       && parmclass != var_uinteger && parmclass != var_integer
       && parmclass != var_string && parmclass != var_string_noescape
       && parmclass != var_optional_filename && parmclass != var_filename
-      && parmclass != var_zinteger && parmclass != var_enum)
+      && parmclass != var_zinteger && parmclass != var_zuinteger
+      && parmclass != var_zuinteger_unlimited && parmclass != var_enum)
     {
       PyErr_SetString (PyExc_RuntimeError,
                       _("Invalid parameter class argument."));
index 0dd7d6a6adad1ede603eda3835eb6f39fe0006d7..fbd6770479535f3864ea2864fa0d5d8cb926a777 100644 (file)
@@ -467,6 +467,7 @@ gdbpy_parameter_value (enum var_types type, void *var)
        Py_RETURN_NONE;
       /* Fall through.  */
     case var_zinteger:
+    case var_zuinteger_unlimited:
       return PyLong_FromLong (* (int *) var);
 
     case var_uinteger:
@@ -477,6 +478,12 @@ gdbpy_parameter_value (enum var_types type, void *var)
          Py_RETURN_NONE;
        return PyLong_FromUnsignedLong (val);
       }
+
+    case var_zuinteger:
+      {
+       unsigned int val = * (unsigned int *) var;
+       return PyLong_FromUnsignedLong (val);
+      }
     }
 
   return PyErr_Format (PyExc_RuntimeError,
index cb5e6d02f851da0da798dc460af10a25ab347b6c..5bbcb2f4206e5c10133c31fe4f831782c41d5456 100644 (file)
@@ -1,3 +1,9 @@
+2018-05-02  Tom Tromey  <tom@tromey.com>
+
+       PR python/20084:
+       * gdb.python/py-parameter.exp: Add PARAM_ZUINTEGER and
+       PARAM_ZUINTEGER_UNLIMITED tests.
+
 2018-04-28  Dan Robertson  <danlrobertson89@gmail.com>
 
        PR rust/23124
index 3cd1198462a3e805a64437c8a0d3b6cd02da7237..b9ff9f1ec0c6a4553342c9804d1264c15ae6b5b7 100644 (file)
@@ -179,3 +179,26 @@ gdb_test "python print (test_param.value)" "False" "test parameter value"
 gdb_test "help show print test-param" "State of the Test Parameter.*" "test show help"
 gdb_test "help set print test-param" "Set the state of the Test Parameter.*" "test set help"
 gdb_test "help set print" "set print test-param -- Set the state of the Test Parameter.*" "test general help"
+
+foreach kind {PARAM_ZUINTEGER PARAM_ZUINTEGER_UNLIMITED} {
+    gdb_py_test_multiple "Simple gdb $kind" \
+       "python" "" \
+       "class TestNodocParam (gdb.Parameter):" "" \
+       "   def __init__ (self, name):" "" \
+       "      super (TestNodocParam, self).__init__ (name, gdb.COMMAND_DATA, gdb.$kind)" "" \
+       "      self.value = 0" "" \
+       "test_param_$kind = TestNodocParam ('test-$kind')" "" \
+       "end"
+
+    gdb_test "python print(gdb.parameter('test-$kind'))" "0"
+
+    gdb_test "python test_param_$kind.value = -5" "RuntimeError: Range exceeded.*"
+
+    if {$kind == "PARAM_ZUINTEGER"} {
+       gdb_test "python test_param_$kind.value = -1" "RuntimeError: Range exceeded.*"
+    } else {
+       gdb_test_no_output "python test_param_$kind.value = -1" ""
+       gdb_test "python print(gdb.parameter('test-$kind'))" "-1" \
+           "check that PARAM_ZUINTEGER value is -1 after setting"
+    }
+}