aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Eggert2019-07-23 01:42:32 -0700
committerPaul Eggert2019-07-23 01:46:41 -0700
commitdfb0ba79b5f41ca6fed25a03d2a5cd6996ec4753 (patch)
tree87426b1fde8da618b4e7657b09bc256f5c011dcc
parent56a3e4a5d366a8453608d9a604ebd5ddb4e52245 (diff)
downloademacs-dfb0ba79b5f41ca6fed25a03d2a5cd6996ec4753.tar.gz
emacs-dfb0ba79b5f41ca6fed25a03d2a5cd6996ec4753.zip
Support "%x" etc. formats on more floats
* doc/lispref/strings.texi (Formatting Strings): Document this. * src/editfns.c (styled_format): Support %o, %x, and %X on finite floats less than zero or greater than UINTMAX_MAX. * test/src/editfns-tests.el (format-%x-large-float) (read-large-integer, format-%o-negative-float): Adjust tests to match extended behavior. Rename the latter test from format-%o-invalid-float, since the float is no longer invalid. * test/src/editfns-tests.el (format-%x-large-float) (read-large-integer): Test this.
-rw-r--r--doc/lispref/strings.texi10
-rw-r--r--src/editfns.c17
-rw-r--r--test/src/editfns-tests.el23
3 files changed, 28 insertions, 22 deletions
diff --git a/doc/lispref/strings.texi b/doc/lispref/strings.texi
index 521f163663d..69d571fab8a 100644
--- a/doc/lispref/strings.texi
+++ b/doc/lispref/strings.texi
@@ -923,9 +923,8 @@ Functions}). Thus, strings are enclosed in @samp{"} characters, and
923@cindex integer to octal 923@cindex integer to octal
924Replace the specification with the base-eight representation of an 924Replace the specification with the base-eight representation of an
925integer. Negative integers are formatted in a platform-dependent 925integer. Negative integers are formatted in a platform-dependent
926way. The object can also be a nonnegative floating-point 926way. The object can also be a floating-point number that is formatted
927number that is formatted as an integer, dropping any fraction, if the 927as an integer, dropping any fraction.
928integer does not exceed machine limits.
929 928
930@item %d 929@item %d
931Replace the specification with the base-ten representation of a signed 930Replace the specification with the base-ten representation of a signed
@@ -938,9 +937,8 @@ formatted as an integer, dropping any fraction.
938Replace the specification with the base-sixteen representation of an 937Replace the specification with the base-sixteen representation of an
939integer. Negative integers are formatted in a platform-dependent 938integer. Negative integers are formatted in a platform-dependent
940way. @samp{%x} uses lower case and @samp{%X} uses upper 939way. @samp{%x} uses lower case and @samp{%X} uses upper
941case. The object can also be a nonnegative floating-point number that 940case. The object can also be a floating-point number that is
942is formatted as an integer, dropping any fraction, if the integer does 941formatted as an integer, dropping any fraction.
943not exceed machine limits.
944 942
945@item %c 943@item %c
946Replace the specification with the character which is the value given. 944Replace the specification with the character which is the value given.
diff --git a/src/editfns.c b/src/editfns.c
index 8e0c0c451e6..1b33f397110 100644
--- a/src/editfns.c
+++ b/src/editfns.c
@@ -3594,6 +3594,7 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message)
3594 sprintf_bytes = prec != 0; 3594 sprintf_bytes = prec != 0;
3595 } 3595 }
3596 else if (BIGNUMP (arg)) 3596 else if (BIGNUMP (arg))
3597 bignum_arg:
3597 { 3598 {
3598 int base = ((conversion == 'd' || conversion == 'i') ? 10 3599 int base = ((conversion == 'd' || conversion == 'i') ? 10
3599 : conversion == 'o' ? 8 : 16); 3600 : conversion == 'o' ? 8 : 16);
@@ -3655,11 +3656,17 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message)
3655 else 3656 else
3656 { 3657 {
3657 double d = XFLOAT_DATA (arg); 3658 double d = XFLOAT_DATA (arg);
3658 double uintmax = UINTMAX_MAX; 3659 double abs_d = fabs (d);
3659 if (! (0 <= d && d < uintmax + 1)) 3660 if (abs_d < UINTMAX_MAX + 1.0)
3660 xsignal1 (Qoverflow_error, arg); 3661 {
3661 x = d; 3662 negative = d <= -1;
3662 negative = false; 3663 x = abs_d;
3664 }
3665 else
3666 {
3667 arg = double_to_integer (d);
3668 goto bignum_arg;
3669 }
3663 } 3670 }
3664 p[0] = negative ? '-' : plus_flag ? '+' : ' '; 3671 p[0] = negative ? '-' : plus_flag ? '+' : ' ';
3665 bool signedp = negative | plus_flag | space_flag; 3672 bool signedp = negative | plus_flag | space_flag;
diff --git a/test/src/editfns-tests.el b/test/src/editfns-tests.el
index 69cca5d2bdd..a1060808f66 100644
--- a/test/src/editfns-tests.el
+++ b/test/src/editfns-tests.el
@@ -165,13 +165,9 @@
165 (should (string-equal (format "%d" -18446744073709551616.0) 165 (should (string-equal (format "%d" -18446744073709551616.0)
166 "-18446744073709551616"))) 166 "-18446744073709551616")))
167 167
168;; Perhaps Emacs will be improved someday to return the correct
169;; answer for positive numbers instead of overflowing; in
170;; that case these tests will need to be changed. In the meantime make
171;; sure Emacs is reporting the overflow correctly.
172(ert-deftest format-%x-large-float () 168(ert-deftest format-%x-large-float ()
173 (should-error (format "%x" 18446744073709551616.0) 169 (should (string-equal (format "%x" 18446744073709551616.0)
174 :type 'overflow-error)) 170 "10000000000000000")))
175(ert-deftest read-large-integer () 171(ert-deftest read-large-integer ()
176 (should (eq (type-of (read (format "%d0" most-negative-fixnum))) 'integer)) 172 (should (eq (type-of (read (format "%d0" most-negative-fixnum))) 'integer))
177 (should (eq (type-of (read (format "%+d" (* -8.0 most-negative-fixnum)))) 173 (should (eq (type-of (read (format "%+d" (* -8.0 most-negative-fixnum))))
@@ -188,11 +184,16 @@
188 (dolist (val (list most-negative-fixnum (1+ most-negative-fixnum) 184 (dolist (val (list most-negative-fixnum (1+ most-negative-fixnum)
189 -1 0 1 185 -1 0 1
190 (1- most-positive-fixnum) most-positive-fixnum)) 186 (1- most-positive-fixnum) most-positive-fixnum))
191 (should (eq val (read (format fmt val))))))) 187 (should (eq val (read (format fmt val)))))
192 188 (dolist (val (list (1+ most-positive-fixnum)
193(ert-deftest format-%o-invalid-float () 189 (* 2 (1+ most-positive-fixnum))
194 (should-error (format "%o" -1e-37) 190 (* 4 (1+ most-positive-fixnum))
195 :type 'overflow-error)) 191 (* 8 (1+ most-positive-fixnum))
192 18446744073709551616.0))
193 (should (= val (read (format fmt val)))))))
194
195(ert-deftest format-%o-negative-float ()
196 (should (string-equal (format "%o" -1e-37) "0")))
196 197
197;; Bug#31938 198;; Bug#31938
198(ert-deftest format-%d-float () 199(ert-deftest format-%d-float ()