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