ignore invalid DOF provider sections
[binutils-gdb.git] / gdb / common / format.c
blobdeea93ca9536be8d616164b93d1fe255f19b764b
1 /* Parse a printf-style format string.
3 Copyright (C) 1986-2015 Free Software Foundation, Inc.
5 This file is part of GDB.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
20 #include "common-defs.h"
21 #include "format.h"
23 struct format_piece *
24 parse_format_string (const char **arg)
26 const char *s;
27 char *f, *string;
28 const char *prev_start;
29 const char *percent_loc;
30 char *sub_start, *current_substring;
31 struct format_piece *pieces;
32 int next_frag;
33 int max_pieces;
34 enum argclass this_argclass;
36 s = *arg;
38 /* Parse the format-control string and copy it into the string STRING,
39 processing some kinds of escape sequence. */
41 f = string = (char *) alloca (strlen (s) + 1);
43 while (*s != '"' && *s != '\0')
45 int c = *s++;
46 switch (c)
48 case '\0':
49 continue;
51 case '\\':
52 switch (c = *s++)
54 case '\\':
55 *f++ = '\\';
56 break;
57 case 'a':
58 *f++ = '\a';
59 break;
60 case 'b':
61 *f++ = '\b';
62 break;
63 case 'f':
64 *f++ = '\f';
65 break;
66 case 'n':
67 *f++ = '\n';
68 break;
69 case 'r':
70 *f++ = '\r';
71 break;
72 case 't':
73 *f++ = '\t';
74 break;
75 case 'v':
76 *f++ = '\v';
77 break;
78 case '"':
79 *f++ = '"';
80 break;
81 default:
82 /* ??? TODO: handle other escape sequences. */
83 error (_("Unrecognized escape character \\%c in format string."),
84 c);
86 break;
88 default:
89 *f++ = c;
93 /* Terminate our escape-processed copy. */
94 *f++ = '\0';
96 /* Whether the format string ended with double-quote or zero, we're
97 done with it; it's up to callers to complain about syntax. */
98 *arg = s;
100 /* Need extra space for the '\0's. Doubling the size is sufficient. */
102 current_substring = xmalloc (strlen (string) * 2 + 1000);
104 max_pieces = strlen (string) + 2;
106 pieces = (struct format_piece *)
107 xmalloc (max_pieces * sizeof (struct format_piece));
109 next_frag = 0;
111 /* Now scan the string for %-specs and see what kinds of args they want.
112 argclass classifies the %-specs so we can give printf-type functions
113 something of the right size. */
115 f = string;
116 prev_start = string;
117 while (*f)
118 if (*f++ == '%')
120 int seen_hash = 0, seen_zero = 0, lcount = 0, seen_prec = 0;
121 int seen_space = 0, seen_plus = 0;
122 int seen_big_l = 0, seen_h = 0, seen_big_h = 0;
123 int seen_big_d = 0, seen_double_big_d = 0;
124 int bad = 0;
126 /* Skip over "%%", it will become part of a literal piece. */
127 if (*f == '%')
129 f++;
130 continue;
133 sub_start = current_substring;
135 strncpy (current_substring, prev_start, f - 1 - prev_start);
136 current_substring += f - 1 - prev_start;
137 *current_substring++ = '\0';
139 pieces[next_frag].string = sub_start;
140 pieces[next_frag].argclass = literal_piece;
141 next_frag++;
143 percent_loc = f - 1;
145 /* Check the validity of the format specifier, and work
146 out what argument it expects. We only accept C89
147 format strings, with the exception of long long (which
148 we autoconf for). */
150 /* The first part of a format specifier is a set of flag
151 characters. */
152 while (*f != '\0' && strchr ("0-+ #", *f))
154 if (*f == '#')
155 seen_hash = 1;
156 else if (*f == '0')
157 seen_zero = 1;
158 else if (*f == ' ')
159 seen_space = 1;
160 else if (*f == '+')
161 seen_plus = 1;
162 f++;
165 /* The next part of a format specifier is a width. */
166 while (*f != '\0' && strchr ("0123456789", *f))
167 f++;
169 /* The next part of a format specifier is a precision. */
170 if (*f == '.')
172 seen_prec = 1;
173 f++;
174 while (*f != '\0' && strchr ("0123456789", *f))
175 f++;
178 /* The next part of a format specifier is a length modifier. */
179 if (*f == 'h')
181 seen_h = 1;
182 f++;
184 else if (*f == 'l')
186 f++;
187 lcount++;
188 if (*f == 'l')
190 f++;
191 lcount++;
194 else if (*f == 'L')
196 seen_big_l = 1;
197 f++;
199 /* Decimal32 modifier. */
200 else if (*f == 'H')
202 seen_big_h = 1;
203 f++;
205 /* Decimal64 and Decimal128 modifiers. */
206 else if (*f == 'D')
208 f++;
210 /* Check for a Decimal128. */
211 if (*f == 'D')
213 f++;
214 seen_double_big_d = 1;
216 else
217 seen_big_d = 1;
220 switch (*f)
222 case 'u':
223 if (seen_hash)
224 bad = 1;
225 /* FALLTHROUGH */
227 case 'o':
228 case 'x':
229 case 'X':
230 if (seen_space || seen_plus)
231 bad = 1;
232 /* FALLTHROUGH */
234 case 'd':
235 case 'i':
236 if (lcount == 0)
237 this_argclass = int_arg;
238 else if (lcount == 1)
239 this_argclass = long_arg;
240 else
241 this_argclass = long_long_arg;
243 if (seen_big_l)
244 bad = 1;
245 break;
247 case 'c':
248 this_argclass = lcount == 0 ? int_arg : wide_char_arg;
249 if (lcount > 1 || seen_h || seen_big_l)
250 bad = 1;
251 if (seen_prec || seen_zero || seen_space || seen_plus)
252 bad = 1;
253 break;
255 case 'p':
256 this_argclass = ptr_arg;
257 if (lcount || seen_h || seen_big_l)
258 bad = 1;
259 if (seen_prec)
260 bad = 1;
261 if (seen_hash || seen_zero || seen_space || seen_plus)
262 bad = 1;
263 break;
265 case 's':
266 this_argclass = lcount == 0 ? string_arg : wide_string_arg;
267 if (lcount > 1 || seen_h || seen_big_l)
268 bad = 1;
269 if (seen_zero || seen_space || seen_plus)
270 bad = 1;
271 break;
273 case 'e':
274 case 'f':
275 case 'g':
276 case 'E':
277 case 'G':
278 if (seen_big_h || seen_big_d || seen_double_big_d)
279 this_argclass = decfloat_arg;
280 else if (seen_big_l)
281 this_argclass = long_double_arg;
282 else
283 this_argclass = double_arg;
285 if (lcount || seen_h)
286 bad = 1;
287 break;
289 case '*':
290 error (_("`*' not supported for precision or width in printf"));
292 case 'n':
293 error (_("Format specifier `n' not supported in printf"));
295 case '\0':
296 error (_("Incomplete format specifier at end of format string"));
298 default:
299 error (_("Unrecognized format specifier '%c' in printf"), *f);
302 if (bad)
303 error (_("Inappropriate modifiers to "
304 "format specifier '%c' in printf"),
305 *f);
307 f++;
309 sub_start = current_substring;
311 if (lcount > 1 && USE_PRINTF_I64)
313 /* Windows' printf does support long long, but not the usual way.
314 Convert %lld to %I64d. */
315 int length_before_ll = f - percent_loc - 1 - lcount;
317 strncpy (current_substring, percent_loc, length_before_ll);
318 strcpy (current_substring + length_before_ll, "I64");
319 current_substring[length_before_ll + 3] =
320 percent_loc[length_before_ll + lcount];
321 current_substring += length_before_ll + 4;
323 else if (this_argclass == wide_string_arg
324 || this_argclass == wide_char_arg)
326 /* Convert %ls or %lc to %s. */
327 int length_before_ls = f - percent_loc - 2;
329 strncpy (current_substring, percent_loc, length_before_ls);
330 strcpy (current_substring + length_before_ls, "s");
331 current_substring += length_before_ls + 2;
333 else
335 strncpy (current_substring, percent_loc, f - percent_loc);
336 current_substring += f - percent_loc;
339 *current_substring++ = '\0';
341 prev_start = f;
343 pieces[next_frag].string = sub_start;
344 pieces[next_frag].argclass = this_argclass;
345 next_frag++;
348 /* Record the remainder of the string. */
350 sub_start = current_substring;
352 strncpy (current_substring, prev_start, f - prev_start);
353 current_substring += f - prev_start;
354 *current_substring++ = '\0';
356 pieces[next_frag].string = sub_start;
357 pieces[next_frag].argclass = literal_piece;
358 next_frag++;
360 /* Record an end-of-array marker. */
362 pieces[next_frag].string = NULL;
363 pieces[next_frag].argclass = literal_piece;
365 return pieces;
368 void
369 free_format_pieces (struct format_piece *pieces)
371 if (!pieces)
372 return;
374 /* We happen to know that all the string pieces are in the block
375 pointed to by the first string piece. */
376 if (pieces[0].string)
377 xfree (pieces[0].string);
379 xfree (pieces);
382 void
383 free_format_pieces_cleanup (void *ptr)
385 void **location = ptr;
387 if (location == NULL)
388 return;
390 if (*location != NULL)
392 free_format_pieces (*location);
393 *location = NULL;