/* history... 19 Sept 84 Can send output to a file using putc() or STDOUT using putchar(). 3 Aug 84 Calling putchar() directly rather than through cout(). 10 Aug 83 changed back to &argcnt+i-1. 8 Aug 83 Changed addr of first arg to &argcnt + i + 1. */ #include iolib.h #include printf1.h #define NULL 0 #define ERR -1 int device; /* ** printf(controlstring, arg, arg, ...) or ** printf(file, controlstring, arg, arg, ...) -- formatted print ** operates as described by Kernighan & Ritchie ** only d, x, c, s, and u specs are supported. */ printf(argcnt) int argcnt; { int i, width, prec, preclen, len, *nxtarg; char *ctl, *cx, c, right, str[7], *sptr, pad; i = argc(); /* fetch arg count from A reg first */ nxtarg = &argcnt + i - 1; ctl = device = *nxtarg; if (device==(device&31)) /* *small* value must be device # */ {ctl=*--nxtarg;} else device=0; while(c=*ctl++) { if(c!='%') {_outc(c); continue;} if(*ctl=='%') {_outc(*ctl++); continue;} cx=ctl; if(*cx=='-') {right=0; ++cx;} else right=1; if(*cx=='0') {pad='0'; ++cx;} else pad=' '; if((i=utoi(cx, &width)) >= 0) cx=cx+i; else continue; if(*cx=='.') { if((preclen=utoi(++cx, &prec)) >= 0) cx=cx+preclen; else continue; } else preclen=0; sptr=str; c=*cx++; i=*(--nxtarg); if(c=='d') itod(i, str, 7); else if(c=='x') itox(i, str, 7); else if(c=='c') {str[0]=i; str[1]=NULL;} else if(c=='s') sptr=i; else if(c=='u') itou(i, str, 7); else continue; ctl=cx; /* accept conversion spec */ if(c!='s') while(*sptr==' ') ++sptr; len=-1; while(sptr[++len]); /* get length */ if((c=='s')&(len>prec)&(preclen>0)) len=prec; if(right) while(((width--)-len)>0) _outc(pad); while(len) {_outc(*sptr++); --len; --width;} while(((width--)-len)>0) _outc(pad); } } /* ** utoi -- convert unsigned decimal string to integer nbr ** returns field size, else ERR on error */ utoi(decstr, nbr) char *decstr; int *nbr; { int d,t; d=0; *nbr=0; while((*decstr>='0')&(*decstr<='9')) { t=*nbr;t=(10*t) + (*decstr++ - '0'); if ((t>=0)&(*nbr<0)) return ERR; d++; *nbr=t; } return d; } /* ** itod -- convert nbr to signed decimal string of width sz ** right adjusted, blank filled; returns str ** ** if sz > 0 terminate with null byte ** if sz = 0 find end of string ** if sz < 0 use last byte for data */ itod(nbr, str, sz) int nbr; char str[]; int sz; { char sgn; if(nbr<0) {nbr = -nbr; sgn='-';} else sgn=' '; if(sz>0) str[--sz]=NULL; else if(sz<0) sz = -sz; else while(str[sz]!=NULL) ++sz; while(sz) { str[--sz]=(nbr%10+'0'); if((nbr=nbr/10)==0) break; } if(sz) str[--sz]=sgn; while(sz>0) str[--sz]=' '; return str; } /* ** itou -- convert nbr to unsigned decimal string of width sz ** right adjusted, blank filled; returns str ** ** if sz > 0 terminate with null byte ** if sz = 0 find end of string ** if sz < 0 use last byte for data */ itou(nbr, str, sz) int nbr; char str[]; int sz; { int lowbit; if(sz>0) str[--sz]=NULL; else if(sz<0) sz = -sz; else while(str[sz]!=NULL) ++sz; while(sz) { lowbit=nbr&1; nbr=(nbr>>1)&32767; /* divide by 2 */ str[--sz]=((nbr%5)<<1)+lowbit+'0'; if((nbr=nbr/5)==0) break; } while(sz) str[--sz]=' '; return str; } /* ** itox -- converts nbr to hex string of length sz ** right adjusted and blank filled, returns str ** ** if sz > 0 terminate with null byte ** if sz = 0 find end of string ** if sz < 0 use last byte for data */ itox(nbr, str, sz) int nbr; char str[]; int sz; { int digit, offset; if(sz>0) str[--sz]=NULL; else if(sz<0) sz = -sz; else while(str[sz]!=NULL) ++sz; while(sz) { digit=nbr&15; nbr=(nbr>>4)&4095; if(digit<10) offset=48; else offset=55; str[--sz]=digit+offset; if(nbr==0) break; } while(sz) str[--sz]=' '; return str; } _outc(c) char c; { if(device) putc(c,device); else putchar(c); }  .