Rev 5191 | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 5191 | Rev 6324 | ||
---|---|---|---|
Line 1... | Line 1... | ||
1 | /* Like vsprintf but provides a pointer to malloc'd storage, which must |
1 | /* Like vsprintf but provides a pointer to malloc'd storage, which must |
2 | be freed by the caller. |
2 | be freed by the caller. |
3 | Copyright (C) 1994, 2003, 2011 Free Software Foundation, Inc. |
3 | Copyright (C) 1994, 2003, 2011, 2013 Free Software Foundation, Inc. |
Line 4... | Line 4... | ||
4 | 4 | ||
5 | This file is part of the libiberty library. |
5 | This file is part of the libiberty library. |
6 | Libiberty is free software; you can redistribute it and/or |
6 | Libiberty is free software; you can redistribute it and/or |
7 | modify it under the terms of the GNU Library General Public |
7 | modify it under the terms of the GNU Library General Public |
Line 12... | Line 12... | ||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
14 | Library General Public License for more details. |
14 | Library General Public License for more details. |
Line 15... | Line 15... | ||
15 | 15 | ||
16 | You should have received a copy of the GNU Library General Public |
16 | You should have received a copy of the GNU Library General Public |
17 | License along with libiberty; see the file COPYING.LIB. If |
17 | License along with libiberty; see the file COPYING.LIB. If not, write |
18 | not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, |
18 | to the Free Software Foundation, Inc., 51 Franklin Street - Fifth |
Line 19... | Line 19... | ||
19 | Boston, MA 02110-1301, USA. */ |
19 | Floor, Boston, MA 02110-1301, USA. */ |
20 | 20 | ||
21 | #ifdef HAVE_CONFIG_H |
21 | #ifdef HAVE_CONFIG_H |
22 | #include "config.h" |
22 | #include "config.h" |
Line 31... | Line 31... | ||
31 | #include |
31 | #include |
32 | #endif |
32 | #endif |
33 | #ifdef HAVE_STDLIB_H |
33 | #ifdef HAVE_STDLIB_H |
34 | #include |
34 | #include |
35 | #else |
35 | #else |
36 | extern unsigned long strtoul (); |
- | |
37 | extern PTR malloc (); |
36 | extern PTR malloc (); |
38 | #endif |
37 | #endif |
39 | #include "libiberty.h" |
38 | #include "libiberty.h" |
- | 39 | #include "vprintf-support.h" |
|
Line 40... | Line 40... | ||
40 | 40 | ||
41 | #ifdef TEST |
41 | #ifdef TEST |
42 | int global_total_width; |
42 | int global_total_width; |
Line 62... | Line 62... | ||
62 | static int int_vasprintf (char **, const char *, va_list); |
62 | static int int_vasprintf (char **, const char *, va_list); |
Line 63... | Line 63... | ||
63 | 63 | ||
64 | static int |
64 | static int |
65 | int_vasprintf (char **result, const char *format, va_list args) |
65 | int_vasprintf (char **result, const char *format, va_list args) |
66 | { |
- | |
67 | const char *p = format; |
- | |
68 | /* Add one to make sure that it is never zero, which might cause malloc |
- | |
69 | to return NULL. */ |
66 | { |
70 | int total_width = strlen (format) + 1; |
- | |
71 | va_list ap; |
- | |
72 | - | ||
73 | #ifdef va_copy |
- | |
74 | va_copy (ap, args); |
- | |
75 | #else |
- | |
76 | memcpy ((PTR) &ap, (PTR) &args, sizeof (va_list)); |
- | |
77 | #endif |
- | |
78 | - | ||
79 | while (*p != '\0') |
- | |
80 | { |
- | |
81 | if (*p++ == '%') |
- | |
82 | { |
- | |
83 | while (strchr ("-+ #0", *p)) |
- | |
84 | ++p; |
- | |
85 | if (*p == '*') |
- | |
86 | { |
- | |
87 | ++p; |
- | |
88 | total_width += abs (va_arg (ap, int)); |
- | |
89 | } |
- | |
90 | else |
- | |
91 | total_width += strtoul (p, (char **) &p, 10); |
- | |
92 | if (*p == '.') |
- | |
93 | { |
- | |
94 | ++p; |
- | |
95 | if (*p == '*') |
- | |
96 | { |
- | |
97 | ++p; |
- | |
98 | total_width += abs (va_arg (ap, int)); |
- | |
99 | } |
- | |
100 | else |
- | |
101 | total_width += strtoul (p, (char **) &p, 10); |
- | |
102 | } |
- | |
103 | while (strchr ("hlL", *p)) |
- | |
104 | ++p; |
- | |
105 | /* Should be big enough for any format specifier except %s and floats. */ |
- | |
106 | total_width += 30; |
- | |
107 | switch (*p) |
- | |
108 | { |
- | |
109 | case 'd': |
- | |
110 | case 'i': |
- | |
111 | case 'o': |
- | |
112 | case 'u': |
- | |
113 | case 'x': |
- | |
114 | case 'X': |
- | |
115 | case 'c': |
- | |
116 | (void) va_arg (ap, int); |
- | |
117 | break; |
- | |
118 | case 'f': |
- | |
119 | case 'e': |
- | |
120 | case 'E': |
- | |
121 | case 'g': |
- | |
122 | case 'G': |
- | |
123 | (void) va_arg (ap, double); |
- | |
124 | /* Since an ieee double can have an exponent of 307, we'll |
- | |
125 | make the buffer wide enough to cover the gross case. */ |
- | |
126 | total_width += 307; |
- | |
127 | break; |
- | |
128 | case 's': |
- | |
129 | total_width += strlen (va_arg (ap, char *)); |
- | |
130 | break; |
- | |
131 | case 'p': |
- | |
132 | case 'n': |
- | |
133 | (void) va_arg (ap, char *); |
- | |
134 | break; |
- | |
135 | } |
- | |
136 | p++; |
- | |
137 | } |
- | |
138 | } |
- | |
139 | #ifdef va_copy |
- | |
140 | va_end (ap); |
- | |
141 | #endif |
67 | int total_width = libiberty_vprintf_buffer_size (format, args); |
142 | #ifdef TEST |
68 | #ifdef TEST |
143 | global_total_width = total_width; |
69 | global_total_width = total_width; |
144 | #endif |
70 | #endif |
145 | *result = (char *) malloc (total_width); |
71 | *result = (char *) malloc (total_width); |
Line 163... | Line 89... | ||
163 | #ifdef TEST |
89 | #ifdef TEST |
164 | static void ATTRIBUTE_PRINTF_1 |
90 | static void ATTRIBUTE_PRINTF_1 |
165 | checkit (const char *format, ...) |
91 | checkit (const char *format, ...) |
166 | { |
92 | { |
167 | char *result; |
93 | char *result; |
168 | VA_OPEN (args, format); |
94 | va_list args; |
169 | VA_FIXEDARG (args, const char *, format); |
95 | va_start (args, format); |
170 | vasprintf (&result, format, args); |
96 | vasprintf (&result, format, args); |
171 | VA_CLOSE (args); |
97 | va_end (args); |
Line 172... | Line 98... | ||
172 | 98 | ||
173 | if (strlen (result) < (size_t) global_total_width) |
99 | if (strlen (result) < (size_t) global_total_width) |
174 | printf ("PASS: "); |
100 | printf ("PASS: "); |
175 | else |
101 | else |