h25543
s 00209/00000/00000
d D 1.1 82/08/03 08:43:52 cecily 1 0
e
u
U
t
T
I 1
/*
 *	_doprnt - in C, based on the ancient 'printf'
 */

#include "stdio.h"

#define	BIG	32	/* something big enough to hold any repn of a number */

_doprnt(afmt, argp, file)
char *afmt;
register int *argp;
FILE *file;
{
	register char *fmt, *p, *bp;
	register int c, n;
	register int left, zfill, width, ndigs, prec;
	char *_print();
	char *_prflt();
	char buff[128];

	/*
	 * argp is used to step along list of arguments, since
	 * the number of args is not known in advance.
	 */
	p = buff;

	for (fmt = afmt; c = *fmt; fmt++) {
		/*
		 * Copy format string to output string until
		 * escape character is encountered.
		 */
		if (c != '%') {
			*p++ = c;
			continue;
		}
		if (p > buff)
			_strout(buff, p-buff, 0, file);
		/* '-' means left-justification of field. */
		left = 0;
		if (*++fmt == '-') {
			left++;
			fmt++;
		}
		/* Allow for zero or blank fill, sorry COBOL, no '*' yet */
		zfill = ' ';
		if (*fmt == '0') {
			zfill = '0';
			fmt++;
		}
		/* Convert width field if present. */
		n = 0;
		if (*fmt == '*') {
			n = *argp++;
			c = *++fmt;
		} else while ((c = *fmt) <= '9' && c >= '0') {
			n =* 10;
			n =+ c - '0';
			fmt++;
		}
		width = n;
		/* Convert precision field if present. */
		n = 0;
		prec = 0;
		if (c == '.') {
			prec++;
			if ((c = *++fmt) == '*') {
				n = *argp++;
				c = *++fmt;
			} else while (c <= '9' && c >= '0') {
				n =* 10;
				n =+ c - '0';
				c = *++fmt;
			}
		}
		ndigs = n;
		/*
		 * Print the argument in the requested format.
		 */
		bp = p = buff;
		switch (c) {

			/* floating point types */
		case 'e':
		case 'f':
		case 'g':
			p = _prflt(*((double*)argp)++, buff, ndigs, prec, c);
			break;

			/* character & string types */
		case 'c':
			if (c = *argp++ & 0377)
				*p++ = c;
			zfill = ' ';
			break;

		case 's':
			bp = p = *((char**)argp)++;
			if (p) while (*p)
				p++;
			zfill = ' ';
			break;

			/* remote format string */
		case 'r':
			fmt = *((char**)argp)++;
			fmt--;
			continue;

			/* %t for 'tab' may someday go here */

			/* integer, short, unsigned, long, ... */
		case 'd':
			bp = _print((long)*argp++, p += BIG, ndigs, 1, 10);
			break;
		case 'D':
			bp = _print(*((long*)argp)++, p += BIG, ndigs, 1, 10);
			break;
		case 'o':
			bp = _print((long)*argp++, p += BIG, ndigs, 0, 8);
			break;
		case 'O':
			bp = _print(*((long*)argp)++, p += BIG, ndigs, 0, 8);
			break;
		case 'x':
			bp = _print((long)*argp++, p += BIG, ndigs, 0, 16);
			break;
		case 'X':
			bp = _print(*((long*)argp)++, p += BIG, ndigs, 0, 16);
			break;
		case 'u':
			bp = _print((long)*((unsigned*)argp)++, p += BIG, ndigs, 0, 10);
			break;
		case 'U':
			bp = _print(*((long unsigned *)argp)++, p += BIG, ndigs, 0, 10);
			break;
		case 'l': case 'L':
			switch (*++fmt) {
			case 'd':
				bp = _print(*((long*)argp)++, p += BIG, ndigs, 1, 10);
				break;
			case 'o':
				bp = _print(*((long*)argp)++, p += BIG, ndigs, 0, 8);
				break;
			case 'x':
				bp = _print(*((long*)argp)++, p += BIG, ndigs, 0, 16);
				break;
			case 'u':
				bp = _print(*((long*)argp)++, p += BIG, ndigs, 0, 10);
				break;
			default:
				if (c == 'l')
					bp = _print((long)*((unsigned*)argp)++, p += BIG, ndigs, 0, 10);
				else
					bp = _print(*((long unsigned *)argp)++, p += BIG, ndigs, 0, 10);
				--fmt;
				break;
			}
			break;

			/* anything else is a literal */
		default:
			if (c)
				*p++ = c;
			break;
		}

		/* now to calculate fill etc */

		n = p - bp;
		if (*fmt == 's' && prec && n > ndigs) {
			n = ndigs;
			p = bp + n;
		}
		if ((n -= width) > 0)
			n = 0;
		if (left)
			n = -n;
		_strout(bp, p-bp, n, file, zfill);
		p = buff;
	} /* end 'for' */
	if (p > buff)
		_strout(buff, p-buff, 0, file);
}

static char *_print(num, p, zero, sgnd, base)
register long num;
register char *p;
register int sgnd;		/* != 0 ==> signed repn wanted */
register unsigned base;
{
	register unsigned long n;
	static char prfhex[]	= { "0123456789ABCDEF" };		/* Hexadecimal digits */

	if (sgnd && num < 0)
		n = (unsigned long) -num;
	else
		n = (unsigned long) num;

	do
		*--p = prfhex[ n % base ];
	while ( n /= base );

	if (zero && num != 0)
		*--p = '0';			/* bloody stupid this is */
	if (sgnd && num < 0)
		*--p = '-';

	return(p);
}
E 1
