xref: /onnv-gate/usr/src/lib/libbc/libc/stdio/common/doprnt.c (revision 722:636b850d4ee9)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
50Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
60Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
70Sstevel@tonic-gate  * with the License.
80Sstevel@tonic-gate  *
90Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
100Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
110Sstevel@tonic-gate  * See the License for the specific language governing permissions
120Sstevel@tonic-gate  * and limitations under the License.
130Sstevel@tonic-gate  *
140Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
150Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
160Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
170Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
180Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
190Sstevel@tonic-gate  *
200Sstevel@tonic-gate  * CDDL HEADER END
210Sstevel@tonic-gate  */
220Sstevel@tonic-gate /*
23*722Smuffin  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24*722Smuffin  * Use is subject to license terms.
250Sstevel@tonic-gate  */
260Sstevel@tonic-gate 
270Sstevel@tonic-gate /* Copyright (c) 1988 AT&T */
280Sstevel@tonic-gate /* All Rights Reserved */
290Sstevel@tonic-gate 
300Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
310Sstevel@tonic-gate 
320Sstevel@tonic-gate /*
330Sstevel@tonic-gate  *	_doprnt: common code for printf, fprintf, sprintf
340Sstevel@tonic-gate  *	Floating-point code is included or not, depending
350Sstevel@tonic-gate  *	on whether the preprocessor variable FLOAT is 1 or 0.
360Sstevel@tonic-gate  */
370Sstevel@tonic-gate #define MAXARGS 50
380Sstevel@tonic-gate #ifndef FLOAT
390Sstevel@tonic-gate #define	FLOAT	1	/* YES! we want floating */
400Sstevel@tonic-gate #endif
410Sstevel@tonic-gate 
420Sstevel@tonic-gate #include <stdio.h>
430Sstevel@tonic-gate #include <ctype.h>
44*722Smuffin #include <stdarg.h>
450Sstevel@tonic-gate #include <values.h>
460Sstevel@tonic-gate #include <locale.h>
470Sstevel@tonic-gate #include "doprnt.h"
480Sstevel@tonic-gate #include "stdiom.h"
490Sstevel@tonic-gate #include <string.h>	/* strchr, strlen, strspn */
500Sstevel@tonic-gate 
510Sstevel@tonic-gate #define max(a,b)	((a) > (b) ? (a) : (b))
520Sstevel@tonic-gate #define min(a,b)	((a) < (b) ? (a) : (b))
530Sstevel@tonic-gate 
540Sstevel@tonic-gate /* If this symbol is nonzero, allow '0' as a flag */
550Sstevel@tonic-gate /* If this symbol is nonzero, allow '0' as a flag */
560Sstevel@tonic-gate #define FZERO 1
570Sstevel@tonic-gate 
580Sstevel@tonic-gate #if FLOAT
590Sstevel@tonic-gate /*
600Sstevel@tonic-gate  *	libc/gen/common functions for floating-point conversion
610Sstevel@tonic-gate  */
620Sstevel@tonic-gate #include <floatingpoint.h>
630Sstevel@tonic-gate extern void _fourdigitsquick();
640Sstevel@tonic-gate #endif
650Sstevel@tonic-gate 
660Sstevel@tonic-gate #define emitchar(c)   { if (--filecnt < 0) { \
67*722Smuffin 				FILE *iop = file; \
680Sstevel@tonic-gate 				if (((iop->_flag & (_IOLBF|_IONBF)) == 0 \
690Sstevel@tonic-gate 				    || -filecnt >= iop->_bufsiz)) { \
700Sstevel@tonic-gate 					iop->_ptr = fileptr; \
710Sstevel@tonic-gate 					if (iop->_flag & _IOSTRG) \
720Sstevel@tonic-gate 						return iop->_ptr - iop->_base; \
730Sstevel@tonic-gate 					else \
740Sstevel@tonic-gate 						(void) _xflsbuf(iop); \
750Sstevel@tonic-gate 					fileptr = iop->_ptr; \
760Sstevel@tonic-gate 					filecnt = iop->_cnt; \
770Sstevel@tonic-gate 					filecnt--; \
780Sstevel@tonic-gate 				    } \
790Sstevel@tonic-gate 			} \
800Sstevel@tonic-gate 			*fileptr++ = (unsigned)(c); \
810Sstevel@tonic-gate 			count++; \
820Sstevel@tonic-gate                       }
830Sstevel@tonic-gate 
840Sstevel@tonic-gate static char *nullstr = "(null)";
850Sstevel@tonic-gate static char *lowerhex = "0123456789abcdef";
860Sstevel@tonic-gate static char *upperhex = "0123456789ABCDEF";
870Sstevel@tonic-gate 
880Sstevel@tonic-gate /* stva_list is used to subvert C's restriction that a variable with an
890Sstevel@tonic-gate  * array type can not appear on the left hand side of an assignment operator.
900Sstevel@tonic-gate  * By putting the array inside a structure, the functionality of assigning to
910Sstevel@tonic-gate  * the whole array through a simple assignment is achieved..
920Sstevel@tonic-gate */
930Sstevel@tonic-gate typedef struct stva_list {
940Sstevel@tonic-gate 	va_list ap;
950Sstevel@tonic-gate } stva_list;
960Sstevel@tonic-gate 
97*722Smuffin void	_mkarglst(char *, stva_list, stva_list []);
98*722Smuffin void	_getarg(char *, stva_list *, int);
99*722Smuffin static char	*_check_dol(char *, int *);
100*722Smuffin 
101*722Smuffin int
_doprnt(char * format,va_list in_args,FILE * file)102*722Smuffin _doprnt(char *format, va_list in_args, FILE *file)
1030Sstevel@tonic-gate {
1040Sstevel@tonic-gate 	char convertbuffer[1024] ;
1050Sstevel@tonic-gate 
1060Sstevel@tonic-gate 	/* Current position in format */
107*722Smuffin 	char *cp;
1080Sstevel@tonic-gate 
1090Sstevel@tonic-gate 	/* Starting and ending points for value to be printed */
110*722Smuffin 	char *bp;
1110Sstevel@tonic-gate 	char *p;
1120Sstevel@tonic-gate 
1130Sstevel@tonic-gate 	/* Pointer and count for I/O buffer */
114*722Smuffin 	unsigned char *fileptr;
115*722Smuffin 	int filecnt;
1160Sstevel@tonic-gate 
1170Sstevel@tonic-gate 	/* Field width and precision */
1180Sstevel@tonic-gate 	int width;
119*722Smuffin 	int prec;
1200Sstevel@tonic-gate 
1210Sstevel@tonic-gate 	/* Format code */
1220Sstevel@tonic-gate 	char fcode;
1230Sstevel@tonic-gate 
1240Sstevel@tonic-gate 	/* Number of padding zeroes required on the left */
1250Sstevel@tonic-gate 	int lzero;
1260Sstevel@tonic-gate 
1270Sstevel@tonic-gate 	/* Flags - nonzero if corresponding character appears in format */
1280Sstevel@tonic-gate 	bool fplus;		/* + */
1290Sstevel@tonic-gate 	bool fminus;		/* - */
1300Sstevel@tonic-gate 	bool fblank;		/* blank */
1310Sstevel@tonic-gate 	bool fsharp;		/* # */
1320Sstevel@tonic-gate #if FZERO
1330Sstevel@tonic-gate 	bool ansi_fzero;	/* 0 for ansi-dictated formats */
1340Sstevel@tonic-gate 	bool compat_fzero;	/* 0 for backward compatibility */
1350Sstevel@tonic-gate #endif
1360Sstevel@tonic-gate 	bool Lsize;             /* Capital L for size = long double = quadruple */
1370Sstevel@tonic-gate 
1380Sstevel@tonic-gate 	/* Pointer to sign, "0x", "0X", or empty */
1390Sstevel@tonic-gate 	char *prefix;
1400Sstevel@tonic-gate 
1410Sstevel@tonic-gate 	/* Scratch */
1420Sstevel@tonic-gate 	int nblank;
1430Sstevel@tonic-gate 
1440Sstevel@tonic-gate #if FLOAT
1450Sstevel@tonic-gate 	/* Exponent or empty */
1460Sstevel@tonic-gate 	char *suffix;
1470Sstevel@tonic-gate 
1480Sstevel@tonic-gate 	/* Buffer to create exponent */
1490Sstevel@tonic-gate 	char expbuf[7];  /* "e+xxxx\0" */
1500Sstevel@tonic-gate 
1510Sstevel@tonic-gate 	/* Number of padding zeroes required on the right */
1520Sstevel@tonic-gate 	int rzero;
1530Sstevel@tonic-gate 
1540Sstevel@tonic-gate 	/* Length of exponent suffix. */
1550Sstevel@tonic-gate 	int suffixlength;
1560Sstevel@tonic-gate 
1570Sstevel@tonic-gate 	/* The value being converted, if real or quadruple */
1580Sstevel@tonic-gate 	double dval;
1590Sstevel@tonic-gate 	quadruple qval;
1600Sstevel@tonic-gate 
1610Sstevel@tonic-gate 	/* Output values from fconvert and econvert */
1620Sstevel@tonic-gate 	int decpt, sign;
1630Sstevel@tonic-gate 
1640Sstevel@tonic-gate 	/* Values are developed in this buffer */
1650Sstevel@tonic-gate 	char buf[1034];		/* Size of convertbuffer, plus some for exponent and sign. */
1660Sstevel@tonic-gate 
1670Sstevel@tonic-gate 	/* Current locale's decimal point */
1680Sstevel@tonic-gate 	char decpt_char = *(localeconv()->decimal_point);
1690Sstevel@tonic-gate 
1700Sstevel@tonic-gate #else
1710Sstevel@tonic-gate 	/* Values are developed in this buffer */
1720Sstevel@tonic-gate 	char buf[MAXDIGS];
1730Sstevel@tonic-gate #endif
1740Sstevel@tonic-gate 
1750Sstevel@tonic-gate 
1760Sstevel@tonic-gate 	/* The value being converted, if integer */
177*722Smuffin 	unsigned long val;
1780Sstevel@tonic-gate 
1790Sstevel@tonic-gate 	/* Work variables */
180*722Smuffin 	int n;
181*722Smuffin 	char c;
1820Sstevel@tonic-gate 	char radix;
1830Sstevel@tonic-gate 	int svswitch = 0;
1840Sstevel@tonic-gate 	/* count of output characters */
185*722Smuffin 	int count;
1860Sstevel@tonic-gate 
1870Sstevel@tonic-gate 	/* variables for positional parameters */
1880Sstevel@tonic-gate 	char    *sformat = format;      /* save the beginning of the format */
1890Sstevel@tonic-gate 	int     fpos = 1;               /* 1 if first positional parameter */
1900Sstevel@tonic-gate 	stva_list       args,   /* used to step through the argument list */
1910Sstevel@tonic-gate 			args_width, 	/* for width */
1920Sstevel@tonic-gate 			args_prec, 	/* for prec */
1930Sstevel@tonic-gate 			sargs;  /* used to save the start of the argument list */
1940Sstevel@tonic-gate 	stva_list       arglst[MAXARGS];/* array giving the approriate values
1950Sstevel@tonic-gate 					 * for va_arg() to retrieve the
1960Sstevel@tonic-gate 				  	 * corresponding argument:
1970Sstevel@tonic-gate 					 * arglst[0] is the first argument
1980Sstevel@tonic-gate 				         * arglst[1] is the second argument, etc.
1990Sstevel@tonic-gate 				         */
2000Sstevel@tonic-gate 											      int index = 0;			/* argument placeolder */
2010Sstevel@tonic-gate 											     /* Initialize args and sargs to the start of the argument list.
2020Sstevel@tonic-gate         * Note that ANSI guarantees that the address of the first member of
2030Sstevel@tonic-gate         * a structure will be the same as the address of the structure. */
2040Sstevel@tonic-gate 											       args_width = args_prec = args = sargs = *(struct stva_list *)&in_args;
2050Sstevel@tonic-gate 
2060Sstevel@tonic-gate 
2070Sstevel@tonic-gate /*  initialize p an bp (starting and ending points)  bugid 1141781 */
2080Sstevel@tonic-gate 
2090Sstevel@tonic-gate 	p = bp = NULL;
2100Sstevel@tonic-gate 
2110Sstevel@tonic-gate 	cp = format;
2120Sstevel@tonic-gate 	if ((c = *cp++) != '\0') {
2130Sstevel@tonic-gate 		/*
2140Sstevel@tonic-gate 		 * We know we're going to write something; make sure
2150Sstevel@tonic-gate 		 * we can write and set up buffers, etc..
2160Sstevel@tonic-gate 		 */
2170Sstevel@tonic-gate 		if (_WRTCHK(file))
2180Sstevel@tonic-gate 			return(EOF);
2190Sstevel@tonic-gate 	} else
2200Sstevel@tonic-gate 		return(0);	/* no fault, no error */
2210Sstevel@tonic-gate 
2220Sstevel@tonic-gate 	count = 0;
2230Sstevel@tonic-gate 	fileptr = file->_ptr;
2240Sstevel@tonic-gate 	filecnt = file->_cnt;
2250Sstevel@tonic-gate 
2260Sstevel@tonic-gate 	/*
2270Sstevel@tonic-gate 	 *	The main loop -- this loop goes through one iteration
2280Sstevel@tonic-gate 	 *	for each ordinary character or format specification.
2290Sstevel@tonic-gate 	 */
2300Sstevel@tonic-gate 	do {
2310Sstevel@tonic-gate 		if (c != '%') {
2320Sstevel@tonic-gate 			/* Ordinary (non-%) character */
2330Sstevel@tonic-gate 			emitchar(c);
2340Sstevel@tonic-gate 		} else {
2350Sstevel@tonic-gate 			/*
2360Sstevel@tonic-gate 			 *	% has been spotted!
2370Sstevel@tonic-gate 			 *
2380Sstevel@tonic-gate 			 *	First, try the 99% cases.
2390Sstevel@tonic-gate 			 *	then parse the format specification.
2400Sstevel@tonic-gate 			 *
2410Sstevel@tonic-gate 			 *	Note that this code assumes the Sun
2420Sstevel@tonic-gate 			 *	Workstation environment (all params
2430Sstevel@tonic-gate 			 *	passed as int == long, no interrupts
2440Sstevel@tonic-gate 			 *	for fixed point overflow from negating
2450Sstevel@tonic-gate 			 *	the most negative number).
2460Sstevel@tonic-gate 			 */
2470Sstevel@tonic-gate 		skipit:
2480Sstevel@tonic-gate 			switch(c = *cp++) {
2490Sstevel@tonic-gate 
2500Sstevel@tonic-gate 			case 'l':
2510Sstevel@tonic-gate 			case 'h':
2520Sstevel@tonic-gate 				/* Quickly ignore long & short specifiers */
2530Sstevel@tonic-gate 				goto skipit;
2540Sstevel@tonic-gate 
2550Sstevel@tonic-gate 			case 's':
2560Sstevel@tonic-gate 				bp = va_arg(args.ap, char *);
2570Sstevel@tonic-gate 				if (bp == NULL)
2580Sstevel@tonic-gate 					bp = nullstr;
2590Sstevel@tonic-gate 				while (c = *bp++)
2600Sstevel@tonic-gate 					emitchar(c);
2610Sstevel@tonic-gate 				p = bp;
2620Sstevel@tonic-gate 				continue;
2630Sstevel@tonic-gate 
2640Sstevel@tonic-gate 			case 'c':
2650Sstevel@tonic-gate 				c = va_arg(args.ap, int);
2660Sstevel@tonic-gate 			emitc:
2670Sstevel@tonic-gate 				emitchar(c);
2680Sstevel@tonic-gate 				continue;
2690Sstevel@tonic-gate 
2700Sstevel@tonic-gate 			case 'i':
2710Sstevel@tonic-gate 			case 'd':
2720Sstevel@tonic-gate 			case 'D':
2730Sstevel@tonic-gate 				val = va_arg(args.ap, int);
2740Sstevel@tonic-gate 				if ((long) val < 0) {
2750Sstevel@tonic-gate 					emitchar('-');
2760Sstevel@tonic-gate 					val = -val;
2770Sstevel@tonic-gate 				}
2780Sstevel@tonic-gate 				goto udcommon;
2790Sstevel@tonic-gate 
2800Sstevel@tonic-gate 			case 'U':
2810Sstevel@tonic-gate 			case 'u':
2820Sstevel@tonic-gate 				val = va_arg(args.ap, unsigned);
2830Sstevel@tonic-gate 			udcommon:
2840Sstevel@tonic-gate                                 {
285*722Smuffin                                 char *stringp = lowerhex;
2860Sstevel@tonic-gate                                 bp = buf+MAXDIGS;
2870Sstevel@tonic-gate                                 stringp = lowerhex;
2880Sstevel@tonic-gate                                 do {
2890Sstevel@tonic-gate                                         *--bp = stringp[val%10];
2900Sstevel@tonic-gate                                         val /= 10;
2910Sstevel@tonic-gate                                 } while (val);
2920Sstevel@tonic-gate 				}
2930Sstevel@tonic-gate                                 goto intout;
2940Sstevel@tonic-gate 
2950Sstevel@tonic-gate 			case 'X':
2960Sstevel@tonic-gate 				{
297*722Smuffin 				char *stringp = upperhex;
2980Sstevel@tonic-gate 				val = va_arg(args.ap, unsigned);
2990Sstevel@tonic-gate 				bp = buf + MAXDIGS;
3000Sstevel@tonic-gate 				if (val == 0)
3010Sstevel@tonic-gate 					goto zero;
3020Sstevel@tonic-gate 				while (val) {
3030Sstevel@tonic-gate 					*--bp = stringp[val%16];
3040Sstevel@tonic-gate 					val /= 16;
3050Sstevel@tonic-gate 				}
3060Sstevel@tonic-gate 				}
3070Sstevel@tonic-gate 				goto intout;
3080Sstevel@tonic-gate 
3090Sstevel@tonic-gate 			case 'x':
3100Sstevel@tonic-gate 			case 'p':
3110Sstevel@tonic-gate 				{
312*722Smuffin 				char *stringp = lowerhex;
3130Sstevel@tonic-gate 				val = va_arg(args.ap, unsigned);
3140Sstevel@tonic-gate 				bp = buf + MAXDIGS;
3150Sstevel@tonic-gate 				if (val == 0)
3160Sstevel@tonic-gate 					goto zero;
3170Sstevel@tonic-gate 				while (val) {
3180Sstevel@tonic-gate 					*--bp = stringp[val%16];
3190Sstevel@tonic-gate 					val /= 16;
3200Sstevel@tonic-gate 				}
3210Sstevel@tonic-gate 				}
3220Sstevel@tonic-gate 				goto intout;
3230Sstevel@tonic-gate 
3240Sstevel@tonic-gate 			case 'O':
3250Sstevel@tonic-gate 			case 'o':
3260Sstevel@tonic-gate 				{
327*722Smuffin 				char *stringp = lowerhex;
3280Sstevel@tonic-gate 				val = va_arg(args.ap, unsigned);
3290Sstevel@tonic-gate 				bp = buf + MAXDIGS;
3300Sstevel@tonic-gate 				if (val == 0)
3310Sstevel@tonic-gate 					goto zero;
3320Sstevel@tonic-gate 				while (val) {
3330Sstevel@tonic-gate 					*--bp = stringp[val%8];
3340Sstevel@tonic-gate 					val /= 8;
3350Sstevel@tonic-gate 				}
3360Sstevel@tonic-gate 				}
3370Sstevel@tonic-gate 				/* Common code to output integers */
3380Sstevel@tonic-gate 			intout:
3390Sstevel@tonic-gate 				p = buf + MAXDIGS;
3400Sstevel@tonic-gate 				while (bp < p) {
3410Sstevel@tonic-gate 					c = *bp++;
3420Sstevel@tonic-gate 					emitchar(c);
3430Sstevel@tonic-gate 				}
3440Sstevel@tonic-gate 				continue;
3450Sstevel@tonic-gate 
3460Sstevel@tonic-gate 			zero:
3470Sstevel@tonic-gate 				c = '0';
3480Sstevel@tonic-gate 				goto emitc;
3490Sstevel@tonic-gate 
3500Sstevel@tonic-gate 			default:
3510Sstevel@tonic-gate 				/*
3520Sstevel@tonic-gate 				 * let AT&T deal with it
3530Sstevel@tonic-gate 				 */
3540Sstevel@tonic-gate 				cp-= 2;
3550Sstevel@tonic-gate 			}
3560Sstevel@tonic-gate 
3570Sstevel@tonic-gate 			Lsize = 0;      /* Not long double unless we say so. */
3580Sstevel@tonic-gate                         /* Scan the <flags> */
3590Sstevel@tonic-gate 			fplus = 0;
3600Sstevel@tonic-gate 			fminus = 0;
3610Sstevel@tonic-gate 			fblank = 0;
3620Sstevel@tonic-gate 			fsharp = 0;
3630Sstevel@tonic-gate #if FZERO
3640Sstevel@tonic-gate 			ansi_fzero = 0;
3650Sstevel@tonic-gate 			compat_fzero = 0;
3660Sstevel@tonic-gate #endif
3670Sstevel@tonic-gate 		scan:	switch (*++cp) {
3680Sstevel@tonic-gate 			case '+':
3690Sstevel@tonic-gate 				fplus = 1;
3700Sstevel@tonic-gate 				goto scan;
3710Sstevel@tonic-gate 			case '-':
3720Sstevel@tonic-gate 				fminus = 1;
3730Sstevel@tonic-gate 				goto scan;
3740Sstevel@tonic-gate 			case ' ':
3750Sstevel@tonic-gate 				fblank = 1;
3760Sstevel@tonic-gate 				goto scan;
3770Sstevel@tonic-gate 			case '#':
3780Sstevel@tonic-gate 				fsharp = 1;
3790Sstevel@tonic-gate 				goto scan;
3800Sstevel@tonic-gate #if FZERO
3810Sstevel@tonic-gate 			case '0':
3820Sstevel@tonic-gate 				ansi_fzero = 1;
3830Sstevel@tonic-gate 				compat_fzero = 1;
3840Sstevel@tonic-gate 				goto scan;
3850Sstevel@tonic-gate #endif
3860Sstevel@tonic-gate 			}
3870Sstevel@tonic-gate 
3880Sstevel@tonic-gate 			/* Scan the field width */
3890Sstevel@tonic-gate 			if (*cp == '*') {
3900Sstevel@tonic-gate 				char *p;
3910Sstevel@tonic-gate 				int val;
3920Sstevel@tonic-gate 
3930Sstevel@tonic-gate 				p = _check_dol(cp+1, &val);
3940Sstevel@tonic-gate 				if (p != (char *)NULL) {
3950Sstevel@tonic-gate 					/*
3960Sstevel@tonic-gate 					 * argument re-order
3970Sstevel@tonic-gate 					 */
3980Sstevel@tonic-gate 					if (fpos) {
3990Sstevel@tonic-gate 						_mkarglst(sformat, sargs, arglst);
4000Sstevel@tonic-gate 						fpos = 0;
4010Sstevel@tonic-gate 					}
4020Sstevel@tonic-gate 					if (val <= MAXARGS) {
4030Sstevel@tonic-gate 						args_width = arglst[val - 1];
4040Sstevel@tonic-gate 					} else {
4050Sstevel@tonic-gate 						args_width = arglst[MAXARGS - 1];
4060Sstevel@tonic-gate 						_getarg(sformat, &args_width, val);
4070Sstevel@tonic-gate 					}
4080Sstevel@tonic-gate 					width = va_arg(args_width.ap, int);
4090Sstevel@tonic-gate 					if (width < 0) {
4100Sstevel@tonic-gate 						width = -width;
4110Sstevel@tonic-gate 						fminus = 1;
4120Sstevel@tonic-gate 					}
4130Sstevel@tonic-gate 					cp = p;
4140Sstevel@tonic-gate 				}
4150Sstevel@tonic-gate 				else {
4160Sstevel@tonic-gate 					width = va_arg(args.ap, int);
4170Sstevel@tonic-gate 					if (width < 0) {
4180Sstevel@tonic-gate 						width = -width;
4190Sstevel@tonic-gate 						fminus = 1;
4200Sstevel@tonic-gate 					}
4210Sstevel@tonic-gate 					cp++;
4220Sstevel@tonic-gate 				}
4230Sstevel@tonic-gate 			} else {
4240Sstevel@tonic-gate 				index = width = 0;
4250Sstevel@tonic-gate 				while (isdigit(*cp)) {
4260Sstevel@tonic-gate 					n = tonumber(*cp++);
4270Sstevel@tonic-gate 					index = width = width * 10 + n;
4280Sstevel@tonic-gate 				}
4290Sstevel@tonic-gate 			}
4300Sstevel@tonic-gate 
4310Sstevel@tonic-gate 			/* Scan the precision */
4320Sstevel@tonic-gate 			if (*cp == '.') {
4330Sstevel@tonic-gate 
4340Sstevel@tonic-gate 				/* '*' instead of digits? */
4350Sstevel@tonic-gate 				if (*++cp == '*') {
4360Sstevel@tonic-gate 					char *p;
4370Sstevel@tonic-gate 					int val;
4380Sstevel@tonic-gate 
4390Sstevel@tonic-gate 					p = _check_dol(cp+1, &val);
4400Sstevel@tonic-gate 					if (p != (char *)NULL) {
4410Sstevel@tonic-gate 						/*
4420Sstevel@tonic-gate 						 * argument re-order
4430Sstevel@tonic-gate 						 */
4440Sstevel@tonic-gate 						if (fpos) {
4450Sstevel@tonic-gate 							_mkarglst(sformat, sargs, arglst);
4460Sstevel@tonic-gate 							fpos = 0;
4470Sstevel@tonic-gate 						}
4480Sstevel@tonic-gate 						if (val <= MAXARGS) {
4490Sstevel@tonic-gate 							args_prec = arglst[val - 1];
4500Sstevel@tonic-gate 						} else {
4510Sstevel@tonic-gate 							args_prec = arglst[MAXARGS - 1];
4520Sstevel@tonic-gate 							_getarg(sformat, &args_prec, val);
4530Sstevel@tonic-gate 						}
4540Sstevel@tonic-gate 						prec = va_arg(args_prec.ap, int);
4550Sstevel@tonic-gate 						cp = p;
4560Sstevel@tonic-gate 					}
4570Sstevel@tonic-gate 					else {
4580Sstevel@tonic-gate 						prec = va_arg(args.ap, int);
4590Sstevel@tonic-gate 						cp++;
4600Sstevel@tonic-gate 					}
4610Sstevel@tonic-gate 				} else {
4620Sstevel@tonic-gate 					prec = 0;
4630Sstevel@tonic-gate 					while (isdigit(*cp)) {
4640Sstevel@tonic-gate 						n = tonumber(*cp++);
4650Sstevel@tonic-gate 						prec = prec * 10 + n;
4660Sstevel@tonic-gate 					}
4670Sstevel@tonic-gate 				}
4680Sstevel@tonic-gate 			} else
4690Sstevel@tonic-gate 				prec = -1;
4700Sstevel@tonic-gate 
4710Sstevel@tonic-gate 			if (*cp == '$') {
4720Sstevel@tonic-gate 				if (fpos) {
4730Sstevel@tonic-gate 					_mkarglst(sformat, sargs, arglst);
4740Sstevel@tonic-gate 					fpos = 0;
4750Sstevel@tonic-gate 				}
4760Sstevel@tonic-gate 				if (index <= MAXARGS) {
4770Sstevel@tonic-gate 					args = arglst[index - 1];
4780Sstevel@tonic-gate 				} else {
4790Sstevel@tonic-gate 					args = arglst[MAXARGS - 1];
4800Sstevel@tonic-gate 					_getarg(sformat, &args, index);
4810Sstevel@tonic-gate 				}
4820Sstevel@tonic-gate 				goto scan;
4830Sstevel@tonic-gate 			}
4840Sstevel@tonic-gate 			/*
4850Sstevel@tonic-gate 			 *	The character addressed by cp must be the
4860Sstevel@tonic-gate 			 *	format letter -- there is nothing left for
4870Sstevel@tonic-gate 			 *	it to be.
4880Sstevel@tonic-gate 			 *
4890Sstevel@tonic-gate 			 *	The status of the +, -, #, blank, and 0
4900Sstevel@tonic-gate 			 *	flags are reflected in the variables
4910Sstevel@tonic-gate 			 *	"fplus", "fminus", "fsharp", "fblank",
4920Sstevel@tonic-gate 			 *	and "ansi_fzero"/"compat_fzero", respectively.
4930Sstevel@tonic-gate 			 *	"width" and "prec" contain numbers
4940Sstevel@tonic-gate 			 *	corresponding to the digit strings
4950Sstevel@tonic-gate 			 *	before and after the decimal point,
4960Sstevel@tonic-gate 			 *	respectively. If there was no decimal
4970Sstevel@tonic-gate 			 *	point, "prec" is -1.
4980Sstevel@tonic-gate 			 *
4990Sstevel@tonic-gate 			 *	The following switch sets things up
5000Sstevel@tonic-gate 			 *	for printing.  What ultimately gets
5010Sstevel@tonic-gate 			 *	printed will be padding blanks, a prefix,
5020Sstevel@tonic-gate 			 *	left padding zeroes, a value, right padding
5030Sstevel@tonic-gate 			 *	zeroes, a suffix, and more padding
5040Sstevel@tonic-gate 			 *	blanks.  Padding blanks will not appear
5050Sstevel@tonic-gate 			 *	simultaneously on both the left and the
5060Sstevel@tonic-gate 			 *	right.  Each case in this switch will
5070Sstevel@tonic-gate 			 *	compute the value, and leave in several
5080Sstevel@tonic-gate 			 *	variables the information necessary to
5090Sstevel@tonic-gate 			 *	construct what is to be printed.
5100Sstevel@tonic-gate 			 *
5110Sstevel@tonic-gate 			 *	The prefix is a sign, a blank, "0x", "0X",
5120Sstevel@tonic-gate 			 *	or null, and is addressed by "prefix".
5130Sstevel@tonic-gate 			 *
5140Sstevel@tonic-gate 			 *	The suffix is either null or an exponent,
5150Sstevel@tonic-gate 			 *	and is addressed by "suffix".
5160Sstevel@tonic-gate 			 *
5170Sstevel@tonic-gate 			 *	The value to be printed starts at "bp"
5180Sstevel@tonic-gate 			 *	and continues up to and not including "p".
5190Sstevel@tonic-gate 			 *
5200Sstevel@tonic-gate 			 *	"lzero" and "rzero" will contain the number
5210Sstevel@tonic-gate 			 *	of padding zeroes required on the left
5220Sstevel@tonic-gate 			 *	and right, respectively.  If either of
5230Sstevel@tonic-gate 			 *	these variables is negative, it will be
5240Sstevel@tonic-gate 			 *	treated as if it were zero.
5250Sstevel@tonic-gate 			 *
5260Sstevel@tonic-gate 			 *	The number of padding blanks, and whether
5270Sstevel@tonic-gate 			 *	they go on the left or the right, will be
5280Sstevel@tonic-gate 			 *	computed on exit from the switch.
5290Sstevel@tonic-gate 			 */
5300Sstevel@tonic-gate 
5310Sstevel@tonic-gate 			lzero = 0;
5320Sstevel@tonic-gate 			prefix = "";
5330Sstevel@tonic-gate #if FLOAT
5340Sstevel@tonic-gate 			rzero = 0;
5350Sstevel@tonic-gate 			suffix = prefix;
5360Sstevel@tonic-gate #endif
5370Sstevel@tonic-gate 
5380Sstevel@tonic-gate #if FZERO
5390Sstevel@tonic-gate 		  	/* if both zero-padding and left-justify flags
5400Sstevel@tonic-gate 			 * are used, ignore zero-padding, per ansi c
5410Sstevel@tonic-gate 			 */
5420Sstevel@tonic-gate 		  	if (ansi_fzero & fminus) {
5430Sstevel@tonic-gate 				ansi_fzero = 0;
5440Sstevel@tonic-gate 				compat_fzero = 0;
5450Sstevel@tonic-gate 			}
5460Sstevel@tonic-gate 
5470Sstevel@tonic-gate 		  	/* if zero-padding and precision are specified,
5480Sstevel@tonic-gate 			 * ignore zero-padding for ansi-dictated formats,
5490Sstevel@tonic-gate 			 * per ansi c
5500Sstevel@tonic-gate 			 */
5510Sstevel@tonic-gate 		  	if (ansi_fzero & (prec != -1)) ansi_fzero = 0;
5520Sstevel@tonic-gate #endif
5530Sstevel@tonic-gate 
5540Sstevel@tonic-gate 		next:
5550Sstevel@tonic-gate 			switch (fcode = *cp++) {
5560Sstevel@tonic-gate 
5570Sstevel@tonic-gate 			/* toss the length modifier, if any */
5580Sstevel@tonic-gate 			case 'l':
5590Sstevel@tonic-gate 			case 'h':
5600Sstevel@tonic-gate 				goto next;
5610Sstevel@tonic-gate 
5620Sstevel@tonic-gate                        	case 'L':
5630Sstevel@tonic-gate                       		Lsize = 1;      /* Remember long double size. */
5640Sstevel@tonic-gate                          	goto next;
5650Sstevel@tonic-gate 
5660Sstevel@tonic-gate 			/*
5670Sstevel@tonic-gate 			 *	fixed point representations
5680Sstevel@tonic-gate 			 *
5690Sstevel@tonic-gate 			 *	"radix" is the radix for the conversion.
5700Sstevel@tonic-gate 			 *	Conversion is unsigned unless fcode is 'd'.
5710Sstevel@tonic-gate 			 *	We assume a 2's complement machine and
5720Sstevel@tonic-gate 			 *	that fixed point overflow (from negating
5730Sstevel@tonic-gate 			 *	the largest negative int) is ignored.
5740Sstevel@tonic-gate 			 */
5750Sstevel@tonic-gate 
5760Sstevel@tonic-gate 			case 'i':
5770Sstevel@tonic-gate 			case 'D':
5780Sstevel@tonic-gate 			case 'U':
5790Sstevel@tonic-gate 			case 'd':
5800Sstevel@tonic-gate 			case 'u':
5810Sstevel@tonic-gate 				radix = 10;
5820Sstevel@tonic-gate 				goto fixed;
5830Sstevel@tonic-gate 
5840Sstevel@tonic-gate 			case 'O':
5850Sstevel@tonic-gate 			case 'o':
5860Sstevel@tonic-gate 				radix = 8;
5870Sstevel@tonic-gate 				goto fixed;
5880Sstevel@tonic-gate 
5890Sstevel@tonic-gate 			case 'X':
5900Sstevel@tonic-gate 			case 'x':
5910Sstevel@tonic-gate 				radix = 16;
5920Sstevel@tonic-gate 
5930Sstevel@tonic-gate 			fixed:
5940Sstevel@tonic-gate 				/* Establish default precision */
5950Sstevel@tonic-gate 				if (prec < 0)
5960Sstevel@tonic-gate 					prec = 1;
5970Sstevel@tonic-gate 
5980Sstevel@tonic-gate 				/* Fetch the argument to be printed */
5990Sstevel@tonic-gate 				val = va_arg(args.ap, unsigned);
6000Sstevel@tonic-gate 
6010Sstevel@tonic-gate 				/* If signed conversion, establish sign */
6020Sstevel@tonic-gate 				if (fcode == 'd' || fcode == 'D' || fcode == 'i') {
6030Sstevel@tonic-gate 					if ((long) val < 0) {
6040Sstevel@tonic-gate 						prefix = "-";
6050Sstevel@tonic-gate 						val = -val;
6060Sstevel@tonic-gate 					} else if (fplus)
6070Sstevel@tonic-gate 						prefix = "+";
6080Sstevel@tonic-gate 					else if (fblank)
6090Sstevel@tonic-gate 						prefix = " ";
6100Sstevel@tonic-gate 				}
6110Sstevel@tonic-gate 				/* Set translate table for digits */
6120Sstevel@tonic-gate 				{
613*722Smuffin 				char *stringp;
6140Sstevel@tonic-gate 				if (fcode == 'X')
6150Sstevel@tonic-gate 					stringp = upperhex;
6160Sstevel@tonic-gate 				else
6170Sstevel@tonic-gate 					stringp = lowerhex;
6180Sstevel@tonic-gate 
6190Sstevel@tonic-gate 				/* Develop the digits of the value */
6200Sstevel@tonic-gate 				bp = buf + MAXDIGS;
6210Sstevel@tonic-gate 				switch(radix) {
6220Sstevel@tonic-gate 				case 8:	/*octal*/
6230Sstevel@tonic-gate 					while (val) {
6240Sstevel@tonic-gate 						*--bp = stringp[val%8];
6250Sstevel@tonic-gate 						val /= 8;
6260Sstevel@tonic-gate 					}
6270Sstevel@tonic-gate 					break;
6280Sstevel@tonic-gate 				case 16:/*hex*/
6290Sstevel@tonic-gate 					while (val) {
6300Sstevel@tonic-gate 						*--bp = stringp[val%16];
6310Sstevel@tonic-gate 						val /= 16;
6320Sstevel@tonic-gate 					}
6330Sstevel@tonic-gate 					break;
6340Sstevel@tonic-gate 				default:
6350Sstevel@tonic-gate 					while (val) {
6360Sstevel@tonic-gate 						*--bp = stringp[val%10];
6370Sstevel@tonic-gate 						val /= 10;
6380Sstevel@tonic-gate 					}
6390Sstevel@tonic-gate 					break;
6400Sstevel@tonic-gate 				} /* switch */
6410Sstevel@tonic-gate 				}
6420Sstevel@tonic-gate 
6430Sstevel@tonic-gate 				/* Calculate padding zero requirement */
6440Sstevel@tonic-gate 				p = buf + MAXDIGS;
6450Sstevel@tonic-gate 
6460Sstevel@tonic-gate 				/* Handle the # flag */
6470Sstevel@tonic-gate 				if (fsharp && bp != p) {
6480Sstevel@tonic-gate 					switch (fcode) {
6490Sstevel@tonic-gate 					case 'x':
6500Sstevel@tonic-gate 						prefix = "0x";
6510Sstevel@tonic-gate 						break;
6520Sstevel@tonic-gate 					case 'X':
6530Sstevel@tonic-gate 						prefix = "0X";
6540Sstevel@tonic-gate 						break;
6550Sstevel@tonic-gate 					}
6560Sstevel@tonic-gate 				}
6570Sstevel@tonic-gate #if FZERO
6580Sstevel@tonic-gate 				if (ansi_fzero) {
6590Sstevel@tonic-gate 					n = width - strlen(prefix);
6600Sstevel@tonic-gate 					if (n > prec)
6610Sstevel@tonic-gate 						prec = n;
6620Sstevel@tonic-gate 				}
6630Sstevel@tonic-gate #endif
6640Sstevel@tonic-gate 				lzero = bp - p + prec;
6650Sstevel@tonic-gate 
6660Sstevel@tonic-gate 				/* Handle the # flag for 'o' */
6670Sstevel@tonic-gate 				if (fsharp && bp != p && fcode == 'o' &&
6680Sstevel@tonic-gate 				    lzero < 1) {
6690Sstevel@tonic-gate 					lzero = 1;
6700Sstevel@tonic-gate 				}
6710Sstevel@tonic-gate 				break;
6720Sstevel@tonic-gate #if FLOAT
6730Sstevel@tonic-gate 
674*722Smuffin #if	defined(__sparc)
6750Sstevel@tonic-gate #define GETQVAL /* Sun-4 macro to get a quad q from the argument list, passed as a pointer. */ \
6760Sstevel@tonic-gate       { qval = *(va_arg(args.ap, quadruple*)) ; }
6770Sstevel@tonic-gate #else
6780Sstevel@tonic-gate #define GETQVAL /* Sun-3 macro to get a quad q from the argument list, passed as a value. */ \
6790Sstevel@tonic-gate       { int iq ; unsigned long * pl = (unsigned long *) (&qval) ; for(iq=0;iq<4;iq++) pl[iq] = (unsigned long) va_arg(args.ap, unsigned long) ; }
6800Sstevel@tonic-gate #endif
6810Sstevel@tonic-gate 
6820Sstevel@tonic-gate 			case 'E':
6830Sstevel@tonic-gate 			case 'e':
6840Sstevel@tonic-gate 				/*
6850Sstevel@tonic-gate 				 *	E-format.  The general strategy
6860Sstevel@tonic-gate 				 *	here is fairly easy: we take
6870Sstevel@tonic-gate 				 *	what econvert gives us and re-format it.
6880Sstevel@tonic-gate 				 */
6890Sstevel@tonic-gate 
6900Sstevel@tonic-gate 				/* Establish default precision */
6910Sstevel@tonic-gate 				if (prec < 0)
6920Sstevel@tonic-gate 					prec = 6;
6930Sstevel@tonic-gate 
6940Sstevel@tonic-gate 				/* Fetch the value */
6950Sstevel@tonic-gate                                if (Lsize == 0) { /* Double */
6960Sstevel@tonic-gate                                 dval = va_arg(args.ap, double);
6970Sstevel@tonic-gate                                 bp = econvert(dval, prec + 1, &decpt, &sign, convertbuffer);
6980Sstevel@tonic-gate                                } else { /* Long Double = quadruple */
6990Sstevel@tonic-gate                                GETQVAL;
7000Sstevel@tonic-gate                                bp = qeconvert(&qval, prec + 1, &decpt, &sign, convertbuffer);
7010Sstevel@tonic-gate                                }
7020Sstevel@tonic-gate 
7030Sstevel@tonic-gate 				/* Determine the prefix */
7040Sstevel@tonic-gate 				if (sign)
7050Sstevel@tonic-gate 					prefix = "-";
7060Sstevel@tonic-gate 				else if (fplus)
7070Sstevel@tonic-gate 					prefix = "+";
7080Sstevel@tonic-gate 				else if (fblank)
7090Sstevel@tonic-gate 					prefix = " ";
7100Sstevel@tonic-gate 				if (convertbuffer[0] > '9')
7110Sstevel@tonic-gate 					{ /* handle infinity, nan */
7120Sstevel@tonic-gate 					bp = &convertbuffer[0];
7130Sstevel@tonic-gate 					for (p = bp+1 ; *p != 0 ; p++) ;
7140Sstevel@tonic-gate 					goto ebreak ;
7150Sstevel@tonic-gate 					}
7160Sstevel@tonic-gate 				{
717*722Smuffin 				char *stringp;
7180Sstevel@tonic-gate 				/* Place the first digit in the buffer */
7190Sstevel@tonic-gate 				stringp = &buf[0];
7200Sstevel@tonic-gate 				*stringp++ = *bp != '\0'? *bp++: '0';
7210Sstevel@tonic-gate 
7220Sstevel@tonic-gate 				/* Put in a decimal point if needed */
7230Sstevel@tonic-gate 				if (prec != 0 || fsharp)
7240Sstevel@tonic-gate 					*stringp++ = decpt_char;
7250Sstevel@tonic-gate 
7260Sstevel@tonic-gate 				/* Create the rest of the mantissa */
7270Sstevel@tonic-gate 				rzero = prec;
7280Sstevel@tonic-gate 				while (rzero > 0 && *bp!= '\0') {
7290Sstevel@tonic-gate 					--rzero;
7300Sstevel@tonic-gate 					*stringp++ = *bp++;
7310Sstevel@tonic-gate 				}
7320Sstevel@tonic-gate 				p = stringp;
7330Sstevel@tonic-gate 				}
7340Sstevel@tonic-gate 
7350Sstevel@tonic-gate 				bp = &buf[0];
7360Sstevel@tonic-gate 
7370Sstevel@tonic-gate 				/* Create the exponent */
7380Sstevel@tonic-gate 				if (convertbuffer[0] != '0')
7390Sstevel@tonic-gate 					n = decpt - 1;
7400Sstevel@tonic-gate 				else
7410Sstevel@tonic-gate 					n = 0 ;
7420Sstevel@tonic-gate 				if (n < 0)
7430Sstevel@tonic-gate 					n = -n;
7440Sstevel@tonic-gate 				_fourdigitsquick( (short unsigned) n, &(expbuf[2]) ) ;
7450Sstevel@tonic-gate 				expbuf[6] = 0 ;
7460Sstevel@tonic-gate 				if (n < 100)
7470Sstevel@tonic-gate 					/*
7480Sstevel@tonic-gate                                          * Normally two digit exponent field,
7490Sstevel@tonic-gate                                          * three or four if required.
7500Sstevel@tonic-gate 					 */
7510Sstevel@tonic-gate 					{ suffix = &(expbuf[4]) ; suffixlength = 4 ; }
7520Sstevel@tonic-gate                                 else if (n < 1000)
7530Sstevel@tonic-gate                                         { suffix = &(expbuf[3]) ; suffixlength = 5 ; }
7540Sstevel@tonic-gate                                 else
7550Sstevel@tonic-gate                                         { suffix = &(expbuf[2]) ; suffixlength = 6 ; }
7560Sstevel@tonic-gate 				/* Put in the exponent sign */
7570Sstevel@tonic-gate 				*--suffix = (decpt > 0 || convertbuffer[0] == '0' )? '+': '-';
7580Sstevel@tonic-gate 
7590Sstevel@tonic-gate 				/* Put in the e; note kludge in 'g' format */
7600Sstevel@tonic-gate 				*--suffix = fcode;
7610Sstevel@tonic-gate ebreak:
7620Sstevel@tonic-gate #if FZERO
7630Sstevel@tonic-gate 				if (compat_fzero &! fminus)
7640Sstevel@tonic-gate 					/* Calculate padding zero requirement */
7650Sstevel@tonic-gate 					lzero = width - (strlen(prefix)
7660Sstevel@tonic-gate 					    + (p - buf) + rzero + suffixlength);
7670Sstevel@tonic-gate #endif
7680Sstevel@tonic-gate 				break;
7690Sstevel@tonic-gate 
7700Sstevel@tonic-gate 			case 'f':
7710Sstevel@tonic-gate 				/*
7720Sstevel@tonic-gate 				 *	F-format floating point.  This is
7730Sstevel@tonic-gate 				 *	a good deal less simple than E-format.
7740Sstevel@tonic-gate 				 *	The overall strategy will be to call
7750Sstevel@tonic-gate 				 *	fconvert, reformat its result into buf,
7760Sstevel@tonic-gate 				 *	and calculate how many trailing
7770Sstevel@tonic-gate 				 *	zeroes will be required.  There will
7780Sstevel@tonic-gate 				 *	never be any leading zeroes needed.
7790Sstevel@tonic-gate 				 */
7800Sstevel@tonic-gate 
7810Sstevel@tonic-gate 				/* Establish default precision */
7820Sstevel@tonic-gate 				if (prec < 0)
7830Sstevel@tonic-gate 					prec = 6;
7840Sstevel@tonic-gate 
7850Sstevel@tonic-gate                                 if (Lsize == 0) {
7860Sstevel@tonic-gate                                 dval = va_arg(args.ap, double);
7870Sstevel@tonic-gate                                 bp = fconvert(dval, prec, &decpt, &sign, convertbuffer);
7880Sstevel@tonic-gate                                 } else {
7890Sstevel@tonic-gate                                 GETQVAL ;
7900Sstevel@tonic-gate                                 bp = qfconvert(&qval, prec, &decpt, &sign, convertbuffer);
7910Sstevel@tonic-gate                                 }
7920Sstevel@tonic-gate 
7930Sstevel@tonic-gate 				/* Determine the prefix */
7940Sstevel@tonic-gate 				if (sign)
7950Sstevel@tonic-gate 					prefix = "-";
7960Sstevel@tonic-gate 				else if (fplus)
7970Sstevel@tonic-gate 					prefix = "+";
7980Sstevel@tonic-gate 				else if (fblank)
7990Sstevel@tonic-gate 					prefix = " ";
8000Sstevel@tonic-gate 				if (convertbuffer[0] > '9')
8010Sstevel@tonic-gate 					{ /* handle infinity, nan */
8020Sstevel@tonic-gate 					bp = &convertbuffer[0];
8030Sstevel@tonic-gate 					for (p = bp+1 ; *p != 0 ; p++) ;
8040Sstevel@tonic-gate 					goto fbreak ;
8050Sstevel@tonic-gate 					}
8060Sstevel@tonic-gate 				{
807*722Smuffin 				char *stringp;
8080Sstevel@tonic-gate 				/* Initialize buffer pointer */
8090Sstevel@tonic-gate 				stringp = &buf[0];
8100Sstevel@tonic-gate 
8110Sstevel@tonic-gate 				/* Emit the digits before the decimal point */
8120Sstevel@tonic-gate 				n = decpt;
8130Sstevel@tonic-gate 				if (n <= 0)
8140Sstevel@tonic-gate 					*stringp++ = '0';
8150Sstevel@tonic-gate 				else
8160Sstevel@tonic-gate 					do
8170Sstevel@tonic-gate 						if (*bp == '\0' )
8180Sstevel@tonic-gate 							*stringp++ = '0';
8190Sstevel@tonic-gate 						else {
8200Sstevel@tonic-gate 							*stringp++ = *bp++;
8210Sstevel@tonic-gate 						}
8220Sstevel@tonic-gate 					while (--n != 0);
8230Sstevel@tonic-gate 
8240Sstevel@tonic-gate 				/* Decide whether we need a decimal point */
8250Sstevel@tonic-gate 				if (fsharp || prec > 0)
8260Sstevel@tonic-gate 					*stringp++ = decpt_char;
8270Sstevel@tonic-gate 
8280Sstevel@tonic-gate 				/* Digits(if any) after the decimal point */
8290Sstevel@tonic-gate 				n = prec;
8300Sstevel@tonic-gate 				rzero = prec - n;
8310Sstevel@tonic-gate 				while (--n >= 0) {
8320Sstevel@tonic-gate 					if (++decpt <= 0 || *bp == '\0')
8330Sstevel@tonic-gate 						*stringp++ = '0';
8340Sstevel@tonic-gate 					else {
8350Sstevel@tonic-gate 						*stringp++ = *bp++;
8360Sstevel@tonic-gate 					}
8370Sstevel@tonic-gate 				}
8380Sstevel@tonic-gate #if FZERO
8390Sstevel@tonic-gate 				if (compat_fzero &! fminus)
8400Sstevel@tonic-gate 					/* Calculate padding zero requirement */
8410Sstevel@tonic-gate 					lzero = width - (strlen(prefix)
8420Sstevel@tonic-gate 					    + (stringp - buf) + rzero);
8430Sstevel@tonic-gate #endif
8440Sstevel@tonic-gate 				p = stringp;
8450Sstevel@tonic-gate 				}
8460Sstevel@tonic-gate 
8470Sstevel@tonic-gate 				bp = &buf[0];
8480Sstevel@tonic-gate fbreak:
8490Sstevel@tonic-gate 				break;
8500Sstevel@tonic-gate 
8510Sstevel@tonic-gate 			case 'G':
8520Sstevel@tonic-gate 			case 'g':
8530Sstevel@tonic-gate 				/*
8540Sstevel@tonic-gate 				 *	g-format.  We play around a bit
8550Sstevel@tonic-gate 				 *	and then jump into e or f, as needed.
8560Sstevel@tonic-gate 				 */
8570Sstevel@tonic-gate 
8580Sstevel@tonic-gate 				/* Establish default precision */
8590Sstevel@tonic-gate 				if (prec < 0)
8600Sstevel@tonic-gate 					prec = 6;
8610Sstevel@tonic-gate 				else if (prec == 0)
8620Sstevel@tonic-gate 					prec = 1;
8630Sstevel@tonic-gate 
8640Sstevel@tonic-gate                                 if (Lsize == 0) {
8650Sstevel@tonic-gate                                 dval = va_arg(args.ap, double);
8660Sstevel@tonic-gate                                 bp = gconvert(dval, prec, fsharp, convertbuffer);
8670Sstevel@tonic-gate                                 } else {
8680Sstevel@tonic-gate                                 GETQVAL;
8690Sstevel@tonic-gate                                 bp = qgconvert(&qval, prec, fsharp, convertbuffer);
8700Sstevel@tonic-gate                                 }
8710Sstevel@tonic-gate 				bp = convertbuffer ;
8720Sstevel@tonic-gate 				if (convertbuffer[0] == '-') {
8730Sstevel@tonic-gate 					prefix = "-" ;
8740Sstevel@tonic-gate 					bp++;
8750Sstevel@tonic-gate 					}
8760Sstevel@tonic-gate 				else if (fplus)
8770Sstevel@tonic-gate 					prefix = "+";
8780Sstevel@tonic-gate 				else if (fblank)
8790Sstevel@tonic-gate 					prefix = " ";
8800Sstevel@tonic-gate 				if (isupper(fcode))
8810Sstevel@tonic-gate 				        { /* Put in a big E for small minds. */
8820Sstevel@tonic-gate 				        for (p = bp ; (*p != NULL) && (*p != 'e') ; p++) ;
8830Sstevel@tonic-gate 				        if (*p == 'e') *p = 'E' ;
8840Sstevel@tonic-gate 				        for (; (*p != NULL) ; p++) ;
8850Sstevel@tonic-gate 				                                /* Find end of string. */
8860Sstevel@tonic-gate 			                }
8870Sstevel@tonic-gate 				else
8880Sstevel@tonic-gate 				        for (p = bp ; *p != NULL ; p++) ;
8890Sstevel@tonic-gate 				                                /* Find end of string. */
8900Sstevel@tonic-gate 				rzero = 0;
8910Sstevel@tonic-gate #if FZERO
8920Sstevel@tonic-gate 				if (compat_fzero & !fminus)
8930Sstevel@tonic-gate 					/* Calculate padding zero requirement */
8940Sstevel@tonic-gate 					lzero = width - (strlen(prefix)
8950Sstevel@tonic-gate 					    + (p - bp) + rzero);
8960Sstevel@tonic-gate #endif
8970Sstevel@tonic-gate 				break ;
8980Sstevel@tonic-gate 
8990Sstevel@tonic-gate #endif
9000Sstevel@tonic-gate 			case 'c':
9010Sstevel@tonic-gate 				buf[0] = va_arg(args.ap, int);
9020Sstevel@tonic-gate 				bp = &buf[0];
9030Sstevel@tonic-gate 				p = bp + 1;
9040Sstevel@tonic-gate 				break;
9050Sstevel@tonic-gate 
9060Sstevel@tonic-gate                         case 's':
9070Sstevel@tonic-gate 				bp = va_arg(args.ap, char *);
9080Sstevel@tonic-gate 				if (prec < 0)
9090Sstevel@tonic-gate 					prec = MAXINT;
9100Sstevel@tonic-gate 				/* avoid *(0) */
9110Sstevel@tonic-gate 				if (bp == NULL)
9120Sstevel@tonic-gate 					bp = nullstr;
9130Sstevel@tonic-gate 				for (n=0; *bp++ != '\0' && n < prec; n++)
9140Sstevel@tonic-gate 					;
9150Sstevel@tonic-gate #if FZERO
9160Sstevel@tonic-gate 				if (compat_fzero &! fminus)
9170Sstevel@tonic-gate 				        lzero = width - n;
9180Sstevel@tonic-gate #endif
9190Sstevel@tonic-gate 				p = --bp;
9200Sstevel@tonic-gate 				bp -= n;
9210Sstevel@tonic-gate 				break;
9220Sstevel@tonic-gate 
9230Sstevel@tonic-gate 			case '\0':
9240Sstevel@tonic-gate 				/* well, what's the punch line? */
9250Sstevel@tonic-gate 				goto out;
9260Sstevel@tonic-gate 
9270Sstevel@tonic-gate 			case 'n':
9280Sstevel@tonic-gate 				svswitch = 1;
9290Sstevel@tonic-gate 				break;
9300Sstevel@tonic-gate 			default:
9310Sstevel@tonic-gate 				p = bp = &fcode;
9320Sstevel@tonic-gate 				p++;
9330Sstevel@tonic-gate 				break;
9340Sstevel@tonic-gate 
9350Sstevel@tonic-gate 			}
9360Sstevel@tonic-gate 			/* Calculate number of padding blanks */
9370Sstevel@tonic-gate 			nblank = width
9380Sstevel@tonic-gate #if FLOAT
9390Sstevel@tonic-gate 				- (rzero < 0? 0: rzero)
9400Sstevel@tonic-gate 				- strlen(suffix)
9410Sstevel@tonic-gate #endif
9420Sstevel@tonic-gate 				- (p - bp)
9430Sstevel@tonic-gate 				- (lzero < 0? 0: lzero)
9440Sstevel@tonic-gate 				- strlen(prefix);
9450Sstevel@tonic-gate 
9460Sstevel@tonic-gate 			/* Blanks on left if required */
9470Sstevel@tonic-gate 			if (!fminus)
9480Sstevel@tonic-gate 				while (--nblank >= 0)
9490Sstevel@tonic-gate 					emitchar(' ');
9500Sstevel@tonic-gate 
9510Sstevel@tonic-gate 			/* Prefix, if any */
9520Sstevel@tonic-gate 			while (*prefix != '\0') {
9530Sstevel@tonic-gate 				emitchar(*prefix);
9540Sstevel@tonic-gate 				prefix++;
9550Sstevel@tonic-gate 			}
9560Sstevel@tonic-gate 
9570Sstevel@tonic-gate 			/* Zeroes on the left */
9580Sstevel@tonic-gate 			while (--lzero >= 0)
9590Sstevel@tonic-gate 				emitchar('0');
9600Sstevel@tonic-gate 
9610Sstevel@tonic-gate 			/* The value itself */
9620Sstevel@tonic-gate 			while (bp < p) {
9630Sstevel@tonic-gate 				emitchar(*bp);
9640Sstevel@tonic-gate 				bp++;
9650Sstevel@tonic-gate 			}
9660Sstevel@tonic-gate #if FLOAT
9670Sstevel@tonic-gate 			/* Zeroes on the right */
9680Sstevel@tonic-gate 			while (--rzero >= 0)
9690Sstevel@tonic-gate 				emitchar('0');
9700Sstevel@tonic-gate 
9710Sstevel@tonic-gate 			/* The suffix */
9720Sstevel@tonic-gate 			while (*suffix != '\0') {
9730Sstevel@tonic-gate 				emitchar(*suffix);
9740Sstevel@tonic-gate 				suffix++;
9750Sstevel@tonic-gate 			}
9760Sstevel@tonic-gate #endif
9770Sstevel@tonic-gate 			/* Blanks on the right if required */
9780Sstevel@tonic-gate 			if (fminus)
9790Sstevel@tonic-gate 				while (--nblank >= 0)
9800Sstevel@tonic-gate 					emitchar(' ');
9810Sstevel@tonic-gate 			/* If %n is seen, save count in argument */
9820Sstevel@tonic-gate 			if (svswitch == 1) {
9830Sstevel@tonic-gate 				long *svcount;
9840Sstevel@tonic-gate 				svcount = va_arg (args.ap, long *);
9850Sstevel@tonic-gate 				*svcount = count;
9860Sstevel@tonic-gate 				svswitch = 0;
9870Sstevel@tonic-gate 			}
9880Sstevel@tonic-gate 		} /* else */
9890Sstevel@tonic-gate 	} while ((c = *cp++) != '\0');	/* do */
9900Sstevel@tonic-gate out:
9910Sstevel@tonic-gate 	file->_ptr = fileptr;
9920Sstevel@tonic-gate 	file->_cnt = filecnt;
9930Sstevel@tonic-gate 	if (file->_flag & (_IONBF | _IOLBF) &&
9940Sstevel@tonic-gate 	    (file->_flag & _IONBF ||
9950Sstevel@tonic-gate 	     memchr((char *)file->_base, '\n', fileptr - file->_base) != NULL))
9960Sstevel@tonic-gate 		(void) _xflsbuf(file);
9970Sstevel@tonic-gate 	return (ferror(file)? EOF: count);
9980Sstevel@tonic-gate }
9990Sstevel@tonic-gate 
1000*722Smuffin #if	defined(__sparc)
10010Sstevel@tonic-gate /*
10020Sstevel@tonic-gate  * We use "double *" instead of "quadruple *" to skip over the pointer to
10030Sstevel@tonic-gate  * long double on the argument list since a pointer is a pointer after all.
10040Sstevel@tonic-gate  */
10050Sstevel@tonic-gate #define SKIPQVAL { \
10060Sstevel@tonic-gate 	(void) va_arg(args.ap, double *); \
10070Sstevel@tonic-gate }
10080Sstevel@tonic-gate #else	/* Sun-3 */
10090Sstevel@tonic-gate #define SKIPQVAL { \
10100Sstevel@tonic-gate 	int iq; \
10110Sstevel@tonic-gate 	for (iq = 0; iq < 4; iq++) \
10120Sstevel@tonic-gate 		(void) va_arg(args.ap, unsigned long); \
10130Sstevel@tonic-gate }
10140Sstevel@tonic-gate #endif
1015*722Smuffin /*
1016*722Smuffin  * This function initializes arglst, to contain the appropriate va_list values
1017*722Smuffin  * for the first MAXARGS arguments.
1018*722Smuffin  */
10190Sstevel@tonic-gate void
_mkarglst(char * fmt,stva_list args,stva_list arglst[])1020*722Smuffin _mkarglst(char *fmt, stva_list args, stva_list arglst[])
10210Sstevel@tonic-gate {
10220Sstevel@tonic-gate 	static char *digits = "01234567890", *skips = "# +-.0123456789h$";
10230Sstevel@tonic-gate 
10240Sstevel@tonic-gate 	enum types {INT = 1, LONG, CHAR_PTR, DOUBLE, LONG_DOUBLE, VOID_PTR,
10250Sstevel@tonic-gate 		LONG_PTR, INT_PTR};
10260Sstevel@tonic-gate 	enum types typelst[MAXARGS], curtype;
10270Sstevel@tonic-gate 	int maxnum, n, curargno, flags;
10280Sstevel@tonic-gate 
10290Sstevel@tonic-gate 	/*
10300Sstevel@tonic-gate 	* Algorithm	1. set all argument types to zero.
10310Sstevel@tonic-gate 	*		2. walk through fmt putting arg types in typelst[].
10320Sstevel@tonic-gate 	*		3. walk through args using va_arg(args.ap, typelst[n])
10330Sstevel@tonic-gate 	*		   and set arglst[] to the appropriate values.
10340Sstevel@tonic-gate 	* Assumptions:	Cannot use %*$... to specify variable position.
10350Sstevel@tonic-gate 	*/
10360Sstevel@tonic-gate 
10370Sstevel@tonic-gate 	(void)memset((void *)typelst, 0, sizeof(typelst));
10380Sstevel@tonic-gate 	maxnum = -1;
10390Sstevel@tonic-gate 	curargno = 0;
10400Sstevel@tonic-gate 	while ((fmt = strchr(fmt, '%')) != 0)
10410Sstevel@tonic-gate 	{
10420Sstevel@tonic-gate 		fmt++;	/* skip % */
10430Sstevel@tonic-gate 		if (fmt[n = strspn(fmt, digits)] == '$')
10440Sstevel@tonic-gate 		{
10450Sstevel@tonic-gate 			curargno = atoi(fmt) - 1;	/* convert to zero base */
10460Sstevel@tonic-gate 			fmt += n + 1;
10470Sstevel@tonic-gate 		}
10480Sstevel@tonic-gate 		flags = 0;
10490Sstevel@tonic-gate 	again:;
10500Sstevel@tonic-gate 		fmt += strspn(fmt, skips);
10510Sstevel@tonic-gate 		switch (*fmt++)
10520Sstevel@tonic-gate 		{
10530Sstevel@tonic-gate 		case '%':	/*there is no argument! */
10540Sstevel@tonic-gate 			continue;
10550Sstevel@tonic-gate 		case 'l':
10560Sstevel@tonic-gate 			flags |= 0x1;
10570Sstevel@tonic-gate 			goto again;
10580Sstevel@tonic-gate 		case 'L':
10590Sstevel@tonic-gate 			flags |= 0x8;
10600Sstevel@tonic-gate 			goto again;
10610Sstevel@tonic-gate 		case '*':	/* int argument used for value */
10620Sstevel@tonic-gate 			flags |= 0x2;
10630Sstevel@tonic-gate 			curtype = INT;
10640Sstevel@tonic-gate 			break;
10650Sstevel@tonic-gate 		case 'e':
10660Sstevel@tonic-gate 		case 'E':
10670Sstevel@tonic-gate 		case 'f':
10680Sstevel@tonic-gate 		case 'g':
10690Sstevel@tonic-gate 		case 'G':
10700Sstevel@tonic-gate 			if (flags & 0x8)
10710Sstevel@tonic-gate 				curtype = LONG_DOUBLE;
10720Sstevel@tonic-gate 			else
10730Sstevel@tonic-gate 				curtype = DOUBLE;
10740Sstevel@tonic-gate 			break;
10750Sstevel@tonic-gate 		case 's':
10760Sstevel@tonic-gate 			curtype = CHAR_PTR;
10770Sstevel@tonic-gate 			break;
10780Sstevel@tonic-gate 		case 'p':
10790Sstevel@tonic-gate 			curtype = VOID_PTR;
10800Sstevel@tonic-gate 			break;
10810Sstevel@tonic-gate 		case 'n':
10820Sstevel@tonic-gate 			if (flags & 0x1)
10830Sstevel@tonic-gate 				curtype = LONG_PTR;
10840Sstevel@tonic-gate 			else
10850Sstevel@tonic-gate 				curtype = INT_PTR;
10860Sstevel@tonic-gate 			break;
10870Sstevel@tonic-gate 		default:
10880Sstevel@tonic-gate 			if (flags & 0x1)
10890Sstevel@tonic-gate 				curtype = LONG;
10900Sstevel@tonic-gate 			else
10910Sstevel@tonic-gate 				curtype = INT;
10920Sstevel@tonic-gate 			break;
10930Sstevel@tonic-gate 		}
10940Sstevel@tonic-gate 		if (curargno >= 0 && curargno < MAXARGS)
10950Sstevel@tonic-gate 		{
10960Sstevel@tonic-gate 			typelst[curargno] = curtype;
10970Sstevel@tonic-gate 			if (maxnum < curargno)
10980Sstevel@tonic-gate 				maxnum = curargno;
10990Sstevel@tonic-gate 		}
11000Sstevel@tonic-gate 		curargno++;	/* default to next in list */
11010Sstevel@tonic-gate 		if (flags & 0x2)	/* took care of *, keep going */
11020Sstevel@tonic-gate 		{
11030Sstevel@tonic-gate 			flags ^= 0x2;
11040Sstevel@tonic-gate 			goto again;
11050Sstevel@tonic-gate 		}
11060Sstevel@tonic-gate 	}
11070Sstevel@tonic-gate 	for (n = 0 ; n <= maxnum; n++)
11080Sstevel@tonic-gate 	{
11090Sstevel@tonic-gate 		arglst[n] = args;
11100Sstevel@tonic-gate 		if (typelst[n] == 0)
11110Sstevel@tonic-gate 			typelst[n] = INT;
11120Sstevel@tonic-gate 
11130Sstevel@tonic-gate 		switch (typelst[n])
11140Sstevel@tonic-gate 		{
11150Sstevel@tonic-gate 		case INT:
11160Sstevel@tonic-gate 			va_arg(args.ap, int);
11170Sstevel@tonic-gate 			break;
11180Sstevel@tonic-gate 		case LONG:
11190Sstevel@tonic-gate 			va_arg(args.ap, long);
11200Sstevel@tonic-gate 			break;
11210Sstevel@tonic-gate 		case CHAR_PTR:
11220Sstevel@tonic-gate 			va_arg(args.ap, char *);
11230Sstevel@tonic-gate 			break;
11240Sstevel@tonic-gate 		case DOUBLE:
11250Sstevel@tonic-gate 			va_arg(args.ap, double);
11260Sstevel@tonic-gate 			break;
11270Sstevel@tonic-gate 		case LONG_DOUBLE:
11280Sstevel@tonic-gate 			SKIPQVAL
11290Sstevel@tonic-gate 			break;
11300Sstevel@tonic-gate 		case VOID_PTR:
11310Sstevel@tonic-gate 			va_arg(args.ap, void *);
11320Sstevel@tonic-gate 			break;
11330Sstevel@tonic-gate 		case LONG_PTR:
11340Sstevel@tonic-gate 			va_arg(args.ap, long *);
11350Sstevel@tonic-gate 			break;
11360Sstevel@tonic-gate 		case INT_PTR:
11370Sstevel@tonic-gate 			va_arg(args.ap, int *);
11380Sstevel@tonic-gate 			break;
11390Sstevel@tonic-gate 		}
11400Sstevel@tonic-gate 	}
11410Sstevel@tonic-gate }
11420Sstevel@tonic-gate 
11430Sstevel@tonic-gate /*
11440Sstevel@tonic-gate  * This function is used to find the va_list value for arguments whose
11450Sstevel@tonic-gate  * position is greater than MAXARGS.  This function is slow, so hopefully
11460Sstevel@tonic-gate  * MAXARGS will be big enough so that this function need only be called in
11470Sstevel@tonic-gate  * unusual circumstances.
11480Sstevel@tonic-gate  * pargs is assumed to contain the value of arglst[MAXARGS - 1].
11490Sstevel@tonic-gate  */
11500Sstevel@tonic-gate void
_getarg(char * fmt,stva_list * pargs,int argno)1151*722Smuffin _getarg(char *fmt, stva_list *pargs, int argno)
11520Sstevel@tonic-gate {
11530Sstevel@tonic-gate 	static char *digits = "01234567890", *skips = "# +-.0123456789h$";
11540Sstevel@tonic-gate 	int i, n, curargno, flags;
11550Sstevel@tonic-gate 	char	*sfmt = fmt;
11560Sstevel@tonic-gate 	int	found = 1;
11570Sstevel@tonic-gate 
11580Sstevel@tonic-gate 	curargno = i = MAXARGS;
11590Sstevel@tonic-gate 	while (found)
11600Sstevel@tonic-gate 	{
11610Sstevel@tonic-gate 		fmt = sfmt;
11620Sstevel@tonic-gate 		found = 0;
11630Sstevel@tonic-gate 		while ((i != argno) && (fmt = strchr(fmt, '%')) != 0)
11640Sstevel@tonic-gate 		{
11650Sstevel@tonic-gate 			fmt++;	/* skip % */
11660Sstevel@tonic-gate 			if (fmt[n = strspn(fmt, digits)] == '$')
11670Sstevel@tonic-gate 			{
11680Sstevel@tonic-gate 				curargno = atoi(fmt);
11690Sstevel@tonic-gate 				fmt += n + 1;
11700Sstevel@tonic-gate 			}
11710Sstevel@tonic-gate 
11720Sstevel@tonic-gate 			/* find conversion specifier for next argument */
11730Sstevel@tonic-gate 			if (i != curargno)
11740Sstevel@tonic-gate 			{
11750Sstevel@tonic-gate 				curargno++;
11760Sstevel@tonic-gate 				continue;
11770Sstevel@tonic-gate 			} else
11780Sstevel@tonic-gate 				found = 1;
11790Sstevel@tonic-gate 			flags = 0;
11800Sstevel@tonic-gate 		again:;
11810Sstevel@tonic-gate 			fmt += strspn(fmt, skips);
11820Sstevel@tonic-gate 			switch (*fmt++)
11830Sstevel@tonic-gate 			{
11840Sstevel@tonic-gate 			case '%':	/*there is no argument! */
11850Sstevel@tonic-gate 				continue;
11860Sstevel@tonic-gate 			case 'l':
11870Sstevel@tonic-gate 				flags |= 0x1;
11880Sstevel@tonic-gate 				goto again;
11890Sstevel@tonic-gate 			case 'L':
11900Sstevel@tonic-gate 				flags |= 0x8;
11910Sstevel@tonic-gate 				goto again;
11920Sstevel@tonic-gate 			case '*':	/* int argument used for value */
11930Sstevel@tonic-gate 				flags |= 0x2;
11940Sstevel@tonic-gate 				(void)va_arg((*pargs).ap, int);
11950Sstevel@tonic-gate 				break;
11960Sstevel@tonic-gate 			case 'e':
11970Sstevel@tonic-gate 			case 'E':
11980Sstevel@tonic-gate 			case 'f':
11990Sstevel@tonic-gate 			case 'g':
12000Sstevel@tonic-gate 			case 'G':
12010Sstevel@tonic-gate 				if (flags & 0x8) {
12020Sstevel@tonic-gate #define	args	(*pargs)
12030Sstevel@tonic-gate 					SKIPQVAL
12040Sstevel@tonic-gate #undef	args
12050Sstevel@tonic-gate 				}
12060Sstevel@tonic-gate 				else
12070Sstevel@tonic-gate 					(void)va_arg((*pargs).ap, double);
12080Sstevel@tonic-gate 				break;
12090Sstevel@tonic-gate 			case 's':
12100Sstevel@tonic-gate 				(void)va_arg((*pargs).ap, char *);
12110Sstevel@tonic-gate 				break;
12120Sstevel@tonic-gate 			case 'p':
12130Sstevel@tonic-gate 				(void)va_arg((*pargs).ap, void *);
12140Sstevel@tonic-gate 				break;
12150Sstevel@tonic-gate 			case 'n':
12160Sstevel@tonic-gate 				if (flags & 0x1)
12170Sstevel@tonic-gate 					(void)va_arg((*pargs).ap, long *);
12180Sstevel@tonic-gate 				else
12190Sstevel@tonic-gate 					(void)va_arg((*pargs).ap, int *);
12200Sstevel@tonic-gate 				break;
12210Sstevel@tonic-gate 			default:
12220Sstevel@tonic-gate 				if (flags & 0x1)
12230Sstevel@tonic-gate 					(void)va_arg((*pargs).ap, long int);
12240Sstevel@tonic-gate 				else
12250Sstevel@tonic-gate 					(void)va_arg((*pargs).ap, int);
12260Sstevel@tonic-gate 				break;
12270Sstevel@tonic-gate 			}
12280Sstevel@tonic-gate 			i++;
12290Sstevel@tonic-gate 			curargno++;	/* default to next in list */
12300Sstevel@tonic-gate 			if (flags & 0x2)	/* took care of *, keep going */
12310Sstevel@tonic-gate 			{
12320Sstevel@tonic-gate 				flags ^= 0x2;
12330Sstevel@tonic-gate 				goto again;
12340Sstevel@tonic-gate 			}
12350Sstevel@tonic-gate 		}
12360Sstevel@tonic-gate 
12370Sstevel@tonic-gate 		/* missing specifier for parameter, assume parameter is an int */
12380Sstevel@tonic-gate 		if (!found && i != argno) {
12390Sstevel@tonic-gate 			(void)va_arg((*pargs).ap, int);
12400Sstevel@tonic-gate 			i++;
12410Sstevel@tonic-gate 			curargno++;
12420Sstevel@tonic-gate 			found = 1;
12430Sstevel@tonic-gate 		}
12440Sstevel@tonic-gate 	}
12450Sstevel@tonic-gate }
12460Sstevel@tonic-gate 
12470Sstevel@tonic-gate 
12480Sstevel@tonic-gate /*
12490Sstevel@tonic-gate  * parse a string, mini parse
12500Sstevel@tonic-gate  */
12510Sstevel@tonic-gate static char *
_check_dol(char * s,int * val)1252*722Smuffin _check_dol(char *s, int *val)
12530Sstevel@tonic-gate {
12540Sstevel@tonic-gate 	char *os;	/* save old string */
12550Sstevel@tonic-gate 	int tmp_val = 0;
12560Sstevel@tonic-gate 	int flag = 0;
12570Sstevel@tonic-gate 
12580Sstevel@tonic-gate 	while (isdigit (*s)) {
12590Sstevel@tonic-gate 		++flag;
12600Sstevel@tonic-gate 		tmp_val = tmp_val*10 + *s - '0';
12610Sstevel@tonic-gate 		s++;
12620Sstevel@tonic-gate 	}
12630Sstevel@tonic-gate 	if (flag == 0)
12640Sstevel@tonic-gate 		return ((char *)NULL);
12650Sstevel@tonic-gate 	if (*s == '$') {
12660Sstevel@tonic-gate 		*val = tmp_val;
12670Sstevel@tonic-gate 		return(++s);
12680Sstevel@tonic-gate 	}
12690Sstevel@tonic-gate 	return ((char *)NULL);
12700Sstevel@tonic-gate }
1271