diff src/doprnt.c @ 4329:d9eb5ea14f65

Provide %b in #'format; use it for converting between ints and bit vectors. lisp/ChangeLog addition: 2007-12-17 Aidan Kehoe <kehoea@parhasard.net> * subr.el (integer-to-bit-vector): New. * subr.el (bit-vector-to-integer): New. Provide naive implementations using the Lisp reader for these. src/ChangeLog addition: 2007-12-17 Aidan Kehoe <kehoea@parhasard.net> * doprnt.c (emacs_doprnt_1): Add support for formatted printing of both longs and bignums as base 2. * editfns.c (Fformat): Document the new %b escape for #'format. * lisp.h: Make ulong_to_bit_string available beside long_to_string. * lread.c: Fix a bug where the integer base was being ignored in certain contexts; thank you Sebastian Freundt. This is necessary for correct behaviour of #'integer-to-bit-vector and #'bit-vector-to-integer, just added to subr.el * print.c (ulong_to_bit_string): New. Analagous to long_to_string, but used all the time when %b is encountered, since we can't pass that to sprintf. man/ChangeLog addition: 2007-12-17 Aidan Kehoe <kehoea@parhasard.net> * lispref/strings.texi (Formatting Strings): Document %b for binary output.
author Aidan Kehoe <kehoea@parhasard.net>
date Mon, 17 Dec 2007 08:44:14 +0100
parents 89e64783d068
children 3483b381b0a9
line wrap: on
line diff
--- a/src/doprnt.c	Fri Dec 14 14:25:04 2007 +0100
+++ b/src/doprnt.c	Mon Dec 17 08:44:14 2007 +0100
@@ -34,7 +34,7 @@
 #include "lstream.h"
 
 static const char * const valid_flags = "-+ #0";
-static const char * const valid_converters = "dic" "ouxX" "feEgG" "sS"
+static const char * const valid_converters = "dic" "ouxX" "feEgG" "sS" "b"
 #if defined(HAVE_BIGNUM) || defined(HAVE_RATIO)
   "npyY"
 #endif
@@ -43,11 +43,11 @@
 #endif
   ;
 static const char * const int_converters = "dic";
-static const char * const unsigned_int_converters = "ouxX";
+static const char * const unsigned_int_converters = "ouxXb";
 static const char * const double_converters = "feEgG";
 static const char * const string_converters = "sS";
 #if defined(HAVE_BIGNUM) || defined(HAVE_RATIO)
-static const char * const bignum_converters = "npyY";
+static const char * const bignum_converters = "npyY\337";
 #endif
 #ifdef HAVE_BIGFLOAT
 static const char * const bigfloat_converters = "FhHkK";
@@ -665,6 +665,7 @@
 			case 'o': ch = 'p'; break;
 			case 'x': ch = 'y'; break;
 			case 'X': ch = 'Y'; break;
+                        case 'b': ch = 'b'; break;
 			default: /* ch == 'u' */
 			  if (strchr (unsigned_int_converters, ch) &&
 			      ratio_sign (XRATIO_DATA (obj)) < 0)
@@ -684,6 +685,7 @@
 			case 'o': ch = 'p'; break;
 			case 'x': ch = 'y'; break;
 			case 'X': ch = 'Y'; break;
+                        case 'b': ch = '\337'; break;
 			default: /* ch == 'u' */
 			  if (strchr (unsigned_int_converters, ch) &&
 			      bignum_sign (XBIGNUM_DATA (obj)) < 0)
@@ -733,13 +735,22 @@
 #if defined(HAVE_BIGNUM) || defined(HAVE_RATIO)
 	  else if (strchr (bignum_converters, ch))
 	    {
+              int base = 16;
+              
+              if (ch == 'n')
+                base = 10;
+              else if (ch == 'p')
+                base = 8;
+              else if (ch == '\337')
+                base = 2;
+
 #ifdef HAVE_BIGNUM
 	      if (BIGNUMP (arg.obj))
 		{
+                  bignum *d = XBIGNUM_DATA (arg.obj);
 		  Ibyte *text_to_print =
 		    (Ibyte *) bignum_to_string (XBIGNUM_DATA (arg.obj),
-						ch == 'n' ? 10 :
-						(ch == 'p' ? 8 : 16));
+						base);
 		  doprnt_2 (stream, text_to_print,
 			    strlen ((const char *) text_to_print),
 			    spec->minwidth, -1, spec->minus_flag,
@@ -751,9 +762,7 @@
 	      if (RATIOP (arg.obj))
 		{
 		  Ibyte *text_to_print =
-		    (Ibyte *) ratio_to_string (XRATIO_DATA (arg.obj),
-					       ch == 'n' ? 10 :
-					       (ch == 'p' ? 8 : 16));
+		    (Ibyte *) ratio_to_string (XRATIO_DATA (arg.obj), base);
 		  doprnt_2 (stream, text_to_print,
 			    strlen ((const char *) text_to_print),
 			    spec->minwidth, -1, spec->minus_flag,
@@ -774,6 +783,15 @@
 	      xfree (text_to_print, Ibyte *);
 	    }
 #endif /* HAVE_BIGFLOAT */
+          else if (ch == 'b')
+            {
+              Ascbyte *text_to_print = alloca_array (char, SIZEOF_LONG * 8 + 1);
+              
+              ulong_to_bit_string (text_to_print, arg.ul);
+              doprnt_2 (stream, (Ibyte *)text_to_print,
+                        qxestrlen ((Ibyte *)text_to_print), 
+                        spec->minwidth, -1, spec->minus_flag, spec->zero_flag);
+            }
 	  else
 	    {
 	      Ascbyte *text_to_print;