jai@lab.ultra.nyu.edu (Benchiao Jai) (02/24/91)
/*
* three compile time options:
* STACKUP fetch arguments using *p-- instead of *p++
* NO_LONGD %d and %ld/%D are equal
* NO_FLOAT abort on %e, %f and %g
*/
#define NO_FLOAT
#define MAXDIG 11 /* 32 bits in radix 8 */
static 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) != 0);
i = p + MAXDIG - q;
do
*p++ = *q++;
while (--i);
return(p);
}
#ifndef NO_LONGD
static 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) != 0);
i = p + MAXDIG - q;
do
*p++ = *q++;
while (--i);
return(p);
}
#endif
#ifdef STACKUP
#define GETARG(typ) *((typ *)args)--
#else
#define GETARG(typ) *((typ *)args)++
#endif STACKUP
printk(fmt, arg1)
register char *fmt;
{
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, GETARG(long), c);
break;
}
#endif
p = itoa(p, 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, l, 10);
break;
}
#endif
if ((i = GETARG(int)) < 0) {
*p++ = '-';
i = -i;
}
p = itoa(p, i, 10);
break;
case 'e':
case 'f':
case 'g':
zfill = ' ';
*p++ = '?';
break;
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--;
}
}
}