/* printf.c: library file for format, fformat, and printf * compile: c -l32000 * J. J. Gillogly, Apr 80 * sprintf added J. J. Gillogly, Jul 80 * Modified Jan 82 to work with #define kludge for multiple printf args * %u and unsigned octal and hex added WB Feb 82 * Fix for I/O redirection; John Toscano 4/17/84. */ #undef printf #undef fprintf #undef sprintf static int *prnt_p, /* Pointer into printf arglist */ Pfo; /* Channel number for output */ static char *Pf = "", /* current location in user's format */ *Pst; /* current location in user's output string */ static int Pr; /* precision */ static char Pad; static int Rad, Neg, Uns; prnt_1(firstarg) { prnt_p = &firstarg; } /* Record arglist start */ prnt_2(lastarg) { format(*--prnt_p); /* Process arglist */ #asm @prnt@: DS 0 #endasm while (prnt_p > &lastarg) printf(*--prnt_p); } prnt_3(lastarg) { Pfo = *--prnt_p; fformat(Pfo,*--prnt_p); #asm JMP @prnt@ #endasm } prnt_4(lastarg) { Pst = *--prnt_p; sformat(Pst,*--prnt_p); #asm JMP @prnt@ #endasm } format(form) char *form; { extern fout; fformat(fout,form); } fformat(chan,form) int chan; char *form; { Pfo = chan; Pf = form; Ps(); } sformat(string,form) /* user wants data to go to a string */ char *string,*form; { Pst = string; fformat(-2,form);/* illegal value for a channel */ } Ps() /* output format up to next % */ { while (*Pf != 0 && *Pf != '%') Pc(*Pf++); } Pc(c) char c; { if (Pfo == -2) { *Pst++ = c; *Pst = 0; /* terminate each intermediate string */ return; } putc(c,Pfo); } printf(arg) /* print one arg using current format */ char *arg; { if (*Pf++ == 0) return; /* otherwise next char is % */ for (Pr = 0; *Pf >= '0' && *Pf <= '9';) /* precision */ Pr = 10*Pr + *Pf++ - '0'; Pad = ' '; Rad = Uns = 10; Neg = 0; switch(*Pf++) { case 'd': Uns = 0; /* decimal */ case 'u': On(arg); break; /* unsigned decimal */ case 'o': Pad = '0'; Rad = 8; On(arg); break; /* octal */ case 'x': Pad = '0'; Rad = 16; On(arg); break; /* hex */ case 'c': Pc(arg); break; /* single char */ case 's': while (*arg) { Pc(*arg++); --Pr; } Pd(' '); break; /* left-adjusted strings only */ } Ps(); } Od(n) /* output digit: hex, octal, or decimal */ int n; { Pc(n < 10? n+'0' : 'A'+n-10); } Pd() { while (--Pr >= 0) Pc(Pad); } On(num) register unsigned num; { Pr--; /* if negative, don't output the - yet, but save it for end */ if (Uns == 0) if (num & 0100000) {Pr--; num = -num; Neg = 1; } if (num < Rad && num >= 0) { Pd(); if (Neg) Pc('-'); Od(num); } else { On(Rad==8? num>>3: Rad==10? num/10 : num>>4); Od(Rad==10? num % 10 : num & (Rad-1)); } } /* Definitions for printf and fprintf to allow multiple args. */ #define printf prnt_1(),prnt_2 #define fprintf prnt_1(),prnt_3 #define sprintf prnt_1(),prnt_4