Files
Digital-Research-Source-Code/CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102a/libf/printf.c
Sepp J Morris 31738079c4 Upload
Digital Research
2020-11-06 18:50:37 +01:00

302 lines
4.5 KiB
C

/*
Copyright 1983
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
@(#)printf.c 1.2 10/19/83
*/
#include <stdio.h>
struct {
int word0;
int word1;
};
#define BUFSIZ 80
FILE *__stream;
static char *__str;
static char **_p;
extern char *__prtshort(), *__prtld();
char *etoa();
char *ftoa();
char *petoa();
char *pftoa();
printf(arg1,arg2,arg3)
char *arg1, *arg2, *arg3;
{
FILE *fp;
if( arg1 == -1 ) {
/*
* printf( ((char *)-1), buf, fmt...) is sprintf(buf, fmt...)
*/
__str = arg2;
_p = &arg3;
*__str = NULL;
__doprint(1);
*__str = NULL;
}
else if( arg1 < _NUFILE ) {
/*
* printf( ((char *)fd), fmt...) is fprintf( fd to fp, fmt,...)
*/
fp = fdopen( (arg1).word1 , "w");
__stream = fp;
_p = &arg2;
__doprintf(0);
fflush(fp);
fp->_flag = 0;
fp->_nextp = fp->_base = NULL;
}
else {
__stream = stdout;
_p = &arg1;
__doprintf(0);
}
}
fprintf(fp, plist)
FILE *fp;
char *plist;
{
if( (fp->_flag&(_WMODE|_UPDATE|_APPEND)) == 0 )
return;
__stream = fp;
_p = &plist;
__doprintf(0);
}
sprintf(s, plist)
char *s, *plist;
{
__str = s;
_p = &plist;
__doprint(1);
*__str = NULL;
}
__doprint(mode)
int mode;
{
register char *fmt, c;
register int *pi;
char buf[BUFSIZ];
int width, prec, left, longf, n, len, prepend;
char padchar;
char *s;
auto (*fn)();
fmt = *_p++;
pi = _p;
while( c = *fmt++ ) {
_p = pi;
if( c != '%' ) {
__putch(mode, c);
continue;
}
prepend = left = 0;
if( (c = *fmt++) == '-' ) {
c = *fmt++;
left++;
}
if (c == '#') { /* [vlh] 26 jul 83 */
c = *fmt++;
prepend++;
}
padchar = ' ';
if( c == '0' ) {
padchar = c;
c = *fmt++;
}
width = -1;
while( c >= '0' && c <= '9' ) {
if( width < 0 )
width = 0;
width = width * 10 + (c - '0');
c = *fmt++;
}
if (c == '*') { /* [vlh] 26 jul 83 */
c = *fmt++;
width = *pi++;
}
prec = -1;
if( c == '.' ) {
prec = 0;
c = *fmt++;
}
while( c >= '0' && c <= '9' ) {
prec = prec * 10 + (c - '0');
c = *fmt++;
}
if (c == '*') { /* [vlh] 26 jul 83 */
c = *fmt++;
prec = *pi++;
}
longf = 0;
if( c == 'l' ) {
longf++;
c = *fmt++;
}
/*
* we now have all the prelims out of the way;
* let's see what we want to print
*/
s = buf;
switch (c) {
case 'd': /* decimal signed */
case 'D':
if( longf )
fn = __prtld;
else
fn = __prtshort;
__prtint(pi++, buf, 10, 1, fn, 0);
if( longf )
pi++;
break;
case 'u': /* decimal unsigned */
case 'U':
__prtint(pi++, buf, 10, 0, __prtshort, 0);
break;
case 'o': /* octal unsigned */
case 'O':
if (prepend) /* [vlh] 26 jul 83 */
__putch(mode, '0');
if( longf )
fn = __prtld;
else
fn = __prtshort;
__prtint(pi++, buf, 8, 0, fn, 0);
if( longf )
pi++;
break;
case 'x': /* hexadecimal unsigned */
case 'X':
if (prepend) { /* [vlh] 26 jul 83 */
__putch(mode, '0');
__putch(mode, 'x');
}
if( longf )
fn = __prtld;
else
fn = __prtshort;
__prtint(pi++, buf, 16, 0, fn, c == 'X');
if( longf )
pi++;
break;
case 's': /* string */
case 'S':
s = *_p++;
pi = _p;
break;
case 'c': /* character */
case 'C':
n = *pi++;
buf[0] = n;
buf[1] = '\0';
break;
case 'e': /* exponential */
case 'E':
petoa(pi, buf, prec);
pi += 2;
prec = -1;
break;
case 'f': /* floating */
case 'F':
pftoa(pi, buf, prec);
pi += 2;
prec = -1;
break;
case 'g': /* e or f */
case 'G':
pftoa(pi, buf, prec);
if (strlen(buf) > (7 + prec) ) /* smallest fp string */
petoa(pi, buf, prec);
pi += 2;
prec = -1;
break;
default: /* just print the character */
__putch(mode, c);
continue;
}
len = __length(s);
if( prec < len && prec >= 0 )
len = prec;
n = width - len;
if( !left ) {
if( padchar != ' ' && *s == '-' ) {
len--;
__putch(mode, *s++);
}
while( n-- > 0 )
__putch(mode, padchar);
}
while( len-- )
__putch(mode, *s++);
while( n-- > 0 )
__putch(mode, padchar);
}
if( mode == 0 && (__stream->_flag&_UNBUF) )
fflush(__stream);
}
__putch(mode, c)
int mode;
char c;
{
if( mode )
*__str++ = c;
else
putc(c,__stream);
return (c);
}
char *
pftoa(addr,buf,prec)
float *addr;
char *buf;
int prec;
{
float fp;
if (prec<0)
prec = 6;
fp = *addr;
return( ftoa(fp, buf, prec) );
}
char *
petoa(addr,buf,prec)
float *addr;
char *buf;
int prec;
{
float fp;
if (prec<0)
prec = 6;
fp = *addr;
return( etoa(fp, buf, prec) );
}