From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED!not-for-mail From: Paul Eggert Newsgroups: gmane.emacs.bugs Subject: bug#32252: [PATCH] %o and %x now format signed numbers Date: Mon, 23 Jul 2018 12:12:50 -0700 Message-ID: <20180723191250.19182-1-eggert@cs.ucla.edu> NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable X-Trace: blaine.gmane.org 1532373129 24643 195.159.176.226 (23 Jul 2018 19:12:09 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Mon, 23 Jul 2018 19:12:09 +0000 (UTC) Cc: Paul Eggert To: 32252@debbugs.gnu.org Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Mon Jul 23 21:12:05 2018 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by blaine.gmane.org with esmtp (Exim 4.84_2) (envelope-from ) id 1fhgFZ-0006IU-1v for geb-bug-gnu-emacs@m.gmane.org; Mon, 23 Jul 2018 21:12:05 +0200 Original-Received: from localhost ([::1]:36120 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fhgHf-0000KD-Gl for geb-bug-gnu-emacs@m.gmane.org; Mon, 23 Jul 2018 15:14:15 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:52310) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fhgHY-0000K8-5L for bug-gnu-emacs@gnu.org; Mon, 23 Jul 2018 15:14:09 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fhgHS-0002h0-LH for bug-gnu-emacs@gnu.org; Mon, 23 Jul 2018 15:14:07 -0400 Original-Received: from debbugs.gnu.org ([208.118.235.43]:49320) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1fhgHS-0002gq-G2 for bug-gnu-emacs@gnu.org; Mon, 23 Jul 2018 15:14:02 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1fhgHS-0003XT-7E for bug-gnu-emacs@gnu.org; Mon, 23 Jul 2018 15:14:02 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Paul Eggert Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Mon, 23 Jul 2018 19:14:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: report 32252 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch X-Debbugs-Original-To: bug-gnu-emacs@gnu.org Original-Received: via spool by submit@debbugs.gnu.org id=B.153237319513538 (code B ref -1); Mon, 23 Jul 2018 19:14:02 +0000 Original-Received: (at submit) by debbugs.gnu.org; 23 Jul 2018 19:13:15 +0000 Original-Received: from localhost ([127.0.0.1]:54338 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1fhgGh-0003WI-1Z for submit@debbugs.gnu.org; Mon, 23 Jul 2018 15:13:15 -0400 Original-Received: from eggs.gnu.org ([208.118.235.92]:32998) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1fhgGf-0003W5-Ak for submit@debbugs.gnu.org; Mon, 23 Jul 2018 15:13:14 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fhgGY-0002G3-I3 for submit@debbugs.gnu.org; Mon, 23 Jul 2018 15:13:08 -0400 Original-Received: from lists.gnu.org ([2001:4830:134:3::11]:50828) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1fhgGY-0002Fx-Ed for submit@debbugs.gnu.org; Mon, 23 Jul 2018 15:13:06 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:52201) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fhgGW-0000HY-Nq for bug-gnu-emacs@gnu.org; Mon, 23 Jul 2018 15:13:06 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fhgGR-0002D5-J5 for bug-gnu-emacs@gnu.org; Mon, 23 Jul 2018 15:13:04 -0400 Original-Received: from zimbra.cs.ucla.edu ([131.179.128.68]:52600) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1fhgGR-0002CJ-32 for bug-gnu-emacs@gnu.org; Mon, 23 Jul 2018 15:12:59 -0400 Original-Received: from localhost (localhost [127.0.0.1]) by zimbra.cs.ucla.edu (Postfix) with ESMTP id D0B31160E02 for ; Mon, 23 Jul 2018 12:12:57 -0700 (PDT) Original-Received: from zimbra.cs.ucla.edu ([127.0.0.1]) by localhost (zimbra.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10032) with ESMTP id AO7EXxHsK51C; Mon, 23 Jul 2018 12:12:56 -0700 (PDT) Original-Received: from localhost (localhost [127.0.0.1]) by zimbra.cs.ucla.edu (Postfix) with ESMTP id 85D4E160DFD; Mon, 23 Jul 2018 12:12:56 -0700 (PDT) X-Virus-Scanned: amavisd-new at zimbra.cs.ucla.edu Original-Received: from zimbra.cs.ucla.edu ([127.0.0.1]) by localhost (zimbra.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id 5e0yfoIrYJJS; Mon, 23 Jul 2018 12:12:56 -0700 (PDT) Original-Received: from Penguin.CS.UCLA.EDU (Penguin.CS.UCLA.EDU [131.179.64.200]) by zimbra.cs.ucla.edu (Postfix) with ESMTPSA id 61434160DFC; Mon, 23 Jul 2018 12:12:56 -0700 (PDT) X-Mailer: git-send-email 2.17.1 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6.x X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 208.118.235.43 X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.org gmane.emacs.bugs:148866 Archived-At: Treat integers as signed numbers when using the %o and %x format specifiers, instead of treating them as a machine-dependent two=E2=80=99s complement representation. This should make Emacs more machine-independent, and better-insulated for future changes involving bignums. The new compatibility variable =E2=80=98binary-as-unsigned=E2=80=99 enables the old machine-dependent behavior. This is a simplified version of the change proposed in: https://lists.gnu.org/r/emacs-devel/2018-07/msg00763.html I simplified that proposal by omitting bitwidth modifiers, as I could not find an any example uses in the Emacs source code that needed them and doing them correctly would have been quite a bit more work for apparently little benefit. * doc/lispref/strings.texi (Formatting Strings): * etc/NEWS: Document change. * src/editfns.c (styled_format): Treat integers as signed numbers even with %o and %x. Support the + and space flags with %o and %x, since they=E2=80=99re about signs. (syms_of_editfns): New compatibility variable binary-as-signed. * test/src/editfns-tests.el (read-large-integer): Test that maximal integers can be read after printing with all integer formats. (format-%o-invalid-float): Adjust test to match new behavior, which allows negative octal. --- doc/lispref/strings.texi | 6 +++--- etc/NEWS | 8 ++++++++ src/editfns.c | 42 ++++++++++++++++++++++++++++++++++----- test/src/editfns-tests.el | 11 +++++----- 4 files changed, 54 insertions(+), 13 deletions(-) diff --git a/doc/lispref/strings.texi b/doc/lispref/strings.texi index 2fff3c7c75..582561fe42 100644 --- a/doc/lispref/strings.texi +++ b/doc/lispref/strings.texi @@ -922,7 +922,7 @@ Formatting Strings @item %o @cindex integer to octal Replace the specification with the base-eight representation of an -unsigned integer. The object can also be a nonnegative floating-point +integer. The object can also be a floating-point number that is formatted as an integer, dropping any fraction, if the integer does not exceed machine limits. =20 @@ -935,8 +935,8 @@ Formatting Strings @itemx %X @cindex integer to hexadecimal Replace the specification with the base-sixteen representation of an -unsigned integer. @samp{%x} uses lower case and @samp{%X} uses upper -case. The object can also be a nonnegative floating-point number that +integer. @samp{%x} uses lower case and @samp{%X} uses upper +case. The object can also be a floating-point number that is formatted as an integer, dropping any fraction, if the integer does not exceed machine limits. =20 diff --git a/etc/NEWS b/etc/NEWS index fc2a5d4c03..b735cf49b3 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -697,6 +697,14 @@ To get the old behavior, set the new, experimental v= ariable read-integer-overflow-as-float to t and please email 30408@debbugs.gnu.org if you need that. (Bug#30408). =20 ++++ +** Numbers formatted via %o or %x are now formatted as signed integers. +Formerly they were formatted using machine-dependent two's complement +representations. To get the old behavior, set the new, experimental +variable binary-as-unsigned to t and please email emacs-devel@gnu.org +if you need that. Because %o and %x now format signed integers, they +now support the + and space flags. + --- ** Some functions and variables obsolete since Emacs 22 have been remove= d: archive-mouse-extract, assoc-ignore-case, assoc-ignore-representation, diff --git a/src/editfns.c b/src/editfns.c index 09f836c3eb..a8fc499d63 100644 --- a/src/editfns.c +++ b/src/editfns.c @@ -4196,8 +4196,8 @@ contain either numbered or unnumbered %-sequences b= ut not both, except that %% can be mixed with numbered %-sequences. =20 The + flag character inserts a + before any nonnegative number, while a -space inserts a space before any nonnegative number; these flags only -affect %d, %e, %f, and %g sequences, and the + flag takes precedence. +space inserts a space before any nonnegative number; these flags +affect only numeric %-sequences, and the + flag takes precedence. The - and 0 flags affect the width specifier, as described below. =20 The # flag means to use an alternate display form for %o, %x, %X, %e, @@ -4736,19 +4736,42 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args= , bool message) } else { - /* Don't sign-extend for octal or hex printing. */ uprintmax_t x; + bool negative; if (INTEGERP (arg)) - x =3D XUINT (arg); + { + EMACS_INT i; + if (binary_as_unsigned) + { + i =3D XUINT (arg); + negative =3D false; + } + else + { + i =3D XINT (arg); + negative =3D i < 0; + if (negative) + i =3D -i; + } + x =3D i; + } else { double d =3D XFLOAT_DATA (arg); double uprintmax =3D TYPE_MAXIMUM (uprintmax_t); + negative =3D d < 0; + if (negative) + d =3D -d; if (! (0 <=3D d && d < uprintmax + 1)) xsignal1 (Qoverflow_error, arg); x =3D d; + negative &=3D x !=3D 0; } - sprintf_bytes =3D sprintf (sprintf_buf, convspec, prec, x); + sprintf_buf[0] =3D negative ? '-' : plus_flag ? '+' : ' '; + bool signedp =3D negative | plus_flag | space_flag; + sprintf_bytes =3D sprintf (sprintf_buf + signedp, + convspec, prec, x); + sprintf_bytes +=3D signedp; } =20 /* Now the length of the formatted item is known, except it omits @@ -5558,6 +5581,15 @@ functions if all the text being accessed has this = property. */); DEFVAR_LISP ("operating-system-release", Voperating_system_release, doc: /* The release of the operating system Emacs is running on.= */); =20 + DEFVAR_BOOL ("binary-as-unsigned", + binary_as_unsigned, + doc: /* Non-nil means `format' %x and %o treat numbers as unsign= ed. +Nil (the default) means to treat them as signed. +Treating them as unsigned has machine-dependent results. + +This variable is experimental; email emacs-devel@gnu.org if you need it.= */); + binary_as_unsigned =3D false; + defsubr (&Spropertize); defsubr (&Schar_equal); defsubr (&Sgoto_char); diff --git a/test/src/editfns-tests.el b/test/src/editfns-tests.el index c828000bb4..57a2081fc5 100644 --- a/test/src/editfns-tests.el +++ b/test/src/editfns-tests.el @@ -165,15 +165,16 @@ transpose-test-get-byte-positions :type 'overflow-error) (should-error (read (substring (format "%d" most-negative-fixnum) 1)) :type 'overflow-error) - (should-error (read (format "#x%x" most-negative-fixnum)) - :type 'overflow-error) - (should-error (read (format "#o%o" most-negative-fixnum)) - :type 'overflow-error) + (dolist (fmt '("%d" "%s" "#o%o" "#x%x")) + (dolist (val (list most-negative-fixnum (1+ most-negative-fixnum) + -1 0 1 + (1- most-positive-fixnum) most-positive-fixnum)) + (should (eq val (read (format fmt val)))))) (should-error (read (format "#32rG%x" most-positive-fixnum)) :type 'overflow-error)) =20 (ert-deftest format-%o-invalid-float () - (should-error (format "%o" -1e-37) + (should-error (format "%o" -1e+INF) :type 'overflow-error)) =20 ;; Bug#31938 --=20 2.17.1