source: buchla-68k/iolib/dofmt.c@ 7bb1284

Last change on this file since 7bb1284 was 7ecfb7b, checked in by Thomas Lopatic <thomas@…>, 7 years ago

Unused variables and parameters.

  • Property mode set to 100644
File size: 4.8 KB
Line 
1/*
2 =============================================================================
3 dofmt.c -- integer and string formatted output function
4 Version 4 -- 1987-06-12 -- D.N. Lynx Crowe
5
6 Supports most of the BSD & SysV Unix(tm) [f|s]printf conversion codes -
7 No floating point support in this implementation.
8
9 Returns a long instead of the int returned by the Unix(tm) functions.
10
11 WARNING - "Crufty code":
12
13 This code contains hacks to work around a bug in
14 the Alcyon C compiler, which, among other things,
15 doesn't handle % properly for longs. Conversions for
16 o and x are hacked to use shifts instead of modulus.
17
18 Alcyon 'cruft' is enabled by defining CRUFTY non-zero.
19 =============================================================================
20*/
21
22#define CRUFTY 1
23
24#include "ram.h"
25
26#define MAXDIGS 11
27#define HIBITL (1L << ( (8 * sizeof(int32_t)) - 1))
28
29#define LONGHMSK 0x0FFFFFFFL
30#define LONGOMSK 0x1FFFFFFFL
31
32#define tonum(x) ((x)-'0')
33#define todigit(x) ((x)+'0')
34#define max(a,b) ((a)>(b)?(a):(b))
35#define min(a,b) ((a)<(b)?(a):(b))
36
37int32_t dofmt_(int16_t (*putsub)(int16_t c), int8_t *format, va_list args)
38{
39 register int16_t fcode;
40
41 int32_t k,
42 n,
43 lzero,
44 count;
45
46 int16_t hradix,
47 length,
48 fplus,
49 fminus,
50 fblank,
51 fsharp,
52 flzero,
53 width,
54 prec;
55
56 register int8_t *bp, *p;
57
58 int8_t *prefix,
59 *tab,
60 buf[MAXDIGS];
61
62 int32_t val;
63
64 count = 0;
65
66 for ( ; ; ) {
67
68 for (bp = format;
69 (fcode = *format) NE '\0' AND fcode NE '%';
70 format++)
71 ;
72
73 if (n = (int32_t)format - (int32_t)bp) {
74
75 count += n;
76
77 while (n--)
78 (*putsub)(*bp++);
79 }
80
81 if (fcode EQ '\0')
82 return(count);
83
84 fplus = fminus = fblank = fsharp = flzero = 0;
85
86 for ( ; ; ) {
87
88 switch (fcode = *++format) {
89
90 case '+':
91 fplus++;
92 continue;
93
94 case '-':
95 fminus++;
96 continue;
97
98 case ' ':
99 fblank++;
100 continue;
101
102 case '#':
103 fsharp++;
104 continue;
105 }
106
107 break;
108 }
109
110 if (fcode EQ '*') {
111
112 width = va_arg(args, int16_t);
113
114 if (width < 0) {
115
116 width = -width;
117 fminus++;
118 }
119
120 format++;
121
122 } else {
123
124 if (fcode EQ '0')
125 flzero++;
126
127 for (width = 0; isdigit(fcode = *format); format++)
128 width = width * 10 + tonum(fcode);
129 }
130
131 if (*format NE '.')
132 prec = -1;
133 else if (*++format EQ '*') {
134
135 prec = va_arg(args, int16_t);
136 format++;
137 } else
138 for (prec = 0; isdigit(fcode = *format); format++)
139 prec = prec * 10 + tonum(fcode);
140
141 length = 0;
142
143 if (*format EQ 'l') {
144
145 length++;
146 format++;
147 }
148
149 prefix = "";
150 lzero = 0;
151
152
153 switch (fcode = *format++) {
154
155 case 'd':
156 case 'u':
157 hradix = 10/2;
158 goto fixed;
159
160 case 'o':
161 hradix = 8/2;
162 goto fixed;
163
164 case 'X':
165 case 'x':
166 hradix = 16/2;
167
168 fixed:
169
170 if (prec < 0)
171 if (flzero AND width > 0)
172 prec = width;
173 else
174 prec = 1;
175
176 if (length)
177 val = va_arg(args, int32_t);
178 else if (fcode EQ 'd')
179 val = va_arg(args, int16_t);
180 else
181 val = va_arg(args, uint16_t);
182
183 if (fcode EQ 'd') {
184
185 if (val < 0) {
186
187 prefix = "-";
188
189 if (val NE HIBITL)
190 val = -val;
191
192 } else if (fplus)
193 prefix = "+";
194 else if (fblank)
195 prefix = " ";
196 }
197
198 tab = (fcode EQ 'X') ?
199 "0123456789ABCDEF" : "0123456789abcdef";
200
201 p = bp = buf + MAXDIGS;
202
203
204 switch (hradix) {
205
206 case 4:
207
208 while (val NE 0) {
209
210 *--bp = tab[val & 0x07L];
211 val = (val >> 3) & LONGOMSK;
212 }
213
214 break;
215
216 case 5:
217
218 while (val NE 0) {
219
220#if CRUFTY
221 /* uldiv does a long divide */
222 /* ... with remainder in uldivr */
223
224 val = uldiv(val, 10L);
225 *--bp = tab[uldivr];
226#else
227 /* on most compilers, this works */
228
229 lowbit = val & 1;
230 val = (val >> 1) & ~HIBITL;
231 *--bp = tab[val % hradix * 2 + lowbit];
232 val /= hradix;
233#endif
234 }
235
236 break;
237
238 case 8:
239
240 while (val NE 0) {
241
242 *--bp = tab[val & 0x0FL];
243 val = (val >> 4) & LONGHMSK;
244 }
245 }
246
247 lzero = (int32_t)bp - (int32_t)p + (int32_t)prec;
248
249 if (fsharp AND bp NE p)
250 switch (fcode) {
251
252 case 'o':
253 if (lzero < 1)
254 lzero = 1;
255 break;
256
257 case 'x':
258 case 'X':
259 prefix = "0x";
260 break;
261 }
262
263 break;
264
265
266 default:
267 buf[0] = fcode;
268 goto c_merge;
269
270 case 'c':
271 buf[0] = va_arg(args, int16_t);
272
273 c_merge:
274
275 p = (bp = &buf[0]) + 1;
276 break;
277
278 case 's':
279 p = bp = va_arg(args, int8_t *);
280
281 if (prec < 0)
282 p += strlen(bp);
283 else {
284 while (*p++ NE '\0' AND --prec GE 0)
285 ;
286 --p;
287 }
288
289 break;
290
291 case '\0':
292 return(-1);
293
294 }
295
296
297 if (lzero < 0)
298 lzero = 0;
299
300 k = (n = (int32_t)p - (int32_t)bp) + (int32_t)(lzero +
301 (prefix[0] EQ '\0' ? 0 : (prefix[1] EQ '\0' ? 1 : 2)));
302
303 count += (width >k) ? width : k;
304
305 if (!fminus)
306 while (--width GE k)
307 (*putsub)(' ');
308
309 while (*prefix NE '\0')
310 (*putsub)(*prefix++);
311
312 while (--lzero GE 0)
313 (*putsub)('0');
314
315 if (n > 0)
316 while (n--)
317 (*putsub)(*bp++);
318
319 while (--width GE k)
320 (*putsub)(' ');
321 }
322}
323
Note: See TracBrowser for help on using the repository browser.