sparc: Make kill_unused_stacknodes() work by not shadowing the variable, which should...
[libfirm] / ir / obstack / obstack_printf.c
1 #include <config.h>
2 #include <stdarg.h>
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <assert.h>
6 #include "obstack.h"
7
8 #ifdef _WIN32
9 /* win32/C89 has no va_copy function... so we have to use the stupid fixed-length version */
10 int obstack_vprintf(struct obstack *obst, const char *fmt, va_list ap) FIRM_NOTHROW
11 {
12         char buf[16384];
13         int len = _vsnprintf(buf, sizeof(buf), fmt, ap);
14         obstack_grow(obst, buf, len);
15         return len;
16 }
17 #else
18 int obstack_vprintf(struct obstack *obst, const char *fmt, va_list ap) FIRM_NOTHROW
19 {
20         char    buf[128];
21         char   *buffer = buf;
22         size_t  size   = sizeof(buf);
23         int     len;
24
25         for (;;) {
26                 va_list tap;
27                 va_copy(tap, ap);
28                 len = vsnprintf(buffer, size, fmt, tap);
29
30                 /* snprintf should return -1 only in the error case, but older glibcs
31                  * and probably other systems are buggy in this respect and return -1 if
32                  * the buffer was too small. We only abort for LARGE unrealistic buffer
33                  * sizes here */
34                 if (len < 0) {
35                         if (buffer != buf)
36                                 free(buffer);
37                         if (size > 65536)
38                                 return -1;
39                         size *= 2;
40                 } else if ((size_t)len >= size) {
41                         /* If we come here more than once, vsnprintf() returned garbage */
42                         assert(buffer == buf);
43                         size = (size_t)len + 1;
44                 } else {
45                         break;
46                 }
47                 buffer = (char*)malloc(size);
48         }
49
50         obstack_grow(obst, buffer, len);
51         if (buffer != buf)
52                 free(buffer);
53
54         return len;
55 }
56 #endif
57
58 int obstack_printf(struct obstack *obst, const char *fmt, ...) FIRM_NOTHROW
59 {
60         va_list ap;
61         int     res;
62
63         va_start(ap, fmt);
64         res = obstack_vprintf(obst, fmt, ap);
65         va_end(ap);
66
67         return res;
68 }