dos_compilers/Mix C v251/PRINTF.C
2024-07-24 09:30:16 -07:00

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 */
}