]> git.eshelyaron.com Git - emacs.git/commitdiff
Make format handle bignums
authorTom Tromey <tom@tromey.com>
Thu, 5 Jul 2018 20:46:26 +0000 (14:46 -0600)
committerTom Tromey <tom@tromey.com>
Fri, 13 Jul 2018 04:12:27 +0000 (22:12 -0600)
* src/editfns.c (styled_format): Handle bignums.
* test/src/editfns-tests.el (read-large-integer): Update.
(format-bignum): New test.

src/editfns.c
test/src/editfns-tests.el

index 6b54b41cbd9c023d25e7918903865cbd3b521f89..09c17cbd926a3fee3bf18c85aec2a84b504dc862 100644 (file)
@@ -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
            {
index c828000bb4fba457a663584724a8ccf1d0c737cf..501e0d87818398dcfb47c6ed1912873e575c4c13 100644 (file)
   (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)
     (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