1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 3*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 4*7c478bd9Sstevel@tonic-gate */ 5*7c478bd9Sstevel@tonic-gate 6*7c478bd9Sstevel@tonic-gate /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ 7*7c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 8*7c478bd9Sstevel@tonic-gate 9*7c478bd9Sstevel@tonic-gate /* 10*7c478bd9Sstevel@tonic-gate * Copyright (c) 1980 Regents of the University of California. 11*7c478bd9Sstevel@tonic-gate * All rights reserved. The Berkeley Software License Agreement 12*7c478bd9Sstevel@tonic-gate * specifies the terms and conditions for redistribution. 13*7c478bd9Sstevel@tonic-gate */ 14*7c478bd9Sstevel@tonic-gate 15*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 16*7c478bd9Sstevel@tonic-gate 17*7c478bd9Sstevel@tonic-gate /* 18*7c478bd9Sstevel@tonic-gate * Hacked "printf" which prints through putbyte and Putchar. 19*7c478bd9Sstevel@tonic-gate * putbyte() is used to send a pure byte, which might be a part 20*7c478bd9Sstevel@tonic-gate * of a mutlibyte character, mainly for %s. A control character 21*7c478bd9Sstevel@tonic-gate * for putbyte() may be QUOTE'd meaning not to convert it to ^x 22*7c478bd9Sstevel@tonic-gate * sequence. In all other cases Putchar() is used to send a character 23*7c478bd9Sstevel@tonic-gate * in tchar (== wchar_t + * optional QUOE.) 24*7c478bd9Sstevel@tonic-gate * DONT USE WITH STDIO! 25*7c478bd9Sstevel@tonic-gate * This printf has been hacked again so that it understands tchar string 26*7c478bd9Sstevel@tonic-gate * when the format specifier %t is used. Also %c has been expanded 27*7c478bd9Sstevel@tonic-gate * to take a tchar character as well as normal int. 28*7c478bd9Sstevel@tonic-gate * %t is supported in its simplest form; no width or precision will 29*7c478bd9Sstevel@tonic-gate * be understood. 30*7c478bd9Sstevel@tonic-gate * Assumption here is that sizeof(tchar)<=sizeof(int) so that tchar is 31*7c478bd9Sstevel@tonic-gate * passed as int. Otherwise, %T must be specified instead of %c to 32*7c478bd9Sstevel@tonic-gate * print a character in tchar. 33*7c478bd9Sstevel@tonic-gate */ 34*7c478bd9Sstevel@tonic-gate 35*7c478bd9Sstevel@tonic-gate #include <stdarg.h> 36*7c478bd9Sstevel@tonic-gate #include <values.h> 37*7c478bd9Sstevel@tonic-gate #include "sh.h" /* For tchar. */ 38*7c478bd9Sstevel@tonic-gate 39*7c478bd9Sstevel@tonic-gate #define HIBITLL (1ULL << 63) 40*7c478bd9Sstevel@tonic-gate 41*7c478bd9Sstevel@tonic-gate void _print(char *format, va_list *args); 42*7c478bd9Sstevel@tonic-gate 43*7c478bd9Sstevel@tonic-gate static char *p; 44*7c478bd9Sstevel@tonic-gate 45*7c478bd9Sstevel@tonic-gate int 46*7c478bd9Sstevel@tonic-gate printf(const char *format, ...) 47*7c478bd9Sstevel@tonic-gate { 48*7c478bd9Sstevel@tonic-gate va_list stupid; 49*7c478bd9Sstevel@tonic-gate 50*7c478bd9Sstevel@tonic-gate p = (char *)gettext(format); 51*7c478bd9Sstevel@tonic-gate va_start(stupid, format); 52*7c478bd9Sstevel@tonic-gate _print(p, &stupid); 53*7c478bd9Sstevel@tonic-gate va_end(stupid); 54*7c478bd9Sstevel@tonic-gate } 55*7c478bd9Sstevel@tonic-gate 56*7c478bd9Sstevel@tonic-gate /* 57*7c478bd9Sstevel@tonic-gate * Floating-point code is included or not, depending 58*7c478bd9Sstevel@tonic-gate * on whether the preprocessor variable FLOAT is 1 or 0. 59*7c478bd9Sstevel@tonic-gate */ 60*7c478bd9Sstevel@tonic-gate 61*7c478bd9Sstevel@tonic-gate /* Maximum number of digits in any integer (long) representation */ 62*7c478bd9Sstevel@tonic-gate #define MAXDIGS 20 63*7c478bd9Sstevel@tonic-gate 64*7c478bd9Sstevel@tonic-gate /* Convert a digit character to the corresponding number */ 65*7c478bd9Sstevel@tonic-gate #define tonumber(x) ((x) - '0') 66*7c478bd9Sstevel@tonic-gate 67*7c478bd9Sstevel@tonic-gate /* Convert a number between 0 and 9 to the corresponding digit */ 68*7c478bd9Sstevel@tonic-gate #define todigit(x) ((x) + '0') 69*7c478bd9Sstevel@tonic-gate 70*7c478bd9Sstevel@tonic-gate /* Maximum total number of digits in E format */ 71*7c478bd9Sstevel@tonic-gate #define MAXECVT 17 72*7c478bd9Sstevel@tonic-gate 73*7c478bd9Sstevel@tonic-gate /* Maximum number of digits after decimal point in F format */ 74*7c478bd9Sstevel@tonic-gate #define MAXFCVT 60 75*7c478bd9Sstevel@tonic-gate 76*7c478bd9Sstevel@tonic-gate /* Maximum significant figures in a floating-point number */ 77*7c478bd9Sstevel@tonic-gate #define MAXFSIG 17 78*7c478bd9Sstevel@tonic-gate 79*7c478bd9Sstevel@tonic-gate /* Maximum number of characters in an exponent */ 80*7c478bd9Sstevel@tonic-gate #define MAXESIZ 4 81*7c478bd9Sstevel@tonic-gate 82*7c478bd9Sstevel@tonic-gate /* Maximum (positive) exponent or greater */ 83*7c478bd9Sstevel@tonic-gate #define MAXEXP 40 84*7c478bd9Sstevel@tonic-gate 85*7c478bd9Sstevel@tonic-gate 86*7c478bd9Sstevel@tonic-gate 87*7c478bd9Sstevel@tonic-gate #define max(a, b) ((a) > (b) ? (a) : (b)) 88*7c478bd9Sstevel@tonic-gate #define min(a, b) ((a) < (b) ? (a) : (b)) 89*7c478bd9Sstevel@tonic-gate 90*7c478bd9Sstevel@tonic-gate /* If this symbol is nonzero, allow '0' as a flag */ 91*7c478bd9Sstevel@tonic-gate #define FZERO 1 92*7c478bd9Sstevel@tonic-gate 93*7c478bd9Sstevel@tonic-gate #if FLOAT 94*7c478bd9Sstevel@tonic-gate /* 95*7c478bd9Sstevel@tonic-gate * System-supplied routines for floating conversion 96*7c478bd9Sstevel@tonic-gate */ 97*7c478bd9Sstevel@tonic-gate char *fcvt(); 98*7c478bd9Sstevel@tonic-gate char *ecvt(); 99*7c478bd9Sstevel@tonic-gate #endif 100*7c478bd9Sstevel@tonic-gate 101*7c478bd9Sstevel@tonic-gate void 102*7c478bd9Sstevel@tonic-gate _print(char *format, va_list *args) 103*7c478bd9Sstevel@tonic-gate { 104*7c478bd9Sstevel@tonic-gate /* Current position in format */ 105*7c478bd9Sstevel@tonic-gate char *cp; 106*7c478bd9Sstevel@tonic-gate 107*7c478bd9Sstevel@tonic-gate /* Starting and ending points for value to be printed */ 108*7c478bd9Sstevel@tonic-gate char *bp, *p; 109*7c478bd9Sstevel@tonic-gate tchar *tbp, *tep; /* For "%t". */ 110*7c478bd9Sstevel@tonic-gate tchar tcbuf[2]; /* For "%c" or "%T". */ 111*7c478bd9Sstevel@tonic-gate 112*7c478bd9Sstevel@tonic-gate /* Field width and precision */ 113*7c478bd9Sstevel@tonic-gate int width, prec; 114*7c478bd9Sstevel@tonic-gate 115*7c478bd9Sstevel@tonic-gate /* Format code */ 116*7c478bd9Sstevel@tonic-gate char fcode; 117*7c478bd9Sstevel@tonic-gate 118*7c478bd9Sstevel@tonic-gate /* Number of padding zeroes required on the left */ 119*7c478bd9Sstevel@tonic-gate int lzero; 120*7c478bd9Sstevel@tonic-gate 121*7c478bd9Sstevel@tonic-gate /* Flags - nonzero if corresponding character appears in format */ 122*7c478bd9Sstevel@tonic-gate bool length; /* l */ 123*7c478bd9Sstevel@tonic-gate bool double_length; /* ll */ 124*7c478bd9Sstevel@tonic-gate bool fplus; /* + */ 125*7c478bd9Sstevel@tonic-gate bool fminus; /* - */ 126*7c478bd9Sstevel@tonic-gate bool fblank; /* blank */ 127*7c478bd9Sstevel@tonic-gate bool fsharp; /* # */ 128*7c478bd9Sstevel@tonic-gate #if FZERO 129*7c478bd9Sstevel@tonic-gate bool fzero; /* 0 */ 130*7c478bd9Sstevel@tonic-gate #endif 131*7c478bd9Sstevel@tonic-gate 132*7c478bd9Sstevel@tonic-gate /* Pointer to sign, "0x", "0X", or empty */ 133*7c478bd9Sstevel@tonic-gate char *prefix; 134*7c478bd9Sstevel@tonic-gate #if FLOAT 135*7c478bd9Sstevel@tonic-gate /* Exponent or empty */ 136*7c478bd9Sstevel@tonic-gate char *suffix; 137*7c478bd9Sstevel@tonic-gate 138*7c478bd9Sstevel@tonic-gate /* Buffer to create exponent */ 139*7c478bd9Sstevel@tonic-gate char expbuf[MAXESIZ + 1]; 140*7c478bd9Sstevel@tonic-gate 141*7c478bd9Sstevel@tonic-gate /* Number of padding zeroes required on the right */ 142*7c478bd9Sstevel@tonic-gate int rzero; 143*7c478bd9Sstevel@tonic-gate 144*7c478bd9Sstevel@tonic-gate /* The value being converted, if real */ 145*7c478bd9Sstevel@tonic-gate double dval; 146*7c478bd9Sstevel@tonic-gate 147*7c478bd9Sstevel@tonic-gate /* Output values from fcvt and ecvt */ 148*7c478bd9Sstevel@tonic-gate int decpt, sign; 149*7c478bd9Sstevel@tonic-gate 150*7c478bd9Sstevel@tonic-gate /* Scratch */ 151*7c478bd9Sstevel@tonic-gate int k; 152*7c478bd9Sstevel@tonic-gate 153*7c478bd9Sstevel@tonic-gate /* Values are developed in this buffer */ 154*7c478bd9Sstevel@tonic-gate char buf[max(MAXDIGS, max(MAXFCVT + DMAXEXP, MAXECVT) + 1)]; 155*7c478bd9Sstevel@tonic-gate #else 156*7c478bd9Sstevel@tonic-gate char buf[MAXDIGS]; 157*7c478bd9Sstevel@tonic-gate #endif 158*7c478bd9Sstevel@tonic-gate /* The value being converted, if integer */ 159*7c478bd9Sstevel@tonic-gate long long val; 160*7c478bd9Sstevel@tonic-gate 161*7c478bd9Sstevel@tonic-gate /* Set to point to a translate table for digits of whatever radix */ 162*7c478bd9Sstevel@tonic-gate char *tab; 163*7c478bd9Sstevel@tonic-gate 164*7c478bd9Sstevel@tonic-gate /* Work variables */ 165*7c478bd9Sstevel@tonic-gate int n, hradix, lowbit; 166*7c478bd9Sstevel@tonic-gate 167*7c478bd9Sstevel@tonic-gate cp = format; 168*7c478bd9Sstevel@tonic-gate 169*7c478bd9Sstevel@tonic-gate /* 170*7c478bd9Sstevel@tonic-gate * The main loop -- this loop goes through one iteration 171*7c478bd9Sstevel@tonic-gate * for each ordinary character or format specification. 172*7c478bd9Sstevel@tonic-gate */ 173*7c478bd9Sstevel@tonic-gate while (*cp) 174*7c478bd9Sstevel@tonic-gate if (*cp != '%') { 175*7c478bd9Sstevel@tonic-gate /* Ordinary (non-%) character */ 176*7c478bd9Sstevel@tonic-gate putbyte (*cp++); 177*7c478bd9Sstevel@tonic-gate } else { 178*7c478bd9Sstevel@tonic-gate /* 179*7c478bd9Sstevel@tonic-gate * % has been found. 180*7c478bd9Sstevel@tonic-gate * First, parse the format specification. 181*7c478bd9Sstevel@tonic-gate */ 182*7c478bd9Sstevel@tonic-gate 183*7c478bd9Sstevel@tonic-gate /* Scan the <flags> */ 184*7c478bd9Sstevel@tonic-gate fplus = fminus = fblank = fsharp = 0; 185*7c478bd9Sstevel@tonic-gate #if FZERO 186*7c478bd9Sstevel@tonic-gate fzero = 0; 187*7c478bd9Sstevel@tonic-gate #endif 188*7c478bd9Sstevel@tonic-gate scan: 189*7c478bd9Sstevel@tonic-gate switch (*++cp) { 190*7c478bd9Sstevel@tonic-gate case '+': 191*7c478bd9Sstevel@tonic-gate fplus = 1; 192*7c478bd9Sstevel@tonic-gate goto scan; 193*7c478bd9Sstevel@tonic-gate case '-': 194*7c478bd9Sstevel@tonic-gate fminus = 1; 195*7c478bd9Sstevel@tonic-gate goto scan; 196*7c478bd9Sstevel@tonic-gate case ' ': 197*7c478bd9Sstevel@tonic-gate fblank = 1; 198*7c478bd9Sstevel@tonic-gate goto scan; 199*7c478bd9Sstevel@tonic-gate case '#': 200*7c478bd9Sstevel@tonic-gate fsharp = 1; 201*7c478bd9Sstevel@tonic-gate goto scan; 202*7c478bd9Sstevel@tonic-gate #if FZERO 203*7c478bd9Sstevel@tonic-gate case '0': 204*7c478bd9Sstevel@tonic-gate fzero = 1; 205*7c478bd9Sstevel@tonic-gate goto scan; 206*7c478bd9Sstevel@tonic-gate #endif 207*7c478bd9Sstevel@tonic-gate } 208*7c478bd9Sstevel@tonic-gate 209*7c478bd9Sstevel@tonic-gate /* Scan the field width */ 210*7c478bd9Sstevel@tonic-gate if (*cp == '*') { 211*7c478bd9Sstevel@tonic-gate width = va_arg (*args, int); 212*7c478bd9Sstevel@tonic-gate if (width < 0) { 213*7c478bd9Sstevel@tonic-gate width = -width; 214*7c478bd9Sstevel@tonic-gate fminus = 1; 215*7c478bd9Sstevel@tonic-gate } 216*7c478bd9Sstevel@tonic-gate cp++; 217*7c478bd9Sstevel@tonic-gate } else { 218*7c478bd9Sstevel@tonic-gate width = 0; 219*7c478bd9Sstevel@tonic-gate while (isdigit(*cp)) { 220*7c478bd9Sstevel@tonic-gate n = tonumber(*cp++); 221*7c478bd9Sstevel@tonic-gate width = width * 10 + n; 222*7c478bd9Sstevel@tonic-gate } 223*7c478bd9Sstevel@tonic-gate } 224*7c478bd9Sstevel@tonic-gate 225*7c478bd9Sstevel@tonic-gate /* Scan the precision */ 226*7c478bd9Sstevel@tonic-gate if (*cp == '.') { 227*7c478bd9Sstevel@tonic-gate 228*7c478bd9Sstevel@tonic-gate /* '*' instead of digits? */ 229*7c478bd9Sstevel@tonic-gate if (*++cp == '*') { 230*7c478bd9Sstevel@tonic-gate prec = va_arg(*args, int); 231*7c478bd9Sstevel@tonic-gate cp++; 232*7c478bd9Sstevel@tonic-gate } else { 233*7c478bd9Sstevel@tonic-gate prec = 0; 234*7c478bd9Sstevel@tonic-gate while (isdigit(*cp)) { 235*7c478bd9Sstevel@tonic-gate n = tonumber(*cp++); 236*7c478bd9Sstevel@tonic-gate prec = prec * 10 + n; 237*7c478bd9Sstevel@tonic-gate } 238*7c478bd9Sstevel@tonic-gate } 239*7c478bd9Sstevel@tonic-gate } else { 240*7c478bd9Sstevel@tonic-gate prec = -1; 241*7c478bd9Sstevel@tonic-gate } 242*7c478bd9Sstevel@tonic-gate 243*7c478bd9Sstevel@tonic-gate /* Scan the length modifier */ 244*7c478bd9Sstevel@tonic-gate double_length = length = 0; 245*7c478bd9Sstevel@tonic-gate switch (*cp) { 246*7c478bd9Sstevel@tonic-gate case 'l': 247*7c478bd9Sstevel@tonic-gate if (*(cp + 1) == 'l') { 248*7c478bd9Sstevel@tonic-gate cp++; 249*7c478bd9Sstevel@tonic-gate double_length = 1; 250*7c478bd9Sstevel@tonic-gate } else { 251*7c478bd9Sstevel@tonic-gate length = 1; 252*7c478bd9Sstevel@tonic-gate } 253*7c478bd9Sstevel@tonic-gate /* No break */ 254*7c478bd9Sstevel@tonic-gate case 'h': 255*7c478bd9Sstevel@tonic-gate cp++; 256*7c478bd9Sstevel@tonic-gate } 257*7c478bd9Sstevel@tonic-gate 258*7c478bd9Sstevel@tonic-gate /* 259*7c478bd9Sstevel@tonic-gate * The character addressed by cp must be the 260*7c478bd9Sstevel@tonic-gate * format letter -- there is nothing left for 261*7c478bd9Sstevel@tonic-gate * it to be. 262*7c478bd9Sstevel@tonic-gate * 263*7c478bd9Sstevel@tonic-gate * The status of the +, -, #, blank, and 0 264*7c478bd9Sstevel@tonic-gate * flags are reflected in the variables 265*7c478bd9Sstevel@tonic-gate * "fplus", "fminus", "fsharp", "fblank", 266*7c478bd9Sstevel@tonic-gate * and "fzero", respectively. 267*7c478bd9Sstevel@tonic-gate * "width" and "prec" contain numbers 268*7c478bd9Sstevel@tonic-gate * corresponding to the digit strings 269*7c478bd9Sstevel@tonic-gate * before and after the decimal point, 270*7c478bd9Sstevel@tonic-gate * respectively. If there was no decimal 271*7c478bd9Sstevel@tonic-gate * point, "prec" is -1. 272*7c478bd9Sstevel@tonic-gate * 273*7c478bd9Sstevel@tonic-gate * The following switch sets things up 274*7c478bd9Sstevel@tonic-gate * for printing. What ultimately gets 275*7c478bd9Sstevel@tonic-gate * printed will be padding blanks, a prefix, 276*7c478bd9Sstevel@tonic-gate * left padding zeroes, a value, right padding 277*7c478bd9Sstevel@tonic-gate * zeroes, a suffix, and more padding 278*7c478bd9Sstevel@tonic-gate * blanks. Padding blanks will not appear 279*7c478bd9Sstevel@tonic-gate * simultaneously on both the left and the 280*7c478bd9Sstevel@tonic-gate * right. Each case in this switch will 281*7c478bd9Sstevel@tonic-gate * compute the value, and leave in several 282*7c478bd9Sstevel@tonic-gate * variables the information necessary to 283*7c478bd9Sstevel@tonic-gate * construct what is to be printed. 284*7c478bd9Sstevel@tonic-gate * 285*7c478bd9Sstevel@tonic-gate * The prefix is a sign, a blank, "0x", "0X", 286*7c478bd9Sstevel@tonic-gate * or null, and is addressed by "prefix". 287*7c478bd9Sstevel@tonic-gate * 288*7c478bd9Sstevel@tonic-gate * The suffix is either null or an exponent, 289*7c478bd9Sstevel@tonic-gate * and is addressed by "suffix". 290*7c478bd9Sstevel@tonic-gate * 291*7c478bd9Sstevel@tonic-gate * The value to be printed starts at "bp" 292*7c478bd9Sstevel@tonic-gate * and continues up to and not including "p". 293*7c478bd9Sstevel@tonic-gate * 294*7c478bd9Sstevel@tonic-gate * "lzero" and "rzero" will contain the number 295*7c478bd9Sstevel@tonic-gate * of padding zeroes required on the left 296*7c478bd9Sstevel@tonic-gate * and right, respectively. If either of 297*7c478bd9Sstevel@tonic-gate * these variables is negative, it will be 298*7c478bd9Sstevel@tonic-gate * treated as if it were zero. 299*7c478bd9Sstevel@tonic-gate * 300*7c478bd9Sstevel@tonic-gate * The number of padding blanks, and whether 301*7c478bd9Sstevel@tonic-gate * they go on the left or the right, will be 302*7c478bd9Sstevel@tonic-gate * computed on exit from the switch. 303*7c478bd9Sstevel@tonic-gate */ 304*7c478bd9Sstevel@tonic-gate 305*7c478bd9Sstevel@tonic-gate lzero = 0; 306*7c478bd9Sstevel@tonic-gate prefix = ""; 307*7c478bd9Sstevel@tonic-gate #if FLOAT 308*7c478bd9Sstevel@tonic-gate rzero = lzero; 309*7c478bd9Sstevel@tonic-gate suffix = prefix; 310*7c478bd9Sstevel@tonic-gate #endif 311*7c478bd9Sstevel@tonic-gate switch (fcode = *cp++) { 312*7c478bd9Sstevel@tonic-gate 313*7c478bd9Sstevel@tonic-gate /* 314*7c478bd9Sstevel@tonic-gate * fixed point representations 315*7c478bd9Sstevel@tonic-gate * 316*7c478bd9Sstevel@tonic-gate * "hradix" is half the radix for the conversion. 317*7c478bd9Sstevel@tonic-gate * Conversion is unsigned unless fcode is 'd'. 318*7c478bd9Sstevel@tonic-gate * HIBITLL is 1000...000 binary, and is equal to 319*7c478bd9Sstevel@tonic-gate * the maximum negative number. 320*7c478bd9Sstevel@tonic-gate * We assume a 2's complement machine 321*7c478bd9Sstevel@tonic-gate */ 322*7c478bd9Sstevel@tonic-gate 323*7c478bd9Sstevel@tonic-gate case 'D': 324*7c478bd9Sstevel@tonic-gate case 'U': 325*7c478bd9Sstevel@tonic-gate length = 1; 326*7c478bd9Sstevel@tonic-gate case 'd': 327*7c478bd9Sstevel@tonic-gate case 'u': 328*7c478bd9Sstevel@tonic-gate hradix = 5; 329*7c478bd9Sstevel@tonic-gate goto fixed; 330*7c478bd9Sstevel@tonic-gate 331*7c478bd9Sstevel@tonic-gate case 'O': 332*7c478bd9Sstevel@tonic-gate length = 1; 333*7c478bd9Sstevel@tonic-gate case 'o': 334*7c478bd9Sstevel@tonic-gate hradix = 4; 335*7c478bd9Sstevel@tonic-gate goto fixed; 336*7c478bd9Sstevel@tonic-gate 337*7c478bd9Sstevel@tonic-gate case 'X': 338*7c478bd9Sstevel@tonic-gate case 'x': 339*7c478bd9Sstevel@tonic-gate hradix = 8; 340*7c478bd9Sstevel@tonic-gate 341*7c478bd9Sstevel@tonic-gate fixed: 342*7c478bd9Sstevel@tonic-gate /* Establish default precision */ 343*7c478bd9Sstevel@tonic-gate if (prec < 0) { 344*7c478bd9Sstevel@tonic-gate prec = 1; 345*7c478bd9Sstevel@tonic-gate } 346*7c478bd9Sstevel@tonic-gate 347*7c478bd9Sstevel@tonic-gate /* Fetch the argument to be printed */ 348*7c478bd9Sstevel@tonic-gate if (double_length) { 349*7c478bd9Sstevel@tonic-gate val = va_arg(*args, long long); 350*7c478bd9Sstevel@tonic-gate } else if (length) { 351*7c478bd9Sstevel@tonic-gate val = va_arg(*args, long); 352*7c478bd9Sstevel@tonic-gate } else if (fcode == 'd') { 353*7c478bd9Sstevel@tonic-gate val = va_arg(*args, int); 354*7c478bd9Sstevel@tonic-gate } else { 355*7c478bd9Sstevel@tonic-gate val = va_arg(*args, unsigned); 356*7c478bd9Sstevel@tonic-gate } 357*7c478bd9Sstevel@tonic-gate 358*7c478bd9Sstevel@tonic-gate /* If signed conversion, establish sign */ 359*7c478bd9Sstevel@tonic-gate if (fcode == 'd' || fcode == 'D') { 360*7c478bd9Sstevel@tonic-gate if (val < 0) { 361*7c478bd9Sstevel@tonic-gate prefix = "-"; 362*7c478bd9Sstevel@tonic-gate /* 363*7c478bd9Sstevel@tonic-gate * Negate, checking in 364*7c478bd9Sstevel@tonic-gate * advance for possible 365*7c478bd9Sstevel@tonic-gate * overflow. 366*7c478bd9Sstevel@tonic-gate */ 367*7c478bd9Sstevel@tonic-gate if (val != HIBITLL) { 368*7c478bd9Sstevel@tonic-gate val = -val; 369*7c478bd9Sstevel@tonic-gate } 370*7c478bd9Sstevel@tonic-gate } else if (fplus) { 371*7c478bd9Sstevel@tonic-gate prefix = "+"; 372*7c478bd9Sstevel@tonic-gate } else if (fblank) { 373*7c478bd9Sstevel@tonic-gate prefix = " "; 374*7c478bd9Sstevel@tonic-gate } 375*7c478bd9Sstevel@tonic-gate } 376*7c478bd9Sstevel@tonic-gate #if FZERO 377*7c478bd9Sstevel@tonic-gate if (fzero) { 378*7c478bd9Sstevel@tonic-gate int n = width - strlen(prefix); 379*7c478bd9Sstevel@tonic-gate if (n > prec) { 380*7c478bd9Sstevel@tonic-gate prec = n; 381*7c478bd9Sstevel@tonic-gate } 382*7c478bd9Sstevel@tonic-gate } 383*7c478bd9Sstevel@tonic-gate #endif 384*7c478bd9Sstevel@tonic-gate /* Set translate table for digits */ 385*7c478bd9Sstevel@tonic-gate if (fcode == 'X') { 386*7c478bd9Sstevel@tonic-gate tab = "0123456789ABCDEF"; 387*7c478bd9Sstevel@tonic-gate } else { 388*7c478bd9Sstevel@tonic-gate tab = "0123456789abcdef"; 389*7c478bd9Sstevel@tonic-gate } 390*7c478bd9Sstevel@tonic-gate 391*7c478bd9Sstevel@tonic-gate /* Develop the digits of the value */ 392*7c478bd9Sstevel@tonic-gate p = bp = buf + MAXDIGS; 393*7c478bd9Sstevel@tonic-gate while (val) { 394*7c478bd9Sstevel@tonic-gate lowbit = val & 1; 395*7c478bd9Sstevel@tonic-gate val = (val >> 1) & ~HIBITLL; 396*7c478bd9Sstevel@tonic-gate *--bp = tab[val % hradix * 2 + lowbit]; 397*7c478bd9Sstevel@tonic-gate val /= hradix; 398*7c478bd9Sstevel@tonic-gate } 399*7c478bd9Sstevel@tonic-gate 400*7c478bd9Sstevel@tonic-gate /* Calculate padding zero requirement */ 401*7c478bd9Sstevel@tonic-gate lzero = bp - p + prec; 402*7c478bd9Sstevel@tonic-gate 403*7c478bd9Sstevel@tonic-gate /* Handle the # flag */ 404*7c478bd9Sstevel@tonic-gate if (fsharp && bp != p) { 405*7c478bd9Sstevel@tonic-gate switch (fcode) { 406*7c478bd9Sstevel@tonic-gate case 'o': 407*7c478bd9Sstevel@tonic-gate if (lzero < 1) 408*7c478bd9Sstevel@tonic-gate lzero = 1; 409*7c478bd9Sstevel@tonic-gate break; 410*7c478bd9Sstevel@tonic-gate case 'x': 411*7c478bd9Sstevel@tonic-gate prefix = "0x"; 412*7c478bd9Sstevel@tonic-gate break; 413*7c478bd9Sstevel@tonic-gate case 'X': 414*7c478bd9Sstevel@tonic-gate prefix = "0X"; 415*7c478bd9Sstevel@tonic-gate break; 416*7c478bd9Sstevel@tonic-gate } 417*7c478bd9Sstevel@tonic-gate } 418*7c478bd9Sstevel@tonic-gate 419*7c478bd9Sstevel@tonic-gate break; 420*7c478bd9Sstevel@tonic-gate #if FLOAT 421*7c478bd9Sstevel@tonic-gate case 'E': 422*7c478bd9Sstevel@tonic-gate case 'e': 423*7c478bd9Sstevel@tonic-gate /* 424*7c478bd9Sstevel@tonic-gate * E-format. The general strategy 425*7c478bd9Sstevel@tonic-gate * here is fairly easy: we take 426*7c478bd9Sstevel@tonic-gate * what ecvt gives us and re-format it. 427*7c478bd9Sstevel@tonic-gate */ 428*7c478bd9Sstevel@tonic-gate 429*7c478bd9Sstevel@tonic-gate /* Establish default precision */ 430*7c478bd9Sstevel@tonic-gate if (prec < 0) { 431*7c478bd9Sstevel@tonic-gate prec = 6; 432*7c478bd9Sstevel@tonic-gate } 433*7c478bd9Sstevel@tonic-gate 434*7c478bd9Sstevel@tonic-gate /* Fetch the value */ 435*7c478bd9Sstevel@tonic-gate dval = va_arg(*args, double); 436*7c478bd9Sstevel@tonic-gate 437*7c478bd9Sstevel@tonic-gate /* Develop the mantissa */ 438*7c478bd9Sstevel@tonic-gate bp = ecvt(dval, 439*7c478bd9Sstevel@tonic-gate min(prec + 1, MAXECVT), 440*7c478bd9Sstevel@tonic-gate &decpt, 441*7c478bd9Sstevel@tonic-gate &sign); 442*7c478bd9Sstevel@tonic-gate 443*7c478bd9Sstevel@tonic-gate /* Determine the prefix */ 444*7c478bd9Sstevel@tonic-gate e_merge: 445*7c478bd9Sstevel@tonic-gate if (sign) { 446*7c478bd9Sstevel@tonic-gate prefix = "-"; 447*7c478bd9Sstevel@tonic-gate } else if (fplus) { 448*7c478bd9Sstevel@tonic-gate prefix = "+"; 449*7c478bd9Sstevel@tonic-gate } else if (fblank) { 450*7c478bd9Sstevel@tonic-gate prefix = " "; 451*7c478bd9Sstevel@tonic-gate } 452*7c478bd9Sstevel@tonic-gate 453*7c478bd9Sstevel@tonic-gate /* Place the first digit in the buffer */ 454*7c478bd9Sstevel@tonic-gate p = &buf[0]; 455*7c478bd9Sstevel@tonic-gate *p++ = *bp != '\0' ? *bp++ : '0'; 456*7c478bd9Sstevel@tonic-gate 457*7c478bd9Sstevel@tonic-gate /* Put in a decimal point if needed */ 458*7c478bd9Sstevel@tonic-gate if (prec != 0 || fsharp) { 459*7c478bd9Sstevel@tonic-gate *p++ = '.'; 460*7c478bd9Sstevel@tonic-gate } 461*7c478bd9Sstevel@tonic-gate 462*7c478bd9Sstevel@tonic-gate /* Create the rest of the mantissa */ 463*7c478bd9Sstevel@tonic-gate rzero = prec; 464*7c478bd9Sstevel@tonic-gate while (rzero > 0 && *bp != '\0') { 465*7c478bd9Sstevel@tonic-gate --rzero; 466*7c478bd9Sstevel@tonic-gate *p++ = *bp++; 467*7c478bd9Sstevel@tonic-gate } 468*7c478bd9Sstevel@tonic-gate 469*7c478bd9Sstevel@tonic-gate bp = &buf[0]; 470*7c478bd9Sstevel@tonic-gate 471*7c478bd9Sstevel@tonic-gate /* Create the exponent */ 472*7c478bd9Sstevel@tonic-gate suffix = &expbuf[MAXESIZ]; 473*7c478bd9Sstevel@tonic-gate *suffix = '\0'; 474*7c478bd9Sstevel@tonic-gate if (dval != 0) { 475*7c478bd9Sstevel@tonic-gate n = decpt - 1; 476*7c478bd9Sstevel@tonic-gate if (n < 0) { 477*7c478bd9Sstevel@tonic-gate n = -n; 478*7c478bd9Sstevel@tonic-gate } 479*7c478bd9Sstevel@tonic-gate while (n != 0) { 480*7c478bd9Sstevel@tonic-gate *--suffix = todigit(n % 10); 481*7c478bd9Sstevel@tonic-gate n /= 10; 482*7c478bd9Sstevel@tonic-gate } 483*7c478bd9Sstevel@tonic-gate } 484*7c478bd9Sstevel@tonic-gate 485*7c478bd9Sstevel@tonic-gate /* Prepend leading zeroes to the exponent */ 486*7c478bd9Sstevel@tonic-gate while (suffix > &expbuf[MAXESIZ - 2]) { 487*7c478bd9Sstevel@tonic-gate *--suffix = '0'; 488*7c478bd9Sstevel@tonic-gate } 489*7c478bd9Sstevel@tonic-gate 490*7c478bd9Sstevel@tonic-gate /* Put in the exponent sign */ 491*7c478bd9Sstevel@tonic-gate *--suffix = (decpt > 0 || dval == 0) ? 492*7c478bd9Sstevel@tonic-gate '+' : '-'; 493*7c478bd9Sstevel@tonic-gate 494*7c478bd9Sstevel@tonic-gate /* Put in the e */ 495*7c478bd9Sstevel@tonic-gate *--suffix = isupper(fcode) ? 'E' : 'e'; 496*7c478bd9Sstevel@tonic-gate 497*7c478bd9Sstevel@tonic-gate break; 498*7c478bd9Sstevel@tonic-gate 499*7c478bd9Sstevel@tonic-gate case 'f': 500*7c478bd9Sstevel@tonic-gate /* 501*7c478bd9Sstevel@tonic-gate * F-format floating point. This is 502*7c478bd9Sstevel@tonic-gate * a good deal less simple than E-format. 503*7c478bd9Sstevel@tonic-gate * The overall strategy will be to call 504*7c478bd9Sstevel@tonic-gate * fcvt, reformat its result into buf, 505*7c478bd9Sstevel@tonic-gate * and calculate how many trailing 506*7c478bd9Sstevel@tonic-gate * zeroes will be required. There will 507*7c478bd9Sstevel@tonic-gate * never be any leading zeroes needed. 508*7c478bd9Sstevel@tonic-gate */ 509*7c478bd9Sstevel@tonic-gate 510*7c478bd9Sstevel@tonic-gate /* Establish default precision */ 511*7c478bd9Sstevel@tonic-gate if (prec < 0) { 512*7c478bd9Sstevel@tonic-gate prec = 6; 513*7c478bd9Sstevel@tonic-gate } 514*7c478bd9Sstevel@tonic-gate 515*7c478bd9Sstevel@tonic-gate /* Fetch the value */ 516*7c478bd9Sstevel@tonic-gate dval = va_arg(*args, double); 517*7c478bd9Sstevel@tonic-gate 518*7c478bd9Sstevel@tonic-gate /* Do the conversion */ 519*7c478bd9Sstevel@tonic-gate bp = fcvt(dval, 520*7c478bd9Sstevel@tonic-gate min(prec, MAXFCVT), 521*7c478bd9Sstevel@tonic-gate &decpt, 522*7c478bd9Sstevel@tonic-gate &sign); 523*7c478bd9Sstevel@tonic-gate 524*7c478bd9Sstevel@tonic-gate /* Determine the prefix */ 525*7c478bd9Sstevel@tonic-gate f_merge: 526*7c478bd9Sstevel@tonic-gate if (sign && decpt > -prec && 527*7c478bd9Sstevel@tonic-gate *bp != '\0' && *bp != '0') { 528*7c478bd9Sstevel@tonic-gate prefix = "-"; 529*7c478bd9Sstevel@tonic-gate } else if (fplus) { 530*7c478bd9Sstevel@tonic-gate prefix = "+"; 531*7c478bd9Sstevel@tonic-gate } else if (fblank) { 532*7c478bd9Sstevel@tonic-gate prefix = " "; 533*7c478bd9Sstevel@tonic-gate } 534*7c478bd9Sstevel@tonic-gate 535*7c478bd9Sstevel@tonic-gate /* Initialize buffer pointer */ 536*7c478bd9Sstevel@tonic-gate p = &buf[0]; 537*7c478bd9Sstevel@tonic-gate 538*7c478bd9Sstevel@tonic-gate /* Emit the digits before the decimal point */ 539*7c478bd9Sstevel@tonic-gate n = decpt; 540*7c478bd9Sstevel@tonic-gate k = 0; 541*7c478bd9Sstevel@tonic-gate if (n <= 0) { 542*7c478bd9Sstevel@tonic-gate *p++ = '0'; 543*7c478bd9Sstevel@tonic-gate } else { 544*7c478bd9Sstevel@tonic-gate do { 545*7c478bd9Sstevel@tonic-gate if (*bp == '\0' || 546*7c478bd9Sstevel@tonic-gate k >= MAXFSIG) { 547*7c478bd9Sstevel@tonic-gate *p++ = '0'; 548*7c478bd9Sstevel@tonic-gate } else { 549*7c478bd9Sstevel@tonic-gate *p++ = *bp++; 550*7c478bd9Sstevel@tonic-gate ++k; 551*7c478bd9Sstevel@tonic-gate } 552*7c478bd9Sstevel@tonic-gate } while (--n != 0); 553*7c478bd9Sstevel@tonic-gate } 554*7c478bd9Sstevel@tonic-gate 555*7c478bd9Sstevel@tonic-gate /* Decide whether we need a decimal point */ 556*7c478bd9Sstevel@tonic-gate if (fsharp || prec > 0) { 557*7c478bd9Sstevel@tonic-gate *p++ = '.'; 558*7c478bd9Sstevel@tonic-gate } 559*7c478bd9Sstevel@tonic-gate 560*7c478bd9Sstevel@tonic-gate /* Digits (if any) after the decimal point */ 561*7c478bd9Sstevel@tonic-gate n = min(prec, MAXFCVT); 562*7c478bd9Sstevel@tonic-gate rzero = prec - n; 563*7c478bd9Sstevel@tonic-gate while (--n >= 0) { 564*7c478bd9Sstevel@tonic-gate if (++decpt <= 0 || *bp == '\0' || 565*7c478bd9Sstevel@tonic-gate k >= MAXFSIG) { 566*7c478bd9Sstevel@tonic-gate *p++ = '0'; 567*7c478bd9Sstevel@tonic-gate } else { 568*7c478bd9Sstevel@tonic-gate *p++ = *bp++; 569*7c478bd9Sstevel@tonic-gate ++k; 570*7c478bd9Sstevel@tonic-gate } 571*7c478bd9Sstevel@tonic-gate } 572*7c478bd9Sstevel@tonic-gate 573*7c478bd9Sstevel@tonic-gate bp = &buf[0]; 574*7c478bd9Sstevel@tonic-gate 575*7c478bd9Sstevel@tonic-gate break; 576*7c478bd9Sstevel@tonic-gate 577*7c478bd9Sstevel@tonic-gate case 'G': 578*7c478bd9Sstevel@tonic-gate case 'g': 579*7c478bd9Sstevel@tonic-gate /* 580*7c478bd9Sstevel@tonic-gate * g-format. We play around a bit 581*7c478bd9Sstevel@tonic-gate * and then jump into e or f, as needed. 582*7c478bd9Sstevel@tonic-gate */ 583*7c478bd9Sstevel@tonic-gate 584*7c478bd9Sstevel@tonic-gate /* Establish default precision */ 585*7c478bd9Sstevel@tonic-gate if (prec < 0) { 586*7c478bd9Sstevel@tonic-gate prec = 6; 587*7c478bd9Sstevel@tonic-gate } 588*7c478bd9Sstevel@tonic-gate 589*7c478bd9Sstevel@tonic-gate /* Fetch the value */ 590*7c478bd9Sstevel@tonic-gate dval = va_arg(*args, double); 591*7c478bd9Sstevel@tonic-gate 592*7c478bd9Sstevel@tonic-gate /* Do the conversion */ 593*7c478bd9Sstevel@tonic-gate bp = ecvt(dval, 594*7c478bd9Sstevel@tonic-gate min(prec, MAXECVT), 595*7c478bd9Sstevel@tonic-gate &decpt, 596*7c478bd9Sstevel@tonic-gate &sign); 597*7c478bd9Sstevel@tonic-gate if (dval == 0) { 598*7c478bd9Sstevel@tonic-gate decpt = 1; 599*7c478bd9Sstevel@tonic-gate } 600*7c478bd9Sstevel@tonic-gate 601*7c478bd9Sstevel@tonic-gate k = prec; 602*7c478bd9Sstevel@tonic-gate if (!fsharp) { 603*7c478bd9Sstevel@tonic-gate n = strlen(bp); 604*7c478bd9Sstevel@tonic-gate if (n < k) { 605*7c478bd9Sstevel@tonic-gate k = n; 606*7c478bd9Sstevel@tonic-gate } 607*7c478bd9Sstevel@tonic-gate while (k >= 1 && bp[k-1] == '0') { 608*7c478bd9Sstevel@tonic-gate --k; 609*7c478bd9Sstevel@tonic-gate } 610*7c478bd9Sstevel@tonic-gate } 611*7c478bd9Sstevel@tonic-gate 612*7c478bd9Sstevel@tonic-gate if (decpt < -3 || decpt > prec) { 613*7c478bd9Sstevel@tonic-gate prec = k - 1; 614*7c478bd9Sstevel@tonic-gate goto e_merge; 615*7c478bd9Sstevel@tonic-gate } else { 616*7c478bd9Sstevel@tonic-gate prec = k - decpt; 617*7c478bd9Sstevel@tonic-gate goto f_merge; 618*7c478bd9Sstevel@tonic-gate } 619*7c478bd9Sstevel@tonic-gate 620*7c478bd9Sstevel@tonic-gate #endif 621*7c478bd9Sstevel@tonic-gate case 'c': 622*7c478bd9Sstevel@tonic-gate #ifdef MBCHAR_1 /* sizeof(int)>=sizeof(tchar) */ 623*7c478bd9Sstevel@tonic-gate /* 624*7c478bd9Sstevel@tonic-gate * A tchar arg is passed as int so we used the normal %c to specify 625*7c478bd9Sstevel@tonic-gate * such an arugument. 626*7c478bd9Sstevel@tonic-gate */ 627*7c478bd9Sstevel@tonic-gate tcbuf[0] = va_arg(*args, int); 628*7c478bd9Sstevel@tonic-gate tbp = &tcbuf[0]; 629*7c478bd9Sstevel@tonic-gate tep = tbp + 1; 630*7c478bd9Sstevel@tonic-gate fcode = 't'; /* Fake the rest of code. */ 631*7c478bd9Sstevel@tonic-gate break; 632*7c478bd9Sstevel@tonic-gate #else 633*7c478bd9Sstevel@tonic-gate /* 634*7c478bd9Sstevel@tonic-gate * We would have to invent another new format speficier such as "%T" to 635*7c478bd9Sstevel@tonic-gate * take a tchar arg. Let's worry about when that time comes. 636*7c478bd9Sstevel@tonic-gate */ 637*7c478bd9Sstevel@tonic-gate /* 638*7c478bd9Sstevel@tonic-gate * Following code take care of a char arg 639*7c478bd9Sstevel@tonic-gate * only. 640*7c478bd9Sstevel@tonic-gate */ 641*7c478bd9Sstevel@tonic-gate buf[0] = va_arg(*args, int); 642*7c478bd9Sstevel@tonic-gate bp = &buf[0]; 643*7c478bd9Sstevel@tonic-gate p = bp + 1; 644*7c478bd9Sstevel@tonic-gate break; 645*7c478bd9Sstevel@tonic-gate case 'T': /* Corresponding arg is tchar. */ 646*7c478bd9Sstevel@tonic-gate tcbuf[0] = va_arg(*args, tchar); 647*7c478bd9Sstevel@tonic-gate tbp = &tcbuf[0]; 648*7c478bd9Sstevel@tonic-gate tep = tbp + 1; 649*7c478bd9Sstevel@tonic-gate fcode = 't'; /* Fake the rest of code. */ 650*7c478bd9Sstevel@tonic-gate break; 651*7c478bd9Sstevel@tonic-gate #endif 652*7c478bd9Sstevel@tonic-gate case 's': 653*7c478bd9Sstevel@tonic-gate bp = va_arg(*args, char *); 654*7c478bd9Sstevel@tonic-gate if (bp == 0) { 655*7c478bd9Sstevel@tonic-gate nullstr: bp = "(null)"; 656*7c478bd9Sstevel@tonic-gate p = bp + strlen("(null)"); 657*7c478bd9Sstevel@tonic-gate break; 658*7c478bd9Sstevel@tonic-gate } 659*7c478bd9Sstevel@tonic-gate if (prec < 0) { 660*7c478bd9Sstevel@tonic-gate prec = MAXINT; 661*7c478bd9Sstevel@tonic-gate } 662*7c478bd9Sstevel@tonic-gate for (n = 0; *bp++ != '\0' && n < prec; n++) 663*7c478bd9Sstevel@tonic-gate ; 664*7c478bd9Sstevel@tonic-gate p = --bp; 665*7c478bd9Sstevel@tonic-gate bp -= n; 666*7c478bd9Sstevel@tonic-gate break; 667*7c478bd9Sstevel@tonic-gate 668*7c478bd9Sstevel@tonic-gate case 't': 669*7c478bd9Sstevel@tonic-gate /* 670*7c478bd9Sstevel@tonic-gate * Special format specifier "%t" tells 671*7c478bd9Sstevel@tonic-gate * printf() to print char strings written 672*7c478bd9Sstevel@tonic-gate * as tchar string. 673*7c478bd9Sstevel@tonic-gate */ 674*7c478bd9Sstevel@tonic-gate tbp = va_arg(*args, tchar *); 675*7c478bd9Sstevel@tonic-gate if (tbp == 0) { 676*7c478bd9Sstevel@tonic-gate fcode = 's'; /* Act as if it were %s. */ 677*7c478bd9Sstevel@tonic-gate goto nullstr; 678*7c478bd9Sstevel@tonic-gate } 679*7c478bd9Sstevel@tonic-gate if (prec < 0) { 680*7c478bd9Sstevel@tonic-gate prec = MAXINT; 681*7c478bd9Sstevel@tonic-gate } 682*7c478bd9Sstevel@tonic-gate for (n = 0; *tbp++ != 0 && n < prec; n++) 683*7c478bd9Sstevel@tonic-gate ; 684*7c478bd9Sstevel@tonic-gate tep = --tbp; 685*7c478bd9Sstevel@tonic-gate tbp -= n; 686*7c478bd9Sstevel@tonic-gate 687*7c478bd9Sstevel@tonic-gate /* 688*7c478bd9Sstevel@tonic-gate * Just to make the following padding 689*7c478bd9Sstevel@tonic-gate * calculation not to go very crazy... 690*7c478bd9Sstevel@tonic-gate */ 691*7c478bd9Sstevel@tonic-gate bp = NULL; 692*7c478bd9Sstevel@tonic-gate p = bp + n; 693*7c478bd9Sstevel@tonic-gate break; 694*7c478bd9Sstevel@tonic-gate 695*7c478bd9Sstevel@tonic-gate case '\0': 696*7c478bd9Sstevel@tonic-gate cp--; 697*7c478bd9Sstevel@tonic-gate break; 698*7c478bd9Sstevel@tonic-gate 699*7c478bd9Sstevel@tonic-gate default: 700*7c478bd9Sstevel@tonic-gate p = bp = &fcode; 701*7c478bd9Sstevel@tonic-gate p++; 702*7c478bd9Sstevel@tonic-gate break; 703*7c478bd9Sstevel@tonic-gate 704*7c478bd9Sstevel@tonic-gate } 705*7c478bd9Sstevel@tonic-gate if (fcode != '\0') { 706*7c478bd9Sstevel@tonic-gate /* Calculate number of padding blanks */ 707*7c478bd9Sstevel@tonic-gate int nblank; 708*7c478bd9Sstevel@tonic-gate nblank = width 709*7c478bd9Sstevel@tonic-gate #if FLOAT 710*7c478bd9Sstevel@tonic-gate - (rzero < 0 ? 0: rzero) 711*7c478bd9Sstevel@tonic-gate - strlen(suffix) 712*7c478bd9Sstevel@tonic-gate #endif 713*7c478bd9Sstevel@tonic-gate - (p - bp) 714*7c478bd9Sstevel@tonic-gate - (lzero < 0 ? 0 : lzero) 715*7c478bd9Sstevel@tonic-gate - strlen(prefix); 716*7c478bd9Sstevel@tonic-gate 717*7c478bd9Sstevel@tonic-gate /* Blanks on left if required */ 718*7c478bd9Sstevel@tonic-gate if (!fminus) { 719*7c478bd9Sstevel@tonic-gate while (--nblank >= 0) { 720*7c478bd9Sstevel@tonic-gate Putchar(' '); 721*7c478bd9Sstevel@tonic-gate } 722*7c478bd9Sstevel@tonic-gate } 723*7c478bd9Sstevel@tonic-gate 724*7c478bd9Sstevel@tonic-gate /* Prefix, if any */ 725*7c478bd9Sstevel@tonic-gate while (*prefix != '\0') { 726*7c478bd9Sstevel@tonic-gate Putchar(*prefix++); 727*7c478bd9Sstevel@tonic-gate } 728*7c478bd9Sstevel@tonic-gate 729*7c478bd9Sstevel@tonic-gate /* Zeroes on the left */ 730*7c478bd9Sstevel@tonic-gate while (--lzero >= 0) { 731*7c478bd9Sstevel@tonic-gate Putchar('0'); 732*7c478bd9Sstevel@tonic-gate } 733*7c478bd9Sstevel@tonic-gate 734*7c478bd9Sstevel@tonic-gate /* The value itself */ 735*7c478bd9Sstevel@tonic-gate if (fcode == 't') { /* %t is special. */ 736*7c478bd9Sstevel@tonic-gate while (tbp < tep) { 737*7c478bd9Sstevel@tonic-gate Putchar(*tbp++); 738*7c478bd9Sstevel@tonic-gate } 739*7c478bd9Sstevel@tonic-gate } else { /* For rest of the cases. */ 740*7c478bd9Sstevel@tonic-gate while (bp < p) { 741*7c478bd9Sstevel@tonic-gate putbyte(*bp++); 742*7c478bd9Sstevel@tonic-gate } 743*7c478bd9Sstevel@tonic-gate } 744*7c478bd9Sstevel@tonic-gate #if FLOAT 745*7c478bd9Sstevel@tonic-gate /* Zeroes on the right */ 746*7c478bd9Sstevel@tonic-gate while (--rzero >= 0) 747*7c478bd9Sstevel@tonic-gate Putchar('0'); 748*7c478bd9Sstevel@tonic-gate 749*7c478bd9Sstevel@tonic-gate /* The suffix */ 750*7c478bd9Sstevel@tonic-gate while (*suffix != '\0') { 751*7c478bd9Sstevel@tonic-gate Putchar(*suffix++); 752*7c478bd9Sstevel@tonic-gate } 753*7c478bd9Sstevel@tonic-gate #endif 754*7c478bd9Sstevel@tonic-gate /* Blanks on the right if required */ 755*7c478bd9Sstevel@tonic-gate if (fminus) { 756*7c478bd9Sstevel@tonic-gate while (--nblank >= 0) { 757*7c478bd9Sstevel@tonic-gate Putchar(' '); 758*7c478bd9Sstevel@tonic-gate } 759*7c478bd9Sstevel@tonic-gate } 760*7c478bd9Sstevel@tonic-gate } 761*7c478bd9Sstevel@tonic-gate } 762*7c478bd9Sstevel@tonic-gate } 763