Mercurial > hg > CbC > CbC_gcc
comparison libiberty/vasprintf.c @ 111:04ced10e8804
gcc 7
author | kono |
---|---|
date | Fri, 27 Oct 2017 22:46:09 +0900 |
parents | f6334be47118 |
children | 84e7813d76e9 |
comparison
equal
deleted
inserted
replaced
68:561a7518be6b | 111:04ced10e8804 |
---|---|
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-2017 Free Software Foundation, Inc. |
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 |
8 License as published by the Free Software Foundation; either | 8 License as published by the Free Software Foundation; either |
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. |
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 |
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" |
23 #endif | 23 #endif |
24 #include <ansidecl.h> | 24 #include <ansidecl.h> |
31 #include <string.h> | 31 #include <string.h> |
32 #endif | 32 #endif |
33 #ifdef HAVE_STDLIB_H | 33 #ifdef HAVE_STDLIB_H |
34 #include <stdlib.h> | 34 #include <stdlib.h> |
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" | |
40 | 40 |
41 #ifdef TEST | 41 #ifdef TEST |
42 int global_total_width; | 42 int global_total_width; |
43 #endif | 43 #endif |
44 | 44 |
62 static int int_vasprintf (char **, const char *, va_list); | 62 static int int_vasprintf (char **, const char *, va_list); |
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 { | 66 { |
67 const char *p = format; | 67 int total_width = libiberty_vprintf_buffer_size (format, args); |
68 /* Add one to make sure that it is never zero, which might cause malloc | |
69 to return NULL. */ | |
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 | |
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); |
146 if (*result != NULL) | 72 if (*result != NULL) |
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); |
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 |
176 printf ("FAIL: "); | 102 printf ("FAIL: "); |