Coherent4.2.10/tboot/printf.c
/*
* printf.c
*/
/*
* For indirecting and incrementing argument pointer.
*/
#define ind(p, t) (*((t *) p))
#define inc(t1, t2) ((sizeof(t2 *)+sizeof(t1)-1) / sizeof(t1))
/*
* Table for printing out digits.
*/
char digtab[] ={
'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
};
/*
* A simple printf.
*/
printf(fp, a1)
register char *fp;
{
char * cp;
register int c;
register unsigned *ap;
int lflag;
ap = (char *)&a1;
for (;;) {
while ((c=*fp++) != '%') {
if (c == '\0')
return;
putchar(c);
}
lflag = 0;
if ( *fp == 'l' ) {
lflag = 1;
fp++;
}
switch ( c = *fp++ ) {
case 'c':
putchar(*ap++);
continue;
case 'd':
if ( lflag == 0 ) {
if ( ((int)(*ap)) < 0 ) {
putchar('-');
printn( -((long) ((int)(*ap))), 10 );
}
else
printn( ((long)(*ap)), 10 );
ap++;
continue;
}
/* fall through */
case 'D':
if ( *((long *)(ap)) < 0 ) {
putchar('-');
printn( - *((long *)(ap)), 10 );
}
else
printn( *((long *)(ap)), 10 );
((long *)(ap))++;
continue;
case 'o':
if ( lflag == 0 ) {
printn( ((long)(*ap)), 8);
ap++;
continue;
}
/* fall through */
case 'O':
printf( *((long *)(ap)), 8 );
((long *)(ap))++;
continue;
case 'r':
ap = *((int **) ap);
fp = ind(ap, char *);
ap += inc(int, char *);
continue;
case 's':
cp = ind(ap, char *);
ap += inc(int, char *);
while ((c=*cp++) != '\0')
putchar(c);
continue;
case 'x':
if ( lflag == 0 ) {
printn( ((long)(*ap)), 16 );
ap++;
continue;
}
/* fall through */
case 'X':
printn( *((long *)(ap)), 16 );
((long *)(ap))++;
continue;
case 'u':
if ( lflag == 0 ) {
printn( ((long)(*ap)), 10);
ap++;
continue;
}
/* fall through */
case 'U':
printn( *((long *)(ap)), 10 );
((long *)(ap))++;
continue;
case 'p':
if (sizeof(char *) > sizeof(int)) {
printn( ((long)(*ap)), 16);
putchar(':');
ap++;
}
printn( ((long)(*ap)), 16);
ap++;
continue;
default:
putchar(c);
continue;
}
}
}
/*
* Print out the unsigned long `v' in the base `b'.
*/
printn( v, b )
unsigned long v;
{
unsigned long n;
if (n=v/b)
printn(n, b);
putchar(digtab[v%b]);
}