Minix1.5/lib/other/printk.c

Compare this file to the similar file:
Show the results in this format:

#include <lib.h>
#include <stdarg.h>

/* three compile time options:
 *	NO_LONGD	%d and %ld/%D are equal
 *	NO_FLOAT	abort on %e, %f and %g
 */

#define	NO_FLOAT

#ifdef NO_FLOAT
#define	MAXDIG		11	/* 32 bits in radix 8 */
#else
#define	MAXDIG		128	/* this must be enough */
#endif

_PROTOTYPE( void putc, (int ch));	/* user-supplied, should be putk */

PRIVATE _PROTOTYPE( char *_itoa, (char *p, unsigned num, int radix));
#ifndef NO_LONGD
PRIVATE _PROTOTYPE( char *ltoa, (char *p, unsigned long num, int radix));
#endif

PRIVATE char *_itoa(p, num, radix)
register char *p;
register unsigned num;
register radix;
{
  register i;
  register char *q;

  q = p + MAXDIG;
  do {
        i = (int) (num % radix);
        i += '0';
        if (i > '9') i += 'A' - '0' - 10;
        *--q = i;
  } while (num = num / radix);
  i = p + MAXDIG - q;
  do
        *p++ = *q++;
  while (--i);
  return(p);
}

#ifndef NO_LONGD
PRIVATE char *ltoa(p, num, radix)
register char *p;
register unsigned long num;
register radix;
{
  register i;
  register char *q;

  q = p + MAXDIG;
  do {
	i = (int) (num % radix);
	i += '0';
	if (i > '9') i += 'A' - '0' - 10;
	*--q = i;
  } while (num = num / radix);
  i = p + MAXDIG - q;
  do
	*p++ = *q++;
  while (--i);
  return(p);
}

#endif

#ifndef NO_FLOAT
extern char *_ecvt();
extern char *_fcvt();
extern char *_gcvt();
#endif

#define	GETARG(typ)	va_arg(args, typ)

void printk(fmt, arg1)
register char *fmt;
int arg1;
{
  char buf[MAXDIG + 1];		/* +1 for sign */
  register int *args = &arg1;
  register char *p;
  register char *s;
  register c;
  register i;
  register short width;
  register short ndigit;
  register ndfnd;
  register ljust;
  register zfill;
#ifndef NO_LONGD
  register lflag;
  register long l;
#endif

  for (;;) {
	c = *fmt++;
	if (c == 0) return;
	if (c != '%') {
		putc(c);
		continue;
	}
	p = buf;
	s = buf;
	ljust = 0;
	if (*fmt == '-') {
		fmt++;
		ljust++;
	}
	zfill = ' ';
	if (*fmt == '0') {
		fmt++;
		zfill = '0';
	}
	for (width = 0;;) {
		c = *fmt++;
		if (c >= '0' && c <= '9')
			c -= '0';
		else if (c == '*')
			c = GETARG(int);
		else
			break;
		width *= 10;
		width += c;
	}
	ndfnd = 0;
	ndigit = 0;
	if (c == '.') {
		for (;;) {
			c = *fmt++;
			if (c >= '0' && c <= '9')
				c -= '0';
			else if (c == '*')
				c = GETARG(int);
			else
				break;
			ndigit *= 10;
			ndigit += c;
			ndfnd++;
		}
	}
#ifndef NO_LONGD
	lflag = 0;
#endif
	if (c == 'l' || c == 'L') {
#ifndef NO_LONGD
		lflag++;
#endif
		if (*fmt) c = *fmt++;
	}
	switch (c) {
	    case 'X':
#ifndef NO_LONGD
		lflag++;
#endif
	    case 'x':
		c = 16;
		goto oxu;
	    case 'U':
#ifndef NO_LONGD
		lflag++;
#endif
	    case 'u':
		c = 10;
		goto oxu;
	    case 'O':
#ifndef NO_LONGD
		lflag++;
#endif
	    case 'o':
		c = 8;
  oxu:
#ifndef NO_LONGD
		if (lflag) {
			p = ltoa(p, (unsigned long)GETARG(long), c);
			break;
		}
#endif
		p = _itoa(p, (unsigned int)GETARG(int), c);
		break;
	    case 'D':
#ifndef NO_LONGD
		lflag++;
#endif
	    case 'd':
#ifndef NO_LONGD
		if (lflag) {
			if ((l = GETARG(long)) < 0) {
				*p++ = '-';
				l = -l;
			}
			p = ltoa(p, (unsigned long)l, 10);
			break;
		}
#endif
		if ((i = GETARG(int)) < 0) {
			*p++ = '-';
			i = -i;
		}
		p = _itoa(p, (unsigned int)i, 10);
		break;
#ifdef NO_FLOAT
	    case 'e':
	    case 'f':
	    case 'g':
		zfill = ' ';
		*p++ = '?';
		break;
#else
	    case 'e':
		if (ndfnd == 0) ndigit = 6;
		ndigit++;
		p = _ecvt(p, GETARG(double), ndigit);
		break;
	    case 'f':
		if (ndfnd == 0) ndigit = 6;
		p = _fcvt(p, GETARG(double), ndigit);
		break;
	    case 'g':
		if (ndfnd == 0) ndigit = 6;
		p = _gcvt(p, GETARG(double), ndigit);
		break;
#endif
	    case 'c':
		zfill = ' ';
		*p++ = GETARG(int);
		break;
	    case 's':
		zfill = ' ';
		if ((s = GETARG(char *)) == 0) s = "(null)";
		if (ndigit == 0) ndigit = 32767;
		for (p = s; *p && --ndigit >= 0; p++);
		break;
	    default:	*p++ = c;	  		break;
	}
	i = p - s;
	if ((width -= i) < 0) width = 0;
	if (ljust == 0) width = -width;
	if (width < 0) {
		if (*s == '-' && zfill == '0') {
			putc(*s++);
			i--;
		}
		do
			putc(zfill);
		while (++width != 0);
	}
	while (--i >= 0) putc(*s++);
	while (width) {
		putc(zfill);
		width--;
	}
  }
}