243 lines
3.9 KiB
C
243 lines
3.9 KiB
C
|
#include <stdio.h>
|
||
|
|
||
|
#ifndef NOFLOAT
|
||
|
extern char *_pfloat();
|
||
|
extern char *_pscien();
|
||
|
#endif
|
||
|
|
||
|
static int *nextarg ;
|
||
|
|
||
|
static geta(p,size) int *p; int size; {
|
||
|
/* get 'size' words from arglist */
|
||
|
|
||
|
if ( (int *)&p - &size >0 ) {
|
||
|
p += size;
|
||
|
while ( size-- ) {
|
||
|
*--p = *nextarg--;
|
||
|
}
|
||
|
} else {
|
||
|
while ( size-- ) {
|
||
|
*p++ = *nextarg++ ;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
# define wsize(par) ( (sizeof par) / sizeof (int) )
|
||
|
|
||
|
|
||
|
static char *gnum(f,ip) register char *f; int *ip; {
|
||
|
register int i,c;
|
||
|
|
||
|
if (*f == '*') {
|
||
|
geta(ip,wsize(i)) ;
|
||
|
f++;
|
||
|
} else {
|
||
|
i = 0;
|
||
|
while ((c = *f - '0') >= 0 && c <= 9) {
|
||
|
i = i*10 + c;
|
||
|
f++;
|
||
|
}
|
||
|
*ip = i;
|
||
|
}
|
||
|
return(f);
|
||
|
}
|
||
|
|
||
|
#define signbit(par) (1L<<(sizeof par*8 -1))
|
||
|
|
||
|
static char *i_compute(val,base,s) unsigned val; char *s; {
|
||
|
int c;
|
||
|
|
||
|
c= val % base ;
|
||
|
val/= base ;
|
||
|
if (val)
|
||
|
s = i_compute(val,base,s);
|
||
|
*s++ = (c>9 ? c-10+'a' : c+'0');
|
||
|
return(s);
|
||
|
}
|
||
|
|
||
|
#ifndef NOLONG
|
||
|
static char *l_compute(l1,d,s) long l1; char *s; {
|
||
|
int c;
|
||
|
long l2;
|
||
|
|
||
|
if ( l1<0 ) {
|
||
|
/* assumption: d is a multiple of 2 */
|
||
|
c= l1&1 ;
|
||
|
l2= ( (l1>>1) & ~signbit(l1) );
|
||
|
l1= l2/(d>>1) ;
|
||
|
c += (l2%(d>>1))<<1 ;
|
||
|
} else {
|
||
|
c= l1 % d ;
|
||
|
l1= l1 / d ;
|
||
|
}
|
||
|
if (l1)
|
||
|
s = l_compute(l1,d,s);
|
||
|
*s++ = (c>9 ? c-10+'a' : c+'0');
|
||
|
return(s);
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
_doprnt(fmt,args,stream)
|
||
|
register char *fmt; int *args ; FILE *stream;
|
||
|
{
|
||
|
register char *s;
|
||
|
#ifndef NOLONG
|
||
|
long l;
|
||
|
int lflag ;
|
||
|
#else
|
||
|
#define lflag 0
|
||
|
#endif
|
||
|
#ifndef NOFLOAT
|
||
|
double dbl ;
|
||
|
#endif
|
||
|
int inte ;
|
||
|
unsigned int uint ;
|
||
|
register int j ;
|
||
|
int i,c,rjust,width,ndigit,ndfnd,zfill;
|
||
|
char *oldfmt,*s1,buf[40];
|
||
|
|
||
|
nextarg = args;
|
||
|
while (c = *fmt++) {
|
||
|
if (c != '%') {
|
||
|
#ifdef CPM
|
||
|
if (c == '\n') putc('\r',stream);
|
||
|
#endif
|
||
|
putc(c,stream);
|
||
|
continue;
|
||
|
}
|
||
|
#ifndef NOLONG
|
||
|
lflag = 0 ;
|
||
|
#endif
|
||
|
j = 10 ;
|
||
|
rjust = 0;
|
||
|
if (*fmt == '-') {
|
||
|
fmt++;
|
||
|
rjust++;
|
||
|
}
|
||
|
zfill = ' ';
|
||
|
if (*fmt == '0') {
|
||
|
fmt++;
|
||
|
zfill = '0';
|
||
|
}
|
||
|
fmt = gnum(fmt,&width);
|
||
|
ndigit = 0; ndfnd = 0;
|
||
|
if (*fmt == '.') {
|
||
|
fmt++; oldfmt = fmt;
|
||
|
fmt = gnum(fmt,&ndigit);
|
||
|
ndfnd = (fmt != oldfmt);
|
||
|
}
|
||
|
s = s1 = buf;
|
||
|
#ifndef NOLONG
|
||
|
if ( *fmt == 'l' || *fmt == 'L' ) {
|
||
|
fmt++ ; lflag++ ;
|
||
|
}
|
||
|
#endif
|
||
|
switch (c = *fmt++) {
|
||
|
default:
|
||
|
#ifdef CPM
|
||
|
if (c == '\n') putc('r',stream);
|
||
|
#endif
|
||
|
putc(c,stream);
|
||
|
continue;
|
||
|
case 's':
|
||
|
geta(&s1,wsize(s1)) ;
|
||
|
s = s1;
|
||
|
do {
|
||
|
if (*s == 0)
|
||
|
break;
|
||
|
s++;
|
||
|
} while (--ndigit);
|
||
|
break;
|
||
|
case 'b':
|
||
|
j = 2;
|
||
|
case 'u':
|
||
|
getu:
|
||
|
if ( !lflag ) {
|
||
|
geta(&inte,wsize(inte)) ;
|
||
|
goto i_unsignd ;
|
||
|
}
|
||
|
#ifndef NOLONG
|
||
|
case 'U':
|
||
|
getlu:
|
||
|
geta( &l,wsize(l)) ;
|
||
|
goto l_unsignd ;
|
||
|
case 'B':
|
||
|
j = 2 ;
|
||
|
goto getlu ;
|
||
|
case 'X':
|
||
|
j = 16;
|
||
|
goto getlu ;
|
||
|
case 'O':
|
||
|
j = 8;
|
||
|
goto getlu ;
|
||
|
case 'D':
|
||
|
l_signed:
|
||
|
geta(&l,wsize(l)) ;
|
||
|
if (l < 0) {
|
||
|
*s++ = '-';
|
||
|
l = -l;
|
||
|
}
|
||
|
goto do_l;
|
||
|
l_unsignd:
|
||
|
if (l && ndigit)
|
||
|
*s++ = '0';
|
||
|
do_l:
|
||
|
s = l_compute(l,j,s);
|
||
|
break;
|
||
|
#endif
|
||
|
|
||
|
case 'x':
|
||
|
j = 16;
|
||
|
goto getu ;
|
||
|
case 'o':
|
||
|
j = 8;
|
||
|
goto getu ;
|
||
|
case 'd':
|
||
|
if ( lflag ) goto l_signed; ;
|
||
|
geta(&inte,wsize(inte)) ;
|
||
|
if ( inte<0 ) {
|
||
|
*s++ = '-';
|
||
|
inte= -inte ;
|
||
|
}
|
||
|
goto do_i ;
|
||
|
i_unsignd:
|
||
|
if (inte && ndigit)
|
||
|
*s++ = '0';
|
||
|
do_i:
|
||
|
s = i_compute(inte,j,s);
|
||
|
break;
|
||
|
case 'c':
|
||
|
geta ( &uint, wsize(uint)) ;
|
||
|
for ( i= sizeof uint -1 ; i>=0 ; i-- ) {
|
||
|
if ( *s = uint%256 ) s++;
|
||
|
uint/= 256 ;
|
||
|
}
|
||
|
break;
|
||
|
#ifndef NOFLOAT
|
||
|
case 'e':
|
||
|
geta(&dbl,wsize(dbl)) ;
|
||
|
s = _pscien(dbl,s,ndigit,ndfnd);
|
||
|
break;
|
||
|
case 'f':
|
||
|
geta(&dbl,wsize(dbl)) ;
|
||
|
s = _pfloat(dbl,s,ndigit,ndfnd);
|
||
|
break;
|
||
|
#endif
|
||
|
case 'r':
|
||
|
geta(&nextarg,wsize(nextarg)) ;
|
||
|
geta(&oldfmt,wsize(fmt)) ;
|
||
|
fmt=oldfmt;
|
||
|
continue;
|
||
|
}
|
||
|
j = s - s1;
|
||
|
if ((c = width - j) > 0)
|
||
|
if (rjust == 0)
|
||
|
do putc(zfill,stream);
|
||
|
while (--c);
|
||
|
while (--j >= 0)
|
||
|
putc(*s1++,stream);
|
||
|
while (--c >= 0)
|
||
|
putc(zfill,stream);
|
||
|
}
|
||
|
}
|