2 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
6 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
7 /* All Rights Reserved */
10 * Copyright (c) 1980 Regents of the University of California.
11 * All rights reserved. The Berkeley Software License Agreement
12 * specifies the terms and conditions for redistribution.
15 #pragma ident "%Z%%M% %I% %E% SMI"
18 * Hacked "printf" which prints through putbyte and Putchar.
19 * putbyte() is used to send a pure byte, which might be a part
20 * of a mutlibyte character, mainly for %s. A control character
21 * for putbyte() may be QUOTE'd meaning not to convert it to ^x
22 * sequence. In all other cases Putchar() is used to send a character
23 * in tchar (== wchar_t + * optional QUOE.)
24 * DONT USE WITH STDIO!
25 * This printf has been hacked again so that it understands tchar string
26 * when the format specifier %t is used. Also %c has been expanded
27 * to take a tchar character as well as normal int.
28 * %t is supported in its simplest form; no width or precision will
30 * Assumption here is that sizeof(tchar)<=sizeof(int) so that tchar is
31 * passed as int. Otherwise, %T must be specified instead of %c to
32 * print a character in tchar.
37 #include "sh.h" /* For tchar. */
39 #define HIBITLL (1ULL << 63)
41 void _print(char *format
, va_list *args
);
46 printf(const char *format
, ...)
50 p
= (char *)gettext(format
);
51 va_start(stupid
, format
);
59 * Floating-point code is included or not, depending
60 * on whether the preprocessor variable FLOAT is 1 or 0.
63 /* Maximum number of digits in any integer (long) representation */
66 /* Convert a digit character to the corresponding number */
67 #define tonumber(x) ((x) - '0')
69 /* Convert a number between 0 and 9 to the corresponding digit */
70 #define todigit(x) ((x) + '0')
72 /* Maximum total number of digits in E format */
75 /* Maximum number of digits after decimal point in F format */
78 /* Maximum significant figures in a floating-point number */
81 /* Maximum number of characters in an exponent */
84 /* Maximum (positive) exponent or greater */
89 #define max(a, b) ((a) > (b) ? (a) : (b))
90 #define min(a, b) ((a) < (b) ? (a) : (b))
92 /* If this symbol is nonzero, allow '0' as a flag */
97 * System-supplied routines for floating conversion
104 _print(char *format
, va_list *args
)
106 /* Current position in format */
109 /* Starting and ending points for value to be printed */
111 tchar
*tbp
, *tep
; /* For "%t". */
112 tchar tcbuf
[2]; /* For "%c" or "%T". */
114 /* Field width and precision */
120 /* Number of padding zeroes required on the left */
123 /* Flags - nonzero if corresponding character appears in format */
125 bool double_length
; /* ll */
128 bool fblank
; /* blank */
134 /* Pointer to sign, "0x", "0X", or empty */
137 /* Exponent or empty */
140 /* Buffer to create exponent */
141 char expbuf
[MAXESIZ
+ 1];
143 /* Number of padding zeroes required on the right */
146 /* The value being converted, if real */
149 /* Output values from fcvt and ecvt */
155 /* Values are developed in this buffer */
156 char buf
[max(MAXDIGS
, max(MAXFCVT
+ DMAXEXP
, MAXECVT
) + 1)];
160 /* The value being converted, if integer */
163 /* Set to point to a translate table for digits of whatever radix */
167 int n
, hradix
, lowbit
;
172 * The main loop -- this loop goes through one iteration
173 * for each ordinary character or format specification.
177 /* Ordinary (non-%) character */
182 * First, parse the format specification.
185 /* Scan the <flags> */
186 fplus
= fminus
= fblank
= fsharp
= 0;
211 /* Scan the field width */
213 width
= va_arg (*args
, int);
221 while (isdigit(*cp
)) {
223 width
= width
* 10 + n
;
227 /* Scan the precision */
230 /* '*' instead of digits? */
232 prec
= va_arg(*args
, int);
236 while (isdigit(*cp
)) {
238 prec
= prec
* 10 + n
;
245 /* Scan the length modifier */
246 double_length
= length
= 0;
249 if (*(cp
+ 1) == 'l') {
261 * The character addressed by cp must be the
262 * format letter -- there is nothing left for
265 * The status of the +, -, #, blank, and 0
266 * flags are reflected in the variables
267 * "fplus", "fminus", "fsharp", "fblank",
268 * and "fzero", respectively.
269 * "width" and "prec" contain numbers
270 * corresponding to the digit strings
271 * before and after the decimal point,
272 * respectively. If there was no decimal
273 * point, "prec" is -1.
275 * The following switch sets things up
276 * for printing. What ultimately gets
277 * printed will be padding blanks, a prefix,
278 * left padding zeroes, a value, right padding
279 * zeroes, a suffix, and more padding
280 * blanks. Padding blanks will not appear
281 * simultaneously on both the left and the
282 * right. Each case in this switch will
283 * compute the value, and leave in several
284 * variables the information necessary to
285 * construct what is to be printed.
287 * The prefix is a sign, a blank, "0x", "0X",
288 * or null, and is addressed by "prefix".
290 * The suffix is either null or an exponent,
291 * and is addressed by "suffix".
293 * The value to be printed starts at "bp"
294 * and continues up to and not including "p".
296 * "lzero" and "rzero" will contain the number
297 * of padding zeroes required on the left
298 * and right, respectively. If either of
299 * these variables is negative, it will be
300 * treated as if it were zero.
302 * The number of padding blanks, and whether
303 * they go on the left or the right, will be
304 * computed on exit from the switch.
313 switch (fcode
= *cp
++) {
316 * fixed point representations
318 * "hradix" is half the radix for the conversion.
319 * Conversion is unsigned unless fcode is 'd'.
320 * HIBITLL is 1000...000 binary, and is equal to
321 * the maximum negative number.
322 * We assume a 2's complement machine
344 /* Establish default precision */
349 /* Fetch the argument to be printed */
351 val
= va_arg(*args
, long long);
353 val
= va_arg(*args
, long);
354 } else if (fcode
== 'd') {
355 val
= va_arg(*args
, int);
357 val
= va_arg(*args
, unsigned);
360 /* If signed conversion, establish sign */
361 if (fcode
== 'd' || fcode
== 'D') {
365 * Negate, checking in
366 * advance for possible
369 if (val
!= HIBITLL
) {
380 int n
= width
- strlen(prefix
);
386 /* Set translate table for digits */
388 tab
= "0123456789ABCDEF";
390 tab
= "0123456789abcdef";
393 /* Develop the digits of the value */
394 p
= bp
= buf
+ MAXDIGS
;
397 val
= (val
>> 1) & ~HIBITLL
;
398 *--bp
= tab
[val
% hradix
* 2 + lowbit
];
402 /* Calculate padding zero requirement */
403 lzero
= bp
- p
+ prec
;
405 /* Handle the # flag */
406 if (fsharp
&& bp
!= p
) {
426 * E-format. The general strategy
427 * here is fairly easy: we take
428 * what ecvt gives us and re-format it.
431 /* Establish default precision */
436 /* Fetch the value */
437 dval
= va_arg(*args
, double);
439 /* Develop the mantissa */
441 min(prec
+ 1, MAXECVT
),
445 /* Determine the prefix */
455 /* Place the first digit in the buffer */
457 *p
++ = *bp
!= '\0' ? *bp
++ : '0';
459 /* Put in a decimal point if needed */
460 if (prec
!= 0 || fsharp
) {
464 /* Create the rest of the mantissa */
466 while (rzero
> 0 && *bp
!= '\0') {
473 /* Create the exponent */
474 suffix
= &expbuf
[MAXESIZ
];
482 *--suffix
= todigit(n
% 10);
487 /* Prepend leading zeroes to the exponent */
488 while (suffix
> &expbuf
[MAXESIZ
- 2]) {
492 /* Put in the exponent sign */
493 *--suffix
= (decpt
> 0 || dval
== 0) ?
497 *--suffix
= isupper(fcode
) ? 'E' : 'e';
503 * F-format floating point. This is
504 * a good deal less simple than E-format.
505 * The overall strategy will be to call
506 * fcvt, reformat its result into buf,
507 * and calculate how many trailing
508 * zeroes will be required. There will
509 * never be any leading zeroes needed.
512 /* Establish default precision */
517 /* Fetch the value */
518 dval
= va_arg(*args
, double);
520 /* Do the conversion */
526 /* Determine the prefix */
528 if (sign
&& decpt
> -prec
&&
529 *bp
!= '\0' && *bp
!= '0') {
537 /* Initialize buffer pointer */
540 /* Emit the digits before the decimal point */
557 /* Decide whether we need a decimal point */
558 if (fsharp
|| prec
> 0) {
562 /* Digits (if any) after the decimal point */
563 n
= min(prec
, MAXFCVT
);
566 if (++decpt
<= 0 || *bp
== '\0' ||
582 * g-format. We play around a bit
583 * and then jump into e or f, as needed.
586 /* Establish default precision */
591 /* Fetch the value */
592 dval
= va_arg(*args
, double);
594 /* Do the conversion */
609 while (k
>= 1 && bp
[k
-1] == '0') {
614 if (decpt
< -3 || decpt
> prec
) {
624 #ifdef MBCHAR_1 /* sizeof(int)>=sizeof(tchar) */
626 * A tchar arg is passed as int so we used the normal %c to specify
629 tcbuf
[0] = va_arg(*args
, int);
632 fcode
= 't'; /* Fake the rest of code. */
636 * We would have to invent another new format speficier such as "%T" to
637 * take a tchar arg. Let's worry about when that time comes.
640 * Following code take care of a char arg
643 buf
[0] = va_arg(*args
, int);
647 case 'T': /* Corresponding arg is tchar. */
648 tcbuf
[0] = va_arg(*args
, tchar
);
651 fcode
= 't'; /* Fake the rest of code. */
655 bp
= va_arg(*args
, char *);
657 nullstr
: bp
= "(null)";
658 p
= bp
+ strlen("(null)");
664 for (n
= 0; *bp
++ != '\0' && n
< prec
; n
++)
672 * Special format specifier "%t" tells
673 * printf() to print char strings written
676 tbp
= va_arg(*args
, tchar
*);
678 fcode
= 's'; /* Act as if it were %s. */
684 for (n
= 0; *tbp
++ != 0 && n
< prec
; n
++)
690 * Just to make the following padding
691 * calculation not to go very crazy...
708 /* Calculate number of padding blanks */
712 - (rzero
< 0 ? 0: rzero
)
716 - (lzero
< 0 ? 0 : lzero
)
719 /* Blanks on left if required */
721 while (--nblank
>= 0) {
727 while (*prefix
!= '\0') {
731 /* Zeroes on the left */
732 while (--lzero
>= 0) {
736 /* The value itself */
737 if (fcode
== 't') { /* %t is special. */
741 } else { /* For rest of the cases. */
747 /* Zeroes on the right */
752 while (*suffix
!= '\0') {
756 /* Blanks on the right if required */
758 while (--nblank
>= 0) {