xref: /dflybsd-src/contrib/gcc-4.7/gcc/pretty-print.c (revision 04febcfb30580676d3e95f58a16c5137ee478b32)
1*e4b17023SJohn Marino /* Various declarations for language-independent pretty-print subroutines.
2*e4b17023SJohn Marino    Copyright (C) 2003, 2004, 2005, 2007, 2008, 2009, 2010
3*e4b17023SJohn Marino    Free Software Foundation, Inc.
4*e4b17023SJohn Marino    Contributed by Gabriel Dos Reis <gdr@integrable-solutions.net>
5*e4b17023SJohn Marino 
6*e4b17023SJohn Marino This file is part of GCC.
7*e4b17023SJohn Marino 
8*e4b17023SJohn Marino GCC is free software; you can redistribute it and/or modify it under
9*e4b17023SJohn Marino the terms of the GNU General Public License as published by the Free
10*e4b17023SJohn Marino Software Foundation; either version 3, or (at your option) any later
11*e4b17023SJohn Marino version.
12*e4b17023SJohn Marino 
13*e4b17023SJohn Marino GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14*e4b17023SJohn Marino WARRANTY; without even the implied warranty of MERCHANTABILITY or
15*e4b17023SJohn Marino FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16*e4b17023SJohn Marino for more details.
17*e4b17023SJohn Marino 
18*e4b17023SJohn Marino You should have received a copy of the GNU General Public License
19*e4b17023SJohn Marino along with GCC; see the file COPYING3.  If not see
20*e4b17023SJohn Marino <http://www.gnu.org/licenses/>.  */
21*e4b17023SJohn Marino 
22*e4b17023SJohn Marino #include "config.h"
23*e4b17023SJohn Marino #include "system.h"
24*e4b17023SJohn Marino #include "coretypes.h"
25*e4b17023SJohn Marino #include "intl.h"
26*e4b17023SJohn Marino #include "pretty-print.h"
27*e4b17023SJohn Marino 
28*e4b17023SJohn Marino #if HAVE_ICONV
29*e4b17023SJohn Marino #include <iconv.h>
30*e4b17023SJohn Marino #endif
31*e4b17023SJohn Marino 
32*e4b17023SJohn Marino /* A pointer to the formatted diagnostic message.  */
33*e4b17023SJohn Marino #define pp_formatted_text_data(PP) \
34*e4b17023SJohn Marino    ((const char *) obstack_base (pp_base (PP)->buffer->obstack))
35*e4b17023SJohn Marino 
36*e4b17023SJohn Marino /* Format an integer given by va_arg (ARG, type-specifier T) where
37*e4b17023SJohn Marino    type-specifier is a precision modifier as indicated by PREC.  F is
38*e4b17023SJohn Marino    a string used to construct the appropriate format-specifier.  */
39*e4b17023SJohn Marino #define pp_integer_with_precision(PP, ARG, PREC, T, F)       \
40*e4b17023SJohn Marino   do                                                         \
41*e4b17023SJohn Marino     switch (PREC)                                            \
42*e4b17023SJohn Marino       {                                                      \
43*e4b17023SJohn Marino       case 0:                                                \
44*e4b17023SJohn Marino         pp_scalar (PP, "%" F, va_arg (ARG, T));              \
45*e4b17023SJohn Marino         break;                                               \
46*e4b17023SJohn Marino                                                              \
47*e4b17023SJohn Marino       case 1:                                                \
48*e4b17023SJohn Marino         pp_scalar (PP, "%l" F, va_arg (ARG, long T));        \
49*e4b17023SJohn Marino         break;                                               \
50*e4b17023SJohn Marino                                                              \
51*e4b17023SJohn Marino       case 2:                                                \
52*e4b17023SJohn Marino         pp_scalar (PP, "%" HOST_LONG_LONG_FORMAT F, va_arg (ARG, long long T));  \
53*e4b17023SJohn Marino         break;                                               \
54*e4b17023SJohn Marino                                                              \
55*e4b17023SJohn Marino       default:                                               \
56*e4b17023SJohn Marino         break;                                               \
57*e4b17023SJohn Marino       }                                                      \
58*e4b17023SJohn Marino   while (0)
59*e4b17023SJohn Marino 
60*e4b17023SJohn Marino 
61*e4b17023SJohn Marino /* Subroutine of pp_set_maximum_length.  Set up PRETTY-PRINTER's
62*e4b17023SJohn Marino    internal maximum characters per line.  */
63*e4b17023SJohn Marino static void
pp_set_real_maximum_length(pretty_printer * pp)64*e4b17023SJohn Marino pp_set_real_maximum_length (pretty_printer *pp)
65*e4b17023SJohn Marino {
66*e4b17023SJohn Marino   /* If we're told not to wrap lines then do the obvious thing.  In case
67*e4b17023SJohn Marino      we'll emit prefix only once per message, it is appropriate
68*e4b17023SJohn Marino      not to increase unnecessarily the line-length cut-off.  */
69*e4b17023SJohn Marino   if (!pp_is_wrapping_line (pp)
70*e4b17023SJohn Marino       || pp_prefixing_rule (pp) == DIAGNOSTICS_SHOW_PREFIX_ONCE
71*e4b17023SJohn Marino       || pp_prefixing_rule (pp) == DIAGNOSTICS_SHOW_PREFIX_NEVER)
72*e4b17023SJohn Marino     pp->maximum_length = pp_line_cutoff (pp);
73*e4b17023SJohn Marino   else
74*e4b17023SJohn Marino     {
75*e4b17023SJohn Marino       int prefix_length = pp->prefix ? strlen (pp->prefix) : 0;
76*e4b17023SJohn Marino       /* If the prefix is ridiculously too long, output at least
77*e4b17023SJohn Marino          32 characters.  */
78*e4b17023SJohn Marino       if (pp_line_cutoff (pp) - prefix_length < 32)
79*e4b17023SJohn Marino 	pp->maximum_length = pp_line_cutoff (pp) + 32;
80*e4b17023SJohn Marino       else
81*e4b17023SJohn Marino 	pp->maximum_length = pp_line_cutoff (pp);
82*e4b17023SJohn Marino     }
83*e4b17023SJohn Marino }
84*e4b17023SJohn Marino 
85*e4b17023SJohn Marino /* Clear PRETTY-PRINTER's output state.  */
86*e4b17023SJohn Marino static inline void
pp_clear_state(pretty_printer * pp)87*e4b17023SJohn Marino pp_clear_state (pretty_printer *pp)
88*e4b17023SJohn Marino {
89*e4b17023SJohn Marino   pp->emitted_prefix = false;
90*e4b17023SJohn Marino   pp_indentation (pp) = 0;
91*e4b17023SJohn Marino }
92*e4b17023SJohn Marino 
93*e4b17023SJohn Marino /* Flush the formatted text of PRETTY-PRINTER onto the attached stream.  */
94*e4b17023SJohn Marino void
pp_write_text_to_stream(pretty_printer * pp)95*e4b17023SJohn Marino pp_write_text_to_stream (pretty_printer *pp)
96*e4b17023SJohn Marino {
97*e4b17023SJohn Marino   const char *text = pp_formatted_text (pp);
98*e4b17023SJohn Marino   fputs (text, pp->buffer->stream);
99*e4b17023SJohn Marino   pp_clear_output_area (pp);
100*e4b17023SJohn Marino }
101*e4b17023SJohn Marino 
102*e4b17023SJohn Marino /* Wrap a text delimited by START and END into PRETTY-PRINTER.  */
103*e4b17023SJohn Marino static void
pp_wrap_text(pretty_printer * pp,const char * start,const char * end)104*e4b17023SJohn Marino pp_wrap_text (pretty_printer *pp, const char *start, const char *end)
105*e4b17023SJohn Marino {
106*e4b17023SJohn Marino   bool wrapping_line = pp_is_wrapping_line (pp);
107*e4b17023SJohn Marino 
108*e4b17023SJohn Marino   while (start != end)
109*e4b17023SJohn Marino     {
110*e4b17023SJohn Marino       /* Dump anything bordered by whitespaces.  */
111*e4b17023SJohn Marino       {
112*e4b17023SJohn Marino 	const char *p = start;
113*e4b17023SJohn Marino 	while (p != end && !ISBLANK (*p) && *p != '\n')
114*e4b17023SJohn Marino 	  ++p;
115*e4b17023SJohn Marino 	if (wrapping_line
116*e4b17023SJohn Marino             && p - start >= pp_remaining_character_count_for_line (pp))
117*e4b17023SJohn Marino 	  pp_newline (pp);
118*e4b17023SJohn Marino 	pp_append_text (pp, start, p);
119*e4b17023SJohn Marino 	start = p;
120*e4b17023SJohn Marino       }
121*e4b17023SJohn Marino 
122*e4b17023SJohn Marino       if (start != end && ISBLANK (*start))
123*e4b17023SJohn Marino 	{
124*e4b17023SJohn Marino 	  pp_space (pp);
125*e4b17023SJohn Marino 	  ++start;
126*e4b17023SJohn Marino 	}
127*e4b17023SJohn Marino       if (start != end && *start == '\n')
128*e4b17023SJohn Marino 	{
129*e4b17023SJohn Marino 	  pp_newline (pp);
130*e4b17023SJohn Marino 	  ++start;
131*e4b17023SJohn Marino 	}
132*e4b17023SJohn Marino     }
133*e4b17023SJohn Marino }
134*e4b17023SJohn Marino 
135*e4b17023SJohn Marino /* Same as pp_wrap_text but wrap text only when in line-wrapping mode.  */
136*e4b17023SJohn Marino static inline void
pp_maybe_wrap_text(pretty_printer * pp,const char * start,const char * end)137*e4b17023SJohn Marino pp_maybe_wrap_text (pretty_printer *pp, const char *start, const char *end)
138*e4b17023SJohn Marino {
139*e4b17023SJohn Marino   if (pp_is_wrapping_line (pp))
140*e4b17023SJohn Marino     pp_wrap_text (pp, start, end);
141*e4b17023SJohn Marino   else
142*e4b17023SJohn Marino     pp_append_text (pp, start, end);
143*e4b17023SJohn Marino }
144*e4b17023SJohn Marino 
145*e4b17023SJohn Marino /* Append to the output area of PRETTY-PRINTER a string specified by its
146*e4b17023SJohn Marino    STARTing character and LENGTH.  */
147*e4b17023SJohn Marino static inline void
pp_append_r(pretty_printer * pp,const char * start,int length)148*e4b17023SJohn Marino pp_append_r (pretty_printer *pp, const char *start, int length)
149*e4b17023SJohn Marino {
150*e4b17023SJohn Marino   obstack_grow (pp->buffer->obstack, start, length);
151*e4b17023SJohn Marino   pp->buffer->line_length += length;
152*e4b17023SJohn Marino }
153*e4b17023SJohn Marino 
154*e4b17023SJohn Marino /* Insert enough spaces into the output area of PRETTY-PRINTER to bring
155*e4b17023SJohn Marino    the column position to the current indentation level, assuming that a
156*e4b17023SJohn Marino    newline has just been written to the buffer.  */
157*e4b17023SJohn Marino void
pp_base_indent(pretty_printer * pp)158*e4b17023SJohn Marino pp_base_indent (pretty_printer *pp)
159*e4b17023SJohn Marino {
160*e4b17023SJohn Marino   int n = pp_indentation (pp);
161*e4b17023SJohn Marino   int i;
162*e4b17023SJohn Marino 
163*e4b17023SJohn Marino   for (i = 0; i < n; ++i)
164*e4b17023SJohn Marino     pp_space (pp);
165*e4b17023SJohn Marino }
166*e4b17023SJohn Marino 
167*e4b17023SJohn Marino /* The following format specifiers are recognized as being client independent:
168*e4b17023SJohn Marino    %d, %i: (signed) integer in base ten.
169*e4b17023SJohn Marino    %u: unsigned integer in base ten.
170*e4b17023SJohn Marino    %o: unsigned integer in base eight.
171*e4b17023SJohn Marino    %x: unsigned integer in base sixteen.
172*e4b17023SJohn Marino    %ld, %li, %lo, %lu, %lx: long versions of the above.
173*e4b17023SJohn Marino    %lld, %lli, %llo, %llu, %llx: long long versions.
174*e4b17023SJohn Marino    %wd, %wi, %wo, %wu, %wx: HOST_WIDE_INT versions.
175*e4b17023SJohn Marino    %c: character.
176*e4b17023SJohn Marino    %s: string.
177*e4b17023SJohn Marino    %p: pointer.
178*e4b17023SJohn Marino    %m: strerror(text->err_no) - does not consume a value from args_ptr.
179*e4b17023SJohn Marino    %%: '%'.
180*e4b17023SJohn Marino    %<: opening quote.
181*e4b17023SJohn Marino    %>: closing quote.
182*e4b17023SJohn Marino    %': apostrophe (should only be used in untranslated messages;
183*e4b17023SJohn Marino        translations should use appropriate punctuation directly).
184*e4b17023SJohn Marino    %.*s: a substring the length of which is specified by an argument
185*e4b17023SJohn Marino 	 integer.
186*e4b17023SJohn Marino    %Ns: likewise, but length specified as constant in the format string.
187*e4b17023SJohn Marino    Flag 'q': quote formatted text (must come immediately after '%').
188*e4b17023SJohn Marino 
189*e4b17023SJohn Marino    Arguments can be used sequentially, or through %N$ resp. *N$
190*e4b17023SJohn Marino    notation Nth argument after the format string.  If %N$ / *N$
191*e4b17023SJohn Marino    notation is used, it must be used for all arguments, except %m, %%,
192*e4b17023SJohn Marino    %<, %> and %', which may not have a number, as they do not consume
193*e4b17023SJohn Marino    an argument.  When %M$.*N$s is used, M must be N + 1.  (This may
194*e4b17023SJohn Marino    also be written %M$.*s, provided N is not otherwise used.)  The
195*e4b17023SJohn Marino    format string must have conversion specifiers with argument numbers
196*e4b17023SJohn Marino    1 up to highest argument; each argument may only be used once.
197*e4b17023SJohn Marino    A format string can have at most 30 arguments.  */
198*e4b17023SJohn Marino 
199*e4b17023SJohn Marino /* Formatting phases 1 and 2: render TEXT->format_spec plus
200*e4b17023SJohn Marino    TEXT->args_ptr into a series of chunks in PP->buffer->args[].
201*e4b17023SJohn Marino    Phase 3 is in pp_base_format_text.  */
202*e4b17023SJohn Marino 
203*e4b17023SJohn Marino void
pp_base_format(pretty_printer * pp,text_info * text)204*e4b17023SJohn Marino pp_base_format (pretty_printer *pp, text_info *text)
205*e4b17023SJohn Marino {
206*e4b17023SJohn Marino   output_buffer *buffer = pp->buffer;
207*e4b17023SJohn Marino   const char *p;
208*e4b17023SJohn Marino   const char **args;
209*e4b17023SJohn Marino   struct chunk_info *new_chunk_array;
210*e4b17023SJohn Marino 
211*e4b17023SJohn Marino   unsigned int curarg = 0, chunk = 0, argno;
212*e4b17023SJohn Marino   pp_wrapping_mode_t old_wrapping_mode;
213*e4b17023SJohn Marino   bool any_unnumbered = false, any_numbered = false;
214*e4b17023SJohn Marino   const char **formatters[PP_NL_ARGMAX];
215*e4b17023SJohn Marino 
216*e4b17023SJohn Marino   /* Allocate a new chunk structure.  */
217*e4b17023SJohn Marino   new_chunk_array = XOBNEW (&buffer->chunk_obstack, struct chunk_info);
218*e4b17023SJohn Marino   new_chunk_array->prev = buffer->cur_chunk_array;
219*e4b17023SJohn Marino   buffer->cur_chunk_array = new_chunk_array;
220*e4b17023SJohn Marino   args = new_chunk_array->args;
221*e4b17023SJohn Marino 
222*e4b17023SJohn Marino   /* Formatting phase 1: split up TEXT->format_spec into chunks in
223*e4b17023SJohn Marino      PP->buffer->args[].  Even-numbered chunks are to be output
224*e4b17023SJohn Marino      verbatim, odd-numbered chunks are format specifiers.
225*e4b17023SJohn Marino      %m, %%, %<, %>, and %' are replaced with the appropriate text at
226*e4b17023SJohn Marino      this point.  */
227*e4b17023SJohn Marino 
228*e4b17023SJohn Marino   memset (formatters, 0, sizeof formatters);
229*e4b17023SJohn Marino 
230*e4b17023SJohn Marino   for (p = text->format_spec; *p; )
231*e4b17023SJohn Marino     {
232*e4b17023SJohn Marino       while (*p != '\0' && *p != '%')
233*e4b17023SJohn Marino 	{
234*e4b17023SJohn Marino 	  obstack_1grow (&buffer->chunk_obstack, *p);
235*e4b17023SJohn Marino 	  p++;
236*e4b17023SJohn Marino 	}
237*e4b17023SJohn Marino 
238*e4b17023SJohn Marino       if (*p == '\0')
239*e4b17023SJohn Marino 	break;
240*e4b17023SJohn Marino 
241*e4b17023SJohn Marino       switch (*++p)
242*e4b17023SJohn Marino 	{
243*e4b17023SJohn Marino 	case '\0':
244*e4b17023SJohn Marino 	  gcc_unreachable ();
245*e4b17023SJohn Marino 
246*e4b17023SJohn Marino 	case '%':
247*e4b17023SJohn Marino 	  obstack_1grow (&buffer->chunk_obstack, '%');
248*e4b17023SJohn Marino 	  p++;
249*e4b17023SJohn Marino 	  continue;
250*e4b17023SJohn Marino 
251*e4b17023SJohn Marino 	case '<':
252*e4b17023SJohn Marino 	  obstack_grow (&buffer->chunk_obstack,
253*e4b17023SJohn Marino 			open_quote, strlen (open_quote));
254*e4b17023SJohn Marino 	  p++;
255*e4b17023SJohn Marino 	  continue;
256*e4b17023SJohn Marino 
257*e4b17023SJohn Marino 	case '>':
258*e4b17023SJohn Marino 	case '\'':
259*e4b17023SJohn Marino 	  obstack_grow (&buffer->chunk_obstack,
260*e4b17023SJohn Marino 			close_quote, strlen (close_quote));
261*e4b17023SJohn Marino 	  p++;
262*e4b17023SJohn Marino 	  continue;
263*e4b17023SJohn Marino 
264*e4b17023SJohn Marino 	case 'm':
265*e4b17023SJohn Marino 	  {
266*e4b17023SJohn Marino 	    const char *errstr = xstrerror (text->err_no);
267*e4b17023SJohn Marino 	    obstack_grow (&buffer->chunk_obstack, errstr, strlen (errstr));
268*e4b17023SJohn Marino 	  }
269*e4b17023SJohn Marino 	  p++;
270*e4b17023SJohn Marino 	  continue;
271*e4b17023SJohn Marino 
272*e4b17023SJohn Marino 	default:
273*e4b17023SJohn Marino 	  /* Handled in phase 2.  Terminate the plain chunk here.  */
274*e4b17023SJohn Marino 	  obstack_1grow (&buffer->chunk_obstack, '\0');
275*e4b17023SJohn Marino 	  gcc_assert (chunk < PP_NL_ARGMAX * 2);
276*e4b17023SJohn Marino 	  args[chunk++] = XOBFINISH (&buffer->chunk_obstack, const char *);
277*e4b17023SJohn Marino 	  break;
278*e4b17023SJohn Marino 	}
279*e4b17023SJohn Marino 
280*e4b17023SJohn Marino       if (ISDIGIT (*p))
281*e4b17023SJohn Marino 	{
282*e4b17023SJohn Marino 	  char *end;
283*e4b17023SJohn Marino 	  argno = strtoul (p, &end, 10) - 1;
284*e4b17023SJohn Marino 	  p = end;
285*e4b17023SJohn Marino 	  gcc_assert (*p == '$');
286*e4b17023SJohn Marino 	  p++;
287*e4b17023SJohn Marino 
288*e4b17023SJohn Marino 	  any_numbered = true;
289*e4b17023SJohn Marino 	  gcc_assert (!any_unnumbered);
290*e4b17023SJohn Marino 	}
291*e4b17023SJohn Marino       else
292*e4b17023SJohn Marino 	{
293*e4b17023SJohn Marino 	  argno = curarg++;
294*e4b17023SJohn Marino 	  any_unnumbered = true;
295*e4b17023SJohn Marino 	  gcc_assert (!any_numbered);
296*e4b17023SJohn Marino 	}
297*e4b17023SJohn Marino       gcc_assert (argno < PP_NL_ARGMAX);
298*e4b17023SJohn Marino       gcc_assert (!formatters[argno]);
299*e4b17023SJohn Marino       formatters[argno] = &args[chunk];
300*e4b17023SJohn Marino       do
301*e4b17023SJohn Marino 	{
302*e4b17023SJohn Marino 	  obstack_1grow (&buffer->chunk_obstack, *p);
303*e4b17023SJohn Marino 	  p++;
304*e4b17023SJohn Marino 	}
305*e4b17023SJohn Marino       while (strchr ("qwl+#", p[-1]));
306*e4b17023SJohn Marino 
307*e4b17023SJohn Marino       if (p[-1] == '.')
308*e4b17023SJohn Marino 	{
309*e4b17023SJohn Marino 	  /* We handle '%.Ns' and '%.*s' or '%M$.*N$s'
310*e4b17023SJohn Marino 	     (where M == N + 1).  */
311*e4b17023SJohn Marino 	  if (ISDIGIT (*p))
312*e4b17023SJohn Marino 	    {
313*e4b17023SJohn Marino 	      do
314*e4b17023SJohn Marino 		{
315*e4b17023SJohn Marino 		  obstack_1grow (&buffer->chunk_obstack, *p);
316*e4b17023SJohn Marino 		  p++;
317*e4b17023SJohn Marino 		}
318*e4b17023SJohn Marino 	      while (ISDIGIT (p[-1]));
319*e4b17023SJohn Marino 	      gcc_assert (p[-1] == 's');
320*e4b17023SJohn Marino 	    }
321*e4b17023SJohn Marino 	  else
322*e4b17023SJohn Marino 	    {
323*e4b17023SJohn Marino 	      gcc_assert (*p == '*');
324*e4b17023SJohn Marino 	      obstack_1grow (&buffer->chunk_obstack, '*');
325*e4b17023SJohn Marino 	      p++;
326*e4b17023SJohn Marino 
327*e4b17023SJohn Marino 	      if (ISDIGIT (*p))
328*e4b17023SJohn Marino 		{
329*e4b17023SJohn Marino 		  char *end;
330*e4b17023SJohn Marino 		  unsigned int argno2 = strtoul (p, &end, 10) - 1;
331*e4b17023SJohn Marino 		  p = end;
332*e4b17023SJohn Marino 		  gcc_assert (argno2 == argno - 1);
333*e4b17023SJohn Marino 		  gcc_assert (!any_unnumbered);
334*e4b17023SJohn Marino 		  gcc_assert (*p == '$');
335*e4b17023SJohn Marino 
336*e4b17023SJohn Marino 		  p++;
337*e4b17023SJohn Marino 		  formatters[argno2] = formatters[argno];
338*e4b17023SJohn Marino 		}
339*e4b17023SJohn Marino 	      else
340*e4b17023SJohn Marino 		{
341*e4b17023SJohn Marino 		  gcc_assert (!any_numbered);
342*e4b17023SJohn Marino 		  formatters[argno+1] = formatters[argno];
343*e4b17023SJohn Marino 		  curarg++;
344*e4b17023SJohn Marino 		}
345*e4b17023SJohn Marino 	      gcc_assert (*p == 's');
346*e4b17023SJohn Marino 	      obstack_1grow (&buffer->chunk_obstack, 's');
347*e4b17023SJohn Marino 	      p++;
348*e4b17023SJohn Marino 	    }
349*e4b17023SJohn Marino 	}
350*e4b17023SJohn Marino       if (*p == '\0')
351*e4b17023SJohn Marino 	break;
352*e4b17023SJohn Marino 
353*e4b17023SJohn Marino       obstack_1grow (&buffer->chunk_obstack, '\0');
354*e4b17023SJohn Marino       gcc_assert (chunk < PP_NL_ARGMAX * 2);
355*e4b17023SJohn Marino       args[chunk++] = XOBFINISH (&buffer->chunk_obstack, const char *);
356*e4b17023SJohn Marino     }
357*e4b17023SJohn Marino 
358*e4b17023SJohn Marino   obstack_1grow (&buffer->chunk_obstack, '\0');
359*e4b17023SJohn Marino   gcc_assert (chunk < PP_NL_ARGMAX * 2);
360*e4b17023SJohn Marino   args[chunk++] = XOBFINISH (&buffer->chunk_obstack, const char *);
361*e4b17023SJohn Marino   args[chunk] = 0;
362*e4b17023SJohn Marino 
363*e4b17023SJohn Marino   /* Set output to the argument obstack, and switch line-wrapping and
364*e4b17023SJohn Marino      prefixing off.  */
365*e4b17023SJohn Marino   buffer->obstack = &buffer->chunk_obstack;
366*e4b17023SJohn Marino   old_wrapping_mode = pp_set_verbatim_wrapping (pp);
367*e4b17023SJohn Marino 
368*e4b17023SJohn Marino   /* Second phase.  Replace each formatter with the formatted text it
369*e4b17023SJohn Marino      corresponds to.  */
370*e4b17023SJohn Marino 
371*e4b17023SJohn Marino   for (argno = 0; formatters[argno]; argno++)
372*e4b17023SJohn Marino     {
373*e4b17023SJohn Marino       int precision = 0;
374*e4b17023SJohn Marino       bool wide = false;
375*e4b17023SJohn Marino       bool plus = false;
376*e4b17023SJohn Marino       bool hash = false;
377*e4b17023SJohn Marino       bool quote = false;
378*e4b17023SJohn Marino 
379*e4b17023SJohn Marino       /* We do not attempt to enforce any ordering on the modifier
380*e4b17023SJohn Marino 	 characters.  */
381*e4b17023SJohn Marino 
382*e4b17023SJohn Marino       for (p = *formatters[argno];; p++)
383*e4b17023SJohn Marino 	{
384*e4b17023SJohn Marino 	  switch (*p)
385*e4b17023SJohn Marino 	    {
386*e4b17023SJohn Marino 	    case 'q':
387*e4b17023SJohn Marino 	      gcc_assert (!quote);
388*e4b17023SJohn Marino 	      quote = true;
389*e4b17023SJohn Marino 	      continue;
390*e4b17023SJohn Marino 
391*e4b17023SJohn Marino 	    case '+':
392*e4b17023SJohn Marino 	      gcc_assert (!plus);
393*e4b17023SJohn Marino 	      plus = true;
394*e4b17023SJohn Marino 	      continue;
395*e4b17023SJohn Marino 
396*e4b17023SJohn Marino 	    case '#':
397*e4b17023SJohn Marino 	      gcc_assert (!hash);
398*e4b17023SJohn Marino 	      hash = true;
399*e4b17023SJohn Marino 	      continue;
400*e4b17023SJohn Marino 
401*e4b17023SJohn Marino 	    case 'w':
402*e4b17023SJohn Marino 	      gcc_assert (!wide);
403*e4b17023SJohn Marino 	      wide = true;
404*e4b17023SJohn Marino 	      continue;
405*e4b17023SJohn Marino 
406*e4b17023SJohn Marino 	    case 'l':
407*e4b17023SJohn Marino 	      /* We don't support precision beyond that of "long long".  */
408*e4b17023SJohn Marino 	      gcc_assert (precision < 2);
409*e4b17023SJohn Marino 	      precision++;
410*e4b17023SJohn Marino 	      continue;
411*e4b17023SJohn Marino 	    }
412*e4b17023SJohn Marino 	  break;
413*e4b17023SJohn Marino 	}
414*e4b17023SJohn Marino 
415*e4b17023SJohn Marino       gcc_assert (!wide || precision == 0);
416*e4b17023SJohn Marino 
417*e4b17023SJohn Marino       if (quote)
418*e4b17023SJohn Marino 	pp_string (pp, open_quote);
419*e4b17023SJohn Marino 
420*e4b17023SJohn Marino       switch (*p)
421*e4b17023SJohn Marino 	{
422*e4b17023SJohn Marino 	case 'c':
423*e4b17023SJohn Marino 	  pp_character (pp, va_arg (*text->args_ptr, int));
424*e4b17023SJohn Marino 	  break;
425*e4b17023SJohn Marino 
426*e4b17023SJohn Marino 	case 'd':
427*e4b17023SJohn Marino 	case 'i':
428*e4b17023SJohn Marino 	  if (wide)
429*e4b17023SJohn Marino 	    pp_wide_integer (pp, va_arg (*text->args_ptr, HOST_WIDE_INT));
430*e4b17023SJohn Marino 	  else
431*e4b17023SJohn Marino 	    pp_integer_with_precision
432*e4b17023SJohn Marino 	      (pp, *text->args_ptr, precision, int, "d");
433*e4b17023SJohn Marino 	  break;
434*e4b17023SJohn Marino 
435*e4b17023SJohn Marino 	case 'o':
436*e4b17023SJohn Marino 	  if (wide)
437*e4b17023SJohn Marino 	    pp_scalar (pp, "%" HOST_WIDE_INT_PRINT "o",
438*e4b17023SJohn Marino 		       va_arg (*text->args_ptr, unsigned HOST_WIDE_INT));
439*e4b17023SJohn Marino 	  else
440*e4b17023SJohn Marino 	    pp_integer_with_precision
441*e4b17023SJohn Marino 	      (pp, *text->args_ptr, precision, unsigned, "o");
442*e4b17023SJohn Marino 	  break;
443*e4b17023SJohn Marino 
444*e4b17023SJohn Marino 	case 's':
445*e4b17023SJohn Marino 	  pp_string (pp, va_arg (*text->args_ptr, const char *));
446*e4b17023SJohn Marino 	  break;
447*e4b17023SJohn Marino 
448*e4b17023SJohn Marino 	case 'p':
449*e4b17023SJohn Marino 	  pp_pointer (pp, va_arg (*text->args_ptr, void *));
450*e4b17023SJohn Marino 	  break;
451*e4b17023SJohn Marino 
452*e4b17023SJohn Marino 	case 'u':
453*e4b17023SJohn Marino 	  if (wide)
454*e4b17023SJohn Marino 	    pp_scalar (pp, HOST_WIDE_INT_PRINT_UNSIGNED,
455*e4b17023SJohn Marino 		       va_arg (*text->args_ptr, unsigned HOST_WIDE_INT));
456*e4b17023SJohn Marino 	  else
457*e4b17023SJohn Marino 	    pp_integer_with_precision
458*e4b17023SJohn Marino 	      (pp, *text->args_ptr, precision, unsigned, "u");
459*e4b17023SJohn Marino 	  break;
460*e4b17023SJohn Marino 
461*e4b17023SJohn Marino 	case 'x':
462*e4b17023SJohn Marino 	  if (wide)
463*e4b17023SJohn Marino 	    pp_scalar (pp, HOST_WIDE_INT_PRINT_HEX,
464*e4b17023SJohn Marino 		       va_arg (*text->args_ptr, unsigned HOST_WIDE_INT));
465*e4b17023SJohn Marino 	  else
466*e4b17023SJohn Marino 	    pp_integer_with_precision
467*e4b17023SJohn Marino 	      (pp, *text->args_ptr, precision, unsigned, "x");
468*e4b17023SJohn Marino 	  break;
469*e4b17023SJohn Marino 
470*e4b17023SJohn Marino 	case '.':
471*e4b17023SJohn Marino 	  {
472*e4b17023SJohn Marino 	    int n;
473*e4b17023SJohn Marino 	    const char *s;
474*e4b17023SJohn Marino 
475*e4b17023SJohn Marino 	    /* We handle '%.Ns' and '%.*s' or '%M$.*N$s'
476*e4b17023SJohn Marino 	       (where M == N + 1).  The format string should be verified
477*e4b17023SJohn Marino 	       already from the first phase.  */
478*e4b17023SJohn Marino 	    p++;
479*e4b17023SJohn Marino 	    if (ISDIGIT (*p))
480*e4b17023SJohn Marino 	      {
481*e4b17023SJohn Marino 		char *end;
482*e4b17023SJohn Marino 		n = strtoul (p, &end, 10);
483*e4b17023SJohn Marino 		p = end;
484*e4b17023SJohn Marino 		gcc_assert (*p == 's');
485*e4b17023SJohn Marino 	      }
486*e4b17023SJohn Marino 	    else
487*e4b17023SJohn Marino 	      {
488*e4b17023SJohn Marino 		gcc_assert (*p == '*');
489*e4b17023SJohn Marino 		p++;
490*e4b17023SJohn Marino 		gcc_assert (*p == 's');
491*e4b17023SJohn Marino 		n = va_arg (*text->args_ptr, int);
492*e4b17023SJohn Marino 
493*e4b17023SJohn Marino 		/* This consumes a second entry in the formatters array.  */
494*e4b17023SJohn Marino 		gcc_assert (formatters[argno] == formatters[argno+1]);
495*e4b17023SJohn Marino 		argno++;
496*e4b17023SJohn Marino 	      }
497*e4b17023SJohn Marino 
498*e4b17023SJohn Marino 	    s = va_arg (*text->args_ptr, const char *);
499*e4b17023SJohn Marino 	    pp_append_text (pp, s, s + n);
500*e4b17023SJohn Marino 	  }
501*e4b17023SJohn Marino 	  break;
502*e4b17023SJohn Marino 
503*e4b17023SJohn Marino 	default:
504*e4b17023SJohn Marino 	  {
505*e4b17023SJohn Marino 	    bool ok;
506*e4b17023SJohn Marino 
507*e4b17023SJohn Marino 	    gcc_assert (pp_format_decoder (pp));
508*e4b17023SJohn Marino 	    ok = pp_format_decoder (pp) (pp, text, p,
509*e4b17023SJohn Marino 					 precision, wide, plus, hash);
510*e4b17023SJohn Marino 	    gcc_assert (ok);
511*e4b17023SJohn Marino 	  }
512*e4b17023SJohn Marino 	}
513*e4b17023SJohn Marino 
514*e4b17023SJohn Marino       if (quote)
515*e4b17023SJohn Marino 	pp_string (pp, close_quote);
516*e4b17023SJohn Marino 
517*e4b17023SJohn Marino       obstack_1grow (&buffer->chunk_obstack, '\0');
518*e4b17023SJohn Marino       *formatters[argno] = XOBFINISH (&buffer->chunk_obstack, const char *);
519*e4b17023SJohn Marino     }
520*e4b17023SJohn Marino 
521*e4b17023SJohn Marino #ifdef ENABLE_CHECKING
522*e4b17023SJohn Marino   for (; argno < PP_NL_ARGMAX; argno++)
523*e4b17023SJohn Marino     gcc_assert (!formatters[argno]);
524*e4b17023SJohn Marino #endif
525*e4b17023SJohn Marino 
526*e4b17023SJohn Marino   /* Revert to normal obstack and wrapping mode.  */
527*e4b17023SJohn Marino   buffer->obstack = &buffer->formatted_obstack;
528*e4b17023SJohn Marino   buffer->line_length = 0;
529*e4b17023SJohn Marino   pp_wrapping_mode (pp) = old_wrapping_mode;
530*e4b17023SJohn Marino   pp_clear_state (pp);
531*e4b17023SJohn Marino }
532*e4b17023SJohn Marino 
533*e4b17023SJohn Marino /* Format of a message pointed to by TEXT.  */
534*e4b17023SJohn Marino void
pp_base_output_formatted_text(pretty_printer * pp)535*e4b17023SJohn Marino pp_base_output_formatted_text (pretty_printer *pp)
536*e4b17023SJohn Marino {
537*e4b17023SJohn Marino   unsigned int chunk;
538*e4b17023SJohn Marino   output_buffer *buffer = pp_buffer (pp);
539*e4b17023SJohn Marino   struct chunk_info *chunk_array = buffer->cur_chunk_array;
540*e4b17023SJohn Marino   const char **args = chunk_array->args;
541*e4b17023SJohn Marino 
542*e4b17023SJohn Marino   gcc_assert (buffer->obstack == &buffer->formatted_obstack);
543*e4b17023SJohn Marino   gcc_assert (buffer->line_length == 0);
544*e4b17023SJohn Marino 
545*e4b17023SJohn Marino   /* This is a third phase, first 2 phases done in pp_base_format_args.
546*e4b17023SJohn Marino      Now we actually print it.  */
547*e4b17023SJohn Marino   for (chunk = 0; args[chunk]; chunk++)
548*e4b17023SJohn Marino     pp_string (pp, args[chunk]);
549*e4b17023SJohn Marino 
550*e4b17023SJohn Marino   /* Deallocate the chunk structure and everything after it (i.e. the
551*e4b17023SJohn Marino      associated series of formatted strings).  */
552*e4b17023SJohn Marino   buffer->cur_chunk_array = chunk_array->prev;
553*e4b17023SJohn Marino   obstack_free (&buffer->chunk_obstack, chunk_array);
554*e4b17023SJohn Marino }
555*e4b17023SJohn Marino 
556*e4b17023SJohn Marino /* Helper subroutine of output_verbatim and verbatim. Do the appropriate
557*e4b17023SJohn Marino    settings needed by BUFFER for a verbatim formatting.  */
558*e4b17023SJohn Marino void
pp_base_format_verbatim(pretty_printer * pp,text_info * text)559*e4b17023SJohn Marino pp_base_format_verbatim (pretty_printer *pp, text_info *text)
560*e4b17023SJohn Marino {
561*e4b17023SJohn Marino   /* Set verbatim mode.  */
562*e4b17023SJohn Marino   pp_wrapping_mode_t oldmode = pp_set_verbatim_wrapping (pp);
563*e4b17023SJohn Marino 
564*e4b17023SJohn Marino   /* Do the actual formatting.  */
565*e4b17023SJohn Marino   pp_format (pp, text);
566*e4b17023SJohn Marino   pp_output_formatted_text (pp);
567*e4b17023SJohn Marino 
568*e4b17023SJohn Marino   /* Restore previous settings.  */
569*e4b17023SJohn Marino   pp_wrapping_mode (pp) = oldmode;
570*e4b17023SJohn Marino }
571*e4b17023SJohn Marino 
572*e4b17023SJohn Marino /* Flush the content of BUFFER onto the attached stream.  */
573*e4b17023SJohn Marino void
pp_base_flush(pretty_printer * pp)574*e4b17023SJohn Marino pp_base_flush (pretty_printer *pp)
575*e4b17023SJohn Marino {
576*e4b17023SJohn Marino   pp_write_text_to_stream (pp);
577*e4b17023SJohn Marino   pp_clear_state (pp);
578*e4b17023SJohn Marino   fputc ('\n', pp->buffer->stream);
579*e4b17023SJohn Marino   fflush (pp->buffer->stream);
580*e4b17023SJohn Marino   pp_needs_newline (pp) = false;
581*e4b17023SJohn Marino }
582*e4b17023SJohn Marino 
583*e4b17023SJohn Marino /* Sets the number of maximum characters per line PRETTY-PRINTER can
584*e4b17023SJohn Marino    output in line-wrapping mode.  A LENGTH value 0 suppresses
585*e4b17023SJohn Marino    line-wrapping.  */
586*e4b17023SJohn Marino void
pp_base_set_line_maximum_length(pretty_printer * pp,int length)587*e4b17023SJohn Marino pp_base_set_line_maximum_length (pretty_printer *pp, int length)
588*e4b17023SJohn Marino {
589*e4b17023SJohn Marino   pp_line_cutoff (pp) = length;
590*e4b17023SJohn Marino   pp_set_real_maximum_length (pp);
591*e4b17023SJohn Marino }
592*e4b17023SJohn Marino 
593*e4b17023SJohn Marino /* Clear PRETTY-PRINTER output area text info.  */
594*e4b17023SJohn Marino void
pp_base_clear_output_area(pretty_printer * pp)595*e4b17023SJohn Marino pp_base_clear_output_area (pretty_printer *pp)
596*e4b17023SJohn Marino {
597*e4b17023SJohn Marino   obstack_free (pp->buffer->obstack, obstack_base (pp->buffer->obstack));
598*e4b17023SJohn Marino   pp->buffer->line_length = 0;
599*e4b17023SJohn Marino }
600*e4b17023SJohn Marino 
601*e4b17023SJohn Marino /* Set PREFIX for PRETTY-PRINTER.  */
602*e4b17023SJohn Marino void
pp_base_set_prefix(pretty_printer * pp,const char * prefix)603*e4b17023SJohn Marino pp_base_set_prefix (pretty_printer *pp, const char *prefix)
604*e4b17023SJohn Marino {
605*e4b17023SJohn Marino   pp->prefix = prefix;
606*e4b17023SJohn Marino   pp_set_real_maximum_length (pp);
607*e4b17023SJohn Marino   pp->emitted_prefix = false;
608*e4b17023SJohn Marino   pp_indentation (pp) = 0;
609*e4b17023SJohn Marino }
610*e4b17023SJohn Marino 
611*e4b17023SJohn Marino /* Free PRETTY-PRINTER's prefix, a previously malloc()'d string.  */
612*e4b17023SJohn Marino void
pp_base_destroy_prefix(pretty_printer * pp)613*e4b17023SJohn Marino pp_base_destroy_prefix (pretty_printer *pp)
614*e4b17023SJohn Marino {
615*e4b17023SJohn Marino   if (pp->prefix != NULL)
616*e4b17023SJohn Marino     {
617*e4b17023SJohn Marino       free (CONST_CAST (char *, pp->prefix));
618*e4b17023SJohn Marino       pp->prefix = NULL;
619*e4b17023SJohn Marino     }
620*e4b17023SJohn Marino }
621*e4b17023SJohn Marino 
622*e4b17023SJohn Marino /* Write out PRETTY-PRINTER's prefix.  */
623*e4b17023SJohn Marino void
pp_base_emit_prefix(pretty_printer * pp)624*e4b17023SJohn Marino pp_base_emit_prefix (pretty_printer *pp)
625*e4b17023SJohn Marino {
626*e4b17023SJohn Marino   if (pp->prefix != NULL)
627*e4b17023SJohn Marino     {
628*e4b17023SJohn Marino       switch (pp_prefixing_rule (pp))
629*e4b17023SJohn Marino 	{
630*e4b17023SJohn Marino 	default:
631*e4b17023SJohn Marino 	case DIAGNOSTICS_SHOW_PREFIX_NEVER:
632*e4b17023SJohn Marino 	  break;
633*e4b17023SJohn Marino 
634*e4b17023SJohn Marino 	case DIAGNOSTICS_SHOW_PREFIX_ONCE:
635*e4b17023SJohn Marino 	  if (pp->emitted_prefix)
636*e4b17023SJohn Marino 	    {
637*e4b17023SJohn Marino 	      pp_base_indent (pp);
638*e4b17023SJohn Marino 	      break;
639*e4b17023SJohn Marino 	    }
640*e4b17023SJohn Marino 	  pp_indentation (pp) += 3;
641*e4b17023SJohn Marino 	  /* Fall through.  */
642*e4b17023SJohn Marino 
643*e4b17023SJohn Marino 	case DIAGNOSTICS_SHOW_PREFIX_EVERY_LINE:
644*e4b17023SJohn Marino 	  {
645*e4b17023SJohn Marino 	    int prefix_length = strlen (pp->prefix);
646*e4b17023SJohn Marino 	    pp_append_r (pp, pp->prefix, prefix_length);
647*e4b17023SJohn Marino 	    pp->emitted_prefix = true;
648*e4b17023SJohn Marino 	  }
649*e4b17023SJohn Marino 	  break;
650*e4b17023SJohn Marino 	}
651*e4b17023SJohn Marino     }
652*e4b17023SJohn Marino }
653*e4b17023SJohn Marino 
654*e4b17023SJohn Marino /* Construct a PRETTY-PRINTER with PREFIX and of MAXIMUM_LENGTH
655*e4b17023SJohn Marino    characters per line.  */
656*e4b17023SJohn Marino void
pp_construct(pretty_printer * pp,const char * prefix,int maximum_length)657*e4b17023SJohn Marino pp_construct (pretty_printer *pp, const char *prefix, int maximum_length)
658*e4b17023SJohn Marino {
659*e4b17023SJohn Marino   memset (pp, 0, sizeof (pretty_printer));
660*e4b17023SJohn Marino   pp->buffer = XCNEW (output_buffer);
661*e4b17023SJohn Marino   obstack_init (&pp->buffer->chunk_obstack);
662*e4b17023SJohn Marino   obstack_init (&pp->buffer->formatted_obstack);
663*e4b17023SJohn Marino   pp->buffer->obstack = &pp->buffer->formatted_obstack;
664*e4b17023SJohn Marino   pp->buffer->stream = stderr;
665*e4b17023SJohn Marino   pp_line_cutoff (pp) = maximum_length;
666*e4b17023SJohn Marino   pp_prefixing_rule (pp) = DIAGNOSTICS_SHOW_PREFIX_ONCE;
667*e4b17023SJohn Marino   pp_set_prefix (pp, prefix);
668*e4b17023SJohn Marino   pp_translate_identifiers (pp) = true;
669*e4b17023SJohn Marino }
670*e4b17023SJohn Marino 
671*e4b17023SJohn Marino /* Append a string delimited by START and END to the output area of
672*e4b17023SJohn Marino    PRETTY-PRINTER.  No line wrapping is done.  However, if beginning a
673*e4b17023SJohn Marino    new line then emit PRETTY-PRINTER's prefix and skip any leading
674*e4b17023SJohn Marino    whitespace if appropriate.  The caller must ensure that it is
675*e4b17023SJohn Marino    safe to do so.  */
676*e4b17023SJohn Marino void
pp_base_append_text(pretty_printer * pp,const char * start,const char * end)677*e4b17023SJohn Marino pp_base_append_text (pretty_printer *pp, const char *start, const char *end)
678*e4b17023SJohn Marino {
679*e4b17023SJohn Marino   /* Emit prefix and skip whitespace if we're starting a new line.  */
680*e4b17023SJohn Marino   if (pp->buffer->line_length == 0)
681*e4b17023SJohn Marino     {
682*e4b17023SJohn Marino       pp_emit_prefix (pp);
683*e4b17023SJohn Marino       if (pp_is_wrapping_line (pp))
684*e4b17023SJohn Marino 	while (start != end && *start == ' ')
685*e4b17023SJohn Marino 	  ++start;
686*e4b17023SJohn Marino     }
687*e4b17023SJohn Marino   pp_append_r (pp, start, end - start);
688*e4b17023SJohn Marino }
689*e4b17023SJohn Marino 
690*e4b17023SJohn Marino /* Finishes constructing a NULL-terminated character string representing
691*e4b17023SJohn Marino    the PRETTY-PRINTED text.  */
692*e4b17023SJohn Marino const char *
pp_base_formatted_text(pretty_printer * pp)693*e4b17023SJohn Marino pp_base_formatted_text (pretty_printer *pp)
694*e4b17023SJohn Marino {
695*e4b17023SJohn Marino   obstack_1grow (pp->buffer->obstack, '\0');
696*e4b17023SJohn Marino   return pp_formatted_text_data (pp);
697*e4b17023SJohn Marino }
698*e4b17023SJohn Marino 
699*e4b17023SJohn Marino /*  Return a pointer to the last character emitted in PRETTY-PRINTER's
700*e4b17023SJohn Marino     output area.  A NULL pointer means no character available.  */
701*e4b17023SJohn Marino const char *
pp_base_last_position_in_text(const pretty_printer * pp)702*e4b17023SJohn Marino pp_base_last_position_in_text (const pretty_printer *pp)
703*e4b17023SJohn Marino {
704*e4b17023SJohn Marino   const char *p = NULL;
705*e4b17023SJohn Marino   struct obstack *text = pp->buffer->obstack;
706*e4b17023SJohn Marino 
707*e4b17023SJohn Marino   if (obstack_base (text) != obstack_next_free (text))
708*e4b17023SJohn Marino     p = ((const char *) obstack_next_free (text)) - 1;
709*e4b17023SJohn Marino   return p;
710*e4b17023SJohn Marino }
711*e4b17023SJohn Marino 
712*e4b17023SJohn Marino /* Return the amount of characters PRETTY-PRINTER can accept to
713*e4b17023SJohn Marino    make a full line.  Meaningful only in line-wrapping mode.  */
714*e4b17023SJohn Marino int
pp_base_remaining_character_count_for_line(pretty_printer * pp)715*e4b17023SJohn Marino pp_base_remaining_character_count_for_line (pretty_printer *pp)
716*e4b17023SJohn Marino {
717*e4b17023SJohn Marino   return pp->maximum_length - pp->buffer->line_length;
718*e4b17023SJohn Marino }
719*e4b17023SJohn Marino 
720*e4b17023SJohn Marino 
721*e4b17023SJohn Marino /* Format a message into BUFFER a la printf.  */
722*e4b17023SJohn Marino void
pp_printf(pretty_printer * pp,const char * msg,...)723*e4b17023SJohn Marino pp_printf (pretty_printer *pp, const char *msg, ...)
724*e4b17023SJohn Marino {
725*e4b17023SJohn Marino   text_info text;
726*e4b17023SJohn Marino   va_list ap;
727*e4b17023SJohn Marino 
728*e4b17023SJohn Marino   va_start (ap, msg);
729*e4b17023SJohn Marino   text.err_no = errno;
730*e4b17023SJohn Marino   text.args_ptr = &ap;
731*e4b17023SJohn Marino   text.format_spec = msg;
732*e4b17023SJohn Marino   text.locus = NULL;
733*e4b17023SJohn Marino   pp_format (pp, &text);
734*e4b17023SJohn Marino   pp_output_formatted_text (pp);
735*e4b17023SJohn Marino   va_end (ap);
736*e4b17023SJohn Marino }
737*e4b17023SJohn Marino 
738*e4b17023SJohn Marino 
739*e4b17023SJohn Marino /* Output MESSAGE verbatim into BUFFER.  */
740*e4b17023SJohn Marino void
pp_verbatim(pretty_printer * pp,const char * msg,...)741*e4b17023SJohn Marino pp_verbatim (pretty_printer *pp, const char *msg, ...)
742*e4b17023SJohn Marino {
743*e4b17023SJohn Marino   text_info text;
744*e4b17023SJohn Marino   va_list ap;
745*e4b17023SJohn Marino 
746*e4b17023SJohn Marino   va_start (ap, msg);
747*e4b17023SJohn Marino   text.err_no = errno;
748*e4b17023SJohn Marino   text.args_ptr = &ap;
749*e4b17023SJohn Marino   text.format_spec = msg;
750*e4b17023SJohn Marino   text.locus = NULL;
751*e4b17023SJohn Marino   pp_format_verbatim (pp, &text);
752*e4b17023SJohn Marino   va_end (ap);
753*e4b17023SJohn Marino }
754*e4b17023SJohn Marino 
755*e4b17023SJohn Marino 
756*e4b17023SJohn Marino 
757*e4b17023SJohn Marino /* Have PRETTY-PRINTER start a new line.  */
758*e4b17023SJohn Marino void
pp_base_newline(pretty_printer * pp)759*e4b17023SJohn Marino pp_base_newline (pretty_printer *pp)
760*e4b17023SJohn Marino {
761*e4b17023SJohn Marino   obstack_1grow (pp->buffer->obstack, '\n');
762*e4b17023SJohn Marino   pp->buffer->line_length = 0;
763*e4b17023SJohn Marino }
764*e4b17023SJohn Marino 
765*e4b17023SJohn Marino /* Have PRETTY-PRINTER add a CHARACTER.  */
766*e4b17023SJohn Marino void
pp_base_character(pretty_printer * pp,int c)767*e4b17023SJohn Marino pp_base_character (pretty_printer *pp, int c)
768*e4b17023SJohn Marino {
769*e4b17023SJohn Marino   if (pp_is_wrapping_line (pp)
770*e4b17023SJohn Marino       && pp_remaining_character_count_for_line (pp) <= 0)
771*e4b17023SJohn Marino     {
772*e4b17023SJohn Marino       pp_newline (pp);
773*e4b17023SJohn Marino       if (ISSPACE (c))
774*e4b17023SJohn Marino         return;
775*e4b17023SJohn Marino     }
776*e4b17023SJohn Marino   obstack_1grow (pp->buffer->obstack, c);
777*e4b17023SJohn Marino   ++pp->buffer->line_length;
778*e4b17023SJohn Marino }
779*e4b17023SJohn Marino 
780*e4b17023SJohn Marino /* Append a STRING to the output area of PRETTY-PRINTER; the STRING may
781*e4b17023SJohn Marino    be line-wrapped if in appropriate mode.  */
782*e4b17023SJohn Marino void
pp_base_string(pretty_printer * pp,const char * str)783*e4b17023SJohn Marino pp_base_string (pretty_printer *pp, const char *str)
784*e4b17023SJohn Marino {
785*e4b17023SJohn Marino   pp_maybe_wrap_text (pp, str, str + (str ? strlen (str) : 0));
786*e4b17023SJohn Marino }
787*e4b17023SJohn Marino 
788*e4b17023SJohn Marino /* Maybe print out a whitespace if needed.  */
789*e4b17023SJohn Marino 
790*e4b17023SJohn Marino void
pp_base_maybe_space(pretty_printer * pp)791*e4b17023SJohn Marino pp_base_maybe_space (pretty_printer *pp)
792*e4b17023SJohn Marino {
793*e4b17023SJohn Marino   if (pp_base (pp)->padding != pp_none)
794*e4b17023SJohn Marino     {
795*e4b17023SJohn Marino       pp_space (pp);
796*e4b17023SJohn Marino       pp_base (pp)->padding = pp_none;
797*e4b17023SJohn Marino     }
798*e4b17023SJohn Marino }
799*e4b17023SJohn Marino 
800*e4b17023SJohn Marino /* The string starting at P has LEN (at least 1) bytes left; if they
801*e4b17023SJohn Marino    start with a valid UTF-8 sequence, return the length of that
802*e4b17023SJohn Marino    sequence and set *VALUE to the value of that sequence, and
803*e4b17023SJohn Marino    otherwise return 0 and set *VALUE to (unsigned int) -1.  */
804*e4b17023SJohn Marino 
805*e4b17023SJohn Marino static int
decode_utf8_char(const unsigned char * p,size_t len,unsigned int * value)806*e4b17023SJohn Marino decode_utf8_char (const unsigned char *p, size_t len, unsigned int *value)
807*e4b17023SJohn Marino {
808*e4b17023SJohn Marino   unsigned int t = *p;
809*e4b17023SJohn Marino 
810*e4b17023SJohn Marino   if (len == 0)
811*e4b17023SJohn Marino     abort ();
812*e4b17023SJohn Marino   if (t & 0x80)
813*e4b17023SJohn Marino     {
814*e4b17023SJohn Marino       size_t utf8_len = 0;
815*e4b17023SJohn Marino       unsigned int ch;
816*e4b17023SJohn Marino       size_t i;
817*e4b17023SJohn Marino       for (t = *p; t & 0x80; t <<= 1)
818*e4b17023SJohn Marino 	utf8_len++;
819*e4b17023SJohn Marino 
820*e4b17023SJohn Marino       if (utf8_len > len || utf8_len < 2 || utf8_len > 6)
821*e4b17023SJohn Marino 	{
822*e4b17023SJohn Marino 	  *value = (unsigned int) -1;
823*e4b17023SJohn Marino 	  return 0;
824*e4b17023SJohn Marino 	}
825*e4b17023SJohn Marino       ch = *p & ((1 << (7 - utf8_len)) - 1);
826*e4b17023SJohn Marino       for (i = 1; i < utf8_len; i++)
827*e4b17023SJohn Marino 	{
828*e4b17023SJohn Marino 	  unsigned int u = p[i];
829*e4b17023SJohn Marino 	  if ((u & 0xC0) != 0x80)
830*e4b17023SJohn Marino 	    {
831*e4b17023SJohn Marino 	      *value = (unsigned int) -1;
832*e4b17023SJohn Marino 	      return 0;
833*e4b17023SJohn Marino 	    }
834*e4b17023SJohn Marino 	  ch = (ch << 6) | (u & 0x3F);
835*e4b17023SJohn Marino 	}
836*e4b17023SJohn Marino       if (   (ch <=      0x7F && utf8_len > 1)
837*e4b17023SJohn Marino 	  || (ch <=     0x7FF && utf8_len > 2)
838*e4b17023SJohn Marino 	  || (ch <=    0xFFFF && utf8_len > 3)
839*e4b17023SJohn Marino 	  || (ch <=  0x1FFFFF && utf8_len > 4)
840*e4b17023SJohn Marino 	  || (ch <= 0x3FFFFFF && utf8_len > 5)
841*e4b17023SJohn Marino 	  || (ch >= 0xD800 && ch <= 0xDFFF))
842*e4b17023SJohn Marino 	{
843*e4b17023SJohn Marino 	  *value = (unsigned int) -1;
844*e4b17023SJohn Marino 	  return 0;
845*e4b17023SJohn Marino 	}
846*e4b17023SJohn Marino       *value = ch;
847*e4b17023SJohn Marino       return utf8_len;
848*e4b17023SJohn Marino     }
849*e4b17023SJohn Marino   else
850*e4b17023SJohn Marino     {
851*e4b17023SJohn Marino       *value = t;
852*e4b17023SJohn Marino       return 1;
853*e4b17023SJohn Marino     }
854*e4b17023SJohn Marino }
855*e4b17023SJohn Marino 
856*e4b17023SJohn Marino /* Allocator for identifier_to_locale and corresponding function to
857*e4b17023SJohn Marino    free memory.  */
858*e4b17023SJohn Marino 
859*e4b17023SJohn Marino void *(*identifier_to_locale_alloc) (size_t) = xmalloc;
860*e4b17023SJohn Marino void (*identifier_to_locale_free) (void *) = free;
861*e4b17023SJohn Marino 
862*e4b17023SJohn Marino /* Given IDENT, an identifier in the internal encoding, return a
863*e4b17023SJohn Marino    version of IDENT suitable for diagnostics in the locale character
864*e4b17023SJohn Marino    set: either IDENT itself, or a string, allocated using
865*e4b17023SJohn Marino    identifier_to_locale_alloc, converted to the locale character set
866*e4b17023SJohn Marino    and using escape sequences if not representable in the locale
867*e4b17023SJohn Marino    character set or containing control characters or invalid byte
868*e4b17023SJohn Marino    sequences.  Existing backslashes in IDENT are not doubled, so the
869*e4b17023SJohn Marino    result may not uniquely specify the contents of an arbitrary byte
870*e4b17023SJohn Marino    sequence identifier.  */
871*e4b17023SJohn Marino 
872*e4b17023SJohn Marino const char *
identifier_to_locale(const char * ident)873*e4b17023SJohn Marino identifier_to_locale (const char *ident)
874*e4b17023SJohn Marino {
875*e4b17023SJohn Marino   const unsigned char *uid = (const unsigned char *) ident;
876*e4b17023SJohn Marino   size_t idlen = strlen (ident);
877*e4b17023SJohn Marino   bool valid_printable_utf8 = true;
878*e4b17023SJohn Marino   bool all_ascii = true;
879*e4b17023SJohn Marino   size_t i;
880*e4b17023SJohn Marino 
881*e4b17023SJohn Marino   for (i = 0; i < idlen;)
882*e4b17023SJohn Marino     {
883*e4b17023SJohn Marino       unsigned int c;
884*e4b17023SJohn Marino       size_t utf8_len = decode_utf8_char (&uid[i], idlen - i, &c);
885*e4b17023SJohn Marino       if (utf8_len == 0 || c <= 0x1F || (c >= 0x7F && c <= 0x9F))
886*e4b17023SJohn Marino 	{
887*e4b17023SJohn Marino 	  valid_printable_utf8 = false;
888*e4b17023SJohn Marino 	  break;
889*e4b17023SJohn Marino 	}
890*e4b17023SJohn Marino       if (utf8_len > 1)
891*e4b17023SJohn Marino 	all_ascii = false;
892*e4b17023SJohn Marino       i += utf8_len;
893*e4b17023SJohn Marino     }
894*e4b17023SJohn Marino 
895*e4b17023SJohn Marino   /* If IDENT contains invalid UTF-8 sequences (which may occur with
896*e4b17023SJohn Marino      attributes putting arbitrary byte sequences in identifiers), or
897*e4b17023SJohn Marino      control characters, we use octal escape sequences for all bytes
898*e4b17023SJohn Marino      outside printable ASCII.  */
899*e4b17023SJohn Marino   if (!valid_printable_utf8)
900*e4b17023SJohn Marino     {
901*e4b17023SJohn Marino       char *ret = (char *) identifier_to_locale_alloc (4 * idlen + 1);
902*e4b17023SJohn Marino       char *p = ret;
903*e4b17023SJohn Marino       for (i = 0; i < idlen; i++)
904*e4b17023SJohn Marino 	{
905*e4b17023SJohn Marino 	  if (uid[i] > 0x1F && uid[i] < 0x7F)
906*e4b17023SJohn Marino 	    *p++ = uid[i];
907*e4b17023SJohn Marino 	  else
908*e4b17023SJohn Marino 	    {
909*e4b17023SJohn Marino 	      sprintf (p, "\\%03o", uid[i]);
910*e4b17023SJohn Marino 	      p += 4;
911*e4b17023SJohn Marino 	    }
912*e4b17023SJohn Marino 	}
913*e4b17023SJohn Marino       *p = 0;
914*e4b17023SJohn Marino       return ret;
915*e4b17023SJohn Marino     }
916*e4b17023SJohn Marino 
917*e4b17023SJohn Marino   /* Otherwise, if it is valid printable ASCII, or printable UTF-8
918*e4b17023SJohn Marino      with the locale character set being UTF-8, IDENT is used.  */
919*e4b17023SJohn Marino   if (all_ascii || locale_utf8)
920*e4b17023SJohn Marino     return ident;
921*e4b17023SJohn Marino 
922*e4b17023SJohn Marino   /* Otherwise IDENT is converted to the locale character set if
923*e4b17023SJohn Marino      possible.  */
924*e4b17023SJohn Marino #if defined ENABLE_NLS && defined HAVE_LANGINFO_CODESET && HAVE_ICONV
925*e4b17023SJohn Marino   if (locale_encoding != NULL)
926*e4b17023SJohn Marino     {
927*e4b17023SJohn Marino       iconv_t cd = iconv_open (locale_encoding, "UTF-8");
928*e4b17023SJohn Marino       bool conversion_ok = true;
929*e4b17023SJohn Marino       char *ret = NULL;
930*e4b17023SJohn Marino       if (cd != (iconv_t) -1)
931*e4b17023SJohn Marino 	{
932*e4b17023SJohn Marino 	  size_t ret_alloc = 4 * idlen + 1;
933*e4b17023SJohn Marino 	  for (;;)
934*e4b17023SJohn Marino 	    {
935*e4b17023SJohn Marino 	      /* Repeat the whole conversion process as needed with
936*e4b17023SJohn Marino 		 larger buffers so non-reversible transformations can
937*e4b17023SJohn Marino 		 always be detected.  */
938*e4b17023SJohn Marino 	      ICONV_CONST char *inbuf = CONST_CAST (char *, ident);
939*e4b17023SJohn Marino 	      char *outbuf;
940*e4b17023SJohn Marino 	      size_t inbytesleft = idlen;
941*e4b17023SJohn Marino 	      size_t outbytesleft = ret_alloc - 1;
942*e4b17023SJohn Marino 	      size_t iconv_ret;
943*e4b17023SJohn Marino 
944*e4b17023SJohn Marino 	      ret = (char *) identifier_to_locale_alloc (ret_alloc);
945*e4b17023SJohn Marino 	      outbuf = ret;
946*e4b17023SJohn Marino 
947*e4b17023SJohn Marino 	      if (iconv (cd, 0, 0, 0, 0) == (size_t) -1)
948*e4b17023SJohn Marino 		{
949*e4b17023SJohn Marino 		  conversion_ok = false;
950*e4b17023SJohn Marino 		  break;
951*e4b17023SJohn Marino 		}
952*e4b17023SJohn Marino 
953*e4b17023SJohn Marino 	      iconv_ret = iconv (cd, &inbuf, &inbytesleft,
954*e4b17023SJohn Marino 				 &outbuf, &outbytesleft);
955*e4b17023SJohn Marino 	      if (iconv_ret == (size_t) -1 || inbytesleft != 0)
956*e4b17023SJohn Marino 		{
957*e4b17023SJohn Marino 		  if (errno == E2BIG)
958*e4b17023SJohn Marino 		    {
959*e4b17023SJohn Marino 		      ret_alloc *= 2;
960*e4b17023SJohn Marino 		      identifier_to_locale_free (ret);
961*e4b17023SJohn Marino 		      ret = NULL;
962*e4b17023SJohn Marino 		      continue;
963*e4b17023SJohn Marino 		    }
964*e4b17023SJohn Marino 		  else
965*e4b17023SJohn Marino 		    {
966*e4b17023SJohn Marino 		      conversion_ok = false;
967*e4b17023SJohn Marino 		      break;
968*e4b17023SJohn Marino 		    }
969*e4b17023SJohn Marino 		}
970*e4b17023SJohn Marino 	      else if (iconv_ret != 0)
971*e4b17023SJohn Marino 		{
972*e4b17023SJohn Marino 		  conversion_ok = false;
973*e4b17023SJohn Marino 		  break;
974*e4b17023SJohn Marino 		}
975*e4b17023SJohn Marino 	      /* Return to initial shift state.  */
976*e4b17023SJohn Marino 	      if (iconv (cd, 0, 0, &outbuf, &outbytesleft) == (size_t) -1)
977*e4b17023SJohn Marino 		{
978*e4b17023SJohn Marino 		  if (errno == E2BIG)
979*e4b17023SJohn Marino 		    {
980*e4b17023SJohn Marino 		      ret_alloc *= 2;
981*e4b17023SJohn Marino 		      identifier_to_locale_free (ret);
982*e4b17023SJohn Marino 		      ret = NULL;
983*e4b17023SJohn Marino 		      continue;
984*e4b17023SJohn Marino 		    }
985*e4b17023SJohn Marino 		  else
986*e4b17023SJohn Marino 		    {
987*e4b17023SJohn Marino 		      conversion_ok = false;
988*e4b17023SJohn Marino 		      break;
989*e4b17023SJohn Marino 		    }
990*e4b17023SJohn Marino 		}
991*e4b17023SJohn Marino 	      *outbuf = 0;
992*e4b17023SJohn Marino 	      break;
993*e4b17023SJohn Marino 	    }
994*e4b17023SJohn Marino 	  iconv_close (cd);
995*e4b17023SJohn Marino 	  if (conversion_ok)
996*e4b17023SJohn Marino 	    return ret;
997*e4b17023SJohn Marino 	}
998*e4b17023SJohn Marino     }
999*e4b17023SJohn Marino #endif
1000*e4b17023SJohn Marino 
1001*e4b17023SJohn Marino   /* Otherwise, convert non-ASCII characters in IDENT to UCNs.  */
1002*e4b17023SJohn Marino   {
1003*e4b17023SJohn Marino     char *ret = (char *) identifier_to_locale_alloc (10 * idlen + 1);
1004*e4b17023SJohn Marino     char *p = ret;
1005*e4b17023SJohn Marino     for (i = 0; i < idlen;)
1006*e4b17023SJohn Marino       {
1007*e4b17023SJohn Marino 	unsigned int c;
1008*e4b17023SJohn Marino 	size_t utf8_len = decode_utf8_char (&uid[i], idlen - i, &c);
1009*e4b17023SJohn Marino 	if (utf8_len == 1)
1010*e4b17023SJohn Marino 	  *p++ = uid[i];
1011*e4b17023SJohn Marino 	else
1012*e4b17023SJohn Marino 	  {
1013*e4b17023SJohn Marino 	    sprintf (p, "\\U%08x", c);
1014*e4b17023SJohn Marino 	    p += 10;
1015*e4b17023SJohn Marino 	  }
1016*e4b17023SJohn Marino 	i += utf8_len;
1017*e4b17023SJohn Marino       }
1018*e4b17023SJohn Marino     *p = 0;
1019*e4b17023SJohn Marino     return ret;
1020*e4b17023SJohn Marino   }
1021*e4b17023SJohn Marino }
1022