263 lines
8.9 KiB
C++
263 lines
8.9 KiB
C++
|
#include "stdio"
|
||
|
|
||
|
printf(fs) /* standard routine */
|
||
|
char *fs;
|
||
|
{
|
||
|
int putc();
|
||
|
int _write();
|
||
|
return _output(stdout, &fs, putc, _write);
|
||
|
}
|
||
|
|
||
|
fprintf(fp, fs) /* standard routine */
|
||
|
FILE *fp;
|
||
|
char *fs;
|
||
|
{
|
||
|
int putc();
|
||
|
int _write();
|
||
|
return _output(fp, &fs, putc, _write);
|
||
|
}
|
||
|
|
||
|
sprintf(s,fs) /* standard routine */
|
||
|
char *s;
|
||
|
char *fs;
|
||
|
{
|
||
|
int _mputc();
|
||
|
int _mwrite();
|
||
|
int status;
|
||
|
status = _output(&s, &fs, _mputc, _mwrite);
|
||
|
*s = '\0';
|
||
|
return status;
|
||
|
}
|
||
|
|
||
|
_output(fp, parms, putc, write) /* output routine for */
|
||
|
/* printf, sprintf, fprintf */
|
||
|
char *fp; /* pointer to destination */
|
||
|
char **parms; /* pointer to addr of parameters */
|
||
|
int (*putc)(); /* pointer to output function */
|
||
|
int (*write)(); /* pointer to output function */
|
||
|
{
|
||
|
char buffer[80]; /* encode buffer */
|
||
|
char *bufptr; /* pointer into buffer */
|
||
|
char *format; /* format string pointer */
|
||
|
char *cptr; /* pointer to character */
|
||
|
char c; /* current character */
|
||
|
char padchar; /* pad character */
|
||
|
int ljflag; /* left justify flag */
|
||
|
int length; /* length of output string */
|
||
|
int precision; /* precision for reals */
|
||
|
int flag; /* ftoa edit flag */
|
||
|
int left; /* number digits left of decimal */
|
||
|
int right; /* number digits right of decimal */
|
||
|
int width; /* mimimum field width */
|
||
|
int (*enc)(); /* pointer to encode function */
|
||
|
int _eint(); /* encode integer function */
|
||
|
int _elong(); /* encode long function */
|
||
|
int _edouble(); /* encode double function */
|
||
|
int _atoi(); /* convert string to integer */
|
||
|
int _getformat(); /* get format flag */
|
||
|
int strlen(); /* determine length of string */
|
||
|
STRING *dynamic; /* dynamic string pointer */
|
||
|
|
||
|
format = *parms--; /* format points to format string */
|
||
|
while (c = *format++) {
|
||
|
if (c != '%') {
|
||
|
if ((*putc)(c,fp) != EOF) continue;
|
||
|
else return EOF;
|
||
|
}
|
||
|
precision = -1;
|
||
|
bufptr = buffer;
|
||
|
ljflag = 0;
|
||
|
if (*format == '-') {
|
||
|
++format;
|
||
|
++ljflag;
|
||
|
}
|
||
|
padchar = (*format == '0') ? '0' : ' ';
|
||
|
width = (isdigit(*format)) ? _atoi(&format) : 0;
|
||
|
if ((*format) == '.') {
|
||
|
++format;
|
||
|
if (isdigit(*format)) precision = _atoi(&format);
|
||
|
}
|
||
|
enc = _eint;
|
||
|
if (toupper(c = *format++) == 'L') {
|
||
|
c = *format++;
|
||
|
enc = _elong;
|
||
|
--parms;
|
||
|
}
|
||
|
switch(toupper(c)) {
|
||
|
|
||
|
case 'D': /* signed decimal */
|
||
|
(*enc)(parms, buffer, 10, 1);
|
||
|
length = strlen(bufptr);
|
||
|
break;
|
||
|
|
||
|
case 'U': /* unsigned decimal */
|
||
|
(*enc)(parms, buffer, 10, 0);
|
||
|
length = strlen(bufptr);
|
||
|
break;
|
||
|
|
||
|
case 'O': /* unsigned octal */
|
||
|
(*enc)(parms, buffer, 8, 0);
|
||
|
length = strlen(bufptr);
|
||
|
break;
|
||
|
|
||
|
case 'X': /* unsigned hexadecimal */
|
||
|
(*enc)(parms, buffer, 16, 0);
|
||
|
length = strlen(bufptr);
|
||
|
break;
|
||
|
|
||
|
case 'S': /* string */
|
||
|
bufptr = *parms;
|
||
|
length = strlen(bufptr);
|
||
|
break;
|
||
|
|
||
|
case 'C': /* character */
|
||
|
cptr = parms;
|
||
|
buffer[0] = *cptr;
|
||
|
buffer[1] = '\0';
|
||
|
length = 1;
|
||
|
break;
|
||
|
|
||
|
case 'E': /* exponential */
|
||
|
flag = 1;
|
||
|
goto reals;
|
||
|
|
||
|
case 'F': /* fixed point */
|
||
|
flag = 0;
|
||
|
goto reals;
|
||
|
|
||
|
case 'G': /* no trailing 0's */
|
||
|
/* fixed or exponential? */
|
||
|
flag = _getformat(parms-3);
|
||
|
|
||
|
reals:
|
||
|
left = 1;
|
||
|
parms = parms - 3;
|
||
|
if (precision == -1) right = 6;
|
||
|
else right = precision;
|
||
|
_edouble(parms, buffer, flag, left, right);
|
||
|
precision = -1;
|
||
|
length = 0;
|
||
|
while (c=buffer[length]) {
|
||
|
if (c == 'D') buffer[length] = 'E';
|
||
|
++length;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case 'Y': /* dynamic string */
|
||
|
dynamic = *parms;
|
||
|
length = dynamic->length;
|
||
|
bufptr = dynamic->string;
|
||
|
break;
|
||
|
|
||
|
default : /* format string character */
|
||
|
if ((*putc)(c, fp) != EOF) continue;
|
||
|
else return EOF;
|
||
|
}
|
||
|
if (precision >= 0 && length > precision) length = precision;
|
||
|
width = width - length;
|
||
|
if (!ljflag) {
|
||
|
if (padchar == '0' && *bufptr == '-') {
|
||
|
--length;
|
||
|
if ((*putc)(*bufptr++, fp) == EOF) return EOF;
|
||
|
}
|
||
|
while (width-- > 0)
|
||
|
if ((*putc)(padchar, fp) == EOF) return EOF;
|
||
|
}
|
||
|
if ((*write)(fp,bufptr,length) == EOF) return EOF;
|
||
|
while (width-- > 0)
|
||
|
if ((*putc)(padchar,fp) == EOF) return EOF;
|
||
|
--parms;
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
_eint(iptr, bufptr, base, sf) /* encode an integer*/
|
||
|
int *iptr; /* pointer to integer */
|
||
|
char *bufptr; /* pointer to encode buffer */
|
||
|
int base; /* number base */
|
||
|
int sf; /* signed or unsigned flag */
|
||
|
{
|
||
|
if (*iptr < 0 && sf) {
|
||
|
*bufptr++ = '-';
|
||
|
*iptr = -*iptr;
|
||
|
}
|
||
|
_itoa(*iptr, &bufptr, base); /* convert integer to string */
|
||
|
*bufptr = '\0';
|
||
|
}
|
||
|
|
||
|
_elong(lptr, bufptr, base, sf) /* encode a long */
|
||
|
long *lptr; /* pointer to long */
|
||
|
char *bufptr; /* pointer to encode buffer */
|
||
|
int base; /* number base */
|
||
|
int sf; /* sign flag */
|
||
|
{
|
||
|
if (*lptr < 0 && sf) {
|
||
|
*bufptr++ = '-';
|
||
|
*lptr = -*lptr;
|
||
|
}
|
||
|
_ltostr(*lptr, &bufptr, base); /* convert long to string */
|
||
|
*bufptr = '\0';
|
||
|
}
|
||
|
|
||
|
_itoa(n, bufptr, base) /* integer encode routine */
|
||
|
unsigned n; /* unsigned integer */
|
||
|
char **bufptr; /* pointer to the buffer pointer */
|
||
|
int base; /* number base */
|
||
|
{
|
||
|
if (n < base) {
|
||
|
*(*bufptr)++ = (n < 10) ? n + 48 : n + 55;
|
||
|
return;
|
||
|
}
|
||
|
_itoa(n/base, bufptr, base);
|
||
|
_itoa(n%base, bufptr, base);
|
||
|
}
|
||
|
|
||
|
_ltostr(lptr, bufptr, base) /* long encode routine */
|
||
|
long lptr; /* long integer */
|
||
|
char **bufptr; /* pointer to the buffer pointer */
|
||
|
int base; /* number base */
|
||
|
{
|
||
|
if (lptr < base) {
|
||
|
*(*bufptr)++ = (lptr < 10) ? lptr + '0' : lptr + 55;
|
||
|
return;
|
||
|
}
|
||
|
_ltostr(lptr/base, bufptr, base);
|
||
|
_ltostr(lptr%base, bufptr, base);
|
||
|
}
|
||
|
|
||
|
_edouble(dptr, bufptr, flag, left, right) /* encode a double */
|
||
|
double *dptr; /* pointer to double */
|
||
|
char *bufptr; /* pointer to encode buffer */
|
||
|
int flag; /* encode format flag */
|
||
|
int left; /* # of digits left of decimal */
|
||
|
int right; /* # of digits right of decimal */
|
||
|
{
|
||
|
ftoa(*dptr, bufptr, flag, left, right);
|
||
|
}
|
||
|
|
||
|
_mputc(c, fp) /* write c to fp */
|
||
|
int c;
|
||
|
char **fp;
|
||
|
{
|
||
|
*(*fp)++ = c;
|
||
|
return c;
|
||
|
}
|
||
|
|
||
|
_mwrite(fp, s, n)
|
||
|
char **fp;
|
||
|
char *s;
|
||
|
int n;
|
||
|
{
|
||
|
int i;
|
||
|
for (i=0; i < n; i++) *(*fp)++ = *s++;
|
||
|
return n;
|
||
|
}
|
||
|
|
||
|
_getformat(dptr) /* get format flag */
|
||
|
double *dptr; /* for _edouble */
|
||
|
{
|
||
|
if (*dptr < 100000.0) return 2; /* fixed format */
|
||
|
else return 3; /* exponential format */
|
||
|
}
|
||
|
|