|
|
1.1 root 1: /*
2: * Standard output printf using putchar.
3: * Non-portable things:
4: * 1) alignment of arguments is assumed to be completely contiguous.
5: * 2) the smallest number is assumed to negate to itself.
6: * 3) All of long, int, char*, and double are assumed to
7: * be held in an exact number of ints.
8: */
9: #include "fsck.h"
10: #include <sys/mdata.h>
11:
12: union alltypes {
13: char c;
14: int i;
15: unsigned u;
16: long l;
17: double d;
18: char *s;
19: };
20:
21: #define bump(p,s) (p+=sizeof(s)/sizeof(int))
22:
23: char *printi();
24: char *printl();
25:
26: static char null[] = "{NULL}";
27:
28: printf(args)
29: union alltypes args;
30: {
31: xprintf(&args);
32: }
33: xprintf(argp)
34: union alltypes *argp;
35: {
36: register char *cbp;
37: int *iap;
38: register c;
39: char *s;
40: char *cbs;
41: char adj, pad;
42: int prec;
43: int fwidth;
44: int pwidth;
45: register char *fmt;
46: union alltypes elem;
47: char cbuf[64];
48:
49: iap = (int *)argp;
50: fmt = *(char **)iap;
51: bump(iap, char*);
52: for (;;) {
53: while((c = *fmt++) != '%') {
54: if(c == '\0') {
55: return;
56: }
57: putchar(c);
58: }
59: pad = ' ';
60: fwidth = -1;
61: prec = -1;
62: c = *fmt++;
63: if (c == '-') {
64: adj = 1;
65: c = *fmt++;
66: } else
67: adj = 0;
68: if (c == '0') {
69: pad = '0';
70: c = *fmt++;
71: }
72: if (c == '*') {
73: fwidth = *iap++;
74: c = *fmt++;
75: } else
76: for (fwidth = 0; c>='0' && c<='9'; c = *fmt++)
77: fwidth = fwidth*10 + c-'0';
78: if (c == '.') {
79: c = *fmt++;
80: if (c == '*') {
81: prec = *iap++;
82: c = *fmt++;
83: } else
84: for (prec=0; c>='0' && c<='9'; c=*fmt++)
85: prec = prec*10 + c-'0';
86: }
87: if (c == 'l') {
88: c = *fmt++;
89: if (c=='d' || c=='o' || c=='u' || c=='x')
90: c += 'A' - 'a';
91: }
92: cbp = cbs = cbuf;
93: switch (c) {
94:
95: case 'd':
96: elem.i = *iap++;
97: if (elem.i < 0) {
98: elem.i = -elem.i;
99: *cbp++ = '-';
100: }
101: cbp = printi(cbp, elem.i, 10);
102: break;
103:
104: case 'u':
105: cbp = printi(cbp, *iap++, 10);
106: break;
107:
108: case 'o':
109: cbp = printi(cbp, *iap++, 8);
110: break;
111:
112: case 'x':
113: cbp = printi(cbp, *iap++, 16);
114: break;
115:
116: case 'D':
117: elem.l = *(long *)iap;
118: bump(iap, long);
119: if (elem.l < 0) {
120: elem.l = -elem.l;
121: *cbp++ = '-';
122: }
123: cbp = printl(cbp, elem.l, 10);
124: break;
125:
126: case 'U':
127: cbp = printl(cbp, *(long *)iap, 10);
128: bump(iap, long);
129: break;
130:
131: case 'O':
132: cbp = printl(cbp, *(long *)iap, 8);
133: bump(iap, long);
134: break;
135:
136: case 'X':
137: cbp = printl(cbp, *(long *)iap, 16);
138: bump(iap, long);
139: break;
140:
141:
142: case 's':
143: if ((s = *(char **)iap) == NULL)
144: s = null;
145: bump(iap, char*);
146: /*
147: * Do %s specially so it can be longer.
148: */
149: cbp = cbs = s;
150: while (*cbp++ != '\0')
151: if (prec>=0 && cbp-s>prec)
152: break;
153: cbp--;
154: break;
155:
156: case 'c':
157: elem.c = *iap++;
158: *cbp++ = elem.c;
159: break;
160:
161: case 'r':
162: xprintf(*(char ***)iap);
163: bump(iap, char**);
164: break;
165:
166: default:
167: putchar(c);
168: continue;
169: }
170: if ((pwidth = fwidth + cbs-cbp) < 0)
171: pwidth = 0;
172: if (!adj)
173: while (pwidth-- != 0)
174: putchar(pad);
175: while (cbs < cbp)
176: putchar(*cbs++);
177: if (adj)
178: while (pwidth-- != 0)
179: putchar(pad);
180: }
181: }
182:
183: static char digits[] = {
184: '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
185: 'A', 'B', 'C', 'D', 'E', 'F'
186: };
187:
188: /*
189: * Print an unsigned integer in base b.
190: */
191: static
192: char *
193: printi(cp, n, b)
194: char *cp;
195: register unsigned n;
196: {
197: register a;
198: register char *ep;
199: char pbuf[10];
200:
201: ep = &pbuf[10];
202: *--ep = 0;
203: for ( ; a = n/b; n=a)
204: *--ep = digits[n%b];
205: *--ep = digits[n];
206: while (*ep)
207: *cp++ = *ep++;
208: return (cp);
209: }
210:
211: /*
212: * Print an unsigned long in base b.
213: */
214: static
215: char *
216: printl(cp, n, b)
217: register char *cp;
218: unsigned long n;
219: register b;
220: {
221: char pbuf[13];
222: unsigned long a;
223: register char *ep;
224:
225: ep = &pbuf[13];
226: *--ep = '\0';
227: for ( ; (a = n/b) != 0; n = a)
228: *--ep = digits[n%b];
229: *--ep = digits[n];
230: while (*ep)
231: *cp++ = *ep++;
232: return (cp);
233: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.