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