17c478bd9Sstevel@tonic-gate /*
2*6c02b4a4Smuffin * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
37c478bd9Sstevel@tonic-gate * Use is subject to license terms.
47c478bd9Sstevel@tonic-gate */
57c478bd9Sstevel@tonic-gate
67c478bd9Sstevel@tonic-gate /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
77c478bd9Sstevel@tonic-gate /* All Rights Reserved */
87c478bd9Sstevel@tonic-gate
97c478bd9Sstevel@tonic-gate /*
107c478bd9Sstevel@tonic-gate * Copyright (c) 1980 Regents of the University of California.
117c478bd9Sstevel@tonic-gate * All rights reserved. The Berkeley Software License Agreement
127c478bd9Sstevel@tonic-gate * specifies the terms and conditions for redistribution.
137c478bd9Sstevel@tonic-gate */
147c478bd9Sstevel@tonic-gate
157c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI"
167c478bd9Sstevel@tonic-gate
177c478bd9Sstevel@tonic-gate /*
187c478bd9Sstevel@tonic-gate * Hacked "printf" which prints through putbyte and Putchar.
197c478bd9Sstevel@tonic-gate * putbyte() is used to send a pure byte, which might be a part
207c478bd9Sstevel@tonic-gate * of a mutlibyte character, mainly for %s. A control character
217c478bd9Sstevel@tonic-gate * for putbyte() may be QUOTE'd meaning not to convert it to ^x
227c478bd9Sstevel@tonic-gate * sequence. In all other cases Putchar() is used to send a character
237c478bd9Sstevel@tonic-gate * in tchar (== wchar_t + * optional QUOE.)
247c478bd9Sstevel@tonic-gate * DONT USE WITH STDIO!
257c478bd9Sstevel@tonic-gate * This printf has been hacked again so that it understands tchar string
267c478bd9Sstevel@tonic-gate * when the format specifier %t is used. Also %c has been expanded
277c478bd9Sstevel@tonic-gate * to take a tchar character as well as normal int.
287c478bd9Sstevel@tonic-gate * %t is supported in its simplest form; no width or precision will
297c478bd9Sstevel@tonic-gate * be understood.
307c478bd9Sstevel@tonic-gate * Assumption here is that sizeof(tchar)<=sizeof(int) so that tchar is
317c478bd9Sstevel@tonic-gate * passed as int. Otherwise, %T must be specified instead of %c to
327c478bd9Sstevel@tonic-gate * print a character in tchar.
337c478bd9Sstevel@tonic-gate */
347c478bd9Sstevel@tonic-gate
357c478bd9Sstevel@tonic-gate #include <stdarg.h>
367c478bd9Sstevel@tonic-gate #include <values.h>
377c478bd9Sstevel@tonic-gate #include "sh.h" /* For tchar. */
387c478bd9Sstevel@tonic-gate
397c478bd9Sstevel@tonic-gate #define HIBITLL (1ULL << 63)
407c478bd9Sstevel@tonic-gate
417c478bd9Sstevel@tonic-gate void _print(char *format, va_list *args);
427c478bd9Sstevel@tonic-gate
437c478bd9Sstevel@tonic-gate static char *p;
447c478bd9Sstevel@tonic-gate
457c478bd9Sstevel@tonic-gate int
printf(const char * format,...)467c478bd9Sstevel@tonic-gate printf(const char *format, ...)
477c478bd9Sstevel@tonic-gate {
487c478bd9Sstevel@tonic-gate va_list stupid;
497c478bd9Sstevel@tonic-gate
507c478bd9Sstevel@tonic-gate p = (char *)gettext(format);
517c478bd9Sstevel@tonic-gate va_start(stupid, format);
527c478bd9Sstevel@tonic-gate _print(p, &stupid);
537c478bd9Sstevel@tonic-gate va_end(stupid);
54*6c02b4a4Smuffin
55*6c02b4a4Smuffin return (0);
567c478bd9Sstevel@tonic-gate }
577c478bd9Sstevel@tonic-gate
587c478bd9Sstevel@tonic-gate /*
597c478bd9Sstevel@tonic-gate * Floating-point code is included or not, depending
607c478bd9Sstevel@tonic-gate * on whether the preprocessor variable FLOAT is 1 or 0.
617c478bd9Sstevel@tonic-gate */
627c478bd9Sstevel@tonic-gate
637c478bd9Sstevel@tonic-gate /* Maximum number of digits in any integer (long) representation */
647c478bd9Sstevel@tonic-gate #define MAXDIGS 20
657c478bd9Sstevel@tonic-gate
667c478bd9Sstevel@tonic-gate /* Convert a digit character to the corresponding number */
677c478bd9Sstevel@tonic-gate #define tonumber(x) ((x) - '0')
687c478bd9Sstevel@tonic-gate
697c478bd9Sstevel@tonic-gate /* Convert a number between 0 and 9 to the corresponding digit */
707c478bd9Sstevel@tonic-gate #define todigit(x) ((x) + '0')
717c478bd9Sstevel@tonic-gate
727c478bd9Sstevel@tonic-gate /* Maximum total number of digits in E format */
737c478bd9Sstevel@tonic-gate #define MAXECVT 17
747c478bd9Sstevel@tonic-gate
757c478bd9Sstevel@tonic-gate /* Maximum number of digits after decimal point in F format */
767c478bd9Sstevel@tonic-gate #define MAXFCVT 60
777c478bd9Sstevel@tonic-gate
787c478bd9Sstevel@tonic-gate /* Maximum significant figures in a floating-point number */
797c478bd9Sstevel@tonic-gate #define MAXFSIG 17
807c478bd9Sstevel@tonic-gate
817c478bd9Sstevel@tonic-gate /* Maximum number of characters in an exponent */
827c478bd9Sstevel@tonic-gate #define MAXESIZ 4
837c478bd9Sstevel@tonic-gate
847c478bd9Sstevel@tonic-gate /* Maximum (positive) exponent or greater */
857c478bd9Sstevel@tonic-gate #define MAXEXP 40
867c478bd9Sstevel@tonic-gate
877c478bd9Sstevel@tonic-gate
887c478bd9Sstevel@tonic-gate
897c478bd9Sstevel@tonic-gate #define max(a, b) ((a) > (b) ? (a) : (b))
907c478bd9Sstevel@tonic-gate #define min(a, b) ((a) < (b) ? (a) : (b))
917c478bd9Sstevel@tonic-gate
927c478bd9Sstevel@tonic-gate /* If this symbol is nonzero, allow '0' as a flag */
937c478bd9Sstevel@tonic-gate #define FZERO 1
947c478bd9Sstevel@tonic-gate
957c478bd9Sstevel@tonic-gate #if FLOAT
967c478bd9Sstevel@tonic-gate /*
977c478bd9Sstevel@tonic-gate * System-supplied routines for floating conversion
987c478bd9Sstevel@tonic-gate */
997c478bd9Sstevel@tonic-gate char *fcvt();
1007c478bd9Sstevel@tonic-gate char *ecvt();
1017c478bd9Sstevel@tonic-gate #endif
1027c478bd9Sstevel@tonic-gate
1037c478bd9Sstevel@tonic-gate void
_print(char * format,va_list * args)1047c478bd9Sstevel@tonic-gate _print(char *format, va_list *args)
1057c478bd9Sstevel@tonic-gate {
1067c478bd9Sstevel@tonic-gate /* Current position in format */
1077c478bd9Sstevel@tonic-gate char *cp;
1087c478bd9Sstevel@tonic-gate
1097c478bd9Sstevel@tonic-gate /* Starting and ending points for value to be printed */
1107c478bd9Sstevel@tonic-gate char *bp, *p;
1117c478bd9Sstevel@tonic-gate tchar *tbp, *tep; /* For "%t". */
1127c478bd9Sstevel@tonic-gate tchar tcbuf[2]; /* For "%c" or "%T". */
1137c478bd9Sstevel@tonic-gate
1147c478bd9Sstevel@tonic-gate /* Field width and precision */
1157c478bd9Sstevel@tonic-gate int width, prec;
1167c478bd9Sstevel@tonic-gate
1177c478bd9Sstevel@tonic-gate /* Format code */
1187c478bd9Sstevel@tonic-gate char fcode;
1197c478bd9Sstevel@tonic-gate
1207c478bd9Sstevel@tonic-gate /* Number of padding zeroes required on the left */
1217c478bd9Sstevel@tonic-gate int lzero;
1227c478bd9Sstevel@tonic-gate
1237c478bd9Sstevel@tonic-gate /* Flags - nonzero if corresponding character appears in format */
1247c478bd9Sstevel@tonic-gate bool length; /* l */
1257c478bd9Sstevel@tonic-gate bool double_length; /* ll */
1267c478bd9Sstevel@tonic-gate bool fplus; /* + */
1277c478bd9Sstevel@tonic-gate bool fminus; /* - */
1287c478bd9Sstevel@tonic-gate bool fblank; /* blank */
1297c478bd9Sstevel@tonic-gate bool fsharp; /* # */
1307c478bd9Sstevel@tonic-gate #if FZERO
1317c478bd9Sstevel@tonic-gate bool fzero; /* 0 */
1327c478bd9Sstevel@tonic-gate #endif
1337c478bd9Sstevel@tonic-gate
1347c478bd9Sstevel@tonic-gate /* Pointer to sign, "0x", "0X", or empty */
1357c478bd9Sstevel@tonic-gate char *prefix;
1367c478bd9Sstevel@tonic-gate #if FLOAT
1377c478bd9Sstevel@tonic-gate /* Exponent or empty */
1387c478bd9Sstevel@tonic-gate char *suffix;
1397c478bd9Sstevel@tonic-gate
1407c478bd9Sstevel@tonic-gate /* Buffer to create exponent */
1417c478bd9Sstevel@tonic-gate char expbuf[MAXESIZ + 1];
1427c478bd9Sstevel@tonic-gate
1437c478bd9Sstevel@tonic-gate /* Number of padding zeroes required on the right */
1447c478bd9Sstevel@tonic-gate int rzero;
1457c478bd9Sstevel@tonic-gate
1467c478bd9Sstevel@tonic-gate /* The value being converted, if real */
1477c478bd9Sstevel@tonic-gate double dval;
1487c478bd9Sstevel@tonic-gate
1497c478bd9Sstevel@tonic-gate /* Output values from fcvt and ecvt */
1507c478bd9Sstevel@tonic-gate int decpt, sign;
1517c478bd9Sstevel@tonic-gate
1527c478bd9Sstevel@tonic-gate /* Scratch */
1537c478bd9Sstevel@tonic-gate int k;
1547c478bd9Sstevel@tonic-gate
1557c478bd9Sstevel@tonic-gate /* Values are developed in this buffer */
1567c478bd9Sstevel@tonic-gate char buf[max(MAXDIGS, max(MAXFCVT + DMAXEXP, MAXECVT) + 1)];
1577c478bd9Sstevel@tonic-gate #else
1587c478bd9Sstevel@tonic-gate char buf[MAXDIGS];
1597c478bd9Sstevel@tonic-gate #endif
1607c478bd9Sstevel@tonic-gate /* The value being converted, if integer */
1617c478bd9Sstevel@tonic-gate long long val;
1627c478bd9Sstevel@tonic-gate
1637c478bd9Sstevel@tonic-gate /* Set to point to a translate table for digits of whatever radix */
1647c478bd9Sstevel@tonic-gate char *tab;
1657c478bd9Sstevel@tonic-gate
1667c478bd9Sstevel@tonic-gate /* Work variables */
1677c478bd9Sstevel@tonic-gate int n, hradix, lowbit;
1687c478bd9Sstevel@tonic-gate
1697c478bd9Sstevel@tonic-gate cp = format;
1707c478bd9Sstevel@tonic-gate
1717c478bd9Sstevel@tonic-gate /*
1727c478bd9Sstevel@tonic-gate * The main loop -- this loop goes through one iteration
1737c478bd9Sstevel@tonic-gate * for each ordinary character or format specification.
1747c478bd9Sstevel@tonic-gate */
1757c478bd9Sstevel@tonic-gate while (*cp)
1767c478bd9Sstevel@tonic-gate if (*cp != '%') {
1777c478bd9Sstevel@tonic-gate /* Ordinary (non-%) character */
1787c478bd9Sstevel@tonic-gate putbyte (*cp++);
1797c478bd9Sstevel@tonic-gate } else {
1807c478bd9Sstevel@tonic-gate /*
1817c478bd9Sstevel@tonic-gate * % has been found.
1827c478bd9Sstevel@tonic-gate * First, parse the format specification.
1837c478bd9Sstevel@tonic-gate */
1847c478bd9Sstevel@tonic-gate
1857c478bd9Sstevel@tonic-gate /* Scan the <flags> */
1867c478bd9Sstevel@tonic-gate fplus = fminus = fblank = fsharp = 0;
1877c478bd9Sstevel@tonic-gate #if FZERO
1887c478bd9Sstevel@tonic-gate fzero = 0;
1897c478bd9Sstevel@tonic-gate #endif
1907c478bd9Sstevel@tonic-gate scan:
1917c478bd9Sstevel@tonic-gate switch (*++cp) {
1927c478bd9Sstevel@tonic-gate case '+':
1937c478bd9Sstevel@tonic-gate fplus = 1;
1947c478bd9Sstevel@tonic-gate goto scan;
1957c478bd9Sstevel@tonic-gate case '-':
1967c478bd9Sstevel@tonic-gate fminus = 1;
1977c478bd9Sstevel@tonic-gate goto scan;
1987c478bd9Sstevel@tonic-gate case ' ':
1997c478bd9Sstevel@tonic-gate fblank = 1;
2007c478bd9Sstevel@tonic-gate goto scan;
2017c478bd9Sstevel@tonic-gate case '#':
2027c478bd9Sstevel@tonic-gate fsharp = 1;
2037c478bd9Sstevel@tonic-gate goto scan;
2047c478bd9Sstevel@tonic-gate #if FZERO
2057c478bd9Sstevel@tonic-gate case '0':
2067c478bd9Sstevel@tonic-gate fzero = 1;
2077c478bd9Sstevel@tonic-gate goto scan;
2087c478bd9Sstevel@tonic-gate #endif
2097c478bd9Sstevel@tonic-gate }
2107c478bd9Sstevel@tonic-gate
2117c478bd9Sstevel@tonic-gate /* Scan the field width */
2127c478bd9Sstevel@tonic-gate if (*cp == '*') {
2137c478bd9Sstevel@tonic-gate width = va_arg (*args, int);
2147c478bd9Sstevel@tonic-gate if (width < 0) {
2157c478bd9Sstevel@tonic-gate width = -width;
2167c478bd9Sstevel@tonic-gate fminus = 1;
2177c478bd9Sstevel@tonic-gate }
2187c478bd9Sstevel@tonic-gate cp++;
2197c478bd9Sstevel@tonic-gate } else {
2207c478bd9Sstevel@tonic-gate width = 0;
2217c478bd9Sstevel@tonic-gate while (isdigit(*cp)) {
2227c478bd9Sstevel@tonic-gate n = tonumber(*cp++);
2237c478bd9Sstevel@tonic-gate width = width * 10 + n;
2247c478bd9Sstevel@tonic-gate }
2257c478bd9Sstevel@tonic-gate }
2267c478bd9Sstevel@tonic-gate
2277c478bd9Sstevel@tonic-gate /* Scan the precision */
2287c478bd9Sstevel@tonic-gate if (*cp == '.') {
2297c478bd9Sstevel@tonic-gate
2307c478bd9Sstevel@tonic-gate /* '*' instead of digits? */
2317c478bd9Sstevel@tonic-gate if (*++cp == '*') {
2327c478bd9Sstevel@tonic-gate prec = va_arg(*args, int);
2337c478bd9Sstevel@tonic-gate cp++;
2347c478bd9Sstevel@tonic-gate } else {
2357c478bd9Sstevel@tonic-gate prec = 0;
2367c478bd9Sstevel@tonic-gate while (isdigit(*cp)) {
2377c478bd9Sstevel@tonic-gate n = tonumber(*cp++);
2387c478bd9Sstevel@tonic-gate prec = prec * 10 + n;
2397c478bd9Sstevel@tonic-gate }
2407c478bd9Sstevel@tonic-gate }
2417c478bd9Sstevel@tonic-gate } else {
2427c478bd9Sstevel@tonic-gate prec = -1;
2437c478bd9Sstevel@tonic-gate }
2447c478bd9Sstevel@tonic-gate
2457c478bd9Sstevel@tonic-gate /* Scan the length modifier */
2467c478bd9Sstevel@tonic-gate double_length = length = 0;
2477c478bd9Sstevel@tonic-gate switch (*cp) {
2487c478bd9Sstevel@tonic-gate case 'l':
2497c478bd9Sstevel@tonic-gate if (*(cp + 1) == 'l') {
2507c478bd9Sstevel@tonic-gate cp++;
2517c478bd9Sstevel@tonic-gate double_length = 1;
2527c478bd9Sstevel@tonic-gate } else {
2537c478bd9Sstevel@tonic-gate length = 1;
2547c478bd9Sstevel@tonic-gate }
2557c478bd9Sstevel@tonic-gate /* No break */
2567c478bd9Sstevel@tonic-gate case 'h':
2577c478bd9Sstevel@tonic-gate cp++;
2587c478bd9Sstevel@tonic-gate }
2597c478bd9Sstevel@tonic-gate
2607c478bd9Sstevel@tonic-gate /*
2617c478bd9Sstevel@tonic-gate * The character addressed by cp must be the
2627c478bd9Sstevel@tonic-gate * format letter -- there is nothing left for
2637c478bd9Sstevel@tonic-gate * it to be.
2647c478bd9Sstevel@tonic-gate *
2657c478bd9Sstevel@tonic-gate * The status of the +, -, #, blank, and 0
2667c478bd9Sstevel@tonic-gate * flags are reflected in the variables
2677c478bd9Sstevel@tonic-gate * "fplus", "fminus", "fsharp", "fblank",
2687c478bd9Sstevel@tonic-gate * and "fzero", respectively.
2697c478bd9Sstevel@tonic-gate * "width" and "prec" contain numbers
2707c478bd9Sstevel@tonic-gate * corresponding to the digit strings
2717c478bd9Sstevel@tonic-gate * before and after the decimal point,
2727c478bd9Sstevel@tonic-gate * respectively. If there was no decimal
2737c478bd9Sstevel@tonic-gate * point, "prec" is -1.
2747c478bd9Sstevel@tonic-gate *
2757c478bd9Sstevel@tonic-gate * The following switch sets things up
2767c478bd9Sstevel@tonic-gate * for printing. What ultimately gets
2777c478bd9Sstevel@tonic-gate * printed will be padding blanks, a prefix,
2787c478bd9Sstevel@tonic-gate * left padding zeroes, a value, right padding
2797c478bd9Sstevel@tonic-gate * zeroes, a suffix, and more padding
2807c478bd9Sstevel@tonic-gate * blanks. Padding blanks will not appear
2817c478bd9Sstevel@tonic-gate * simultaneously on both the left and the
2827c478bd9Sstevel@tonic-gate * right. Each case in this switch will
2837c478bd9Sstevel@tonic-gate * compute the value, and leave in several
2847c478bd9Sstevel@tonic-gate * variables the information necessary to
2857c478bd9Sstevel@tonic-gate * construct what is to be printed.
2867c478bd9Sstevel@tonic-gate *
2877c478bd9Sstevel@tonic-gate * The prefix is a sign, a blank, "0x", "0X",
2887c478bd9Sstevel@tonic-gate * or null, and is addressed by "prefix".
2897c478bd9Sstevel@tonic-gate *
2907c478bd9Sstevel@tonic-gate * The suffix is either null or an exponent,
2917c478bd9Sstevel@tonic-gate * and is addressed by "suffix".
2927c478bd9Sstevel@tonic-gate *
2937c478bd9Sstevel@tonic-gate * The value to be printed starts at "bp"
2947c478bd9Sstevel@tonic-gate * and continues up to and not including "p".
2957c478bd9Sstevel@tonic-gate *
2967c478bd9Sstevel@tonic-gate * "lzero" and "rzero" will contain the number
2977c478bd9Sstevel@tonic-gate * of padding zeroes required on the left
2987c478bd9Sstevel@tonic-gate * and right, respectively. If either of
2997c478bd9Sstevel@tonic-gate * these variables is negative, it will be
3007c478bd9Sstevel@tonic-gate * treated as if it were zero.
3017c478bd9Sstevel@tonic-gate *
3027c478bd9Sstevel@tonic-gate * The number of padding blanks, and whether
3037c478bd9Sstevel@tonic-gate * they go on the left or the right, will be
3047c478bd9Sstevel@tonic-gate * computed on exit from the switch.
3057c478bd9Sstevel@tonic-gate */
3067c478bd9Sstevel@tonic-gate
3077c478bd9Sstevel@tonic-gate lzero = 0;
3087c478bd9Sstevel@tonic-gate prefix = "";
3097c478bd9Sstevel@tonic-gate #if FLOAT
3107c478bd9Sstevel@tonic-gate rzero = lzero;
3117c478bd9Sstevel@tonic-gate suffix = prefix;
3127c478bd9Sstevel@tonic-gate #endif
3137c478bd9Sstevel@tonic-gate switch (fcode = *cp++) {
3147c478bd9Sstevel@tonic-gate
3157c478bd9Sstevel@tonic-gate /*
3167c478bd9Sstevel@tonic-gate * fixed point representations
3177c478bd9Sstevel@tonic-gate *
3187c478bd9Sstevel@tonic-gate * "hradix" is half the radix for the conversion.
3197c478bd9Sstevel@tonic-gate * Conversion is unsigned unless fcode is 'd'.
3207c478bd9Sstevel@tonic-gate * HIBITLL is 1000...000 binary, and is equal to
3217c478bd9Sstevel@tonic-gate * the maximum negative number.
3227c478bd9Sstevel@tonic-gate * We assume a 2's complement machine
3237c478bd9Sstevel@tonic-gate */
3247c478bd9Sstevel@tonic-gate
3257c478bd9Sstevel@tonic-gate case 'D':
3267c478bd9Sstevel@tonic-gate case 'U':
3277c478bd9Sstevel@tonic-gate length = 1;
3287c478bd9Sstevel@tonic-gate case 'd':
3297c478bd9Sstevel@tonic-gate case 'u':
3307c478bd9Sstevel@tonic-gate hradix = 5;
3317c478bd9Sstevel@tonic-gate goto fixed;
3327c478bd9Sstevel@tonic-gate
3337c478bd9Sstevel@tonic-gate case 'O':
3347c478bd9Sstevel@tonic-gate length = 1;
3357c478bd9Sstevel@tonic-gate case 'o':
3367c478bd9Sstevel@tonic-gate hradix = 4;
3377c478bd9Sstevel@tonic-gate goto fixed;
3387c478bd9Sstevel@tonic-gate
3397c478bd9Sstevel@tonic-gate case 'X':
3407c478bd9Sstevel@tonic-gate case 'x':
3417c478bd9Sstevel@tonic-gate hradix = 8;
3427c478bd9Sstevel@tonic-gate
3437c478bd9Sstevel@tonic-gate fixed:
3447c478bd9Sstevel@tonic-gate /* Establish default precision */
3457c478bd9Sstevel@tonic-gate if (prec < 0) {
3467c478bd9Sstevel@tonic-gate prec = 1;
3477c478bd9Sstevel@tonic-gate }
3487c478bd9Sstevel@tonic-gate
3497c478bd9Sstevel@tonic-gate /* Fetch the argument to be printed */
3507c478bd9Sstevel@tonic-gate if (double_length) {
3517c478bd9Sstevel@tonic-gate val = va_arg(*args, long long);
3527c478bd9Sstevel@tonic-gate } else if (length) {
3537c478bd9Sstevel@tonic-gate val = va_arg(*args, long);
3547c478bd9Sstevel@tonic-gate } else if (fcode == 'd') {
3557c478bd9Sstevel@tonic-gate val = va_arg(*args, int);
3567c478bd9Sstevel@tonic-gate } else {
3577c478bd9Sstevel@tonic-gate val = va_arg(*args, unsigned);
3587c478bd9Sstevel@tonic-gate }
3597c478bd9Sstevel@tonic-gate
3607c478bd9Sstevel@tonic-gate /* If signed conversion, establish sign */
3617c478bd9Sstevel@tonic-gate if (fcode == 'd' || fcode == 'D') {
3627c478bd9Sstevel@tonic-gate if (val < 0) {
3637c478bd9Sstevel@tonic-gate prefix = "-";
3647c478bd9Sstevel@tonic-gate /*
3657c478bd9Sstevel@tonic-gate * Negate, checking in
3667c478bd9Sstevel@tonic-gate * advance for possible
3677c478bd9Sstevel@tonic-gate * overflow.
3687c478bd9Sstevel@tonic-gate */
3697c478bd9Sstevel@tonic-gate if (val != HIBITLL) {
3707c478bd9Sstevel@tonic-gate val = -val;
3717c478bd9Sstevel@tonic-gate }
3727c478bd9Sstevel@tonic-gate } else if (fplus) {
3737c478bd9Sstevel@tonic-gate prefix = "+";
3747c478bd9Sstevel@tonic-gate } else if (fblank) {
3757c478bd9Sstevel@tonic-gate prefix = " ";
3767c478bd9Sstevel@tonic-gate }
3777c478bd9Sstevel@tonic-gate }
3787c478bd9Sstevel@tonic-gate #if FZERO
3797c478bd9Sstevel@tonic-gate if (fzero) {
3807c478bd9Sstevel@tonic-gate int n = width - strlen(prefix);
3817c478bd9Sstevel@tonic-gate if (n > prec) {
3827c478bd9Sstevel@tonic-gate prec = n;
3837c478bd9Sstevel@tonic-gate }
3847c478bd9Sstevel@tonic-gate }
3857c478bd9Sstevel@tonic-gate #endif
3867c478bd9Sstevel@tonic-gate /* Set translate table for digits */
3877c478bd9Sstevel@tonic-gate if (fcode == 'X') {
3887c478bd9Sstevel@tonic-gate tab = "0123456789ABCDEF";
3897c478bd9Sstevel@tonic-gate } else {
3907c478bd9Sstevel@tonic-gate tab = "0123456789abcdef";
3917c478bd9Sstevel@tonic-gate }
3927c478bd9Sstevel@tonic-gate
3937c478bd9Sstevel@tonic-gate /* Develop the digits of the value */
3947c478bd9Sstevel@tonic-gate p = bp = buf + MAXDIGS;
3957c478bd9Sstevel@tonic-gate while (val) {
3967c478bd9Sstevel@tonic-gate lowbit = val & 1;
3977c478bd9Sstevel@tonic-gate val = (val >> 1) & ~HIBITLL;
3987c478bd9Sstevel@tonic-gate *--bp = tab[val % hradix * 2 + lowbit];
3997c478bd9Sstevel@tonic-gate val /= hradix;
4007c478bd9Sstevel@tonic-gate }
4017c478bd9Sstevel@tonic-gate
4027c478bd9Sstevel@tonic-gate /* Calculate padding zero requirement */
4037c478bd9Sstevel@tonic-gate lzero = bp - p + prec;
4047c478bd9Sstevel@tonic-gate
4057c478bd9Sstevel@tonic-gate /* Handle the # flag */
4067c478bd9Sstevel@tonic-gate if (fsharp && bp != p) {
4077c478bd9Sstevel@tonic-gate switch (fcode) {
4087c478bd9Sstevel@tonic-gate case 'o':
4097c478bd9Sstevel@tonic-gate if (lzero < 1)
4107c478bd9Sstevel@tonic-gate lzero = 1;
4117c478bd9Sstevel@tonic-gate break;
4127c478bd9Sstevel@tonic-gate case 'x':
4137c478bd9Sstevel@tonic-gate prefix = "0x";
4147c478bd9Sstevel@tonic-gate break;
4157c478bd9Sstevel@tonic-gate case 'X':
4167c478bd9Sstevel@tonic-gate prefix = "0X";
4177c478bd9Sstevel@tonic-gate break;
4187c478bd9Sstevel@tonic-gate }
4197c478bd9Sstevel@tonic-gate }
4207c478bd9Sstevel@tonic-gate
4217c478bd9Sstevel@tonic-gate break;
4227c478bd9Sstevel@tonic-gate #if FLOAT
4237c478bd9Sstevel@tonic-gate case 'E':
4247c478bd9Sstevel@tonic-gate case 'e':
4257c478bd9Sstevel@tonic-gate /*
4267c478bd9Sstevel@tonic-gate * E-format. The general strategy
4277c478bd9Sstevel@tonic-gate * here is fairly easy: we take
4287c478bd9Sstevel@tonic-gate * what ecvt gives us and re-format it.
4297c478bd9Sstevel@tonic-gate */
4307c478bd9Sstevel@tonic-gate
4317c478bd9Sstevel@tonic-gate /* Establish default precision */
4327c478bd9Sstevel@tonic-gate if (prec < 0) {
4337c478bd9Sstevel@tonic-gate prec = 6;
4347c478bd9Sstevel@tonic-gate }
4357c478bd9Sstevel@tonic-gate
4367c478bd9Sstevel@tonic-gate /* Fetch the value */
4377c478bd9Sstevel@tonic-gate dval = va_arg(*args, double);
4387c478bd9Sstevel@tonic-gate
4397c478bd9Sstevel@tonic-gate /* Develop the mantissa */
4407c478bd9Sstevel@tonic-gate bp = ecvt(dval,
4417c478bd9Sstevel@tonic-gate min(prec + 1, MAXECVT),
4427c478bd9Sstevel@tonic-gate &decpt,
4437c478bd9Sstevel@tonic-gate &sign);
4447c478bd9Sstevel@tonic-gate
4457c478bd9Sstevel@tonic-gate /* Determine the prefix */
4467c478bd9Sstevel@tonic-gate e_merge:
4477c478bd9Sstevel@tonic-gate if (sign) {
4487c478bd9Sstevel@tonic-gate prefix = "-";
4497c478bd9Sstevel@tonic-gate } else if (fplus) {
4507c478bd9Sstevel@tonic-gate prefix = "+";
4517c478bd9Sstevel@tonic-gate } else if (fblank) {
4527c478bd9Sstevel@tonic-gate prefix = " ";
4537c478bd9Sstevel@tonic-gate }
4547c478bd9Sstevel@tonic-gate
4557c478bd9Sstevel@tonic-gate /* Place the first digit in the buffer */
4567c478bd9Sstevel@tonic-gate p = &buf[0];
4577c478bd9Sstevel@tonic-gate *p++ = *bp != '\0' ? *bp++ : '0';
4587c478bd9Sstevel@tonic-gate
4597c478bd9Sstevel@tonic-gate /* Put in a decimal point if needed */
4607c478bd9Sstevel@tonic-gate if (prec != 0 || fsharp) {
4617c478bd9Sstevel@tonic-gate *p++ = '.';
4627c478bd9Sstevel@tonic-gate }
4637c478bd9Sstevel@tonic-gate
4647c478bd9Sstevel@tonic-gate /* Create the rest of the mantissa */
4657c478bd9Sstevel@tonic-gate rzero = prec;
4667c478bd9Sstevel@tonic-gate while (rzero > 0 && *bp != '\0') {
4677c478bd9Sstevel@tonic-gate --rzero;
4687c478bd9Sstevel@tonic-gate *p++ = *bp++;
4697c478bd9Sstevel@tonic-gate }
4707c478bd9Sstevel@tonic-gate
4717c478bd9Sstevel@tonic-gate bp = &buf[0];
4727c478bd9Sstevel@tonic-gate
4737c478bd9Sstevel@tonic-gate /* Create the exponent */
4747c478bd9Sstevel@tonic-gate suffix = &expbuf[MAXESIZ];
4757c478bd9Sstevel@tonic-gate *suffix = '\0';
4767c478bd9Sstevel@tonic-gate if (dval != 0) {
4777c478bd9Sstevel@tonic-gate n = decpt - 1;
4787c478bd9Sstevel@tonic-gate if (n < 0) {
4797c478bd9Sstevel@tonic-gate n = -n;
4807c478bd9Sstevel@tonic-gate }
4817c478bd9Sstevel@tonic-gate while (n != 0) {
4827c478bd9Sstevel@tonic-gate *--suffix = todigit(n % 10);
4837c478bd9Sstevel@tonic-gate n /= 10;
4847c478bd9Sstevel@tonic-gate }
4857c478bd9Sstevel@tonic-gate }
4867c478bd9Sstevel@tonic-gate
4877c478bd9Sstevel@tonic-gate /* Prepend leading zeroes to the exponent */
4887c478bd9Sstevel@tonic-gate while (suffix > &expbuf[MAXESIZ - 2]) {
4897c478bd9Sstevel@tonic-gate *--suffix = '0';
4907c478bd9Sstevel@tonic-gate }
4917c478bd9Sstevel@tonic-gate
4927c478bd9Sstevel@tonic-gate /* Put in the exponent sign */
4937c478bd9Sstevel@tonic-gate *--suffix = (decpt > 0 || dval == 0) ?
4947c478bd9Sstevel@tonic-gate '+' : '-';
4957c478bd9Sstevel@tonic-gate
4967c478bd9Sstevel@tonic-gate /* Put in the e */
4977c478bd9Sstevel@tonic-gate *--suffix = isupper(fcode) ? 'E' : 'e';
4987c478bd9Sstevel@tonic-gate
4997c478bd9Sstevel@tonic-gate break;
5007c478bd9Sstevel@tonic-gate
5017c478bd9Sstevel@tonic-gate case 'f':
5027c478bd9Sstevel@tonic-gate /*
5037c478bd9Sstevel@tonic-gate * F-format floating point. This is
5047c478bd9Sstevel@tonic-gate * a good deal less simple than E-format.
5057c478bd9Sstevel@tonic-gate * The overall strategy will be to call
5067c478bd9Sstevel@tonic-gate * fcvt, reformat its result into buf,
5077c478bd9Sstevel@tonic-gate * and calculate how many trailing
5087c478bd9Sstevel@tonic-gate * zeroes will be required. There will
5097c478bd9Sstevel@tonic-gate * never be any leading zeroes needed.
5107c478bd9Sstevel@tonic-gate */
5117c478bd9Sstevel@tonic-gate
5127c478bd9Sstevel@tonic-gate /* Establish default precision */
5137c478bd9Sstevel@tonic-gate if (prec < 0) {
5147c478bd9Sstevel@tonic-gate prec = 6;
5157c478bd9Sstevel@tonic-gate }
5167c478bd9Sstevel@tonic-gate
5177c478bd9Sstevel@tonic-gate /* Fetch the value */
5187c478bd9Sstevel@tonic-gate dval = va_arg(*args, double);
5197c478bd9Sstevel@tonic-gate
5207c478bd9Sstevel@tonic-gate /* Do the conversion */
5217c478bd9Sstevel@tonic-gate bp = fcvt(dval,
5227c478bd9Sstevel@tonic-gate min(prec, MAXFCVT),
5237c478bd9Sstevel@tonic-gate &decpt,
5247c478bd9Sstevel@tonic-gate &sign);
5257c478bd9Sstevel@tonic-gate
5267c478bd9Sstevel@tonic-gate /* Determine the prefix */
5277c478bd9Sstevel@tonic-gate f_merge:
5287c478bd9Sstevel@tonic-gate if (sign && decpt > -prec &&
5297c478bd9Sstevel@tonic-gate *bp != '\0' && *bp != '0') {
5307c478bd9Sstevel@tonic-gate prefix = "-";
5317c478bd9Sstevel@tonic-gate } else if (fplus) {
5327c478bd9Sstevel@tonic-gate prefix = "+";
5337c478bd9Sstevel@tonic-gate } else if (fblank) {
5347c478bd9Sstevel@tonic-gate prefix = " ";
5357c478bd9Sstevel@tonic-gate }
5367c478bd9Sstevel@tonic-gate
5377c478bd9Sstevel@tonic-gate /* Initialize buffer pointer */
5387c478bd9Sstevel@tonic-gate p = &buf[0];
5397c478bd9Sstevel@tonic-gate
5407c478bd9Sstevel@tonic-gate /* Emit the digits before the decimal point */
5417c478bd9Sstevel@tonic-gate n = decpt;
5427c478bd9Sstevel@tonic-gate k = 0;
5437c478bd9Sstevel@tonic-gate if (n <= 0) {
5447c478bd9Sstevel@tonic-gate *p++ = '0';
5457c478bd9Sstevel@tonic-gate } else {
5467c478bd9Sstevel@tonic-gate do {
5477c478bd9Sstevel@tonic-gate if (*bp == '\0' ||
5487c478bd9Sstevel@tonic-gate k >= MAXFSIG) {
5497c478bd9Sstevel@tonic-gate *p++ = '0';
5507c478bd9Sstevel@tonic-gate } else {
5517c478bd9Sstevel@tonic-gate *p++ = *bp++;
5527c478bd9Sstevel@tonic-gate ++k;
5537c478bd9Sstevel@tonic-gate }
5547c478bd9Sstevel@tonic-gate } while (--n != 0);
5557c478bd9Sstevel@tonic-gate }
5567c478bd9Sstevel@tonic-gate
5577c478bd9Sstevel@tonic-gate /* Decide whether we need a decimal point */
5587c478bd9Sstevel@tonic-gate if (fsharp || prec > 0) {
5597c478bd9Sstevel@tonic-gate *p++ = '.';
5607c478bd9Sstevel@tonic-gate }
5617c478bd9Sstevel@tonic-gate
5627c478bd9Sstevel@tonic-gate /* Digits (if any) after the decimal point */
5637c478bd9Sstevel@tonic-gate n = min(prec, MAXFCVT);
5647c478bd9Sstevel@tonic-gate rzero = prec - n;
5657c478bd9Sstevel@tonic-gate while (--n >= 0) {
5667c478bd9Sstevel@tonic-gate if (++decpt <= 0 || *bp == '\0' ||
5677c478bd9Sstevel@tonic-gate k >= MAXFSIG) {
5687c478bd9Sstevel@tonic-gate *p++ = '0';
5697c478bd9Sstevel@tonic-gate } else {
5707c478bd9Sstevel@tonic-gate *p++ = *bp++;
5717c478bd9Sstevel@tonic-gate ++k;
5727c478bd9Sstevel@tonic-gate }
5737c478bd9Sstevel@tonic-gate }
5747c478bd9Sstevel@tonic-gate
5757c478bd9Sstevel@tonic-gate bp = &buf[0];
5767c478bd9Sstevel@tonic-gate
5777c478bd9Sstevel@tonic-gate break;
5787c478bd9Sstevel@tonic-gate
5797c478bd9Sstevel@tonic-gate case 'G':
5807c478bd9Sstevel@tonic-gate case 'g':
5817c478bd9Sstevel@tonic-gate /*
5827c478bd9Sstevel@tonic-gate * g-format. We play around a bit
5837c478bd9Sstevel@tonic-gate * and then jump into e or f, as needed.
5847c478bd9Sstevel@tonic-gate */
5857c478bd9Sstevel@tonic-gate
5867c478bd9Sstevel@tonic-gate /* Establish default precision */
5877c478bd9Sstevel@tonic-gate if (prec < 0) {
5887c478bd9Sstevel@tonic-gate prec = 6;
5897c478bd9Sstevel@tonic-gate }
5907c478bd9Sstevel@tonic-gate
5917c478bd9Sstevel@tonic-gate /* Fetch the value */
5927c478bd9Sstevel@tonic-gate dval = va_arg(*args, double);
5937c478bd9Sstevel@tonic-gate
5947c478bd9Sstevel@tonic-gate /* Do the conversion */
5957c478bd9Sstevel@tonic-gate bp = ecvt(dval,
5967c478bd9Sstevel@tonic-gate min(prec, MAXECVT),
5977c478bd9Sstevel@tonic-gate &decpt,
5987c478bd9Sstevel@tonic-gate &sign);
5997c478bd9Sstevel@tonic-gate if (dval == 0) {
6007c478bd9Sstevel@tonic-gate decpt = 1;
6017c478bd9Sstevel@tonic-gate }
6027c478bd9Sstevel@tonic-gate
6037c478bd9Sstevel@tonic-gate k = prec;
6047c478bd9Sstevel@tonic-gate if (!fsharp) {
6057c478bd9Sstevel@tonic-gate n = strlen(bp);
6067c478bd9Sstevel@tonic-gate if (n < k) {
6077c478bd9Sstevel@tonic-gate k = n;
6087c478bd9Sstevel@tonic-gate }
6097c478bd9Sstevel@tonic-gate while (k >= 1 && bp[k-1] == '0') {
6107c478bd9Sstevel@tonic-gate --k;
6117c478bd9Sstevel@tonic-gate }
6127c478bd9Sstevel@tonic-gate }
6137c478bd9Sstevel@tonic-gate
6147c478bd9Sstevel@tonic-gate if (decpt < -3 || decpt > prec) {
6157c478bd9Sstevel@tonic-gate prec = k - 1;
6167c478bd9Sstevel@tonic-gate goto e_merge;
6177c478bd9Sstevel@tonic-gate } else {
6187c478bd9Sstevel@tonic-gate prec = k - decpt;
6197c478bd9Sstevel@tonic-gate goto f_merge;
6207c478bd9Sstevel@tonic-gate }
6217c478bd9Sstevel@tonic-gate
6227c478bd9Sstevel@tonic-gate #endif
6237c478bd9Sstevel@tonic-gate case 'c':
6247c478bd9Sstevel@tonic-gate #ifdef MBCHAR_1 /* sizeof(int)>=sizeof(tchar) */
6257c478bd9Sstevel@tonic-gate /*
6267c478bd9Sstevel@tonic-gate * A tchar arg is passed as int so we used the normal %c to specify
6277c478bd9Sstevel@tonic-gate * such an arugument.
6287c478bd9Sstevel@tonic-gate */
6297c478bd9Sstevel@tonic-gate tcbuf[0] = va_arg(*args, int);
6307c478bd9Sstevel@tonic-gate tbp = &tcbuf[0];
6317c478bd9Sstevel@tonic-gate tep = tbp + 1;
6327c478bd9Sstevel@tonic-gate fcode = 't'; /* Fake the rest of code. */
6337c478bd9Sstevel@tonic-gate break;
6347c478bd9Sstevel@tonic-gate #else
6357c478bd9Sstevel@tonic-gate /*
6367c478bd9Sstevel@tonic-gate * We would have to invent another new format speficier such as "%T" to
6377c478bd9Sstevel@tonic-gate * take a tchar arg. Let's worry about when that time comes.
6387c478bd9Sstevel@tonic-gate */
6397c478bd9Sstevel@tonic-gate /*
6407c478bd9Sstevel@tonic-gate * Following code take care of a char arg
6417c478bd9Sstevel@tonic-gate * only.
6427c478bd9Sstevel@tonic-gate */
6437c478bd9Sstevel@tonic-gate buf[0] = va_arg(*args, int);
6447c478bd9Sstevel@tonic-gate bp = &buf[0];
6457c478bd9Sstevel@tonic-gate p = bp + 1;
6467c478bd9Sstevel@tonic-gate break;
6477c478bd9Sstevel@tonic-gate case 'T': /* Corresponding arg is tchar. */
6487c478bd9Sstevel@tonic-gate tcbuf[0] = va_arg(*args, tchar);
6497c478bd9Sstevel@tonic-gate tbp = &tcbuf[0];
6507c478bd9Sstevel@tonic-gate tep = tbp + 1;
6517c478bd9Sstevel@tonic-gate fcode = 't'; /* Fake the rest of code. */
6527c478bd9Sstevel@tonic-gate break;
6537c478bd9Sstevel@tonic-gate #endif
6547c478bd9Sstevel@tonic-gate case 's':
6557c478bd9Sstevel@tonic-gate bp = va_arg(*args, char *);
6567c478bd9Sstevel@tonic-gate if (bp == 0) {
6577c478bd9Sstevel@tonic-gate nullstr: bp = "(null)";
6587c478bd9Sstevel@tonic-gate p = bp + strlen("(null)");
6597c478bd9Sstevel@tonic-gate break;
6607c478bd9Sstevel@tonic-gate }
6617c478bd9Sstevel@tonic-gate if (prec < 0) {
6627c478bd9Sstevel@tonic-gate prec = MAXINT;
6637c478bd9Sstevel@tonic-gate }
6647c478bd9Sstevel@tonic-gate for (n = 0; *bp++ != '\0' && n < prec; n++)
6657c478bd9Sstevel@tonic-gate ;
6667c478bd9Sstevel@tonic-gate p = --bp;
6677c478bd9Sstevel@tonic-gate bp -= n;
6687c478bd9Sstevel@tonic-gate break;
6697c478bd9Sstevel@tonic-gate
6707c478bd9Sstevel@tonic-gate case 't':
6717c478bd9Sstevel@tonic-gate /*
6727c478bd9Sstevel@tonic-gate * Special format specifier "%t" tells
6737c478bd9Sstevel@tonic-gate * printf() to print char strings written
6747c478bd9Sstevel@tonic-gate * as tchar string.
6757c478bd9Sstevel@tonic-gate */
6767c478bd9Sstevel@tonic-gate tbp = va_arg(*args, tchar *);
6777c478bd9Sstevel@tonic-gate if (tbp == 0) {
6787c478bd9Sstevel@tonic-gate fcode = 's'; /* Act as if it were %s. */
6797c478bd9Sstevel@tonic-gate goto nullstr;
6807c478bd9Sstevel@tonic-gate }
6817c478bd9Sstevel@tonic-gate if (prec < 0) {
6827c478bd9Sstevel@tonic-gate prec = MAXINT;
6837c478bd9Sstevel@tonic-gate }
6847c478bd9Sstevel@tonic-gate for (n = 0; *tbp++ != 0 && n < prec; n++)
6857c478bd9Sstevel@tonic-gate ;
6867c478bd9Sstevel@tonic-gate tep = --tbp;
6877c478bd9Sstevel@tonic-gate tbp -= n;
6887c478bd9Sstevel@tonic-gate
6897c478bd9Sstevel@tonic-gate /*
6907c478bd9Sstevel@tonic-gate * Just to make the following padding
6917c478bd9Sstevel@tonic-gate * calculation not to go very crazy...
6927c478bd9Sstevel@tonic-gate */
6937c478bd9Sstevel@tonic-gate bp = NULL;
6947c478bd9Sstevel@tonic-gate p = bp + n;
6957c478bd9Sstevel@tonic-gate break;
6967c478bd9Sstevel@tonic-gate
6977c478bd9Sstevel@tonic-gate case '\0':
6987c478bd9Sstevel@tonic-gate cp--;
6997c478bd9Sstevel@tonic-gate break;
7007c478bd9Sstevel@tonic-gate
7017c478bd9Sstevel@tonic-gate default:
7027c478bd9Sstevel@tonic-gate p = bp = &fcode;
7037c478bd9Sstevel@tonic-gate p++;
7047c478bd9Sstevel@tonic-gate break;
7057c478bd9Sstevel@tonic-gate
7067c478bd9Sstevel@tonic-gate }
7077c478bd9Sstevel@tonic-gate if (fcode != '\0') {
7087c478bd9Sstevel@tonic-gate /* Calculate number of padding blanks */
7097c478bd9Sstevel@tonic-gate int nblank;
7107c478bd9Sstevel@tonic-gate nblank = width
7117c478bd9Sstevel@tonic-gate #if FLOAT
7127c478bd9Sstevel@tonic-gate - (rzero < 0 ? 0: rzero)
7137c478bd9Sstevel@tonic-gate - strlen(suffix)
7147c478bd9Sstevel@tonic-gate #endif
7157c478bd9Sstevel@tonic-gate - (p - bp)
7167c478bd9Sstevel@tonic-gate - (lzero < 0 ? 0 : lzero)
7177c478bd9Sstevel@tonic-gate - strlen(prefix);
7187c478bd9Sstevel@tonic-gate
7197c478bd9Sstevel@tonic-gate /* Blanks on left if required */
7207c478bd9Sstevel@tonic-gate if (!fminus) {
7217c478bd9Sstevel@tonic-gate while (--nblank >= 0) {
7227c478bd9Sstevel@tonic-gate Putchar(' ');
7237c478bd9Sstevel@tonic-gate }
7247c478bd9Sstevel@tonic-gate }
7257c478bd9Sstevel@tonic-gate
7267c478bd9Sstevel@tonic-gate /* Prefix, if any */
7277c478bd9Sstevel@tonic-gate while (*prefix != '\0') {
7287c478bd9Sstevel@tonic-gate Putchar(*prefix++);
7297c478bd9Sstevel@tonic-gate }
7307c478bd9Sstevel@tonic-gate
7317c478bd9Sstevel@tonic-gate /* Zeroes on the left */
7327c478bd9Sstevel@tonic-gate while (--lzero >= 0) {
7337c478bd9Sstevel@tonic-gate Putchar('0');
7347c478bd9Sstevel@tonic-gate }
7357c478bd9Sstevel@tonic-gate
7367c478bd9Sstevel@tonic-gate /* The value itself */
7377c478bd9Sstevel@tonic-gate if (fcode == 't') { /* %t is special. */
7387c478bd9Sstevel@tonic-gate while (tbp < tep) {
7397c478bd9Sstevel@tonic-gate Putchar(*tbp++);
7407c478bd9Sstevel@tonic-gate }
7417c478bd9Sstevel@tonic-gate } else { /* For rest of the cases. */
7427c478bd9Sstevel@tonic-gate while (bp < p) {
7437c478bd9Sstevel@tonic-gate putbyte(*bp++);
7447c478bd9Sstevel@tonic-gate }
7457c478bd9Sstevel@tonic-gate }
7467c478bd9Sstevel@tonic-gate #if FLOAT
7477c478bd9Sstevel@tonic-gate /* Zeroes on the right */
7487c478bd9Sstevel@tonic-gate while (--rzero >= 0)
7497c478bd9Sstevel@tonic-gate Putchar('0');
7507c478bd9Sstevel@tonic-gate
7517c478bd9Sstevel@tonic-gate /* The suffix */
7527c478bd9Sstevel@tonic-gate while (*suffix != '\0') {
7537c478bd9Sstevel@tonic-gate Putchar(*suffix++);
7547c478bd9Sstevel@tonic-gate }
7557c478bd9Sstevel@tonic-gate #endif
7567c478bd9Sstevel@tonic-gate /* Blanks on the right if required */
7577c478bd9Sstevel@tonic-gate if (fminus) {
7587c478bd9Sstevel@tonic-gate while (--nblank >= 0) {
7597c478bd9Sstevel@tonic-gate Putchar(' ');
7607c478bd9Sstevel@tonic-gate }
7617c478bd9Sstevel@tonic-gate }
7627c478bd9Sstevel@tonic-gate }
7637c478bd9Sstevel@tonic-gate }
7647c478bd9Sstevel@tonic-gate }
765