emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] feature/bignum d14808c 11/24: Make format handle bignums


From: Tom Tromey
Subject: [Emacs-diffs] feature/bignum d14808c 11/24: Make format handle bignums
Date: Fri, 13 Jul 2018 00:25:08 -0400 (EDT)

branch: feature/bignum
commit d14808cd271abf6a723bf495a6a01c14d18b5893
Author: Tom Tromey <address@hidden>
Commit: Tom Tromey <address@hidden>

    Make format handle bignums
    
    * src/editfns.c (styled_format): Handle bignums.
    * test/src/editfns-tests.el (read-large-integer): Update.
    (format-bignum): New test.
---
 src/editfns.c             | 22 +++++++++++++++++++++-
 test/src/editfns-tests.el | 33 +++++++++++++++++++++------------
 2 files changed, 42 insertions(+), 13 deletions(-)

diff --git a/src/editfns.c b/src/editfns.c
index 6b54b41..09c17cb 100644
--- a/src/editfns.c
+++ b/src/editfns.c
@@ -4489,6 +4489,25 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool 
message)
                conversion = 's';
              zero_flag = false;
            }
+         else if ((conversion == 'd' || conversion == 'i'
+                   || conversion == 'o' || conversion == 'x'
+                   || conversion == 'X')
+                  && BIGNUMP (arg))
+           {
+             int base = 10;
+
+             if (conversion == 'o')
+               base = 8;
+             else if (conversion == 'x')
+               base = 16;
+             else if (conversion == 'X')
+               base = -16;
+
+             char *str = mpz_get_str (NULL, base, XBIGNUM (arg)->value);
+             arg = make_unibyte_string (str, strlen (str));
+             xfree (str);
+             conversion = 's';
+           }
 
          if (SYMBOLP (arg))
            {
@@ -4600,7 +4619,8 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool 
message)
                      || conversion == 'X'))
            error ("Invalid format operation %%%c",
                   STRING_CHAR ((unsigned char *) format - 1));
-         else if (! (FIXNUMP (arg) || (FLOATP (arg) && conversion != 'c')))
+         else if (! (FIXNUMP (arg) || ((BIGNUMP (arg) || FLOATP (arg))
+                                       && conversion != 'c')))
            error ("Format specifier doesn't match argument type");
          else
            {
diff --git a/test/src/editfns-tests.el b/test/src/editfns-tests.el
index c828000..501e0d8 100644
--- a/test/src/editfns-tests.el
+++ b/test/src/editfns-tests.el
@@ -159,18 +159,17 @@
   (should-error (format "%x" 18446744073709551616.0)
                 :type 'overflow-error))
 (ert-deftest read-large-integer ()
-  (should-error (read (format "%d0" most-negative-fixnum))
-                :type 'overflow-error)
-  (should-error (read (format "%+d" (* -8.0 most-negative-fixnum)))
-                :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)
-  (should-error (read (format "#32rG%x" most-positive-fixnum))
-                :type 'overflow-error))
+  (should (eq (type-of (read (format "%d0" most-negative-fixnum))) 'integer))
+  (should (eq (type-of (read (format "%+d" (* -8.0 most-negative-fixnum))))
+              'integer))
+  (should (eq (type-of (read (substring (format "%d" most-negative-fixnum) 1)))
+              'integer))
+  (should (eq (type-of (read (format "#x%x" most-negative-fixnum)))
+              'integer))
+  (should (eq (type-of (read (format "#o%o" most-negative-fixnum)))
+              'integer))
+  (should (eq (type-of (read (format "#32rG%x" most-positive-fixnum)))
+              'integer)))
 
 (ert-deftest format-%o-invalid-float ()
   (should-error (format "%o" -1e-37)
@@ -358,4 +357,14 @@
     (should (eq (type-of (car (nth 4 buffer-undo-list))) 'marker))
     (garbage-collect)))
 
+(ert-deftest format-bignum ()
+  (let* ((s1 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF")
+         (v1 (read (concat "#x" s1)))
+         (s2 "99999999999999999999999999999999")
+         (v2 (read s2)))
+    (should (> v1 most-positive-fixnum))
+    (should (equal (format "%X" v1) s1))
+    (should (> v2 most-positive-fixnum))
+    (should (equal (format "%d" v2) s2))))
+
 ;;; editfns-tests.el ends here



reply via email to

[Prev in Thread] Current Thread [Next in Thread]