diff options
Diffstat (limited to 'openbsd-compat/bsd-snprintf.c')
-rw-r--r-- | openbsd-compat/bsd-snprintf.c | 557 |
1 files changed, 328 insertions, 229 deletions
diff --git a/openbsd-compat/bsd-snprintf.c b/openbsd-compat/bsd-snprintf.c index e4d8a439a..2f82180d1 100644 --- a/openbsd-compat/bsd-snprintf.c +++ b/openbsd-compat/bsd-snprintf.c | |||
@@ -58,7 +58,7 @@ | |||
58 | 58 | ||
59 | #include "includes.h" | 59 | #include "includes.h" |
60 | 60 | ||
61 | RCSID("$Id: bsd-snprintf.c,v 1.7 2003/05/18 14:13:39 djm Exp $"); | 61 | RCSID("$Id: bsd-snprintf.c,v 1.6 2003/04/01 11:31:56 djm Exp $"); |
62 | 62 | ||
63 | #if defined(BROKEN_SNPRINTF) /* For those with broken snprintf() */ | 63 | #if defined(BROKEN_SNPRINTF) /* For those with broken snprintf() */ |
64 | # undef HAVE_SNPRINTF | 64 | # undef HAVE_SNPRINTF |
@@ -72,15 +72,15 @@ dopr(char *buffer, size_t maxlen, const char *format, va_list args); | |||
72 | 72 | ||
73 | static void | 73 | static void |
74 | fmtstr(char *buffer, size_t *currlen, size_t maxlen, char *value, int flags, | 74 | fmtstr(char *buffer, size_t *currlen, size_t maxlen, char *value, int flags, |
75 | int min, int max); | 75 | int min, int max); |
76 | 76 | ||
77 | static void | 77 | static void |
78 | fmtint(char *buffer, size_t *currlen, size_t maxlen, long value, int base, | 78 | fmtint(char *buffer, size_t *currlen, size_t maxlen, long value, int base, |
79 | int min, int max, int flags); | 79 | int min, int max, int flags); |
80 | 80 | ||
81 | static void | 81 | static void |
82 | fmtfp(char *buffer, size_t *currlen, size_t maxlen, long double fvalue, | 82 | fmtfp(char *buffer, size_t *currlen, size_t maxlen, long double fvalue, |
83 | int min, int max, int flags); | 83 | int min, int max, int flags); |
84 | 84 | ||
85 | static void | 85 | static void |
86 | dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c); | 86 | dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c); |
@@ -121,10 +121,15 @@ dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c); | |||
121 | static void | 121 | static void |
122 | dopr(char *buffer, size_t maxlen, const char *format, va_list args) | 122 | dopr(char *buffer, size_t maxlen, const char *format, va_list args) |
123 | { | 123 | { |
124 | char *strvalue, ch; | 124 | char *strvalue; |
125 | char ch; | ||
125 | long value; | 126 | long value; |
126 | long double fvalue; | 127 | long double fvalue; |
127 | int min = 0, max = -1, state = DP_S_DEFAULT, flags = 0, cflags = 0; | 128 | int min = 0; |
129 | int max = -1; | ||
130 | int state = DP_S_DEFAULT; | ||
131 | int flags = 0; | ||
132 | int cflags = 0; | ||
128 | size_t currlen = 0; | 133 | size_t currlen = 0; |
129 | 134 | ||
130 | ch = *format++; | 135 | ch = *format++; |
@@ -134,224 +139,224 @@ dopr(char *buffer, size_t maxlen, const char *format, va_list args) | |||
134 | state = DP_S_DONE; | 139 | state = DP_S_DONE; |
135 | 140 | ||
136 | switch(state) { | 141 | switch(state) { |
137 | case DP_S_DEFAULT: | 142 | case DP_S_DEFAULT: |
138 | if (ch == '%') | 143 | if (ch == '%') |
139 | state = DP_S_FLAGS; | 144 | state = DP_S_FLAGS; |
140 | else | 145 | else |
141 | dopr_outch(buffer, &currlen, maxlen, ch); | 146 | dopr_outch(buffer, &currlen, maxlen, ch); |
142 | ch = *format++; | ||
143 | break; | ||
144 | case DP_S_FLAGS: | ||
145 | switch (ch) { | ||
146 | case '-': | ||
147 | flags |= DP_F_MINUS; | ||
148 | ch = *format++; | 147 | ch = *format++; |
149 | break; | 148 | break; |
150 | case '+': | 149 | case DP_S_FLAGS: |
151 | flags |= DP_F_PLUS; | 150 | switch (ch) { |
152 | ch = *format++; | 151 | case '-': |
153 | break; | 152 | flags |= DP_F_MINUS; |
154 | case ' ': | 153 | ch = *format++; |
155 | flags |= DP_F_SPACE; | 154 | break; |
156 | ch = *format++; | 155 | case '+': |
157 | break; | 156 | flags |= DP_F_PLUS; |
158 | case '#': | 157 | ch = *format++; |
159 | flags |= DP_F_NUM; | 158 | break; |
160 | ch = *format++; | 159 | case ' ': |
161 | break; | 160 | flags |= DP_F_SPACE; |
162 | case '0': | 161 | ch = *format++; |
163 | flags |= DP_F_ZERO; | 162 | break; |
164 | ch = *format++; | 163 | case '#': |
165 | break; | 164 | flags |= DP_F_NUM; |
166 | default: | 165 | ch = *format++; |
167 | state = DP_S_MIN; | 166 | break; |
168 | break; | 167 | case '0': |
169 | } | 168 | flags |= DP_F_ZERO; |
170 | break; | 169 | ch = *format++; |
171 | case DP_S_MIN: | 170 | break; |
172 | if (isdigit((unsigned char)ch)) { | 171 | default: |
173 | min = 10 * min + char_to_int (ch); | 172 | state = DP_S_MIN; |
174 | ch = *format++; | 173 | break; |
175 | } else if (ch == '*') { | ||
176 | min = va_arg (args, int); | ||
177 | ch = *format++; | ||
178 | state = DP_S_DOT; | ||
179 | } else | ||
180 | state = DP_S_DOT; | ||
181 | break; | ||
182 | case DP_S_DOT: | ||
183 | if (ch == '.') { | ||
184 | state = DP_S_MAX; | ||
185 | ch = *format++; | ||
186 | } else | ||
187 | state = DP_S_MOD; | ||
188 | break; | ||
189 | case DP_S_MAX: | ||
190 | if (isdigit((unsigned char)ch)) { | ||
191 | if (max < 0) | ||
192 | max = 0; | ||
193 | max = 10 * max + char_to_int(ch); | ||
194 | ch = *format++; | ||
195 | } else if (ch == '*') { | ||
196 | max = va_arg (args, int); | ||
197 | ch = *format++; | ||
198 | state = DP_S_MOD; | ||
199 | } else | ||
200 | state = DP_S_MOD; | ||
201 | break; | ||
202 | case DP_S_MOD: | ||
203 | switch (ch) { | ||
204 | case 'h': | ||
205 | cflags = DP_C_SHORT; | ||
206 | ch = *format++; | ||
207 | break; | ||
208 | case 'l': | ||
209 | cflags = DP_C_LONG; | ||
210 | ch = *format++; | ||
211 | if (ch == 'l') { | ||
212 | cflags = DP_C_LONG_LONG; | ||
213 | ch = *format++; | ||
214 | } | 174 | } |
215 | break; | 175 | break; |
216 | case 'q': | 176 | case DP_S_MIN: |
217 | cflags = DP_C_LONG_LONG; | 177 | if (isdigit((unsigned char)ch)) { |
218 | ch = *format++; | 178 | min = 10*min + char_to_int (ch); |
219 | break; | 179 | ch = *format++; |
220 | case 'L': | 180 | } else if (ch == '*') { |
221 | cflags = DP_C_LDOUBLE; | 181 | min = va_arg (args, int); |
222 | ch = *format++; | 182 | ch = *format++; |
223 | break; | 183 | state = DP_S_DOT; |
224 | default: | 184 | } else |
225 | break; | 185 | state = DP_S_DOT; |
226 | } | ||
227 | state = DP_S_CONV; | ||
228 | break; | ||
229 | case DP_S_CONV: | ||
230 | switch (ch) { | ||
231 | case 'd': | ||
232 | case 'i': | ||
233 | if (cflags == DP_C_SHORT) | ||
234 | value = va_arg(args, int); | ||
235 | else if (cflags == DP_C_LONG) | ||
236 | value = va_arg(args, long int); | ||
237 | else if (cflags == DP_C_LONG_LONG) | ||
238 | value = va_arg (args, long long); | ||
239 | else | ||
240 | value = va_arg (args, int); | ||
241 | fmtint(buffer, &currlen, maxlen, value, 10, min, max, flags); | ||
242 | break; | ||
243 | case 'o': | ||
244 | flags |= DP_F_UNSIGNED; | ||
245 | if (cflags == DP_C_SHORT) | ||
246 | value = va_arg(args, unsigned int); | ||
247 | else if (cflags == DP_C_LONG) | ||
248 | value = va_arg(args, unsigned long int); | ||
249 | else if (cflags == DP_C_LONG_LONG) | ||
250 | value = va_arg(args, unsigned long long); | ||
251 | else | ||
252 | value = va_arg(args, unsigned int); | ||
253 | fmtint(buffer, &currlen, maxlen, value, 8, min, max, flags); | ||
254 | break; | ||
255 | case 'u': | ||
256 | flags |= DP_F_UNSIGNED; | ||
257 | if (cflags == DP_C_SHORT) | ||
258 | value = va_arg(args, unsigned int); | ||
259 | else if (cflags == DP_C_LONG) | ||
260 | value = va_arg(args, unsigned long int); | ||
261 | else if (cflags == DP_C_LONG_LONG) | ||
262 | value = va_arg(args, unsigned long long); | ||
263 | else | ||
264 | value = va_arg(args, unsigned int); | ||
265 | fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags); | ||
266 | break; | ||
267 | case 'X': | ||
268 | flags |= DP_F_UP; | ||
269 | case 'x': | ||
270 | flags |= DP_F_UNSIGNED; | ||
271 | if (cflags == DP_C_SHORT) | ||
272 | value = va_arg(args, unsigned int); | ||
273 | else if (cflags == DP_C_LONG) | ||
274 | value = va_arg(args, unsigned long int); | ||
275 | else if (cflags == DP_C_LONG_LONG) | ||
276 | value = va_arg(args, unsigned long long); | ||
277 | else | ||
278 | value = va_arg(args, unsigned int); | ||
279 | fmtint(buffer, &currlen, maxlen, value, 16, min, max, flags); | ||
280 | break; | ||
281 | case 'f': | ||
282 | if (cflags == DP_C_LDOUBLE) | ||
283 | fvalue = va_arg(args, long double); | ||
284 | else | ||
285 | fvalue = va_arg(args, double); | ||
286 | /* um, floating point? */ | ||
287 | fmtfp(buffer, &currlen, maxlen, fvalue, min, max, flags); | ||
288 | break; | ||
289 | case 'E': | ||
290 | flags |= DP_F_UP; | ||
291 | case 'e': | ||
292 | if (cflags == DP_C_LDOUBLE) | ||
293 | fvalue = va_arg(args, long double); | ||
294 | else | ||
295 | fvalue = va_arg(args, double); | ||
296 | break; | ||
297 | case 'G': | ||
298 | flags |= DP_F_UP; | ||
299 | case 'g': | ||
300 | if (cflags == DP_C_LDOUBLE) | ||
301 | fvalue = va_arg(args, long double); | ||
302 | else | ||
303 | fvalue = va_arg(args, double); | ||
304 | break; | ||
305 | case 'c': | ||
306 | dopr_outch(buffer, &currlen, maxlen, va_arg(args, int)); | ||
307 | break; | 186 | break; |
308 | case 's': | 187 | case DP_S_DOT: |
309 | strvalue = va_arg(args, char *); | 188 | if (ch == '.') { |
310 | if (max < 0) | 189 | state = DP_S_MAX; |
311 | max = maxlen; /* ie, no max */ | 190 | ch = *format++; |
312 | fmtstr(buffer, &currlen, maxlen, strvalue, flags, min, max); | 191 | } else |
192 | state = DP_S_MOD; | ||
313 | break; | 193 | break; |
314 | case 'p': | 194 | case DP_S_MAX: |
315 | strvalue = va_arg(args, void *); | 195 | if (isdigit((unsigned char)ch)) { |
316 | fmtint(buffer, &currlen, maxlen, (long) strvalue, 16, min, max, flags); | 196 | if (max < 0) |
197 | max = 0; | ||
198 | max = 10*max + char_to_int(ch); | ||
199 | ch = *format++; | ||
200 | } else if (ch == '*') { | ||
201 | max = va_arg (args, int); | ||
202 | ch = *format++; | ||
203 | state = DP_S_MOD; | ||
204 | } else | ||
205 | state = DP_S_MOD; | ||
317 | break; | 206 | break; |
318 | case 'n': | 207 | case DP_S_MOD: |
319 | if (cflags == DP_C_SHORT) { | 208 | switch (ch) { |
320 | short int *num; | 209 | case 'h': |
321 | num = va_arg(args, short int *); | 210 | cflags = DP_C_SHORT; |
322 | *num = currlen; | 211 | ch = *format++; |
323 | } else if (cflags == DP_C_LONG) { | 212 | break; |
324 | long int *num; | 213 | case 'l': |
325 | num = va_arg(args, long int *); | 214 | cflags = DP_C_LONG; |
326 | *num = currlen; | 215 | ch = *format++; |
327 | } else if (cflags == DP_C_LONG_LONG) { | 216 | if (ch == 'l') { |
328 | long long *num; | 217 | cflags = DP_C_LONG_LONG; |
329 | num = va_arg(args, long long *); | 218 | ch = *format++; |
330 | *num = currlen; | 219 | } |
331 | } else { | 220 | break; |
332 | int *num; | 221 | case 'q': |
333 | num = va_arg(args, int *); | 222 | cflags = DP_C_LONG_LONG; |
334 | *num = currlen; | 223 | ch = *format++; |
224 | break; | ||
225 | case 'L': | ||
226 | cflags = DP_C_LDOUBLE; | ||
227 | ch = *format++; | ||
228 | break; | ||
229 | default: | ||
230 | break; | ||
335 | } | 231 | } |
232 | state = DP_S_CONV; | ||
336 | break; | 233 | break; |
337 | case '%': | 234 | case DP_S_CONV: |
338 | dopr_outch(buffer, &currlen, maxlen, ch); | 235 | switch (ch) { |
339 | break; | 236 | case 'd': |
340 | case 'w': /* not supported yet, treat as next char */ | 237 | case 'i': |
238 | if (cflags == DP_C_SHORT) | ||
239 | value = va_arg(args, int); | ||
240 | else if (cflags == DP_C_LONG) | ||
241 | value = va_arg(args, long int); | ||
242 | else if (cflags == DP_C_LONG_LONG) | ||
243 | value = va_arg (args, long long); | ||
244 | else | ||
245 | value = va_arg (args, int); | ||
246 | fmtint(buffer, &currlen, maxlen, value, 10, min, max, flags); | ||
247 | break; | ||
248 | case 'o': | ||
249 | flags |= DP_F_UNSIGNED; | ||
250 | if (cflags == DP_C_SHORT) | ||
251 | value = va_arg(args, unsigned int); | ||
252 | else if (cflags == DP_C_LONG) | ||
253 | value = va_arg(args, unsigned long int); | ||
254 | else if (cflags == DP_C_LONG_LONG) | ||
255 | value = va_arg(args, unsigned long long); | ||
256 | else | ||
257 | value = va_arg(args, unsigned int); | ||
258 | fmtint(buffer, &currlen, maxlen, value, 8, min, max, flags); | ||
259 | break; | ||
260 | case 'u': | ||
261 | flags |= DP_F_UNSIGNED; | ||
262 | if (cflags == DP_C_SHORT) | ||
263 | value = va_arg(args, unsigned int); | ||
264 | else if (cflags == DP_C_LONG) | ||
265 | value = va_arg(args, unsigned long int); | ||
266 | else if (cflags == DP_C_LONG_LONG) | ||
267 | value = va_arg(args, unsigned long long); | ||
268 | else | ||
269 | value = va_arg(args, unsigned int); | ||
270 | fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags); | ||
271 | break; | ||
272 | case 'X': | ||
273 | flags |= DP_F_UP; | ||
274 | case 'x': | ||
275 | flags |= DP_F_UNSIGNED; | ||
276 | if (cflags == DP_C_SHORT) | ||
277 | value = va_arg(args, unsigned int); | ||
278 | else if (cflags == DP_C_LONG) | ||
279 | value = va_arg(args, unsigned long int); | ||
280 | else if (cflags == DP_C_LONG_LONG) | ||
281 | value = va_arg(args, unsigned long long); | ||
282 | else | ||
283 | value = va_arg(args, unsigned int); | ||
284 | fmtint(buffer, &currlen, maxlen, value, 16, min, max, flags); | ||
285 | break; | ||
286 | case 'f': | ||
287 | if (cflags == DP_C_LDOUBLE) | ||
288 | fvalue = va_arg(args, long double); | ||
289 | else | ||
290 | fvalue = va_arg(args, double); | ||
291 | /* um, floating point? */ | ||
292 | fmtfp(buffer, &currlen, maxlen, fvalue, min, max, flags); | ||
293 | break; | ||
294 | case 'E': | ||
295 | flags |= DP_F_UP; | ||
296 | case 'e': | ||
297 | if (cflags == DP_C_LDOUBLE) | ||
298 | fvalue = va_arg(args, long double); | ||
299 | else | ||
300 | fvalue = va_arg(args, double); | ||
301 | break; | ||
302 | case 'G': | ||
303 | flags |= DP_F_UP; | ||
304 | case 'g': | ||
305 | if (cflags == DP_C_LDOUBLE) | ||
306 | fvalue = va_arg(args, long double); | ||
307 | else | ||
308 | fvalue = va_arg(args, double); | ||
309 | break; | ||
310 | case 'c': | ||
311 | dopr_outch(buffer, &currlen, maxlen, va_arg(args, int)); | ||
312 | break; | ||
313 | case 's': | ||
314 | strvalue = va_arg(args, char *); | ||
315 | if (max < 0) | ||
316 | max = maxlen; /* ie, no max */ | ||
317 | fmtstr(buffer, &currlen, maxlen, strvalue, flags, min, max); | ||
318 | break; | ||
319 | case 'p': | ||
320 | strvalue = va_arg(args, void *); | ||
321 | fmtint(buffer, &currlen, maxlen, (long) strvalue, 16, min, max, flags); | ||
322 | break; | ||
323 | case 'n': | ||
324 | if (cflags == DP_C_SHORT) { | ||
325 | short int *num; | ||
326 | num = va_arg(args, short int *); | ||
327 | *num = currlen; | ||
328 | } else if (cflags == DP_C_LONG) { | ||
329 | long int *num; | ||
330 | num = va_arg(args, long int *); | ||
331 | *num = currlen; | ||
332 | } else if (cflags == DP_C_LONG_LONG) { | ||
333 | long long *num; | ||
334 | num = va_arg(args, long long *); | ||
335 | *num = currlen; | ||
336 | } else { | ||
337 | int *num; | ||
338 | num = va_arg(args, int *); | ||
339 | *num = currlen; | ||
340 | } | ||
341 | break; | ||
342 | case '%': | ||
343 | dopr_outch(buffer, &currlen, maxlen, ch); | ||
344 | break; | ||
345 | case 'w': /* not supported yet, treat as next char */ | ||
346 | ch = *format++; | ||
347 | break; | ||
348 | default: /* Unknown, skip */ | ||
349 | break; | ||
350 | } | ||
341 | ch = *format++; | 351 | ch = *format++; |
352 | state = DP_S_DEFAULT; | ||
353 | flags = cflags = min = 0; | ||
354 | max = -1; | ||
342 | break; | 355 | break; |
343 | default: /* Unknown, skip */ | 356 | case DP_S_DONE: |
344 | break; | 357 | break; |
345 | } | 358 | default: /* hmm? */ |
346 | ch = *format++; | 359 | break; /* some picky compilers need this */ |
347 | state = DP_S_DEFAULT; | ||
348 | flags = cflags = min = 0; | ||
349 | max = -1; | ||
350 | break; | ||
351 | case DP_S_DONE: | ||
352 | break; | ||
353 | default: /* hmm? */ | ||
354 | break; /* some picky compilers need this */ | ||
355 | } | 360 | } |
356 | } | 361 | } |
357 | if (currlen < maxlen - 1) | 362 | if (currlen < maxlen - 1) |
@@ -362,9 +367,10 @@ dopr(char *buffer, size_t maxlen, const char *format, va_list args) | |||
362 | 367 | ||
363 | static void | 368 | static void |
364 | fmtstr(char *buffer, size_t *currlen, size_t maxlen, | 369 | fmtstr(char *buffer, size_t *currlen, size_t maxlen, |
365 | char *value, int flags, int min, int max) | 370 | char *value, int flags, int min, int max) |
366 | { | 371 | { |
367 | int cnt = 0, padlen, strln; /* amount to pad */ | 372 | int padlen, strln; /* amount to pad */ |
373 | int cnt = 0; | ||
368 | 374 | ||
369 | if (value == 0) | 375 | if (value == 0) |
370 | value = "<NULL>"; | 376 | value = "<NULL>"; |
@@ -396,13 +402,15 @@ fmtstr(char *buffer, size_t *currlen, size_t maxlen, | |||
396 | 402 | ||
397 | static void | 403 | static void |
398 | fmtint(char *buffer, size_t *currlen, size_t maxlen, | 404 | fmtint(char *buffer, size_t *currlen, size_t maxlen, |
399 | long value, int base, int min, int max, int flags) | 405 | long value, int base, int min, int max, int flags) |
400 | { | 406 | { |
401 | unsigned long uvalue; | 407 | unsigned long uvalue; |
402 | char convert[20]; | 408 | char convert[20]; |
403 | int signvalue = 0, place = 0, caps = 0; | 409 | int signvalue = 0; |
410 | int place = 0; | ||
404 | int spadlen = 0; /* amount to space pad */ | 411 | int spadlen = 0; /* amount to space pad */ |
405 | int zpadlen = 0; /* amount to zero pad */ | 412 | int zpadlen = 0; /* amount to zero pad */ |
413 | int caps = 0; | ||
406 | 414 | ||
407 | if (max < 0) | 415 | if (max < 0) |
408 | max = 0; | 416 | max = 0; |
@@ -421,10 +429,11 @@ fmtint(char *buffer, size_t *currlen, size_t maxlen, | |||
421 | 429 | ||
422 | if (flags & DP_F_UP) | 430 | if (flags & DP_F_UP) |
423 | caps = 1; /* Should characters be upper case? */ | 431 | caps = 1; /* Should characters be upper case? */ |
432 | |||
424 | do { | 433 | do { |
425 | convert[place++] = | 434 | convert[place++] = |
426 | (caps ? "0123456789ABCDEF" : "0123456789abcdef") | 435 | (caps? "0123456789ABCDEF":"0123456789abcdef") |
427 | [uvalue % (unsigned)base]; | 436 | [uvalue % (unsigned)base]; |
428 | uvalue = (uvalue / (unsigned)base ); | 437 | uvalue = (uvalue / (unsigned)base ); |
429 | } while (uvalue && (place < 20)); | 438 | } while (uvalue && (place < 20)); |
430 | if (place == 20) | 439 | if (place == 20) |
@@ -444,6 +453,7 @@ fmtint(char *buffer, size_t *currlen, size_t maxlen, | |||
444 | if (flags & DP_F_MINUS) | 453 | if (flags & DP_F_MINUS) |
445 | spadlen = -spadlen; /* Left Justifty */ | 454 | spadlen = -spadlen; /* Left Justifty */ |
446 | 455 | ||
456 | |||
447 | /* Spaces */ | 457 | /* Spaces */ |
448 | while (spadlen > 0) { | 458 | while (spadlen > 0) { |
449 | dopr_outch(buffer, currlen, maxlen, ' '); | 459 | dopr_outch(buffer, currlen, maxlen, ' '); |
@@ -502,11 +512,16 @@ static void | |||
502 | fmtfp(char *buffer, size_t *currlen, size_t maxlen, long double fvalue, | 512 | fmtfp(char *buffer, size_t *currlen, size_t maxlen, long double fvalue, |
503 | int min, int max, int flags) | 513 | int min, int max, int flags) |
504 | { | 514 | { |
505 | char iconvert[20], fconvert[20]; | 515 | char iconvert[20]; |
506 | int signvalue = 0, iplace = 0, fplace = 0; | 516 | char fconvert[20]; |
517 | int signvalue = 0; | ||
518 | int iplace = 0; | ||
519 | int fplace = 0; | ||
507 | int padlen = 0; /* amount to pad */ | 520 | int padlen = 0; /* amount to pad */ |
508 | int zpadlen = 0, caps = 0; | 521 | int zpadlen = 0; |
509 | long intpart, fracpart; | 522 | int caps = 0; |
523 | long intpart; | ||
524 | long fracpart; | ||
510 | long double ufvalue; | 525 | long double ufvalue; |
511 | 526 | ||
512 | /* | 527 | /* |
@@ -547,8 +562,7 @@ fmtfp(char *buffer, size_t *currlen, size_t maxlen, long double fvalue, | |||
547 | /* Convert integer part */ | 562 | /* Convert integer part */ |
548 | do { | 563 | do { |
549 | iconvert[iplace++] = | 564 | iconvert[iplace++] = |
550 | (caps ? "0123456789ABCDEF" : "0123456789abcdef") | 565 | (caps? "0123456789ABCDEF":"0123456789abcdef")[intpart % 10]; |
551 | [intpart % 10]; | ||
552 | intpart = (intpart / 10); | 566 | intpart = (intpart / 10); |
553 | } while(intpart && (iplace < 20)); | 567 | } while(intpart && (iplace < 20)); |
554 | if (iplace == 20) | 568 | if (iplace == 20) |
@@ -558,8 +572,7 @@ fmtfp(char *buffer, size_t *currlen, size_t maxlen, long double fvalue, | |||
558 | /* Convert fractional part */ | 572 | /* Convert fractional part */ |
559 | do { | 573 | do { |
560 | fconvert[fplace++] = | 574 | fconvert[fplace++] = |
561 | (caps ? "0123456789ABCDEF" : "0123456789abcdef") | 575 | (caps? "0123456789ABCDEF":"0123456789abcdef")[fracpart % 10]; |
562 | [fracpart % 10]; | ||
563 | fracpart = (fracpart / 10); | 576 | fracpart = (fracpart / 10); |
564 | } while(fracpart && (fplace < 20)); | 577 | } while(fracpart && (fplace < 20)); |
565 | if (fplace == 20) | 578 | if (fplace == 20) |
@@ -598,8 +611,8 @@ fmtfp(char *buffer, size_t *currlen, size_t maxlen, long double fvalue, | |||
598 | dopr_outch(buffer, currlen, maxlen, iconvert[--iplace]); | 611 | dopr_outch(buffer, currlen, maxlen, iconvert[--iplace]); |
599 | 612 | ||
600 | /* | 613 | /* |
601 | * Decimal point. This should probably use locale to find the | 614 | * Decimal point. This should probably use locale to find the correct |
602 | * correct char to print out. | 615 | * char to print out. |
603 | */ | 616 | */ |
604 | dopr_outch(buffer, currlen, maxlen, '.'); | 617 | dopr_outch(buffer, currlen, maxlen, '.'); |
605 | 618 | ||
@@ -649,4 +662,90 @@ snprintf(char *str,size_t count,const char *fmt,...) | |||
649 | return(strlen(str)); | 662 | return(strlen(str)); |
650 | } | 663 | } |
651 | 664 | ||
665 | #ifdef TEST_SNPRINTF | ||
666 | int | ||
667 | main(void) | ||
668 | { | ||
669 | #define LONG_STRING 1024 | ||
670 | char buf1[LONG_STRING]; | ||
671 | char buf2[LONG_STRING]; | ||
672 | char *fp_fmt[] = { | ||
673 | "%-1.5f", | ||
674 | "%1.5f", | ||
675 | "%123.9f", | ||
676 | "%10.5f", | ||
677 | "% 10.5f", | ||
678 | "%+22.9f", | ||
679 | "%+4.9f", | ||
680 | "%01.3f", | ||
681 | "%4f", | ||
682 | "%3.1f", | ||
683 | "%3.2f", | ||
684 | NULL | ||
685 | }; | ||
686 | double fp_nums[] = { | ||
687 | -1.5, | ||
688 | 134.21, | ||
689 | 91340.2, | ||
690 | 341.1234, | ||
691 | 0203.9, | ||
692 | 0.96, | ||
693 | 0.996, | ||
694 | 0.9996, | ||
695 | 1.996, | ||
696 | 4.136, | ||
697 | 0 | ||
698 | }; | ||
699 | char *int_fmt[] = { | ||
700 | "%-1.5d", | ||
701 | "%1.5d", | ||
702 | "%123.9d", | ||
703 | "%5.5d", | ||
704 | "%10.5d", | ||
705 | "% 10.5d", | ||
706 | "%+22.33d", | ||
707 | "%01.3d", | ||
708 | "%4d", | ||
709 | "%lld", | ||
710 | "%qd", | ||
711 | NULL | ||
712 | }; | ||
713 | long long int_nums[] = { -1, 134, 91340, 341, 0203, 0, 9999999 }; | ||
714 | int x, y; | ||
715 | int fail = 0; | ||
716 | int num = 0; | ||
717 | |||
718 | printf("Testing snprintf format codes against system sprintf...\n"); | ||
719 | |||
720 | for (x = 0; fp_fmt[x] != NULL ; x++) { | ||
721 | for (y = 0; fp_nums[y] != 0 ; y++) { | ||
722 | snprintf(buf1, sizeof (buf1), fp_fmt[x], fp_nums[y]); | ||
723 | sprintf (buf2, fp_fmt[x], fp_nums[y]); | ||
724 | if (strcmp (buf1, buf2)) { | ||
725 | printf("snprintf doesn't match Format: %s\n\t" | ||
726 | "snprintf = %s\n\tsprintf = %s\n", | ||
727 | fp_fmt[x], buf1, buf2); | ||
728 | fail++; | ||
729 | } | ||
730 | num++; | ||
731 | } | ||
732 | } | ||
733 | for (x = 0; int_fmt[x] != NULL ; x++) { | ||
734 | for (y = 0; int_nums[y] != 0 ; y++) { | ||
735 | snprintf(buf1, sizeof (buf1), int_fmt[x], int_nums[y]); | ||
736 | sprintf(buf2, int_fmt[x], int_nums[y]); | ||
737 | if (strcmp (buf1, buf2)) { | ||
738 | printf("snprintf doesn't match Format: %s\n\t" | ||
739 | "snprintf = %s\n\tsprintf = %s\n", | ||
740 | int_fmt[x], buf1, buf2); | ||
741 | fail++; | ||
742 | } | ||
743 | num++; | ||
744 | } | ||
745 | } | ||
746 | printf("%d tests failed out of %d.\n", fail, num); | ||
747 | return(0); | ||
748 | } | ||
749 | #endif /* SNPRINTF_TEST */ | ||
750 | |||
652 | #endif /* !HAVE_SNPRINTF */ | 751 | #endif /* !HAVE_SNPRINTF */ |