Mercurial > hg > xemacs-beta
comparison src/doprnt.c @ 448:3078fd1074e8 r21-2-39
Import from CVS: tag r21-2-39
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:38:25 +0200 |
parents | 1ccc32a20af4 |
children | 183866b06e0b |
comparison
equal
deleted
inserted
replaced
447:4fc5f13f3bd3 | 448:3078fd1074e8 |
---|---|
85 typedef struct | 85 typedef struct |
86 { | 86 { |
87 Dynarr_declare (union printf_arg); | 87 Dynarr_declare (union printf_arg); |
88 } printf_arg_dynarr; | 88 } printf_arg_dynarr; |
89 | 89 |
90 /* Append STRING (of length LEN) to STREAM. MINLEN is the minimum field | 90 /* Append STRING (of length LEN bytes) to STREAM. |
91 width. If MINUS_FLAG is set, left-justify the string in its field; | 91 MINLEN is the minimum field width. |
92 otherwise, right-justify. If ZERO_FLAG is set, pad with 0's; otherwise | 92 If MINUS_FLAG is set, left-justify the string in its field; |
93 pad with spaces. If MAXLEN is non-negative, the string is first | 93 otherwise, right-justify. |
94 truncated to that many character. | 94 If ZERO_FLAG is set, pad with 0's; otherwise pad with spaces. |
95 If MAXLEN is non-negative, the string is first truncated on the | |
96 right to that many characters. | |
95 | 97 |
96 Note that MINLEN and MAXLEN are Charcounts but LEN is a Bytecount. */ | 98 Note that MINLEN and MAXLEN are Charcounts but LEN is a Bytecount. */ |
97 | 99 |
98 static void | 100 static void |
99 doprnt_1 (Lisp_Object stream, const Bufbyte *string, Bytecount len, | 101 doprnt_1 (Lisp_Object stream, const Bufbyte *string, Bytecount len, |
100 Charcount minlen, Charcount maxlen, int minus_flag, int zero_flag) | 102 Charcount minlen, Charcount maxlen, int minus_flag, int zero_flag) |
101 { | 103 { |
102 Charcount cclen; | |
103 Bufbyte pad; | |
104 Lstream *lstr = XLSTREAM (stream); | 104 Lstream *lstr = XLSTREAM (stream); |
105 | 105 Charcount cclen = bytecount_to_charcount (string, len); |
106 cclen = bytecount_to_charcount (string, len); | 106 int to_add = minlen - cclen; |
107 | |
108 if (zero_flag) | |
109 pad = '0'; | |
110 else | |
111 pad = ' '; | |
112 | 107 |
113 /* Padding at beginning to right-justify ... */ | 108 /* Padding at beginning to right-justify ... */ |
114 if (minlen > cclen && !minus_flag) | 109 if (!minus_flag) |
115 { | 110 while (to_add-- > 0) |
116 int to_add = minlen - cclen; | 111 Lstream_putc (lstr, zero_flag ? '0' : ' '); |
117 while (to_add > 0) | 112 |
118 { | 113 if (0 <= maxlen && maxlen < cclen) |
119 Lstream_putc (lstr, pad); | 114 len = charcount_to_bytecount (string, maxlen); |
120 to_add--; | |
121 } | |
122 } | |
123 | |
124 if (maxlen >= 0) | |
125 len = charcount_to_bytecount (string, min (maxlen, cclen)); | |
126 Lstream_write (lstr, string, len); | 115 Lstream_write (lstr, string, len); |
127 | 116 |
128 /* Padding at end to left-justify ... */ | 117 /* Padding at end to left-justify ... */ |
129 if (minlen > cclen && minus_flag) | 118 if (minus_flag) |
130 { | 119 while (to_add-- > 0) |
131 int to_add = minlen - cclen; | 120 Lstream_putc (lstr, zero_flag ? '0' : ' '); |
132 while (to_add > 0) | |
133 { | |
134 Lstream_putc (lstr, pad); | |
135 to_add--; | |
136 } | |
137 } | |
138 } | 121 } |
139 | 122 |
140 static const Bufbyte * | 123 static const Bufbyte * |
141 parse_off_posnum (const Bufbyte *start, const Bufbyte *end, int *returned_num) | 124 parse_off_posnum (const Bufbyte *start, const Bufbyte *end, int *returned_num) |
142 { | 125 { |
608 doprnt_1 (stream, charbuf, charlen, spec->minwidth, | 591 doprnt_1 (stream, charbuf, charlen, spec->minwidth, |
609 -1, spec->minus_flag, spec->zero_flag); | 592 -1, spec->minus_flag, spec->zero_flag); |
610 } | 593 } |
611 else | 594 else |
612 { | 595 { |
613 char text_to_print[500]; | 596 /* ASCII Decimal representation uses 2.4 times as many |
597 bits as machine binary. */ | |
598 char *text_to_print = | |
599 alloca_array (char, 32 + | |
600 max (spec->minwidth, | |
601 max (sizeof (double), sizeof (long)) * 3 + | |
602 max (spec->precision, 0))); | |
614 char constructed_spec[100]; | 603 char constructed_spec[100]; |
615 char *p = constructed_spec; | 604 char *p = constructed_spec; |
616 | 605 |
617 /* Partially reconstruct the spec and use sprintf() to | 606 /* Mostly reconstruct the spec and use sprintf() to |
618 format the string. */ | 607 format the string. */ |
619 | |
620 /* Make sure nothing stupid happens */ | |
621 /* DO NOT REMOVE THE (int) CAST! Incorrect results will | |
622 follow! */ | |
623 spec->precision = min (spec->precision, | |
624 (int) (sizeof (text_to_print) - 50)); | |
625 | 608 |
626 *p++ = '%'; | 609 *p++ = '%'; |
627 if (spec->plus_flag) *p++ = '+'; | 610 if (spec->plus_flag) *p++ = '+'; |
628 if (spec->space_flag) *p++ = ' '; | 611 if (spec->space_flag) *p++ = ' '; |
629 if (spec->number_flag) *p++ = '#'; | 612 if (spec->number_flag) *p++ = '#'; |
630 | 613 if (spec->minus_flag) *p++ = '-'; |
631 if (spec->precision >= 0 && !spec->minwidth) | 614 if (spec->zero_flag) *p++ = '0'; |
615 | |
616 if (spec->minwidth >= 0) | |
617 p = long_to_string (p, spec->minwidth); | |
618 if (spec->precision >= 0) | |
632 { | 619 { |
633 *p++ = '.'; | 620 *p++ = '.'; |
634 p = long_to_string (p, spec->precision); | 621 p = long_to_string (p, spec->precision); |
635 } | 622 } |
636 | 623 |
637 /* sprintf the mofo */ | |
638 /* we have to use separate calls to sprintf(), rather than | |
639 a single big conditional, because of the different types | |
640 of the arguments */ | |
641 if (strchr (double_converters, ch)) | 624 if (strchr (double_converters, ch)) |
642 { | 625 { |
643 *p++ = ch; | 626 *p++ = ch; |
644 *p++ = '\0'; | 627 *p++ = '\0'; |
645 sprintf (text_to_print, constructed_spec, arg.d); | 628 sprintf (text_to_print, constructed_spec, arg.d); |
646 } | 629 } |
647 else | 630 else |
648 { | 631 { |
649 if (spec->zero_flag && spec->minwidth) | 632 *p++ = 'l'; /* Always use longs with sprintf() */ |
650 sprintf (p, "0%dl%c", spec->minwidth, ch); | 633 *p++ = ch; |
651 else | 634 *p++ = '\0'; |
652 sprintf (p, "l%c", ch); | |
653 | 635 |
654 if (strchr (unsigned_int_converters, ch)) | 636 if (strchr (unsigned_int_converters, ch)) |
655 sprintf (text_to_print, constructed_spec, arg.ul); | 637 sprintf (text_to_print, constructed_spec, arg.ul); |
656 else | 638 else |
657 sprintf (text_to_print, constructed_spec, arg.l); | 639 sprintf (text_to_print, constructed_spec, arg.l); |
658 } | 640 } |
659 | 641 |
660 doprnt_1 (stream, (Bufbyte *) text_to_print, | 642 doprnt_1 (stream, (Bufbyte *) text_to_print, |
661 strlen (text_to_print), | 643 strlen (text_to_print), 0, -1, 0, 0); |
662 spec->minwidth, -1, spec->minus_flag, spec->zero_flag); | |
663 } | 644 } |
664 } | 645 } |
665 } | 646 } |
666 | 647 |
667 /* #### will not get freed if error */ | 648 /* #### will not get freed if error */ |