From: Paul Eggert <eggert@cs.ucla.edu>
To: 32252@debbugs.gnu.org
Cc: Paul Eggert <eggert@cs.ucla.edu>
Subject: bug#32252: [PATCH] %o and %x now format signed numbers
Date: Mon, 23 Jul 2018 12:12:50 -0700 [thread overview]
Message-ID: <20180723191250.19182-1-eggert@cs.ucla.edu> (raw)
Treat integers as signed numbers when using the %o
and %x format specifiers, instead of treating them as
a machine-dependent two’s complement representation.
This should make Emacs more machine-independent, and
better-insulated for future changes involving bignums.
The new compatibility variable ‘binary-as-unsigned’
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’re 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.
@@ -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.
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 variable
read-integer-overflow-as-float to t and please email
30408@debbugs.gnu.org if you need that. (Bug#30408).
++++
+** 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 removed:
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 but not both, except
that %% can be mixed with numbered %-sequences.
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.
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 = XUINT (arg);
+ {
+ EMACS_INT i;
+ if (binary_as_unsigned)
+ {
+ i = XUINT (arg);
+ negative = false;
+ }
+ else
+ {
+ i = XINT (arg);
+ negative = i < 0;
+ if (negative)
+ i = -i;
+ }
+ x = i;
+ }
else
{
double d = XFLOAT_DATA (arg);
double uprintmax = TYPE_MAXIMUM (uprintmax_t);
+ negative = d < 0;
+ if (negative)
+ d = -d;
if (! (0 <= d && d < uprintmax + 1))
xsignal1 (Qoverflow_error, arg);
x = d;
+ negative &= x != 0;
}
- sprintf_bytes = sprintf (sprintf_buf, convspec, prec, x);
+ sprintf_buf[0] = negative ? '-' : plus_flag ? '+' : ' ';
+ bool signedp = negative | plus_flag | space_flag;
+ sprintf_bytes = sprintf (sprintf_buf + signedp,
+ convspec, prec, x);
+ sprintf_bytes += signedp;
}
/* 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. */);
+ DEFVAR_BOOL ("binary-as-unsigned",
+ binary_as_unsigned,
+ doc: /* Non-nil means `format' %x and %o treat numbers as unsigned.
+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 = 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))
(ert-deftest format-%o-invalid-float ()
- (should-error (format "%o" -1e-37)
+ (should-error (format "%o" -1e+INF)
:type 'overflow-error))
;; Bug#31938
--
2.17.1
next reply other threads:[~2018-07-23 19:12 UTC|newest]
Thread overview: 53+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-07-23 19:12 Paul Eggert [this message]
2018-07-23 19:48 ` bug#32252: [PATCH] %o and %x now format signed numbers Helmut Eller
2018-07-23 19:49 ` Drew Adams
2018-07-23 23:30 ` Paul Eggert
2018-07-24 1:20 ` Drew Adams
2018-07-24 2:04 ` Paul Eggert
2018-07-24 2:38 ` Eli Zaretskii
2018-07-24 2:44 ` Paul Eggert
2018-07-24 14:29 ` Eli Zaretskii
2018-07-24 4:15 ` Drew Adams
2018-07-23 23:39 ` Paul Eggert
2018-07-24 1:16 ` Drew Adams
2018-07-25 3:53 ` Richard Stallman
2018-07-25 21:56 ` Drew Adams
2018-07-27 3:20 ` Richard Stallman
2018-07-24 4:49 ` Helmut Eller
2018-07-24 14:22 ` Paul Eggert
2018-07-24 14:35 ` Andreas Schwab
2018-07-24 18:15 ` Helmut Eller
2018-07-25 0:50 ` Paul Eggert
2018-07-25 2:41 ` Eli Zaretskii
2018-07-25 17:21 ` Paul Eggert
2018-07-25 17:28 ` Eli Zaretskii
2018-07-26 7:44 ` Paul Eggert
2018-07-26 8:04 ` Helmut Eller
2018-07-26 8:16 ` Paul Eggert
2018-07-25 6:58 ` Helmut Eller
2018-07-26 7:59 ` Paul Eggert
2018-07-26 8:43 ` Helmut Eller
2018-07-26 9:15 ` Paul Eggert
2018-07-26 9:39 ` Helmut Eller
2018-07-26 9:31 ` Andreas Schwab
2018-07-26 9:40 ` Robert Pluim
2018-07-26 9:56 ` Helmut Eller
2018-07-26 16:55 ` Paul Eggert
2018-07-26 17:16 ` Helmut Eller
2018-07-26 17:50 ` Paul Eggert
2018-07-26 18:35 ` Helmut Eller
2018-07-26 21:07 ` Paul Eggert
2018-07-24 18:27 ` Eli Zaretskii
2018-07-25 0:54 ` Paul Eggert
2018-07-25 8:09 ` Andreas Schwab
2018-07-25 20:16 ` Paul Eggert
2018-07-25 14:17 ` Eli Zaretskii
2018-07-25 23:33 ` Brett Gilio
2018-07-26 7:26 ` Paul Eggert
2018-07-24 16:26 ` Andy Moreton
2018-07-25 10:08 ` Andy Moreton
2018-07-26 12:52 ` Andy Moreton
2018-07-26 12:54 ` Andy Moreton
2018-07-26 17:18 ` Helmut Eller
2018-08-23 9:37 ` Helmut Eller
2022-07-04 1:03 ` bug#32252: i find binary-as-unsigned to be very helpful snickerbockers
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20180723191250.19182-1-eggert@cs.ucla.edu \
--to=eggert@cs.ucla.edu \
--cc=32252@debbugs.gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).