From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 40564 invoked by alias); 20 Sep 2016 13:26:38 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Received: (qmail 40550 invoked by uid 89); 20 Sep 2016 13:26:37 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-5.0 required=5.0 tests=BAYES_00,RP_MATCHES_RCVD,SPF_HELO_PASS autolearn=ham version=3.3.2 spammy=OTHER, 1011,7, 876, controversial X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 20 Sep 2016 13:26:36 +0000 Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id D44808553C for ; Tue, 20 Sep 2016 13:26:34 +0000 (UTC) Received: from localhost (ovpn-116-66.ams2.redhat.com [10.36.116.66]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id u8KDQXoB002737 for ; Tue, 20 Sep 2016 09:26:34 -0400 Date: Tue, 20 Sep 2016 13:34:00 -0000 From: Jonathan Wakely To: gdb-patches@sourceware.org Subject: [PATCH] Implement floordiv operator for gdb.Value Message-ID: <20160920132633.GA897@redhat.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="h31gzZEtNLTqOjlF" Content-Disposition: inline X-Clacks-Overhead: GNU Terry Pratchett User-Agent: Mutt/1.7.0 (2016-08-17) X-SW-Source: 2016-09/txt/msg00221.txt.bz2 --h31gzZEtNLTqOjlF Content-Type: text/plain; charset=us-ascii; format=flowed Content-Disposition: inline Content-length: 961 This is my attempt to implement the // operator on gdb.Value objects. There is already BINOP_INTDIV which works fine for integral types, but for floats I use BINOP_DIV and then call floor() on the result. This doesn't support decimal floats though. Is this a reasonable solution? Is the test sufficient? I have a follow-up patch which changes the meaning of the / operator for gdb.Value when built against Python 3, to be consistent with Python (see comment 1 in the Bugzilla PR) but I expect that to be more controversial :-) gdb/ChangeLog: 2016-09-20 Jonathan Wakely PR python/20624 * python/py-value.c (VALPY_FLOORDIV): Define new enumerator. (valpy_binop_throw): Handle VALPY_FLOORDIV. (valpy_floordiv): New function. (value_object_as_number): Set valpy_floordiv in relevant slot. gdb/testsuite/ChangeLog: 2016-09-20 Jonathan Wakely PR python/20624 * gdb.python/py-value.exp: Test floor division. --h31gzZEtNLTqOjlF Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="floordiv.txt" Content-length: 4343 commit 3a019f3ba61bde5320419f5782d8f2554ac55ace Author: Jonathan Wakely Date: Tue Sep 20 10:38:35 2016 +0100 gdb: Implement floordiv operator for gdb.Value gdb/ChangeLog: 2016-09-20 Jonathan Wakely PR python/20624 * python/py-value.c (VALPY_FLOORDIV): Define new enumerator. (valpy_binop_throw): Handle VALPY_FLOORDIV. (valpy_floordiv): New function. (value_object_as_number): Set valpy_floordiv in relevant slot. gdb/testsuite/ChangeLog: 2016-09-20 Jonathan Wakely PR python/20624 * gdb.python/py-value.exp: Test floor division. diff --git a/gdb/python/py-value.c b/gdb/python/py-value.c index 21e9247..f6a6c11 100644 --- a/gdb/python/py-value.c +++ b/gdb/python/py-value.c @@ -1011,7 +1011,8 @@ enum valpy_opcode VALPY_RSH, VALPY_BITAND, VALPY_BITOR, - VALPY_BITXOR + VALPY_BITXOR, + VALPY_FLOORDIV }; /* If TYPE is a reference, return the target; otherwise return TYPE. */ @@ -1032,6 +1033,7 @@ valpy_binop_throw (enum valpy_opcode opcode, PyObject *self, PyObject *other) struct value *res_val = NULL; enum exp_opcode op = OP_NULL; int handled = 0; + bool floor_it = false; /* If the gdb.Value object is the second operand, then it will be passed to us as the OTHER argument, and SELF will be an entirely @@ -1113,6 +1115,22 @@ valpy_binop_throw (enum valpy_opcode opcode, PyObject *self, PyObject *other) case VALPY_REM: op = BINOP_REM; break; + case VALPY_FLOORDIV: + { + struct type *ltype = value_type (arg1); + struct type *rtype = value_type (arg2); + ltype = check_typedef (ltype); + rtype = check_typedef (rtype); + if (TYPE_CODE (ltype) == TYPE_CODE_FLT + || TYPE_CODE (rtype) == TYPE_CODE_FLT) + { + op = BINOP_DIV; + floor_it = true; + } + else + op = BINOP_INTDIV; + } + break; case VALPY_POW: op = BINOP_EXP; break; @@ -1142,7 +1160,15 @@ valpy_binop_throw (enum valpy_opcode opcode, PyObject *self, PyObject *other) } if (res_val) - result = value_to_value_object (res_val); + { + if (floor_it) + { + double d = value_as_double (res_val); + d = floor (d); + res_val = value_from_double (value_type (res_val), d); + } + result = value_to_value_object (res_val); + } do_cleanups (cleanup); return result; @@ -1200,6 +1226,12 @@ valpy_remainder (PyObject *self, PyObject *other) } static PyObject * +valpy_floordiv (PyObject *self, PyObject *other) +{ + return valpy_binop (VALPY_FLOORDIV, self, other); +} + +static PyObject * valpy_power (PyObject *self, PyObject *other, PyObject *unused) { /* We don't support the ternary form of pow. I don't know how to express @@ -1837,7 +1869,7 @@ static PyNumberMethods value_object_as_number = { NULL, /* nb_inplace_and */ NULL, /* nb_inplace_xor */ NULL, /* nb_inplace_or */ - NULL, /* nb_floor_divide */ + valpy_floordiv, /* nb_floor_divide */ valpy_divide, /* nb_true_divide */ NULL, /* nb_inplace_floor_divide */ NULL, /* nb_inplace_true_divide */ diff --git a/gdb/testsuite/gdb.python/py-value.exp b/gdb/testsuite/gdb.python/py-value.exp index 57a9ba1..81837e9 100644 --- a/gdb/testsuite/gdb.python/py-value.exp +++ b/gdb/testsuite/gdb.python/py-value.exp @@ -87,6 +87,8 @@ proc test_value_numeric_ops {} { gdb_test "python print ('result = ' + str(f/g))" " = 0.5" "divide two double values" gdb_test "python print ('result = ' + str(i%j))" " = 1" "take remainder of two integer values" # Remainder of float is implemented in Python but not in GDB's value system. + gdb_test "python print ('result = ' + str(i//j))" " = 2" "floor-divide two integer values" + gdb_test "python print ('result = ' + str(f//g))" " = 0" "floor-divide two double values" gdb_test "python print ('result = ' + str(i**j))" " = 25" "integer value raised to the power of another integer value" gdb_test "python print ('result = ' + str(g**j))" " = 6.25" "double value raised to the power of integer value" --h31gzZEtNLTqOjlF--