#define NOCCARGC /* ** Yes, it's right. These function do not call ones which need arg counts. */ #include stdio.h /* ** fprintf(fd, ctlstring, arg, arg, ....) - Formatted print. ** Operates as described by Kernighan and Ritchie. ** b, c, d, o, s, u, and x specifications are supported. ** Note: b (binary) is a non-standard extension. */ fprintf(argc) int argc; { int *nxtarg; nxtarg = CCARGC() + &argc; return(_print(*(--nxtarg), --nxtarg)); } /* ** printf(ctlstring, arg, arg, ...) - Formatted print. ** See note to fprintf. */ printf(argc) int argc; { return(_print(stdout, CCARGC() + &argc - 1)); } /* ** _print(fd, ctlstring, arg, arg, ...) ** Called by fprintf() and printf(). */ _print(fd, nxtarg) int fd, *nxtarg; { int arg, left, pad, cc, len, maxchr, width; char *ctl, *sptr, str[17]; cc = 0; ctl = *nxtarg--; while(*ctl) { if(*ctl!='%') {fputc(*ctl++, fd); ++cc; continue;} else ++ctl; if(*ctl=='%') {fputc(*ctl++, fd); ++cc; continue;} if(*ctl=='-') {left = 1; ++ctl;} else left = 0; if(*ctl=='0') pad = '0'; else pad = ' '; if(isdigit(*ctl)) { width = atoi(ctl++); while(isdigit(*ctl)) ++ctl; } else width = 0; if(*ctl=='.') { maxchr = atoi(++ctl); while(isdigit(*ctl)) ++ctl; } else maxchr = 0; arg = *nxtarg--; sptr = str; switch(*ctl++) { case 'c': str[0] = arg; str[1] = NULL; break; case 's': sptr = arg; break; case 'd': itoa(arg,str); break; case 'b': itoab(arg,str,2); break; case 'o': itoab(arg,str,8); break; case 'u': itoab(arg,str,10); break; case 'x': itoab(arg,str,16); break; default: return (cc); } len = strlen(sptr); if(maxchr && maxchrlen) width = width - len; else width = 0; if(!left) while(width--) {fputc(pad, fd); ++cc;} while(len--) {fputc(*sptr++,fd); ++cc;} if(left) while(width--) {fputc(pad,fd); ++cc;} } return(cc); }