ack/lang/cem/libcc/stdio/doprnt.c
1987-03-31 10:45:53 +00:00

244 lines
3.9 KiB
C

/* $Header$ */
#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);
}
}