libdballe 9.6
vasprintf.h
1#ifndef DBALLE_CORE_VASPRINTF_H
2#define DBALLE_CORE_VASPRINTF_H
3
4#include "config.h"
5#include <cstdarg>
6#include <cstring>
7#include <cstdlib>
8#include <cmath>
9
10#if USE_OWN_VASPRINTF
11static int vasprintf (char **result, const char *format, va_list args)
12{
13 const char *p = format;
14 /* Add one to make sure that it is never zero, which might cause malloc
15 to return NULL. */
16 int total_width = strlen (format) + 1;
17 va_list ap;
18
19 memcpy ((void *)&ap, (void *)&args, sizeof (va_list));
20
21 while (*p != '\0')
22 {
23 if (*p++ == '%')
24 {
25 while (strchr ("-+ #0", *p))
26 ++p;
27 if (*p == '*')
28 {
29 ++p;
30 total_width += abs (va_arg (ap, int));
31 }
32 else
33 total_width += strtoul (p, (char **) &p, 10);
34 if (*p == '.')
35 {
36 ++p;
37 if (*p == '*')
38 {
39 ++p;
40 total_width += abs (va_arg (ap, int));
41 }
42 else
43 total_width += strtoul (p, (char **) &p, 10);
44 }
45 while (strchr ("hlL", *p))
46 ++p;
47 /* Should be big enough for any format specifier except %s and floats. */
48 total_width += 30;
49 switch (*p)
50 {
51 case 'd':
52 case 'i':
53 case 'o':
54 case 'u':
55 case 'x':
56 case 'X':
57 case 'c':
58 (void) va_arg (ap, int);
59 break;
60 case 'f':
61 case 'e':
62 case 'E':
63 case 'g':
64 case 'G':
65 (void) va_arg (ap, double);
66 /* Since an ieee double can have an exponent of 307, we'll
67 make the buffer wide enough to cover the gross case. */
68 total_width += 307;
69 break;
70 case 's':
71 total_width += strlen (va_arg (ap, char *));
72 break;
73 case 'p':
74 case 'n':
75 (void) va_arg (ap, char *);
76 break;
77 }
78 p++;
79 }
80 }
81 *result = (char*)malloc (total_width);
82 if (*result != NULL) {
83 return vsprintf (*result, format, args);}
84 else {
85 return 0;
86 }
87}
88static int asprintf (char **result, const char *format, ...)
89{
90 va_list ap;
91 va_start(ap, format);
92 int res = vasprintf(result, format, ap);
93 va_end(ap);
94 return res;
95}
96#endif
97
98#endif