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