Mercurial > hg > xemacs-beta
comparison 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 |
comparison
equal
deleted
inserted
replaced
4328:dfd878799ef0 | 4329:d9eb5ea14f65 |
---|---|
32 | 32 |
33 #include "buffer.h" | 33 #include "buffer.h" |
34 #include "lstream.h" | 34 #include "lstream.h" |
35 | 35 |
36 static const char * const valid_flags = "-+ #0"; | 36 static const char * const valid_flags = "-+ #0"; |
37 static const char * const valid_converters = "dic" "ouxX" "feEgG" "sS" | 37 static const char * const valid_converters = "dic" "ouxX" "feEgG" "sS" "b" |
38 #if defined(HAVE_BIGNUM) || defined(HAVE_RATIO) | 38 #if defined(HAVE_BIGNUM) || defined(HAVE_RATIO) |
39 "npyY" | 39 "npyY" |
40 #endif | 40 #endif |
41 #ifdef HAVE_BIGFLOAT | 41 #ifdef HAVE_BIGFLOAT |
42 "FhHkK" | 42 "FhHkK" |
43 #endif | 43 #endif |
44 ; | 44 ; |
45 static const char * const int_converters = "dic"; | 45 static const char * const int_converters = "dic"; |
46 static const char * const unsigned_int_converters = "ouxX"; | 46 static const char * const unsigned_int_converters = "ouxXb"; |
47 static const char * const double_converters = "feEgG"; | 47 static const char * const double_converters = "feEgG"; |
48 static const char * const string_converters = "sS"; | 48 static const char * const string_converters = "sS"; |
49 #if defined(HAVE_BIGNUM) || defined(HAVE_RATIO) | 49 #if defined(HAVE_BIGNUM) || defined(HAVE_RATIO) |
50 static const char * const bignum_converters = "npyY"; | 50 static const char * const bignum_converters = "npyY\337"; |
51 #endif | 51 #endif |
52 #ifdef HAVE_BIGFLOAT | 52 #ifdef HAVE_BIGFLOAT |
53 static const char * const bigfloat_converters = "FhHkK"; | 53 static const char * const bigfloat_converters = "FhHkK"; |
54 #endif | 54 #endif |
55 | 55 |
663 { | 663 { |
664 case 'i': case 'd': ch = 'n'; break; | 664 case 'i': case 'd': ch = 'n'; break; |
665 case 'o': ch = 'p'; break; | 665 case 'o': ch = 'p'; break; |
666 case 'x': ch = 'y'; break; | 666 case 'x': ch = 'y'; break; |
667 case 'X': ch = 'Y'; break; | 667 case 'X': ch = 'Y'; break; |
668 case 'b': ch = 'b'; break; | |
668 default: /* ch == 'u' */ | 669 default: /* ch == 'u' */ |
669 if (strchr (unsigned_int_converters, ch) && | 670 if (strchr (unsigned_int_converters, ch) && |
670 ratio_sign (XRATIO_DATA (obj)) < 0) | 671 ratio_sign (XRATIO_DATA (obj)) < 0) |
671 dead_wrong_type_argument (Qnonnegativep, obj); | 672 dead_wrong_type_argument (Qnonnegativep, obj); |
672 else | 673 else |
682 { | 683 { |
683 case 'i': case 'd': ch = 'n'; break; | 684 case 'i': case 'd': ch = 'n'; break; |
684 case 'o': ch = 'p'; break; | 685 case 'o': ch = 'p'; break; |
685 case 'x': ch = 'y'; break; | 686 case 'x': ch = 'y'; break; |
686 case 'X': ch = 'Y'; break; | 687 case 'X': ch = 'Y'; break; |
688 case 'b': ch = '\337'; break; | |
687 default: /* ch == 'u' */ | 689 default: /* ch == 'u' */ |
688 if (strchr (unsigned_int_converters, ch) && | 690 if (strchr (unsigned_int_converters, ch) && |
689 bignum_sign (XBIGNUM_DATA (obj)) < 0) | 691 bignum_sign (XBIGNUM_DATA (obj)) < 0) |
690 dead_wrong_type_argument (Qnatnump, obj); | 692 dead_wrong_type_argument (Qnatnump, obj); |
691 else | 693 else |
731 -1, spec->minus_flag, spec->zero_flag); | 733 -1, spec->minus_flag, spec->zero_flag); |
732 } | 734 } |
733 #if defined(HAVE_BIGNUM) || defined(HAVE_RATIO) | 735 #if defined(HAVE_BIGNUM) || defined(HAVE_RATIO) |
734 else if (strchr (bignum_converters, ch)) | 736 else if (strchr (bignum_converters, ch)) |
735 { | 737 { |
738 int base = 16; | |
739 | |
740 if (ch == 'n') | |
741 base = 10; | |
742 else if (ch == 'p') | |
743 base = 8; | |
744 else if (ch == '\337') | |
745 base = 2; | |
746 | |
736 #ifdef HAVE_BIGNUM | 747 #ifdef HAVE_BIGNUM |
737 if (BIGNUMP (arg.obj)) | 748 if (BIGNUMP (arg.obj)) |
738 { | 749 { |
750 bignum *d = XBIGNUM_DATA (arg.obj); | |
739 Ibyte *text_to_print = | 751 Ibyte *text_to_print = |
740 (Ibyte *) bignum_to_string (XBIGNUM_DATA (arg.obj), | 752 (Ibyte *) bignum_to_string (XBIGNUM_DATA (arg.obj), |
741 ch == 'n' ? 10 : | 753 base); |
742 (ch == 'p' ? 8 : 16)); | |
743 doprnt_2 (stream, text_to_print, | 754 doprnt_2 (stream, text_to_print, |
744 strlen ((const char *) text_to_print), | 755 strlen ((const char *) text_to_print), |
745 spec->minwidth, -1, spec->minus_flag, | 756 spec->minwidth, -1, spec->minus_flag, |
746 spec->zero_flag); | 757 spec->zero_flag); |
747 xfree (text_to_print, Ibyte *); | 758 xfree (text_to_print, Ibyte *); |
749 #endif | 760 #endif |
750 #ifdef HAVE_RATIO | 761 #ifdef HAVE_RATIO |
751 if (RATIOP (arg.obj)) | 762 if (RATIOP (arg.obj)) |
752 { | 763 { |
753 Ibyte *text_to_print = | 764 Ibyte *text_to_print = |
754 (Ibyte *) ratio_to_string (XRATIO_DATA (arg.obj), | 765 (Ibyte *) ratio_to_string (XRATIO_DATA (arg.obj), base); |
755 ch == 'n' ? 10 : | |
756 (ch == 'p' ? 8 : 16)); | |
757 doprnt_2 (stream, text_to_print, | 766 doprnt_2 (stream, text_to_print, |
758 strlen ((const char *) text_to_print), | 767 strlen ((const char *) text_to_print), |
759 spec->minwidth, -1, spec->minus_flag, | 768 spec->minwidth, -1, spec->minus_flag, |
760 spec->zero_flag); | 769 spec->zero_flag); |
761 xfree (text_to_print, Ibyte *); | 770 xfree (text_to_print, Ibyte *); |
772 strlen ((const char *) text_to_print), | 781 strlen ((const char *) text_to_print), |
773 spec->minwidth, -1, spec->minus_flag, spec->zero_flag); | 782 spec->minwidth, -1, spec->minus_flag, spec->zero_flag); |
774 xfree (text_to_print, Ibyte *); | 783 xfree (text_to_print, Ibyte *); |
775 } | 784 } |
776 #endif /* HAVE_BIGFLOAT */ | 785 #endif /* HAVE_BIGFLOAT */ |
786 else if (ch == 'b') | |
787 { | |
788 Ascbyte *text_to_print = alloca_array (char, SIZEOF_LONG * 8 + 1); | |
789 | |
790 ulong_to_bit_string (text_to_print, arg.ul); | |
791 doprnt_2 (stream, (Ibyte *)text_to_print, | |
792 qxestrlen ((Ibyte *)text_to_print), | |
793 spec->minwidth, -1, spec->minus_flag, spec->zero_flag); | |
794 } | |
777 else | 795 else |
778 { | 796 { |
779 Ascbyte *text_to_print; | 797 Ascbyte *text_to_print; |
780 Ascbyte constructed_spec[100]; | 798 Ascbyte constructed_spec[100]; |
781 Ascbyte *p = constructed_spec; | 799 Ascbyte *p = constructed_spec; |