Coherent4.2.10/coh.386/printf.c
/* $Header: /ker/coh.386/RCS/printf.c,v 2.5 93/10/29 00:55:29 nigel Exp Locker: nigel $ */
/* (lgl-
* The information contained herein is a trade secret of Mark Williams
* Company, and is confidential information. It is provided under a
* license agreement, and may be copied or disclosed only under the
* terms of that agreement. Any reproduction or disclosure of this
* material without the express written authorization of Mark Williams
* Company or persuant to the license agreement is unlawful.
*
* COHERENT Version 2.3.37
* Copyright (c) 1982, 1983, 1984.
* An unpublished work by Mark Williams Company, Chicago.
* All rights reserved.
-lgl) */
/*
* Print formatted.
*
* $Log: printf.c,v $
* Revision 2.5 93/10/29 00:55:29 nigel
* R98 (aka 4.2 Beta) prior to removing System Global memory
*
* Revision 2.4 93/08/19 03:26:42 nigel
* Nigel's r83 (Stylistic cleanup)
*
* Revision 2.2 93/07/26 14:29:00 nigel
* Nigel's R80
*
* Revision 1.2 92/01/06 12:00:01 hal
* Compile with cc.mwc.
*
* Revision 1.1 88/03/24 16:14:13 src
* Initial revision
*
* 87/09/20 Allan Cornish /usr/src/sys/coh/printf.c
* %U now correctly displays in base 10 rather than base 16.
*
* 86/12/16 Allan Cornish /usr/src/sys/coh/printf.c
* Added '%D' and '%X options to printf().
*/
#include <stddef.h>
/*
* 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'
};
/*
* Print out the unsigned long `v' in the base `b'.
*/
static void
printn( v, b )
unsigned long v;
int b;
{
unsigned long n;
if ((n=v/b) != 0)
printn(n, b);
putchar(digtab[v%b]);
}
/*
* A simple printf.
*/
void
printf(fp, a1)
char *fp;
int a1;
{
char * cp;
int c;
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 *);
if (cp == NULL)
cp = "{NULL}";
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;
}
}
}