17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate * CDDL HEADER START
37c478bd9Sstevel@tonic-gate *
47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
57c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only
67c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance
77c478bd9Sstevel@tonic-gate * with the License.
87c478bd9Sstevel@tonic-gate *
97c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
107c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
117c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
127c478bd9Sstevel@tonic-gate * and limitations under the License.
137c478bd9Sstevel@tonic-gate *
147c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
157c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
167c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
177c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
187c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
197c478bd9Sstevel@tonic-gate *
207c478bd9Sstevel@tonic-gate * CDDL HEADER END
217c478bd9Sstevel@tonic-gate */
22f6db9f27Scf /*
23f6db9f27Scf * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
24f6db9f27Scf * Use is subject to license terms.
25f6db9f27Scf */
26f6db9f27Scf
277c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
287c478bd9Sstevel@tonic-gate /* All Rights Reserved */
297c478bd9Sstevel@tonic-gate
307c478bd9Sstevel@tonic-gate /*
317c478bd9Sstevel@tonic-gate * University Copyright- Copyright (c) 1982, 1986, 1988
327c478bd9Sstevel@tonic-gate * The Regents of the University of California
337c478bd9Sstevel@tonic-gate * All Rights Reserved
347c478bd9Sstevel@tonic-gate *
357c478bd9Sstevel@tonic-gate * University Acknowledgment- Portions of this document are derived from
367c478bd9Sstevel@tonic-gate * software developed by the University of California, Berkeley, and its
377c478bd9Sstevel@tonic-gate * contributors.
387c478bd9Sstevel@tonic-gate */
397c478bd9Sstevel@tonic-gate
407c478bd9Sstevel@tonic-gate #include <stdarg.h>
417c478bd9Sstevel@tonic-gate #include <stdlib.h>
427c478bd9Sstevel@tonic-gate #include <limits.h>
437c478bd9Sstevel@tonic-gate extern short putoctal;
447c478bd9Sstevel@tonic-gate /*
457c478bd9Sstevel@tonic-gate * This version of printf is compatible with the Version 7 C
46f6db9f27Scf * printf. The differences are only minor except that
47f6db9f27Scf * viprintf assumes it is to print through putchar. Version 7
487c478bd9Sstevel@tonic-gate * printf is more general (and is much larger) and includes
497c478bd9Sstevel@tonic-gate * provisions for floating point.
507c478bd9Sstevel@tonic-gate */
51*55fea89dSDan Cross
527c478bd9Sstevel@tonic-gate
537c478bd9Sstevel@tonic-gate #define MAXOCT 11 /* Maximum octal digits in a long */
547c478bd9Sstevel@tonic-gate #define MAXINT 32767 /* largest normal length positive integer */
557c478bd9Sstevel@tonic-gate #define BIG 1000000000 /* largest power of 10 less than an unsigned long */
567c478bd9Sstevel@tonic-gate #define MAXDIGS 10 /* number of digits in BIG */
577c478bd9Sstevel@tonic-gate
587c478bd9Sstevel@tonic-gate static int width, sign, fill;
597c478bd9Sstevel@tonic-gate
607c478bd9Sstevel@tonic-gate unsigned char *_p_dconv();
61f6db9f27Scf void _p_emit(unsigned char *, unsigned char *);
627c478bd9Sstevel@tonic-gate
63f6db9f27Scf /*VARARGS*/
64f6db9f27Scf void
viprintf(unsigned char * fmt,...)65f6db9f27Scf viprintf(unsigned char *fmt, ...)
667c478bd9Sstevel@tonic-gate {
677c478bd9Sstevel@tonic-gate va_list ap;
687c478bd9Sstevel@tonic-gate unsigned char fcode;
697c478bd9Sstevel@tonic-gate wchar_t wfcode;
707c478bd9Sstevel@tonic-gate int prec;
717c478bd9Sstevel@tonic-gate int length,mask1,nbits,n;
727c478bd9Sstevel@tonic-gate int length2;
737c478bd9Sstevel@tonic-gate long int mask2, num;
74f6db9f27Scf unsigned char *bptr;
757c478bd9Sstevel@tonic-gate unsigned char *ptr;
767c478bd9Sstevel@tonic-gate unsigned char buf[134];
777c478bd9Sstevel@tonic-gate
787c478bd9Sstevel@tonic-gate va_start(ap, fmt);
797c478bd9Sstevel@tonic-gate for (;;) {
807c478bd9Sstevel@tonic-gate /* process format string first */
817c478bd9Sstevel@tonic-gate for (;;) {
827c478bd9Sstevel@tonic-gate length2 = mbtowc(&wfcode, (char *)fmt, MB_LEN_MAX);
837c478bd9Sstevel@tonic-gate if(length2 <= 0) {
847c478bd9Sstevel@tonic-gate if (*fmt == '\0') {
857c478bd9Sstevel@tonic-gate fmt++;
867c478bd9Sstevel@tonic-gate return;
877c478bd9Sstevel@tonic-gate }
887c478bd9Sstevel@tonic-gate putchar(*fmt++);
897c478bd9Sstevel@tonic-gate } else {
907c478bd9Sstevel@tonic-gate if (wfcode == '%') {
917c478bd9Sstevel@tonic-gate fmt++;
927c478bd9Sstevel@tonic-gate break;
937c478bd9Sstevel@tonic-gate }
947c478bd9Sstevel@tonic-gate /* ordinary (non-%) character */
957c478bd9Sstevel@tonic-gate putchar(wfcode);
967c478bd9Sstevel@tonic-gate fmt += length2;
977c478bd9Sstevel@tonic-gate }
987c478bd9Sstevel@tonic-gate }
997c478bd9Sstevel@tonic-gate /* length modifier: -1 for h, 1 for l, 0 for none */
1007c478bd9Sstevel@tonic-gate length = 0;
1017c478bd9Sstevel@tonic-gate /* check for a leading - sign */
1027c478bd9Sstevel@tonic-gate sign = 0;
1037c478bd9Sstevel@tonic-gate if (*fmt == '-') {
1047c478bd9Sstevel@tonic-gate sign++;
1057c478bd9Sstevel@tonic-gate fmt++;
1067c478bd9Sstevel@tonic-gate }
1077c478bd9Sstevel@tonic-gate /* a '0' may follow the - sign */
1087c478bd9Sstevel@tonic-gate /* this is the requested fill character */
1097c478bd9Sstevel@tonic-gate fill = 1;
1107c478bd9Sstevel@tonic-gate if (*fmt == '0') {
1117c478bd9Sstevel@tonic-gate fill--;
1127c478bd9Sstevel@tonic-gate fmt++;
1137c478bd9Sstevel@tonic-gate }
114*55fea89dSDan Cross
1157c478bd9Sstevel@tonic-gate /* Now comes a digit string which may be a '*' */
1167c478bd9Sstevel@tonic-gate if (*fmt == '*') {
1177c478bd9Sstevel@tonic-gate width = va_arg(ap, int);
1187c478bd9Sstevel@tonic-gate if (width < 0) {
1197c478bd9Sstevel@tonic-gate width = -width;
1207c478bd9Sstevel@tonic-gate sign = !sign;
1217c478bd9Sstevel@tonic-gate }
1227c478bd9Sstevel@tonic-gate fmt++;
1237c478bd9Sstevel@tonic-gate }
1247c478bd9Sstevel@tonic-gate else {
1257c478bd9Sstevel@tonic-gate width = 0;
1267c478bd9Sstevel@tonic-gate while (*fmt>='0' && *fmt<='9')
1277c478bd9Sstevel@tonic-gate width = width * 10 + (*fmt++ - '0');
1287c478bd9Sstevel@tonic-gate }
129*55fea89dSDan Cross
1307c478bd9Sstevel@tonic-gate /* maybe a decimal point followed by more digits (or '*') */
1317c478bd9Sstevel@tonic-gate if (*fmt=='.') {
1327c478bd9Sstevel@tonic-gate if (*++fmt == '*') {
1337c478bd9Sstevel@tonic-gate prec = va_arg(ap, int);
1347c478bd9Sstevel@tonic-gate fmt++;
1357c478bd9Sstevel@tonic-gate }
1367c478bd9Sstevel@tonic-gate else {
1377c478bd9Sstevel@tonic-gate prec = 0;
1387c478bd9Sstevel@tonic-gate while (*fmt>='0' && *fmt<='9')
1397c478bd9Sstevel@tonic-gate prec = prec * 10 + (*fmt++ - '0');
1407c478bd9Sstevel@tonic-gate }
1417c478bd9Sstevel@tonic-gate }
1427c478bd9Sstevel@tonic-gate else
1437c478bd9Sstevel@tonic-gate prec = -1;
144*55fea89dSDan Cross
1457c478bd9Sstevel@tonic-gate /*
1467c478bd9Sstevel@tonic-gate * At this point, "sign" is nonzero if there was
1477c478bd9Sstevel@tonic-gate * a sign, "fill" is 0 if there was a leading
1487c478bd9Sstevel@tonic-gate * zero and 1 otherwise, "width" and "prec"
1497c478bd9Sstevel@tonic-gate * contain numbers corresponding to the digit
1507c478bd9Sstevel@tonic-gate * strings before and after the decimal point,
1517c478bd9Sstevel@tonic-gate * respectively, and "fmt" addresses the next
1527c478bd9Sstevel@tonic-gate * character after the whole mess. If there was
1537c478bd9Sstevel@tonic-gate * no decimal point, "prec" will be -1.
1547c478bd9Sstevel@tonic-gate */
1557c478bd9Sstevel@tonic-gate switch (*fmt) {
1567c478bd9Sstevel@tonic-gate case 'L':
1577c478bd9Sstevel@tonic-gate case 'l':
1587c478bd9Sstevel@tonic-gate length = 2;
1599097ca5cSToomas Soome /* FALLTHROUGH */
1607c478bd9Sstevel@tonic-gate case 'h':
1617c478bd9Sstevel@tonic-gate case 'H':
1627c478bd9Sstevel@tonic-gate length--;
1637c478bd9Sstevel@tonic-gate fmt++;
1647c478bd9Sstevel@tonic-gate break;
1657c478bd9Sstevel@tonic-gate }
166*55fea89dSDan Cross
1677c478bd9Sstevel@tonic-gate /*
1687c478bd9Sstevel@tonic-gate * At exit from the following switch, we will
1697c478bd9Sstevel@tonic-gate * emit the characters starting at "bptr" and
1707c478bd9Sstevel@tonic-gate * ending at "ptr"-1, unless fcode is '\0'.
1717c478bd9Sstevel@tonic-gate */
1727c478bd9Sstevel@tonic-gate switch (fcode = *fmt++) {
1737c478bd9Sstevel@tonic-gate /* process characters and strings first */
1747c478bd9Sstevel@tonic-gate case 'c':
1757c478bd9Sstevel@tonic-gate buf[0] = va_arg(ap, int);
1767c478bd9Sstevel@tonic-gate ptr = bptr = &buf[0];
1777c478bd9Sstevel@tonic-gate if (buf[0] != '\0')
1787c478bd9Sstevel@tonic-gate ptr++;
1797c478bd9Sstevel@tonic-gate break;
1807c478bd9Sstevel@tonic-gate case 's':
1817c478bd9Sstevel@tonic-gate bptr = va_arg(ap,unsigned char *);
1827c478bd9Sstevel@tonic-gate if (bptr==0)
1837c478bd9Sstevel@tonic-gate bptr = (unsigned char *)"(null pointer)";
1847c478bd9Sstevel@tonic-gate if (prec < 0)
1857c478bd9Sstevel@tonic-gate prec = MAXINT;
1867c478bd9Sstevel@tonic-gate for (n=0; *bptr++ && n < prec; n++) ;
1877c478bd9Sstevel@tonic-gate ptr = --bptr;
1887c478bd9Sstevel@tonic-gate bptr -= n;
1897c478bd9Sstevel@tonic-gate break;
1907c478bd9Sstevel@tonic-gate case 'O':
1917c478bd9Sstevel@tonic-gate length = 1;
1927c478bd9Sstevel@tonic-gate fcode = 'o';
1939097ca5cSToomas Soome /* FALLTHROUGH */
1947c478bd9Sstevel@tonic-gate case 'o':
1957c478bd9Sstevel@tonic-gate case 'X':
1967c478bd9Sstevel@tonic-gate case 'x':
1977c478bd9Sstevel@tonic-gate if (length > 0)
1987c478bd9Sstevel@tonic-gate num = va_arg(ap,long);
1997c478bd9Sstevel@tonic-gate else
2007c478bd9Sstevel@tonic-gate num = (unsigned)va_arg(ap,int);
2017c478bd9Sstevel@tonic-gate if (fcode=='o') {
2027c478bd9Sstevel@tonic-gate mask1 = 0x7;
2037c478bd9Sstevel@tonic-gate mask2 = 0x1fffffffL;
2047c478bd9Sstevel@tonic-gate nbits = 3;
2057c478bd9Sstevel@tonic-gate }
2067c478bd9Sstevel@tonic-gate else {
2077c478bd9Sstevel@tonic-gate mask1 = 0xf;
2087c478bd9Sstevel@tonic-gate mask2 = 0x0fffffffL;
2097c478bd9Sstevel@tonic-gate nbits = 4;
2107c478bd9Sstevel@tonic-gate }
2117c478bd9Sstevel@tonic-gate n = (num!=0);
2127c478bd9Sstevel@tonic-gate bptr = buf + MAXOCT + 3;
2137c478bd9Sstevel@tonic-gate /* shift and mask for speed */
2147c478bd9Sstevel@tonic-gate do
2157c478bd9Sstevel@tonic-gate if (((int) num & mask1) < 10)
2167c478bd9Sstevel@tonic-gate *--bptr = ((int) num & mask1) + 060;
2177c478bd9Sstevel@tonic-gate else
2187c478bd9Sstevel@tonic-gate *--bptr = ((int) num & mask1) + 0127;
2197c478bd9Sstevel@tonic-gate while (num = (num >> nbits) & mask2);
220*55fea89dSDan Cross
2217c478bd9Sstevel@tonic-gate if (fcode=='o') {
2227c478bd9Sstevel@tonic-gate if (n)
2237c478bd9Sstevel@tonic-gate *--bptr = '0';
2247c478bd9Sstevel@tonic-gate }
2257c478bd9Sstevel@tonic-gate else
2267c478bd9Sstevel@tonic-gate if (!sign && fill <= 0) {
2277c478bd9Sstevel@tonic-gate putchar('0');
2287c478bd9Sstevel@tonic-gate putchar(fcode);
2297c478bd9Sstevel@tonic-gate width -= 2;
2307c478bd9Sstevel@tonic-gate }
2317c478bd9Sstevel@tonic-gate else {
2327c478bd9Sstevel@tonic-gate *--bptr = fcode;
2337c478bd9Sstevel@tonic-gate *--bptr = '0';
2347c478bd9Sstevel@tonic-gate }
2357c478bd9Sstevel@tonic-gate ptr = buf + MAXOCT + 3;
2367c478bd9Sstevel@tonic-gate break;
2377c478bd9Sstevel@tonic-gate case 'D':
2387c478bd9Sstevel@tonic-gate case 'U':
2397c478bd9Sstevel@tonic-gate case 'I':
2407c478bd9Sstevel@tonic-gate length = 1;
2417c478bd9Sstevel@tonic-gate fcode = fcode + 'a' - 'A';
2429097ca5cSToomas Soome /* FALLTHROUGH */
2437c478bd9Sstevel@tonic-gate case 'd':
2447c478bd9Sstevel@tonic-gate case 'i':
2457c478bd9Sstevel@tonic-gate case 'u':
2467c478bd9Sstevel@tonic-gate if (length > 0)
2477c478bd9Sstevel@tonic-gate num = va_arg(ap,long);
2487c478bd9Sstevel@tonic-gate else {
2497c478bd9Sstevel@tonic-gate n = va_arg(ap,int);
2507c478bd9Sstevel@tonic-gate if (fcode=='u')
2517c478bd9Sstevel@tonic-gate num = (unsigned) n;
2527c478bd9Sstevel@tonic-gate else
2537c478bd9Sstevel@tonic-gate num = (long) n;
2547c478bd9Sstevel@tonic-gate }
2557c478bd9Sstevel@tonic-gate if (n = (fcode != 'u' && num < 0))
2567c478bd9Sstevel@tonic-gate num = -num;
2577c478bd9Sstevel@tonic-gate /* now convert to digits */
2587c478bd9Sstevel@tonic-gate bptr = _p_dconv(num, buf);
2597c478bd9Sstevel@tonic-gate if (n)
2607c478bd9Sstevel@tonic-gate *--bptr = '-';
2617c478bd9Sstevel@tonic-gate if (fill == 0)
2627c478bd9Sstevel@tonic-gate fill = -1;
2637c478bd9Sstevel@tonic-gate ptr = buf + MAXDIGS + 1;
2647c478bd9Sstevel@tonic-gate break;
2657c478bd9Sstevel@tonic-gate default:
266*55fea89dSDan Cross /* not a control character,
2677c478bd9Sstevel@tonic-gate * print it.
2687c478bd9Sstevel@tonic-gate */
2697c478bd9Sstevel@tonic-gate ptr = bptr = &fcode;
2707c478bd9Sstevel@tonic-gate ptr++;
2717c478bd9Sstevel@tonic-gate break;
2727c478bd9Sstevel@tonic-gate }
2737c478bd9Sstevel@tonic-gate if (fcode != '\0')
2747c478bd9Sstevel@tonic-gate _p_emit(bptr,ptr);
2757c478bd9Sstevel@tonic-gate }
2767c478bd9Sstevel@tonic-gate va_end(ap);
2777c478bd9Sstevel@tonic-gate }
2787c478bd9Sstevel@tonic-gate
2797c478bd9Sstevel@tonic-gate /* _p_dconv converts the unsigned long integer "value" to
2807c478bd9Sstevel@tonic-gate * printable decimal and places it in "buffer", right-justified.
2817c478bd9Sstevel@tonic-gate * The value returned is the address of the first non-zero character,
2827c478bd9Sstevel@tonic-gate * or the address of the last character if all are zero.
2837c478bd9Sstevel@tonic-gate * The result is NOT null terminated, and is MAXDIGS characters long,
2847c478bd9Sstevel@tonic-gate * starting at buffer[1] (to allow for insertion of a sign).
2857c478bd9Sstevel@tonic-gate *
2867c478bd9Sstevel@tonic-gate * This program assumes it is running on 2's complement machine
2877c478bd9Sstevel@tonic-gate * with reasonable overflow treatment.
2887c478bd9Sstevel@tonic-gate */
2897c478bd9Sstevel@tonic-gate unsigned char *
_p_dconv(value,buffer)2907c478bd9Sstevel@tonic-gate _p_dconv(value, buffer)
2917c478bd9Sstevel@tonic-gate long value;
2927c478bd9Sstevel@tonic-gate unsigned char *buffer;
2937c478bd9Sstevel@tonic-gate {
294f6db9f27Scf unsigned char *bp;
295f6db9f27Scf int svalue;
2967c478bd9Sstevel@tonic-gate int n;
2977c478bd9Sstevel@tonic-gate long lval;
298*55fea89dSDan Cross
2997c478bd9Sstevel@tonic-gate bp = buffer;
300*55fea89dSDan Cross
3017c478bd9Sstevel@tonic-gate /* zero is a special case */
3027c478bd9Sstevel@tonic-gate if (value == 0) {
3037c478bd9Sstevel@tonic-gate bp += MAXDIGS;
3047c478bd9Sstevel@tonic-gate *bp = '0';
3057c478bd9Sstevel@tonic-gate return(bp);
3067c478bd9Sstevel@tonic-gate }
307*55fea89dSDan Cross
3087c478bd9Sstevel@tonic-gate /* develop the leading digit of the value in "n" */
3097c478bd9Sstevel@tonic-gate n = 0;
3107c478bd9Sstevel@tonic-gate while (value < 0) {
3117c478bd9Sstevel@tonic-gate value -= BIG; /* will eventually underflow */
3127c478bd9Sstevel@tonic-gate n++;
3137c478bd9Sstevel@tonic-gate }
3147c478bd9Sstevel@tonic-gate while ((lval = value - BIG) >= 0) {
3157c478bd9Sstevel@tonic-gate value = lval;
3167c478bd9Sstevel@tonic-gate n++;
3177c478bd9Sstevel@tonic-gate }
318*55fea89dSDan Cross
3197c478bd9Sstevel@tonic-gate /* stash it in buffer[1] to allow for a sign */
3207c478bd9Sstevel@tonic-gate bp[1] = n + '0';
3217c478bd9Sstevel@tonic-gate /*
3227c478bd9Sstevel@tonic-gate * Now develop the rest of the digits. Since speed counts here,
3237c478bd9Sstevel@tonic-gate * we do it in two loops. The first gets "value" down until it
3247c478bd9Sstevel@tonic-gate * is no larger than MAXINT. The second one uses integer divides
3257c478bd9Sstevel@tonic-gate * rather than long divides to speed it up.
3267c478bd9Sstevel@tonic-gate */
3277c478bd9Sstevel@tonic-gate bp += MAXDIGS + 1;
3287c478bd9Sstevel@tonic-gate while (value > MAXINT) {
3297c478bd9Sstevel@tonic-gate *--bp = (int)(value % 10) + '0';
3307c478bd9Sstevel@tonic-gate value /= 10;
3317c478bd9Sstevel@tonic-gate }
332*55fea89dSDan Cross
3337c478bd9Sstevel@tonic-gate /* cannot lose precision */
3347c478bd9Sstevel@tonic-gate svalue = value;
3357c478bd9Sstevel@tonic-gate while (svalue > 0) {
3367c478bd9Sstevel@tonic-gate *--bp = (svalue % 10) + '0';
3377c478bd9Sstevel@tonic-gate svalue /= 10;
3387c478bd9Sstevel@tonic-gate }
339*55fea89dSDan Cross
3407c478bd9Sstevel@tonic-gate /* fill in intermediate zeroes if needed */
3417c478bd9Sstevel@tonic-gate if (buffer[1] != '0') {
3427c478bd9Sstevel@tonic-gate while (bp > buffer + 2)
3437c478bd9Sstevel@tonic-gate *--bp = '0';
3447c478bd9Sstevel@tonic-gate --bp;
3457c478bd9Sstevel@tonic-gate }
3467c478bd9Sstevel@tonic-gate return(bp);
3477c478bd9Sstevel@tonic-gate }
3487c478bd9Sstevel@tonic-gate
3497c478bd9Sstevel@tonic-gate /*
3507c478bd9Sstevel@tonic-gate * This program sends string "s" to putchar. The character after
3517c478bd9Sstevel@tonic-gate * the end of "s" is given by "send". This allows the size of the
3527c478bd9Sstevel@tonic-gate * field to be computed; it is stored in "alen". "width" contains the
3537c478bd9Sstevel@tonic-gate * user specified length. If width<alen, the width will be taken to
3547c478bd9Sstevel@tonic-gate * be alen. "sign" is zero if the string is to be right-justified
3557c478bd9Sstevel@tonic-gate * in the field, nonzero if it is to be left-justified. "fill" is
3567c478bd9Sstevel@tonic-gate * 0 if the string is to be padded with '0', positive if it is to be
3577c478bd9Sstevel@tonic-gate * padded with ' ', and negative if an initial '-' should appear before
3587c478bd9Sstevel@tonic-gate * any padding in right-justification (to avoid printing "-3" as
3597c478bd9Sstevel@tonic-gate * "000-3" where "-0003" was intended).
3607c478bd9Sstevel@tonic-gate */
361f6db9f27Scf void
_p_emit(unsigned char * s,unsigned char * send)362f6db9f27Scf _p_emit(unsigned char *s, unsigned char *send)
3637c478bd9Sstevel@tonic-gate {
3647c478bd9Sstevel@tonic-gate unsigned char cfill;
365f6db9f27Scf int alen;
3667c478bd9Sstevel@tonic-gate int npad, length;
3677c478bd9Sstevel@tonic-gate wchar_t wchar;
368*55fea89dSDan Cross
3697c478bd9Sstevel@tonic-gate alen = send - s;
3707c478bd9Sstevel@tonic-gate if (alen > width)
3717c478bd9Sstevel@tonic-gate width = alen;
3727c478bd9Sstevel@tonic-gate cfill = fill>0? ' ': '0';
373*55fea89dSDan Cross
3747c478bd9Sstevel@tonic-gate /* we may want to print a leading '-' before anything */
3757c478bd9Sstevel@tonic-gate if (*s == '-' && fill < 0) {
3767c478bd9Sstevel@tonic-gate putchar(*s++);
3777c478bd9Sstevel@tonic-gate alen--;
3787c478bd9Sstevel@tonic-gate width--;
3797c478bd9Sstevel@tonic-gate }
3807c478bd9Sstevel@tonic-gate npad = width - alen;
381*55fea89dSDan Cross
3827c478bd9Sstevel@tonic-gate /* emit any leading pad characters */
3837c478bd9Sstevel@tonic-gate if (!sign)
3847c478bd9Sstevel@tonic-gate while (--npad >= 0)
3857c478bd9Sstevel@tonic-gate putchar(cfill);
386*55fea89dSDan Cross
3877c478bd9Sstevel@tonic-gate /* emit the string itself */
3887c478bd9Sstevel@tonic-gate while (--alen >= 0) {
3897c478bd9Sstevel@tonic-gate length = mbtowc(&wchar, (char *)s, MB_LEN_MAX);
3907c478bd9Sstevel@tonic-gate if(length <= 0) {
3917c478bd9Sstevel@tonic-gate putoctal = 1;
3927c478bd9Sstevel@tonic-gate putchar((unsigned char)*s++);
3937c478bd9Sstevel@tonic-gate putoctal = 0;
3947c478bd9Sstevel@tonic-gate } else {
3957c478bd9Sstevel@tonic-gate putchar(wchar);
3967c478bd9Sstevel@tonic-gate s += length;
3977c478bd9Sstevel@tonic-gate alen = alen - length + 1;
3987c478bd9Sstevel@tonic-gate }
399*55fea89dSDan Cross }
4007c478bd9Sstevel@tonic-gate /* emit trailing pad characters */
4017c478bd9Sstevel@tonic-gate if (sign)
4027c478bd9Sstevel@tonic-gate while (--npad >= 0)
4037c478bd9Sstevel@tonic-gate putchar(cfill);
4047c478bd9Sstevel@tonic-gate }
405