tarruby 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (85) hide show
  1. data/README.txt +99 -0
  2. data/ext/extconf.rb +19 -0
  3. data/ext/libtar/COPYRIGHT +35 -0
  4. data/ext/libtar/ChangeLog +243 -0
  5. data/ext/libtar/ChangeLog-1.0.x +141 -0
  6. data/ext/libtar/INSTALL +183 -0
  7. data/ext/libtar/Makefile.in +51 -0
  8. data/ext/libtar/README +121 -0
  9. data/ext/libtar/TODO +10 -0
  10. data/ext/libtar/autoconf/ac_path_generic.m4 +136 -0
  11. data/ext/libtar/autoconf/aclocal.m4 +199 -0
  12. data/ext/libtar/autoconf/encap.m4 +133 -0
  13. data/ext/libtar/autoconf/install-sh +251 -0
  14. data/ext/libtar/autom4te.cache/output.0 +8102 -0
  15. data/ext/libtar/autom4te.cache/requests +112 -0
  16. data/ext/libtar/autom4te.cache/traces.0 +382 -0
  17. data/ext/libtar/compat/ChangeLog +31 -0
  18. data/ext/libtar/compat/README +12 -0
  19. data/ext/libtar/compat/TODO +4 -0
  20. data/ext/libtar/compat/basename.c +91 -0
  21. data/ext/libtar/compat/compat.h +260 -0
  22. data/ext/libtar/compat/dirname.c +96 -0
  23. data/ext/libtar/compat/fnmatch.c +237 -0
  24. data/ext/libtar/compat/gethostbyname_r.c +41 -0
  25. data/ext/libtar/compat/gethostname.c +36 -0
  26. data/ext/libtar/compat/getservbyname_r.c +41 -0
  27. data/ext/libtar/compat/glob.c +898 -0
  28. data/ext/libtar/compat/inet_aton.c +27 -0
  29. data/ext/libtar/compat/module.ac +591 -0
  30. data/ext/libtar/compat/snprintf.c +788 -0
  31. data/ext/libtar/compat/strdup.c +62 -0
  32. data/ext/libtar/compat/strlcat.c +72 -0
  33. data/ext/libtar/compat/strlcpy.c +68 -0
  34. data/ext/libtar/compat/strmode.c +199 -0
  35. data/ext/libtar/compat/strrstr.c +40 -0
  36. data/ext/libtar/compat/strsep.c +87 -0
  37. data/ext/libtar/config.h.in +187 -0
  38. data/ext/libtar/configure +8102 -0
  39. data/ext/libtar/configure.ac +114 -0
  40. data/ext/libtar/doc/Makefile.in +152 -0
  41. data/ext/libtar/doc/tar_append_file.3 +50 -0
  42. data/ext/libtar/doc/tar_block_read.3 +24 -0
  43. data/ext/libtar/doc/tar_extract_all.3 +43 -0
  44. data/ext/libtar/doc/tar_extract_file.3 +84 -0
  45. data/ext/libtar/doc/tar_open.3 +97 -0
  46. data/ext/libtar/doc/th_get_pathname.3 +63 -0
  47. data/ext/libtar/doc/th_print_long_ls.3 +22 -0
  48. data/ext/libtar/doc/th_read.3 +34 -0
  49. data/ext/libtar/doc/th_set_from_stat.3 +45 -0
  50. data/ext/libtar/lib/Makefile.in +92 -0
  51. data/ext/libtar/lib/append.c +272 -0
  52. data/ext/libtar/lib/block.c +384 -0
  53. data/ext/libtar/lib/decode.c +130 -0
  54. data/ext/libtar/lib/encode.c +237 -0
  55. data/ext/libtar/lib/extract.c +656 -0
  56. data/ext/libtar/lib/handle.c +150 -0
  57. data/ext/libtar/lib/internal.h +46 -0
  58. data/ext/libtar/lib/libtar.h +311 -0
  59. data/ext/libtar/lib/output.c +146 -0
  60. data/ext/libtar/lib/util.c +153 -0
  61. data/ext/libtar/lib/wrapper.c +175 -0
  62. data/ext/libtar/libtar/Makefile.in +73 -0
  63. data/ext/libtar/libtar/libtar.c +363 -0
  64. data/ext/libtar/listhash/ChangeLog +15 -0
  65. data/ext/libtar/listhash/TODO +21 -0
  66. data/ext/libtar/listhash/hash.c.in +344 -0
  67. data/ext/libtar/listhash/hash_new.3.in +74 -0
  68. data/ext/libtar/listhash/list.c.in +458 -0
  69. data/ext/libtar/listhash/list_new.3.in +86 -0
  70. data/ext/libtar/listhash/listhash.h.in +196 -0
  71. data/ext/libtar/listhash/module.ac +21 -0
  72. data/ext/libtar/win32/config.h +190 -0
  73. data/ext/libtar/win32/dirent.c +115 -0
  74. data/ext/libtar/win32/dirent.h +24 -0
  75. data/ext/libtar/win32/grp.h +4 -0
  76. data/ext/libtar/win32/listhash/libtar_hash.c +344 -0
  77. data/ext/libtar/win32/listhash/libtar_list.c +458 -0
  78. data/ext/libtar/win32/listhash/libtar_listhash.h +196 -0
  79. data/ext/libtar/win32/pwd.h +4 -0
  80. data/ext/libtar/win32/sys/param.h +8 -0
  81. data/ext/libtar/win32/tar.h +35 -0
  82. data/ext/libtar/win32/utime.h +6 -0
  83. data/ext/libtar/win32/win32/types.h +10 -0
  84. data/ext/tarruby.c +648 -0
  85. metadata +150 -0
@@ -0,0 +1,788 @@
1
+ /**************************************************************
2
+ * Original:
3
+ * Patrick Powell Tue Apr 11 09:48:21 PDT 1995
4
+ * A bombproof version of doprnt (dopr) included.
5
+ * Sigh. This sort of thing is always nasty do deal with. Note that
6
+ * the version here does not include floating point...
7
+ *
8
+ * snprintf() is used instead of sprintf() as it does limit checks
9
+ * for string length. This covers a nasty loophole.
10
+ *
11
+ * The other functions are there to prevent NULL pointers from
12
+ * causing nast effects.
13
+ *
14
+ * More Recently:
15
+ * Brandon Long <blong@fiction.net> 9/15/96 for mutt 0.43
16
+ * This was ugly. It is still ugly. I opted out of floating point
17
+ * numbers, but the formatter understands just about everything
18
+ * from the normal C string format, at least as far as I can tell from
19
+ * the Solaris 2.5 printf(3S) man page.
20
+ *
21
+ * Brandon Long <blong@fiction.net> 10/22/97 for mutt 0.87.1
22
+ * Ok, added some minimal floating point support, which means this
23
+ * probably requires libm on most operating systems. Don't yet
24
+ * support the exponent (e,E) and sigfig (g,G). Also, fmtint()
25
+ * was pretty badly broken, it just wasn't being exercised in ways
26
+ * which showed it, so that's been fixed. Also, formated the code
27
+ * to mutt conventions, and removed dead code left over from the
28
+ * original. Also, there is now a builtin-test, just compile with:
29
+ * gcc -DTEST_SNPRINTF -o snprintf snprintf.c -lm
30
+ * and run snprintf for results.
31
+ *
32
+ * Thomas Roessler <roessler@guug.de> 01/27/98 for mutt 0.89i
33
+ * The PGP code was using unsigned hexadecimal formats.
34
+ * Unfortunately, unsigned formats simply didn't work.
35
+ *
36
+ * Michael Elkins <me@cs.hmc.edu> 03/05/98 for mutt 0.90.8
37
+ * The original code assumed that both snprintf() and vsnprintf() were
38
+ * missing. Some systems only have snprintf() but not vsnprintf(), so
39
+ * the code is now broken down under HAVE_SNPRINTF and HAVE_VSNPRINTF.
40
+ *
41
+ **************************************************************/
42
+
43
+ #include <config.h>
44
+
45
+ #if !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF)
46
+
47
+ #include <string.h>
48
+ # include <ctype.h>
49
+ #include <sys/types.h>
50
+
51
+ /* Define this as a fall through, HAVE_STDARG_H is probably already set */
52
+
53
+ #define HAVE_VARARGS_H
54
+
55
+ /* varargs declarations: */
56
+
57
+ #if defined(HAVE_STDARG_H)
58
+ # include <stdarg.h>
59
+ # define HAVE_STDARGS /* let's hope that works everywhere (mj) */
60
+ # define VA_LOCAL_DECL va_list ap
61
+ # define VA_START(f) va_start(ap, f)
62
+ # define VA_SHIFT(v,t) ; /* no-op for ANSI */
63
+ # define VA_END va_end(ap)
64
+ #else
65
+ # if defined(HAVE_VARARGS_H)
66
+ # include <varargs.h>
67
+ # undef HAVE_STDARGS
68
+ # define VA_LOCAL_DECL va_list ap
69
+ # define VA_START(f) va_start(ap) /* f is ignored! */
70
+ # define VA_SHIFT(v,t) v = va_arg(ap,t)
71
+ # define VA_END va_end(ap)
72
+ # else
73
+ /*XX ** NO VARARGS ** XX*/
74
+ # endif
75
+ #endif
76
+
77
+ /*int snprintf (char *str, size_t count, const char *fmt, ...);*/
78
+ /*int vsnprintf (char *str, size_t count, const char *fmt, va_list arg);*/
79
+
80
+ static void dopr (char *buffer, size_t maxlen, const char *format,
81
+ va_list args);
82
+ static void fmtstr (char *buffer, size_t *currlen, size_t maxlen,
83
+ char *value, int flags, int min, int max);
84
+ static void fmtint (char *buffer, size_t *currlen, size_t maxlen,
85
+ long value, int base, int min, int max, int flags);
86
+ static void fmtfp (char *buffer, size_t *currlen, size_t maxlen,
87
+ long double fvalue, int min, int max, int flags);
88
+ static void dopr_outch (char *buffer, size_t *currlen, size_t maxlen, char c );
89
+
90
+ /*
91
+ * dopr(): poor man's version of doprintf
92
+ */
93
+
94
+ /* format read states */
95
+ #define DP_S_DEFAULT 0
96
+ #define DP_S_FLAGS 1
97
+ #define DP_S_MIN 2
98
+ #define DP_S_DOT 3
99
+ #define DP_S_MAX 4
100
+ #define DP_S_MOD 5
101
+ #define DP_S_CONV 6
102
+ #define DP_S_DONE 7
103
+
104
+ /* format flags - Bits */
105
+ #define DP_F_MINUS (1 << 0)
106
+ #define DP_F_PLUS (1 << 1)
107
+ #define DP_F_SPACE (1 << 2)
108
+ #define DP_F_NUM (1 << 3)
109
+ #define DP_F_ZERO (1 << 4)
110
+ #define DP_F_UP (1 << 5)
111
+ #define DP_F_UNSIGNED (1 << 6)
112
+
113
+ /* Conversion Flags */
114
+ #define DP_C_SHORT 1
115
+ #define DP_C_LONG 2
116
+ #define DP_C_LDOUBLE 3
117
+
118
+ #define char_to_int(p) (p - '0')
119
+ #define MAX(p,q) ((p >= q) ? p : q)
120
+
121
+ static void dopr (char *buffer, size_t maxlen, const char *format, va_list args)
122
+ {
123
+ char ch;
124
+ long value;
125
+ long double fvalue;
126
+ char *strvalue;
127
+ int min;
128
+ int max;
129
+ int state;
130
+ int flags;
131
+ int cflags;
132
+ size_t currlen;
133
+
134
+ state = DP_S_DEFAULT;
135
+ currlen = flags = cflags = min = 0;
136
+ max = -1;
137
+ ch = *format++;
138
+
139
+ while (state != DP_S_DONE)
140
+ {
141
+ if ((ch == '\0') || (currlen >= maxlen))
142
+ state = DP_S_DONE;
143
+
144
+ switch(state)
145
+ {
146
+ case DP_S_DEFAULT:
147
+ if (ch == '%')
148
+ state = DP_S_FLAGS;
149
+ else
150
+ dopr_outch (buffer, &currlen, maxlen, ch);
151
+ ch = *format++;
152
+ break;
153
+ case DP_S_FLAGS:
154
+ switch (ch)
155
+ {
156
+ case '-':
157
+ flags |= DP_F_MINUS;
158
+ ch = *format++;
159
+ break;
160
+ case '+':
161
+ flags |= DP_F_PLUS;
162
+ ch = *format++;
163
+ break;
164
+ case ' ':
165
+ flags |= DP_F_SPACE;
166
+ ch = *format++;
167
+ break;
168
+ case '#':
169
+ flags |= DP_F_NUM;
170
+ ch = *format++;
171
+ break;
172
+ case '0':
173
+ flags |= DP_F_ZERO;
174
+ ch = *format++;
175
+ break;
176
+ default:
177
+ state = DP_S_MIN;
178
+ break;
179
+ }
180
+ break;
181
+ case DP_S_MIN:
182
+ if (isdigit((unsigned char)ch))
183
+ {
184
+ min = 10*min + char_to_int (ch);
185
+ ch = *format++;
186
+ }
187
+ else if (ch == '*')
188
+ {
189
+ min = va_arg (args, int);
190
+ ch = *format++;
191
+ state = DP_S_DOT;
192
+ }
193
+ else
194
+ state = DP_S_DOT;
195
+ break;
196
+ case DP_S_DOT:
197
+ if (ch == '.')
198
+ {
199
+ state = DP_S_MAX;
200
+ ch = *format++;
201
+ }
202
+ else
203
+ state = DP_S_MOD;
204
+ break;
205
+ case DP_S_MAX:
206
+ if (isdigit((unsigned char)ch))
207
+ {
208
+ if (max < 0)
209
+ max = 0;
210
+ max = 10*max + char_to_int (ch);
211
+ ch = *format++;
212
+ }
213
+ else if (ch == '*')
214
+ {
215
+ max = va_arg (args, int);
216
+ ch = *format++;
217
+ state = DP_S_MOD;
218
+ }
219
+ else
220
+ state = DP_S_MOD;
221
+ break;
222
+ case DP_S_MOD:
223
+ /* Currently, we don't support Long Long, bummer */
224
+ switch (ch)
225
+ {
226
+ case 'h':
227
+ cflags = DP_C_SHORT;
228
+ ch = *format++;
229
+ break;
230
+ case 'l':
231
+ cflags = DP_C_LONG;
232
+ ch = *format++;
233
+ break;
234
+ case 'L':
235
+ cflags = DP_C_LDOUBLE;
236
+ ch = *format++;
237
+ break;
238
+ default:
239
+ break;
240
+ }
241
+ state = DP_S_CONV;
242
+ break;
243
+ case DP_S_CONV:
244
+ switch (ch)
245
+ {
246
+ case 'd':
247
+ case 'i':
248
+ if (cflags == DP_C_SHORT)
249
+ value = va_arg (args, short int);
250
+ else if (cflags == DP_C_LONG)
251
+ value = va_arg (args, long int);
252
+ else
253
+ value = va_arg (args, int);
254
+ fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags);
255
+ break;
256
+ case 'o':
257
+ flags |= DP_F_UNSIGNED;
258
+ if (cflags == DP_C_SHORT)
259
+ value = va_arg (args, unsigned short int);
260
+ else if (cflags == DP_C_LONG)
261
+ value = va_arg (args, unsigned long int);
262
+ else
263
+ value = va_arg (args, unsigned int);
264
+ fmtint (buffer, &currlen, maxlen, value, 8, min, max, flags);
265
+ break;
266
+ case 'u':
267
+ flags |= DP_F_UNSIGNED;
268
+ if (cflags == DP_C_SHORT)
269
+ value = va_arg (args, unsigned short int);
270
+ else if (cflags == DP_C_LONG)
271
+ value = va_arg (args, unsigned long int);
272
+ else
273
+ value = va_arg (args, unsigned int);
274
+ fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags);
275
+ break;
276
+ case 'X':
277
+ flags |= DP_F_UP;
278
+ case 'x':
279
+ flags |= DP_F_UNSIGNED;
280
+ if (cflags == DP_C_SHORT)
281
+ value = va_arg (args, unsigned short int);
282
+ else if (cflags == DP_C_LONG)
283
+ value = va_arg (args, unsigned long int);
284
+ else
285
+ value = va_arg (args, unsigned int);
286
+ fmtint (buffer, &currlen, maxlen, value, 16, min, max, flags);
287
+ break;
288
+ case 'f':
289
+ if (cflags == DP_C_LDOUBLE)
290
+ fvalue = va_arg (args, long double);
291
+ else
292
+ fvalue = va_arg (args, double);
293
+ /* um, floating point? */
294
+ fmtfp (buffer, &currlen, maxlen, fvalue, min, max, flags);
295
+ break;
296
+ case 'E':
297
+ flags |= DP_F_UP;
298
+ case 'e':
299
+ if (cflags == DP_C_LDOUBLE)
300
+ fvalue = va_arg (args, long double);
301
+ else
302
+ fvalue = va_arg (args, double);
303
+ break;
304
+ case 'G':
305
+ flags |= DP_F_UP;
306
+ case 'g':
307
+ if (cflags == DP_C_LDOUBLE)
308
+ fvalue = va_arg (args, long double);
309
+ else
310
+ fvalue = va_arg (args, double);
311
+ break;
312
+ case 'c':
313
+ dopr_outch (buffer, &currlen, maxlen, va_arg (args, int));
314
+ break;
315
+ case 's':
316
+ strvalue = va_arg (args, char *);
317
+ if (max < 0)
318
+ max = maxlen; /* ie, no max */
319
+ fmtstr (buffer, &currlen, maxlen, strvalue, flags, min, max);
320
+ break;
321
+ case 'p':
322
+ strvalue = va_arg (args, void *);
323
+ fmtint (buffer, &currlen, maxlen, (long) strvalue, 16, min, max, flags);
324
+ break;
325
+ case 'n':
326
+ if (cflags == DP_C_SHORT)
327
+ {
328
+ short int *num;
329
+ num = va_arg (args, short int *);
330
+ *num = currlen;
331
+ }
332
+ else if (cflags == DP_C_LONG)
333
+ {
334
+ long int *num;
335
+ num = va_arg (args, long int *);
336
+ *num = currlen;
337
+ }
338
+ else
339
+ {
340
+ int *num;
341
+ num = va_arg (args, int *);
342
+ *num = currlen;
343
+ }
344
+ break;
345
+ case '%':
346
+ dopr_outch (buffer, &currlen, maxlen, ch);
347
+ break;
348
+ case 'w':
349
+ /* not supported yet, treat as next char */
350
+ ch = *format++;
351
+ break;
352
+ default:
353
+ /* Unknown, skip */
354
+ break;
355
+ }
356
+ ch = *format++;
357
+ state = DP_S_DEFAULT;
358
+ flags = cflags = min = 0;
359
+ max = -1;
360
+ break;
361
+ case DP_S_DONE:
362
+ break;
363
+ default:
364
+ /* hmm? */
365
+ break; /* some picky compilers need this */
366
+ }
367
+ }
368
+ if (currlen < maxlen - 1)
369
+ buffer[currlen] = '\0';
370
+ else
371
+ buffer[maxlen - 1] = '\0';
372
+ }
373
+
374
+ static void fmtstr (char *buffer, size_t *currlen, size_t maxlen,
375
+ char *value, int flags, int min, int max)
376
+ {
377
+ int padlen, strln; /* amount to pad */
378
+ int cnt = 0;
379
+
380
+ if (value == 0)
381
+ {
382
+ value = "<NULL>";
383
+ }
384
+
385
+ for (strln = 0; value[strln]; ++strln); /* strlen */
386
+ padlen = min - strln;
387
+ if (padlen < 0)
388
+ padlen = 0;
389
+ if (flags & DP_F_MINUS)
390
+ padlen = -padlen; /* Left Justify */
391
+
392
+ while ((padlen > 0) && (cnt < max))
393
+ {
394
+ dopr_outch (buffer, currlen, maxlen, ' ');
395
+ --padlen;
396
+ ++cnt;
397
+ }
398
+ while (*value && (cnt < max))
399
+ {
400
+ dopr_outch (buffer, currlen, maxlen, *value++);
401
+ ++cnt;
402
+ }
403
+ while ((padlen < 0) && (cnt < max))
404
+ {
405
+ dopr_outch (buffer, currlen, maxlen, ' ');
406
+ ++padlen;
407
+ ++cnt;
408
+ }
409
+ }
410
+
411
+ /* Have to handle DP_F_NUM (ie 0x and 0 alternates) */
412
+
413
+ static void fmtint (char *buffer, size_t *currlen, size_t maxlen,
414
+ long value, int base, int min, int max, int flags)
415
+ {
416
+ int signvalue = 0;
417
+ unsigned long uvalue;
418
+ char convert[20];
419
+ int place = 0;
420
+ int spadlen = 0; /* amount to space pad */
421
+ int zpadlen = 0; /* amount to zero pad */
422
+ int caps = 0;
423
+
424
+ if (max < 0)
425
+ max = 0;
426
+
427
+ uvalue = value;
428
+
429
+ if(!(flags & DP_F_UNSIGNED))
430
+ {
431
+ if( value < 0 ) {
432
+ signvalue = '-';
433
+ uvalue = -value;
434
+ }
435
+ else
436
+ if (flags & DP_F_PLUS) /* Do a sign (+/i) */
437
+ signvalue = '+';
438
+ else
439
+ if (flags & DP_F_SPACE)
440
+ signvalue = ' ';
441
+ }
442
+
443
+ if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */
444
+
445
+ do {
446
+ convert[place++] =
447
+ (caps? "0123456789ABCDEF":"0123456789abcdef")
448
+ [uvalue % (unsigned)base ];
449
+ uvalue = (uvalue / (unsigned)base );
450
+ } while(uvalue && (place < 20));
451
+ if (place == 20) place--;
452
+ convert[place] = 0;
453
+
454
+ zpadlen = max - place;
455
+ spadlen = min - MAX (max, place) - (signvalue ? 1 : 0);
456
+ if (zpadlen < 0) zpadlen = 0;
457
+ if (spadlen < 0) spadlen = 0;
458
+ if (flags & DP_F_ZERO)
459
+ {
460
+ zpadlen = MAX(zpadlen, spadlen);
461
+ spadlen = 0;
462
+ }
463
+ if (flags & DP_F_MINUS)
464
+ spadlen = -spadlen; /* Left Justifty */
465
+
466
+ #ifdef DEBUG_SNPRINTF
467
+ dprint (1, (debugfile, "zpad: %d, spad: %d, min: %d, max: %d, place: %d\n",
468
+ zpadlen, spadlen, min, max, place));
469
+ #endif
470
+
471
+ /* Spaces */
472
+ while (spadlen > 0)
473
+ {
474
+ dopr_outch (buffer, currlen, maxlen, ' ');
475
+ --spadlen;
476
+ }
477
+
478
+ /* Sign */
479
+ if (signvalue)
480
+ dopr_outch (buffer, currlen, maxlen, signvalue);
481
+
482
+ /* Zeros */
483
+ if (zpadlen > 0)
484
+ {
485
+ while (zpadlen > 0)
486
+ {
487
+ dopr_outch (buffer, currlen, maxlen, '0');
488
+ --zpadlen;
489
+ }
490
+ }
491
+
492
+ /* Digits */
493
+ while (place > 0)
494
+ dopr_outch (buffer, currlen, maxlen, convert[--place]);
495
+
496
+ /* Left Justified spaces */
497
+ while (spadlen < 0) {
498
+ dopr_outch (buffer, currlen, maxlen, ' ');
499
+ ++spadlen;
500
+ }
501
+ }
502
+
503
+ static long double abs_val (long double value)
504
+ {
505
+ long double result = value;
506
+
507
+ if (value < 0)
508
+ result = -value;
509
+
510
+ return result;
511
+ }
512
+
513
+ static long double pow10 (int exp)
514
+ {
515
+ long double result = 1;
516
+
517
+ while (exp)
518
+ {
519
+ result *= 10;
520
+ exp--;
521
+ }
522
+
523
+ return result;
524
+ }
525
+
526
+ static long round (long double value)
527
+ {
528
+ long intpart;
529
+
530
+ intpart = value;
531
+ value = value - intpart;
532
+ if (value >= 0.5)
533
+ intpart++;
534
+
535
+ return intpart;
536
+ }
537
+
538
+ static void fmtfp (char *buffer, size_t *currlen, size_t maxlen,
539
+ long double fvalue, int min, int max, int flags)
540
+ {
541
+ int signvalue = 0;
542
+ long double ufvalue;
543
+ char iconvert[20];
544
+ char fconvert[20];
545
+ int iplace = 0;
546
+ int fplace = 0;
547
+ int padlen = 0; /* amount to pad */
548
+ int zpadlen = 0;
549
+ int caps = 0;
550
+ long intpart;
551
+ long fracpart;
552
+
553
+ /*
554
+ * AIX manpage says the default is 0, but Solaris says the default
555
+ * is 6, and sprintf on AIX defaults to 6
556
+ */
557
+ if (max < 0)
558
+ max = 6;
559
+
560
+ ufvalue = abs_val (fvalue);
561
+
562
+ if (fvalue < 0)
563
+ signvalue = '-';
564
+ else
565
+ if (flags & DP_F_PLUS) /* Do a sign (+/i) */
566
+ signvalue = '+';
567
+ else
568
+ if (flags & DP_F_SPACE)
569
+ signvalue = ' ';
570
+
571
+ #if 0
572
+ if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */
573
+ #endif
574
+
575
+ intpart = ufvalue;
576
+
577
+ /*
578
+ * Sorry, we only support 9 digits past the decimal because of our
579
+ * conversion method
580
+ */
581
+ if (max > 9)
582
+ max = 9;
583
+
584
+ /* We "cheat" by converting the fractional part to integer by
585
+ * multiplying by a factor of 10
586
+ */
587
+ fracpart = round ((pow10 (max)) * (ufvalue - intpart));
588
+
589
+ if (fracpart >= pow10 (max))
590
+ {
591
+ intpart++;
592
+ fracpart -= pow10 (max);
593
+ }
594
+
595
+ #ifdef DEBUG_SNPRINTF
596
+ dprint (1, (debugfile, "fmtfp: %f =? %d.%d\n", fvalue, intpart, fracpart));
597
+ #endif
598
+
599
+ /* Convert integer part */
600
+ do {
601
+ iconvert[iplace++] =
602
+ (caps? "0123456789ABCDEF":"0123456789abcdef")[intpart % 10];
603
+ intpart = (intpart / 10);
604
+ } while(intpart && (iplace < 20));
605
+ if (iplace == 20) iplace--;
606
+ iconvert[iplace] = 0;
607
+
608
+ /* Convert fractional part */
609
+ do {
610
+ fconvert[fplace++] =
611
+ (caps? "0123456789ABCDEF":"0123456789abcdef")[fracpart % 10];
612
+ fracpart = (fracpart / 10);
613
+ } while(fracpart && (fplace < 20));
614
+ if (fplace == 20) fplace--;
615
+ fconvert[fplace] = 0;
616
+
617
+ /* -1 for decimal point, another -1 if we are printing a sign */
618
+ padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0);
619
+ zpadlen = max - fplace;
620
+ if (zpadlen < 0)
621
+ zpadlen = 0;
622
+ if (padlen < 0)
623
+ padlen = 0;
624
+ if (flags & DP_F_MINUS)
625
+ padlen = -padlen; /* Left Justifty */
626
+
627
+ if ((flags & DP_F_ZERO) && (padlen > 0))
628
+ {
629
+ if (signvalue)
630
+ {
631
+ dopr_outch (buffer, currlen, maxlen, signvalue);
632
+ --padlen;
633
+ signvalue = 0;
634
+ }
635
+ while (padlen > 0)
636
+ {
637
+ dopr_outch (buffer, currlen, maxlen, '0');
638
+ --padlen;
639
+ }
640
+ }
641
+ while (padlen > 0)
642
+ {
643
+ dopr_outch (buffer, currlen, maxlen, ' ');
644
+ --padlen;
645
+ }
646
+ if (signvalue)
647
+ dopr_outch (buffer, currlen, maxlen, signvalue);
648
+
649
+ while (iplace > 0)
650
+ dopr_outch (buffer, currlen, maxlen, iconvert[--iplace]);
651
+
652
+ /*
653
+ * Decimal point. This should probably use locale to find the correct
654
+ * char to print out.
655
+ */
656
+ dopr_outch (buffer, currlen, maxlen, '.');
657
+
658
+ while (fplace > 0)
659
+ dopr_outch (buffer, currlen, maxlen, fconvert[--fplace]);
660
+
661
+ while (zpadlen > 0)
662
+ {
663
+ dopr_outch (buffer, currlen, maxlen, '0');
664
+ --zpadlen;
665
+ }
666
+
667
+ while (padlen < 0)
668
+ {
669
+ dopr_outch (buffer, currlen, maxlen, ' ');
670
+ ++padlen;
671
+ }
672
+ }
673
+
674
+ static void dopr_outch (char *buffer, size_t *currlen, size_t maxlen, char c)
675
+ {
676
+ if (*currlen < maxlen)
677
+ buffer[(*currlen)++] = c;
678
+ }
679
+ #endif /* !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF) */
680
+
681
+ #ifndef HAVE_VSNPRINTF
682
+ int mutt_vsnprintf (char *str, size_t count, const char *fmt, va_list args)
683
+ {
684
+ str[0] = 0;
685
+ dopr(str, count, fmt, args);
686
+ return(strlen(str));
687
+ }
688
+ #endif /* !HAVE_VSNPRINTF */
689
+
690
+ #ifndef HAVE_SNPRINTF
691
+ /* VARARGS3 */
692
+ #ifdef HAVE_STDARGS
693
+ int mutt_snprintf (char *str,size_t count,const char *fmt,...)
694
+ #else
695
+ int mutt_snprintf (va_alist) va_dcl
696
+ #endif
697
+ {
698
+ #ifndef HAVE_STDARGS
699
+ char *str;
700
+ size_t count;
701
+ char *fmt;
702
+ #endif
703
+ VA_LOCAL_DECL;
704
+
705
+ VA_START (fmt);
706
+ VA_SHIFT (str, char *);
707
+ VA_SHIFT (count, size_t );
708
+ VA_SHIFT (fmt, char *);
709
+ (void) mutt_vsnprintf(str, count, fmt, ap);
710
+ VA_END;
711
+ return(strlen(str));
712
+ }
713
+
714
+ #ifdef TEST_SNPRINTF
715
+ #ifndef LONG_STRING
716
+ #define LONG_STRING 1024
717
+ #endif
718
+ int main (void)
719
+ {
720
+ char buf1[LONG_STRING];
721
+ char buf2[LONG_STRING];
722
+ char *fp_fmt[] = {
723
+ "%-1.5f",
724
+ "%1.5f",
725
+ "%123.9f",
726
+ "%10.5f",
727
+ "% 10.5f",
728
+ "%+22.9f",
729
+ "%+4.9f",
730
+ "%01.3f",
731
+ "%4f",
732
+ "%3.1f",
733
+ "%3.2f",
734
+ NULL
735
+ };
736
+ double fp_nums[] = { -1.5, 134.21, 91340.2, 341.1234, 0203.9, 0.96, 0.996,
737
+ 0.9996, 1.996, 4.136, 0};
738
+ char *int_fmt[] = {
739
+ "%-1.5d",
740
+ "%1.5d",
741
+ "%123.9d",
742
+ "%5.5d",
743
+ "%10.5d",
744
+ "% 10.5d",
745
+ "%+22.33d",
746
+ "%01.3d",
747
+ "%4d",
748
+ NULL
749
+ };
750
+ long int_nums[] = { -1, 134, 91340, 341, 0203, 0};
751
+ int x, y;
752
+ int fail = 0;
753
+ int num = 0;
754
+
755
+ printf ("Testing snprintf format codes against system sprintf...\n");
756
+
757
+ for (x = 0; fp_fmt[x] != NULL ; x++)
758
+ for (y = 0; fp_nums[y] != 0 ; y++)
759
+ {
760
+ mutt_snprintf (buf1, sizeof (buf1), fp_fmt[x], fp_nums[y]);
761
+ sprintf (buf2, fp_fmt[x], fp_nums[y]);
762
+ if (strcmp (buf1, buf2))
763
+ {
764
+ printf("snprintf doesn't match Format: %s\n\tsnprintf = %s\n\tsprintf = %s\n",
765
+ fp_fmt[x], buf1, buf2);
766
+ fail++;
767
+ }
768
+ num++;
769
+ }
770
+
771
+ for (x = 0; int_fmt[x] != NULL ; x++)
772
+ for (y = 0; int_nums[y] != 0 ; y++)
773
+ {
774
+ mutt_snprintf (buf1, sizeof (buf1), int_fmt[x], int_nums[y]);
775
+ sprintf (buf2, int_fmt[x], int_nums[y]);
776
+ if (strcmp (buf1, buf2))
777
+ {
778
+ printf("snprintf doesn't match Format: %s\n\tsnprintf = %s\n\tsprintf = %s\n",
779
+ int_fmt[x], buf1, buf2);
780
+ fail++;
781
+ }
782
+ num++;
783
+ }
784
+ printf ("%d tests failed out of %d.\n", fail, num);
785
+ }
786
+ #endif /* SNPRINTF_TEST */
787
+
788
+ #endif /* !HAVE_SNPRINTF */