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 */ 22*f6db9f27Scf46844 /* 23*f6db9f27Scf46844 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24*f6db9f27Scf46844 * Use is subject to license terms. 25*f6db9f27Scf46844 */ 26*f6db9f27Scf46844 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 /* The pwb version this is based on */ 417c478bd9Sstevel@tonic-gate static char *printf_id = "@(#) printf.c:2.2 6/5/79"; 427c478bd9Sstevel@tonic-gate /* The local sccs version within ex */ 437c478bd9Sstevel@tonic-gate 447c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 457c478bd9Sstevel@tonic-gate 467c478bd9Sstevel@tonic-gate #include <stdarg.h> 477c478bd9Sstevel@tonic-gate #include <stdlib.h> 487c478bd9Sstevel@tonic-gate #include <limits.h> 497c478bd9Sstevel@tonic-gate extern short putoctal; 507c478bd9Sstevel@tonic-gate /* 517c478bd9Sstevel@tonic-gate * This version of printf is compatible with the Version 7 C 52*f6db9f27Scf46844 * printf. The differences are only minor except that 53*f6db9f27Scf46844 * viprintf assumes it is to print through putchar. Version 7 547c478bd9Sstevel@tonic-gate * printf is more general (and is much larger) and includes 557c478bd9Sstevel@tonic-gate * provisions for floating point. 567c478bd9Sstevel@tonic-gate */ 577c478bd9Sstevel@tonic-gate 587c478bd9Sstevel@tonic-gate 597c478bd9Sstevel@tonic-gate #define MAXOCT 11 /* Maximum octal digits in a long */ 607c478bd9Sstevel@tonic-gate #define MAXINT 32767 /* largest normal length positive integer */ 617c478bd9Sstevel@tonic-gate #define BIG 1000000000 /* largest power of 10 less than an unsigned long */ 627c478bd9Sstevel@tonic-gate #define MAXDIGS 10 /* number of digits in BIG */ 637c478bd9Sstevel@tonic-gate 647c478bd9Sstevel@tonic-gate static int width, sign, fill; 657c478bd9Sstevel@tonic-gate 667c478bd9Sstevel@tonic-gate unsigned char *_p_dconv(); 67*f6db9f27Scf46844 void _p_emit(unsigned char *, unsigned char *); 687c478bd9Sstevel@tonic-gate 69*f6db9f27Scf46844 /*VARARGS*/ 70*f6db9f27Scf46844 void 71*f6db9f27Scf46844 viprintf(unsigned char *fmt, ...) 727c478bd9Sstevel@tonic-gate { 737c478bd9Sstevel@tonic-gate va_list ap; 747c478bd9Sstevel@tonic-gate unsigned char fcode; 757c478bd9Sstevel@tonic-gate wchar_t wfcode; 767c478bd9Sstevel@tonic-gate int prec; 777c478bd9Sstevel@tonic-gate int length,mask1,nbits,n; 787c478bd9Sstevel@tonic-gate int length2; 797c478bd9Sstevel@tonic-gate long int mask2, num; 80*f6db9f27Scf46844 unsigned char *bptr; 817c478bd9Sstevel@tonic-gate unsigned char *ptr; 827c478bd9Sstevel@tonic-gate unsigned char buf[134]; 837c478bd9Sstevel@tonic-gate 847c478bd9Sstevel@tonic-gate va_start(ap, fmt); 857c478bd9Sstevel@tonic-gate for (;;) { 867c478bd9Sstevel@tonic-gate /* process format string first */ 877c478bd9Sstevel@tonic-gate for (;;) { 887c478bd9Sstevel@tonic-gate length2 = mbtowc(&wfcode, (char *)fmt, MB_LEN_MAX); 897c478bd9Sstevel@tonic-gate if(length2 <= 0) { 907c478bd9Sstevel@tonic-gate if (*fmt == '\0') { 917c478bd9Sstevel@tonic-gate fmt++; 927c478bd9Sstevel@tonic-gate return; 937c478bd9Sstevel@tonic-gate } 947c478bd9Sstevel@tonic-gate putchar(*fmt++); 957c478bd9Sstevel@tonic-gate } else { 967c478bd9Sstevel@tonic-gate if (wfcode == '%') { 977c478bd9Sstevel@tonic-gate fmt++; 987c478bd9Sstevel@tonic-gate break; 997c478bd9Sstevel@tonic-gate } 1007c478bd9Sstevel@tonic-gate /* ordinary (non-%) character */ 1017c478bd9Sstevel@tonic-gate putchar(wfcode); 1027c478bd9Sstevel@tonic-gate fmt += length2; 1037c478bd9Sstevel@tonic-gate } 1047c478bd9Sstevel@tonic-gate } 1057c478bd9Sstevel@tonic-gate /* length modifier: -1 for h, 1 for l, 0 for none */ 1067c478bd9Sstevel@tonic-gate length = 0; 1077c478bd9Sstevel@tonic-gate /* check for a leading - sign */ 1087c478bd9Sstevel@tonic-gate sign = 0; 1097c478bd9Sstevel@tonic-gate if (*fmt == '-') { 1107c478bd9Sstevel@tonic-gate sign++; 1117c478bd9Sstevel@tonic-gate fmt++; 1127c478bd9Sstevel@tonic-gate } 1137c478bd9Sstevel@tonic-gate /* a '0' may follow the - sign */ 1147c478bd9Sstevel@tonic-gate /* this is the requested fill character */ 1157c478bd9Sstevel@tonic-gate fill = 1; 1167c478bd9Sstevel@tonic-gate if (*fmt == '0') { 1177c478bd9Sstevel@tonic-gate fill--; 1187c478bd9Sstevel@tonic-gate fmt++; 1197c478bd9Sstevel@tonic-gate } 1207c478bd9Sstevel@tonic-gate 1217c478bd9Sstevel@tonic-gate /* Now comes a digit string which may be a '*' */ 1227c478bd9Sstevel@tonic-gate if (*fmt == '*') { 1237c478bd9Sstevel@tonic-gate width = va_arg(ap, int); 1247c478bd9Sstevel@tonic-gate if (width < 0) { 1257c478bd9Sstevel@tonic-gate width = -width; 1267c478bd9Sstevel@tonic-gate sign = !sign; 1277c478bd9Sstevel@tonic-gate } 1287c478bd9Sstevel@tonic-gate fmt++; 1297c478bd9Sstevel@tonic-gate } 1307c478bd9Sstevel@tonic-gate else { 1317c478bd9Sstevel@tonic-gate width = 0; 1327c478bd9Sstevel@tonic-gate while (*fmt>='0' && *fmt<='9') 1337c478bd9Sstevel@tonic-gate width = width * 10 + (*fmt++ - '0'); 1347c478bd9Sstevel@tonic-gate } 1357c478bd9Sstevel@tonic-gate 1367c478bd9Sstevel@tonic-gate /* maybe a decimal point followed by more digits (or '*') */ 1377c478bd9Sstevel@tonic-gate if (*fmt=='.') { 1387c478bd9Sstevel@tonic-gate if (*++fmt == '*') { 1397c478bd9Sstevel@tonic-gate prec = va_arg(ap, int); 1407c478bd9Sstevel@tonic-gate fmt++; 1417c478bd9Sstevel@tonic-gate } 1427c478bd9Sstevel@tonic-gate else { 1437c478bd9Sstevel@tonic-gate prec = 0; 1447c478bd9Sstevel@tonic-gate while (*fmt>='0' && *fmt<='9') 1457c478bd9Sstevel@tonic-gate prec = prec * 10 + (*fmt++ - '0'); 1467c478bd9Sstevel@tonic-gate } 1477c478bd9Sstevel@tonic-gate } 1487c478bd9Sstevel@tonic-gate else 1497c478bd9Sstevel@tonic-gate prec = -1; 1507c478bd9Sstevel@tonic-gate 1517c478bd9Sstevel@tonic-gate /* 1527c478bd9Sstevel@tonic-gate * At this point, "sign" is nonzero if there was 1537c478bd9Sstevel@tonic-gate * a sign, "fill" is 0 if there was a leading 1547c478bd9Sstevel@tonic-gate * zero and 1 otherwise, "width" and "prec" 1557c478bd9Sstevel@tonic-gate * contain numbers corresponding to the digit 1567c478bd9Sstevel@tonic-gate * strings before and after the decimal point, 1577c478bd9Sstevel@tonic-gate * respectively, and "fmt" addresses the next 1587c478bd9Sstevel@tonic-gate * character after the whole mess. If there was 1597c478bd9Sstevel@tonic-gate * no decimal point, "prec" will be -1. 1607c478bd9Sstevel@tonic-gate */ 1617c478bd9Sstevel@tonic-gate switch (*fmt) { 1627c478bd9Sstevel@tonic-gate case 'L': 1637c478bd9Sstevel@tonic-gate case 'l': 1647c478bd9Sstevel@tonic-gate length = 2; 1657c478bd9Sstevel@tonic-gate /* no break!! */ 1667c478bd9Sstevel@tonic-gate case 'h': 1677c478bd9Sstevel@tonic-gate case 'H': 1687c478bd9Sstevel@tonic-gate length--; 1697c478bd9Sstevel@tonic-gate fmt++; 1707c478bd9Sstevel@tonic-gate break; 1717c478bd9Sstevel@tonic-gate } 1727c478bd9Sstevel@tonic-gate 1737c478bd9Sstevel@tonic-gate /* 1747c478bd9Sstevel@tonic-gate * At exit from the following switch, we will 1757c478bd9Sstevel@tonic-gate * emit the characters starting at "bptr" and 1767c478bd9Sstevel@tonic-gate * ending at "ptr"-1, unless fcode is '\0'. 1777c478bd9Sstevel@tonic-gate */ 1787c478bd9Sstevel@tonic-gate switch (fcode = *fmt++) { 1797c478bd9Sstevel@tonic-gate /* process characters and strings first */ 1807c478bd9Sstevel@tonic-gate case 'c': 1817c478bd9Sstevel@tonic-gate buf[0] = va_arg(ap, int); 1827c478bd9Sstevel@tonic-gate ptr = bptr = &buf[0]; 1837c478bd9Sstevel@tonic-gate if (buf[0] != '\0') 1847c478bd9Sstevel@tonic-gate ptr++; 1857c478bd9Sstevel@tonic-gate break; 1867c478bd9Sstevel@tonic-gate case 's': 1877c478bd9Sstevel@tonic-gate bptr = va_arg(ap,unsigned char *); 1887c478bd9Sstevel@tonic-gate if (bptr==0) 1897c478bd9Sstevel@tonic-gate bptr = (unsigned char *)"(null pointer)"; 1907c478bd9Sstevel@tonic-gate if (prec < 0) 1917c478bd9Sstevel@tonic-gate prec = MAXINT; 1927c478bd9Sstevel@tonic-gate for (n=0; *bptr++ && n < prec; n++) ; 1937c478bd9Sstevel@tonic-gate ptr = --bptr; 1947c478bd9Sstevel@tonic-gate bptr -= n; 1957c478bd9Sstevel@tonic-gate break; 1967c478bd9Sstevel@tonic-gate case 'O': 1977c478bd9Sstevel@tonic-gate length = 1; 1987c478bd9Sstevel@tonic-gate fcode = 'o'; 1997c478bd9Sstevel@tonic-gate /* no break */ 2007c478bd9Sstevel@tonic-gate case 'o': 2017c478bd9Sstevel@tonic-gate case 'X': 2027c478bd9Sstevel@tonic-gate case 'x': 2037c478bd9Sstevel@tonic-gate if (length > 0) 2047c478bd9Sstevel@tonic-gate num = va_arg(ap,long); 2057c478bd9Sstevel@tonic-gate else 2067c478bd9Sstevel@tonic-gate num = (unsigned)va_arg(ap,int); 2077c478bd9Sstevel@tonic-gate if (fcode=='o') { 2087c478bd9Sstevel@tonic-gate mask1 = 0x7; 2097c478bd9Sstevel@tonic-gate mask2 = 0x1fffffffL; 2107c478bd9Sstevel@tonic-gate nbits = 3; 2117c478bd9Sstevel@tonic-gate } 2127c478bd9Sstevel@tonic-gate else { 2137c478bd9Sstevel@tonic-gate mask1 = 0xf; 2147c478bd9Sstevel@tonic-gate mask2 = 0x0fffffffL; 2157c478bd9Sstevel@tonic-gate nbits = 4; 2167c478bd9Sstevel@tonic-gate } 2177c478bd9Sstevel@tonic-gate n = (num!=0); 2187c478bd9Sstevel@tonic-gate bptr = buf + MAXOCT + 3; 2197c478bd9Sstevel@tonic-gate /* shift and mask for speed */ 2207c478bd9Sstevel@tonic-gate do 2217c478bd9Sstevel@tonic-gate if (((int) num & mask1) < 10) 2227c478bd9Sstevel@tonic-gate *--bptr = ((int) num & mask1) + 060; 2237c478bd9Sstevel@tonic-gate else 2247c478bd9Sstevel@tonic-gate *--bptr = ((int) num & mask1) + 0127; 2257c478bd9Sstevel@tonic-gate while (num = (num >> nbits) & mask2); 2267c478bd9Sstevel@tonic-gate 2277c478bd9Sstevel@tonic-gate if (fcode=='o') { 2287c478bd9Sstevel@tonic-gate if (n) 2297c478bd9Sstevel@tonic-gate *--bptr = '0'; 2307c478bd9Sstevel@tonic-gate } 2317c478bd9Sstevel@tonic-gate else 2327c478bd9Sstevel@tonic-gate if (!sign && fill <= 0) { 2337c478bd9Sstevel@tonic-gate putchar('0'); 2347c478bd9Sstevel@tonic-gate putchar(fcode); 2357c478bd9Sstevel@tonic-gate width -= 2; 2367c478bd9Sstevel@tonic-gate } 2377c478bd9Sstevel@tonic-gate else { 2387c478bd9Sstevel@tonic-gate *--bptr = fcode; 2397c478bd9Sstevel@tonic-gate *--bptr = '0'; 2407c478bd9Sstevel@tonic-gate } 2417c478bd9Sstevel@tonic-gate ptr = buf + MAXOCT + 3; 2427c478bd9Sstevel@tonic-gate break; 2437c478bd9Sstevel@tonic-gate case 'D': 2447c478bd9Sstevel@tonic-gate case 'U': 2457c478bd9Sstevel@tonic-gate case 'I': 2467c478bd9Sstevel@tonic-gate length = 1; 2477c478bd9Sstevel@tonic-gate fcode = fcode + 'a' - 'A'; 2487c478bd9Sstevel@tonic-gate /* no break */ 2497c478bd9Sstevel@tonic-gate case 'd': 2507c478bd9Sstevel@tonic-gate case 'i': 2517c478bd9Sstevel@tonic-gate case 'u': 2527c478bd9Sstevel@tonic-gate if (length > 0) 2537c478bd9Sstevel@tonic-gate num = va_arg(ap,long); 2547c478bd9Sstevel@tonic-gate else { 2557c478bd9Sstevel@tonic-gate n = va_arg(ap,int); 2567c478bd9Sstevel@tonic-gate if (fcode=='u') 2577c478bd9Sstevel@tonic-gate num = (unsigned) n; 2587c478bd9Sstevel@tonic-gate else 2597c478bd9Sstevel@tonic-gate num = (long) n; 2607c478bd9Sstevel@tonic-gate } 2617c478bd9Sstevel@tonic-gate if (n = (fcode != 'u' && num < 0)) 2627c478bd9Sstevel@tonic-gate num = -num; 2637c478bd9Sstevel@tonic-gate /* now convert to digits */ 2647c478bd9Sstevel@tonic-gate bptr = _p_dconv(num, buf); 2657c478bd9Sstevel@tonic-gate if (n) 2667c478bd9Sstevel@tonic-gate *--bptr = '-'; 2677c478bd9Sstevel@tonic-gate if (fill == 0) 2687c478bd9Sstevel@tonic-gate fill = -1; 2697c478bd9Sstevel@tonic-gate ptr = buf + MAXDIGS + 1; 2707c478bd9Sstevel@tonic-gate break; 2717c478bd9Sstevel@tonic-gate default: 2727c478bd9Sstevel@tonic-gate /* not a control character, 2737c478bd9Sstevel@tonic-gate * print it. 2747c478bd9Sstevel@tonic-gate */ 2757c478bd9Sstevel@tonic-gate ptr = bptr = &fcode; 2767c478bd9Sstevel@tonic-gate ptr++; 2777c478bd9Sstevel@tonic-gate break; 2787c478bd9Sstevel@tonic-gate } 2797c478bd9Sstevel@tonic-gate if (fcode != '\0') 2807c478bd9Sstevel@tonic-gate _p_emit(bptr,ptr); 2817c478bd9Sstevel@tonic-gate } 2827c478bd9Sstevel@tonic-gate va_end(ap); 2837c478bd9Sstevel@tonic-gate } 2847c478bd9Sstevel@tonic-gate 2857c478bd9Sstevel@tonic-gate /* _p_dconv converts the unsigned long integer "value" to 2867c478bd9Sstevel@tonic-gate * printable decimal and places it in "buffer", right-justified. 2877c478bd9Sstevel@tonic-gate * The value returned is the address of the first non-zero character, 2887c478bd9Sstevel@tonic-gate * or the address of the last character if all are zero. 2897c478bd9Sstevel@tonic-gate * The result is NOT null terminated, and is MAXDIGS characters long, 2907c478bd9Sstevel@tonic-gate * starting at buffer[1] (to allow for insertion of a sign). 2917c478bd9Sstevel@tonic-gate * 2927c478bd9Sstevel@tonic-gate * This program assumes it is running on 2's complement machine 2937c478bd9Sstevel@tonic-gate * with reasonable overflow treatment. 2947c478bd9Sstevel@tonic-gate */ 2957c478bd9Sstevel@tonic-gate unsigned char * 2967c478bd9Sstevel@tonic-gate _p_dconv(value, buffer) 2977c478bd9Sstevel@tonic-gate long value; 2987c478bd9Sstevel@tonic-gate unsigned char *buffer; 2997c478bd9Sstevel@tonic-gate { 300*f6db9f27Scf46844 unsigned char *bp; 301*f6db9f27Scf46844 int svalue; 3027c478bd9Sstevel@tonic-gate int n; 3037c478bd9Sstevel@tonic-gate long lval; 3047c478bd9Sstevel@tonic-gate 3057c478bd9Sstevel@tonic-gate bp = buffer; 3067c478bd9Sstevel@tonic-gate 3077c478bd9Sstevel@tonic-gate /* zero is a special case */ 3087c478bd9Sstevel@tonic-gate if (value == 0) { 3097c478bd9Sstevel@tonic-gate bp += MAXDIGS; 3107c478bd9Sstevel@tonic-gate *bp = '0'; 3117c478bd9Sstevel@tonic-gate return(bp); 3127c478bd9Sstevel@tonic-gate } 3137c478bd9Sstevel@tonic-gate 3147c478bd9Sstevel@tonic-gate /* develop the leading digit of the value in "n" */ 3157c478bd9Sstevel@tonic-gate n = 0; 3167c478bd9Sstevel@tonic-gate while (value < 0) { 3177c478bd9Sstevel@tonic-gate value -= BIG; /* will eventually underflow */ 3187c478bd9Sstevel@tonic-gate n++; 3197c478bd9Sstevel@tonic-gate } 3207c478bd9Sstevel@tonic-gate while ((lval = value - BIG) >= 0) { 3217c478bd9Sstevel@tonic-gate value = lval; 3227c478bd9Sstevel@tonic-gate n++; 3237c478bd9Sstevel@tonic-gate } 3247c478bd9Sstevel@tonic-gate 3257c478bd9Sstevel@tonic-gate /* stash it in buffer[1] to allow for a sign */ 3267c478bd9Sstevel@tonic-gate bp[1] = n + '0'; 3277c478bd9Sstevel@tonic-gate /* 3287c478bd9Sstevel@tonic-gate * Now develop the rest of the digits. Since speed counts here, 3297c478bd9Sstevel@tonic-gate * we do it in two loops. The first gets "value" down until it 3307c478bd9Sstevel@tonic-gate * is no larger than MAXINT. The second one uses integer divides 3317c478bd9Sstevel@tonic-gate * rather than long divides to speed it up. 3327c478bd9Sstevel@tonic-gate */ 3337c478bd9Sstevel@tonic-gate bp += MAXDIGS + 1; 3347c478bd9Sstevel@tonic-gate while (value > MAXINT) { 3357c478bd9Sstevel@tonic-gate *--bp = (int)(value % 10) + '0'; 3367c478bd9Sstevel@tonic-gate value /= 10; 3377c478bd9Sstevel@tonic-gate } 3387c478bd9Sstevel@tonic-gate 3397c478bd9Sstevel@tonic-gate /* cannot lose precision */ 3407c478bd9Sstevel@tonic-gate svalue = value; 3417c478bd9Sstevel@tonic-gate while (svalue > 0) { 3427c478bd9Sstevel@tonic-gate *--bp = (svalue % 10) + '0'; 3437c478bd9Sstevel@tonic-gate svalue /= 10; 3447c478bd9Sstevel@tonic-gate } 3457c478bd9Sstevel@tonic-gate 3467c478bd9Sstevel@tonic-gate /* fill in intermediate zeroes if needed */ 3477c478bd9Sstevel@tonic-gate if (buffer[1] != '0') { 3487c478bd9Sstevel@tonic-gate while (bp > buffer + 2) 3497c478bd9Sstevel@tonic-gate *--bp = '0'; 3507c478bd9Sstevel@tonic-gate --bp; 3517c478bd9Sstevel@tonic-gate } 3527c478bd9Sstevel@tonic-gate return(bp); 3537c478bd9Sstevel@tonic-gate } 3547c478bd9Sstevel@tonic-gate 3557c478bd9Sstevel@tonic-gate /* 3567c478bd9Sstevel@tonic-gate * This program sends string "s" to putchar. The character after 3577c478bd9Sstevel@tonic-gate * the end of "s" is given by "send". This allows the size of the 3587c478bd9Sstevel@tonic-gate * field to be computed; it is stored in "alen". "width" contains the 3597c478bd9Sstevel@tonic-gate * user specified length. If width<alen, the width will be taken to 3607c478bd9Sstevel@tonic-gate * be alen. "sign" is zero if the string is to be right-justified 3617c478bd9Sstevel@tonic-gate * in the field, nonzero if it is to be left-justified. "fill" is 3627c478bd9Sstevel@tonic-gate * 0 if the string is to be padded with '0', positive if it is to be 3637c478bd9Sstevel@tonic-gate * padded with ' ', and negative if an initial '-' should appear before 3647c478bd9Sstevel@tonic-gate * any padding in right-justification (to avoid printing "-3" as 3657c478bd9Sstevel@tonic-gate * "000-3" where "-0003" was intended). 3667c478bd9Sstevel@tonic-gate */ 367*f6db9f27Scf46844 void 368*f6db9f27Scf46844 _p_emit(unsigned char *s, unsigned char *send) 3697c478bd9Sstevel@tonic-gate { 3707c478bd9Sstevel@tonic-gate unsigned char cfill; 371*f6db9f27Scf46844 int alen; 3727c478bd9Sstevel@tonic-gate int npad, length; 3737c478bd9Sstevel@tonic-gate wchar_t wchar; 3747c478bd9Sstevel@tonic-gate 3757c478bd9Sstevel@tonic-gate alen = send - s; 3767c478bd9Sstevel@tonic-gate if (alen > width) 3777c478bd9Sstevel@tonic-gate width = alen; 3787c478bd9Sstevel@tonic-gate cfill = fill>0? ' ': '0'; 3797c478bd9Sstevel@tonic-gate 3807c478bd9Sstevel@tonic-gate /* we may want to print a leading '-' before anything */ 3817c478bd9Sstevel@tonic-gate if (*s == '-' && fill < 0) { 3827c478bd9Sstevel@tonic-gate putchar(*s++); 3837c478bd9Sstevel@tonic-gate alen--; 3847c478bd9Sstevel@tonic-gate width--; 3857c478bd9Sstevel@tonic-gate } 3867c478bd9Sstevel@tonic-gate npad = width - alen; 3877c478bd9Sstevel@tonic-gate 3887c478bd9Sstevel@tonic-gate /* emit any leading pad characters */ 3897c478bd9Sstevel@tonic-gate if (!sign) 3907c478bd9Sstevel@tonic-gate while (--npad >= 0) 3917c478bd9Sstevel@tonic-gate putchar(cfill); 3927c478bd9Sstevel@tonic-gate 3937c478bd9Sstevel@tonic-gate /* emit the string itself */ 3947c478bd9Sstevel@tonic-gate while (--alen >= 0) { 3957c478bd9Sstevel@tonic-gate length = mbtowc(&wchar, (char *)s, MB_LEN_MAX); 3967c478bd9Sstevel@tonic-gate if(length <= 0) { 3977c478bd9Sstevel@tonic-gate putoctal = 1; 3987c478bd9Sstevel@tonic-gate putchar((unsigned char)*s++); 3997c478bd9Sstevel@tonic-gate putoctal = 0; 4007c478bd9Sstevel@tonic-gate } else { 4017c478bd9Sstevel@tonic-gate putchar(wchar); 4027c478bd9Sstevel@tonic-gate s += length; 4037c478bd9Sstevel@tonic-gate alen = alen - length + 1; 4047c478bd9Sstevel@tonic-gate } 4057c478bd9Sstevel@tonic-gate } 4067c478bd9Sstevel@tonic-gate /* emit trailing pad characters */ 4077c478bd9Sstevel@tonic-gate if (sign) 4087c478bd9Sstevel@tonic-gate while (--npad >= 0) 4097c478bd9Sstevel@tonic-gate putchar(cfill); 4107c478bd9Sstevel@tonic-gate } 411