pretty-print.c revision 169689
1309577Sglebius/* Various declarations for language-independent pretty-print subroutines.
2309577Sglebius   Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
3309577Sglebius   Contributed by Gabriel Dos Reis <gdr@integrable-solutions.net>
4309577Sglebius
5309577SglebiusThis file is part of GCC.
6309577Sglebius
7309577SglebiusGCC is free software; you can redistribute it and/or modify it under
8309577Sglebiusthe terms of the GNU General Public License as published by the Free
9309577SglebiusSoftware Foundation; either version 2, or (at your option) any later
10309577Sglebiusversion.
11309577Sglebius
12309577SglebiusGCC is distributed in the hope that it will be useful, but WITHOUT ANY
13309577SglebiusWARRANTY; without even the implied warranty of MERCHANTABILITY or
14309577SglebiusFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15309577Sglebiusfor more details.
16309577Sglebius
17309577SglebiusYou should have received a copy of the GNU General Public License
18309577Sglebiusalong with GCC; see the file COPYING.  If not, write to the Free
19309577SglebiusSoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
20309577Sglebius02110-1301, USA.  */
21309577Sglebius
22309577Sglebius#include "config.h"
23309577Sglebius#undef FLOAT /* This is for hpux. They should change hpux.  */
24309577Sglebius#undef FFS  /* Some systems define this in param.h.  */
25309577Sglebius#include "system.h"
26309577Sglebius#include "coretypes.h"
27309577Sglebius#include "intl.h"
28309577Sglebius#include "pretty-print.h"
29309577Sglebius#include "tree.h"
30309577Sglebius
31309577Sglebius#define obstack_chunk_alloc xmalloc
32309577Sglebius#define obstack_chunk_free  free
33309577Sglebius
34309577Sglebius/* A pointer to the formatted diagnostic message.  */
35309577Sglebius#define pp_formatted_text_data(PP) \
36309577Sglebius   ((const char *) obstack_base (pp_base (PP)->buffer->obstack))
37309577Sglebius
38309577Sglebius/* Format an integer given by va_arg (ARG, type-specifier T) where
39309577Sglebius   type-specifier is a precision modifier as indicated by PREC.  F is
40309577Sglebius   a string used to construct the appropriate format-specifier.  */
41309577Sglebius#define pp_integer_with_precision(PP, ARG, PREC, T, F)       \
42309577Sglebius  do                                                         \
43309577Sglebius    switch (PREC)                                            \
44309577Sglebius      {                                                      \
45309577Sglebius      case 0:                                                \
46309577Sglebius        pp_scalar (PP, "%" F, va_arg (ARG, T));              \
47309577Sglebius        break;                                               \
48309577Sglebius                                                             \
49309577Sglebius      case 1:                                                \
50309577Sglebius        pp_scalar (PP, "%l" F, va_arg (ARG, long T));        \
51309577Sglebius        break;                                               \
52309577Sglebius                                                             \
53309577Sglebius      case 2:                                                \
54309577Sglebius        pp_scalar (PP, "%ll" F, va_arg (ARG, long long T));  \
55309577Sglebius        break;                                               \
56309577Sglebius                                                             \
57309577Sglebius      default:                                               \
58309577Sglebius        break;                                               \
59309577Sglebius      }                                                      \
60309577Sglebius  while (0)
61309577Sglebius
62309577Sglebius
63309577Sglebius/* Subroutine of pp_set_maximum_length.  Set up PRETTY-PRINTER's
64309577Sglebius   internal maximum characters per line.  */
65309577Sglebiusstatic void
66309577Sglebiuspp_set_real_maximum_length (pretty_printer *pp)
67309577Sglebius{
68325322Sgordon  /* If we're told not to wrap lines then do the obvious thing.  In case
69309577Sglebius     we'll emit prefix only once per message, it is appropriate
70309577Sglebius     not to increase unnecessarily the line-length cut-off.  */
71309577Sglebius  if (!pp_is_wrapping_line (pp)
72309577Sglebius      || pp_prefixing_rule (pp) == DIAGNOSTICS_SHOW_PREFIX_ONCE
73309577Sglebius      || pp_prefixing_rule (pp) == DIAGNOSTICS_SHOW_PREFIX_NEVER)
74309577Sglebius    pp->maximum_length = pp_line_cutoff (pp);
75309577Sglebius  else
76309577Sglebius    {
77309577Sglebius      int prefix_length = pp->prefix ? strlen (pp->prefix) : 0;
78325322Sgordon      /* If the prefix is ridiculously too long, output at least
79309577Sglebius         32 characters.  */
80309577Sglebius      if (pp_line_cutoff (pp) - prefix_length < 32)
81309577Sglebius	pp->maximum_length = pp_line_cutoff (pp) + 32;
82309577Sglebius      else
83309577Sglebius	pp->maximum_length = pp_line_cutoff (pp);
84309577Sglebius    }
85309577Sglebius}
86309577Sglebius
87309577Sglebius/* Clear PRETTY-PRINTER's output state.  */
88309577Sglebiusstatic inline void
89309577Sglebiuspp_clear_state (pretty_printer *pp)
90309577Sglebius{
91309577Sglebius  pp->emitted_prefix = false;
92309577Sglebius  pp_indentation (pp) = 0;
93309577Sglebius}
94309577Sglebius
95309577Sglebius/* Flush the formatted text of PRETTY-PRINTER onto the attached stream.  */
96325322Sgordonvoid
97309577Sglebiuspp_write_text_to_stream (pretty_printer *pp)
98309577Sglebius{
99309577Sglebius  const char *text = pp_formatted_text (pp);
100309577Sglebius  fputs (text, pp->buffer->stream);
101325322Sgordon  pp_clear_output_area (pp);
102309577Sglebius}
103309577Sglebius
104309577Sglebius/* Wrap a text delimited by START and END into PRETTY-PRINTER.  */
105309577Sglebiusstatic void
106309577Sglebiuspp_wrap_text (pretty_printer *pp, const char *start, const char *end)
107325322Sgordon{
108309577Sglebius  bool wrapping_line = pp_is_wrapping_line (pp);
109309577Sglebius
110309577Sglebius  while (start != end)
111309577Sglebius    {
112309577Sglebius      /* Dump anything bordered by whitespaces.  */
113309577Sglebius      {
114309577Sglebius	const char *p = start;
115309577Sglebius	while (p != end && !ISBLANK (*p) && *p != '\n')
116309577Sglebius	  ++p;
117309577Sglebius	if (wrapping_line
118309577Sglebius            && p - start >= pp_remaining_character_count_for_line (pp))
119309577Sglebius	  pp_newline (pp);
120309577Sglebius	pp_append_text (pp, start, p);
121309577Sglebius	start = p;
122309577Sglebius      }
123309577Sglebius
124309577Sglebius      if (start != end && ISBLANK (*start))
125325322Sgordon	{
126325322Sgordon	  pp_space (pp);
127325322Sgordon	  ++start;
128309577Sglebius	}
129309577Sglebius      if (start != end && *start == '\n')
130309577Sglebius	{
131309577Sglebius	  pp_newline (pp);
132325322Sgordon	  ++start;
133309577Sglebius	}
134309577Sglebius    }
135309577Sglebius}
136309577Sglebius
137309577Sglebius/* Same as pp_wrap_text but wrap text only when in line-wrapping mode.  */
138309577Sglebiusstatic inline void
139309577Sglebiuspp_maybe_wrap_text (pretty_printer *pp, const char *start, const char *end)
140309577Sglebius{
141309577Sglebius  if (pp_is_wrapping_line (pp))
142309577Sglebius    pp_wrap_text (pp, start, end);
143309577Sglebius  else
144309577Sglebius    pp_append_text (pp, start, end);
145309577Sglebius}
146309577Sglebius
147309577Sglebius/* Append to the output area of PRETTY-PRINTER a string specified by its
148309577Sglebius   STARTing character and LENGTH.  */
149309577Sglebiusstatic inline void
150309577Sglebiuspp_append_r (pretty_printer *pp, const char *start, int length)
151325322Sgordon{
152325322Sgordon  obstack_grow (pp->buffer->obstack, start, length);
153309577Sglebius  pp->buffer->line_length += length;
154309577Sglebius}
155309577Sglebius
156309577Sglebius/* Insert enough spaces into the output area of PRETTY-PRINTER to bring
157309577Sglebius   the column position to the current indentation level, assuming that a
158309577Sglebius   newline has just been written to the buffer.  */
159309577Sglebiusvoid
160309577Sglebiuspp_base_indent (pretty_printer *pp)
161309577Sglebius{
162309577Sglebius  int n = pp_indentation (pp);
163309577Sglebius  int i;
164309577Sglebius
165309577Sglebius  for (i = 0; i < n; ++i)
166309577Sglebius    pp_space (pp);
167309577Sglebius}
168309577Sglebius
169309577Sglebius/* The following format specifiers are recognized as being client independent:
170309577Sglebius   %d, %i: (signed) integer in base ten.
171309577Sglebius   %u: unsigned integer in base ten.
172309577Sglebius   %o: unsigned integer in base eight.
173331986Sgordon   %x: unsigned integer in base sixteen.
174309577Sglebius   %ld, %li, %lo, %lu, %lx: long versions of the above.
175309577Sglebius   %lld, %lli, %llo, %llu, %llx: long long versions.
176331986Sgordon   %wd, %wi, %wo, %wu, %wx: HOST_WIDE_INT versions.
177309577Sglebius   %c: character.
178309577Sglebius   %s: string.
179331986Sgordon   %p: pointer.
180309577Sglebius   %m: strerror(text->err_no) - does not consume a value from args_ptr.
181309577Sglebius   %%: '%'.
182309577Sglebius   %<: opening quote.
183309577Sglebius   %>: closing quote.
184309577Sglebius   %': apostrophe (should only be used in untranslated messages;
185309577Sglebius       translations should use appropriate punctuation directly).
186309577Sglebius   %.*s: a substring the length of which is specified by an argument
187309577Sglebius	 integer.
188309577Sglebius   %Ns: likewise, but length specified as constant in the format string.
189309577Sglebius   %H: location_t.
190309577Sglebius   %J: a decl tree, from which DECL_SOURCE_LOCATION will be recorded.
191309577Sglebius   Flag 'q': quote formatted text (must come immediately after '%').
192309577Sglebius
193309577Sglebius   Arguments can be used sequentially, or through %N$ resp. *N$
194309577Sglebius   notation Nth argument after the format string.  If %N$ / *N$
195309577Sglebius   notation is used, it must be used for all arguments, except %m, %%,
196309577Sglebius   %<, %> and %', which may not have a number, as they do not consume
197309577Sglebius   an argument.  When %M$.*N$s is used, M must be N + 1.  (This may
198309577Sglebius   also be written %M$.*s, provided N is not otherwise used.)  The
199309577Sglebius   format string must have conversion specifiers with argument numbers
200309577Sglebius   1 up to highest argument; each argument may only be used once.
201309577Sglebius   A format string can have at most 30 arguments.  */
202309577Sglebius
203309577Sglebius/* Formatting phases 1 and 2: render TEXT->format_spec plus
204309577Sglebius   TEXT->args_ptr into a series of chunks in PP->buffer->args[].
205309577Sglebius   Phase 3 is in pp_base_format_text.  */
206309577Sglebius
207309577Sglebiusvoid
208309577Sglebiuspp_base_format (pretty_printer *pp, text_info *text)
209309577Sglebius{
210309577Sglebius  output_buffer *buffer = pp->buffer;
211309577Sglebius  const char *p;
212309577Sglebius  const char **args;
213309577Sglebius  struct chunk_info *new_chunk_array;
214325322Sgordon
215309577Sglebius  unsigned int curarg = 0, chunk = 0, argno;
216309577Sglebius  pp_wrapping_mode_t old_wrapping_mode;
217309577Sglebius  bool any_unnumbered = false, any_numbered = false;
218309577Sglebius  const char **formatters[PP_NL_ARGMAX];
219325322Sgordon
220309577Sglebius  /* Allocate a new chunk structure.  */
221309577Sglebius  new_chunk_array = XOBNEW (&buffer->chunk_obstack, struct chunk_info);
222309577Sglebius  new_chunk_array->prev = buffer->cur_chunk_array;
223309577Sglebius  buffer->cur_chunk_array = new_chunk_array;
224309577Sglebius  args = new_chunk_array->args;
225309577Sglebius
226325322Sgordon  /* Formatting phase 1: split up TEXT->format_spec into chunks in
227309577Sglebius     PP->buffer->args[].  Even-numbered chunks are to be output
228309577Sglebius     verbatim, odd-numbered chunks are format specifiers.
229309577Sglebius     %m, %%, %<, %>, and %' are replaced with the appropriate text at
230309577Sglebius     this point.  */
231309577Sglebius
232309577Sglebius  memset (formatters, 0, sizeof formatters);
233309577Sglebius
234309577Sglebius  for (p = text->format_spec; *p; )
235309577Sglebius    {
236309577Sglebius      while (*p != '\0' && *p != '%')
237309577Sglebius	{
238309577Sglebius	  obstack_1grow (&buffer->chunk_obstack, *p);
239309577Sglebius	  p++;
240309577Sglebius	}
241309577Sglebius
242309577Sglebius      if (*p == '\0')
243309577Sglebius	break;
244309577Sglebius
245309577Sglebius      switch (*++p)
246309577Sglebius	{
247309577Sglebius	case '\0':
248309577Sglebius	  gcc_unreachable ();
249309577Sglebius
250309577Sglebius	case '%':
251309577Sglebius	  obstack_1grow (&buffer->chunk_obstack, '%');
252309577Sglebius	  p++;
253309577Sglebius	  continue;
254309577Sglebius
255309577Sglebius	case '<':
256309577Sglebius	  obstack_grow (&buffer->chunk_obstack,
257325322Sgordon			open_quote, strlen (open_quote));
258325322Sgordon	  p++;
259325322Sgordon	  continue;
260325322Sgordon
261325322Sgordon	case '>':
262325322Sgordon	case '\'':
263325322Sgordon	  obstack_grow (&buffer->chunk_obstack,
264325322Sgordon			close_quote, strlen (close_quote));
265325322Sgordon	  p++;
266309577Sglebius	  continue;
267309577Sglebius
268309577Sglebius	case 'm':
269325322Sgordon	  {
270309577Sglebius	    const char *errstr = xstrerror (text->err_no);
271309577Sglebius	    obstack_grow (&buffer->chunk_obstack, errstr, strlen (errstr));
272309577Sglebius	  }
273309577Sglebius	  p++;
274331986Sgordon	  continue;
275309577Sglebius
276309577Sglebius	default:
277331986Sgordon	  /* Handled in phase 2.  Terminate the plain chunk here.  */
278331986Sgordon	  obstack_1grow (&buffer->chunk_obstack, '\0');
279331986Sgordon	  gcc_assert (chunk < PP_NL_ARGMAX * 2);
280331986Sgordon	  args[chunk++] = XOBFINISH (&buffer->chunk_obstack, const char *);
281331986Sgordon	  break;
282331986Sgordon	}
283331986Sgordon
284331986Sgordon      if (ISDIGIT (*p))
285331986Sgordon	{
286331986Sgordon	  char *end;
287309577Sglebius	  argno = strtoul (p, &end, 10) - 1;
288309577Sglebius	  p = end;
289309577Sglebius	  gcc_assert (*p == '$');
290309577Sglebius	  p++;
291309577Sglebius
292309577Sglebius	  any_numbered = true;
293309577Sglebius	  gcc_assert (!any_unnumbered);
294309577Sglebius	}
295309577Sglebius      else
296309577Sglebius	{
297309577Sglebius	  argno = curarg++;
298309577Sglebius	  any_unnumbered = true;
299309577Sglebius	  gcc_assert (!any_numbered);
300309577Sglebius	}
301309577Sglebius      gcc_assert (argno < PP_NL_ARGMAX);
302309577Sglebius      gcc_assert (!formatters[argno]);
303309577Sglebius      formatters[argno] = &args[chunk];
304309577Sglebius      do
305309577Sglebius	{
306309577Sglebius	  obstack_1grow (&buffer->chunk_obstack, *p);
307309577Sglebius	  p++;
308309577Sglebius	}
309309577Sglebius      while (strchr ("qwl+#", p[-1]));
310309577Sglebius
311309577Sglebius      if (p[-1] == '.')
312309577Sglebius	{
313309577Sglebius	  /* We handle '%.Ns' and '%.*s' or '%M$.*N$s'
314309577Sglebius	     (where M == N + 1).  */
315309577Sglebius	  if (ISDIGIT (*p))
316309577Sglebius	    {
317309577Sglebius	      do
318309577Sglebius		{
319309577Sglebius		  obstack_1grow (&buffer->chunk_obstack, *p);
320309577Sglebius		  p++;
321309577Sglebius		}
322309577Sglebius	      while (ISDIGIT (p[-1]));
323309577Sglebius	      gcc_assert (p[-1] == 's');
324309577Sglebius	    }
325309577Sglebius	  else
326309577Sglebius	    {
327309577Sglebius	      gcc_assert (*p == '*');
328309577Sglebius	      obstack_1grow (&buffer->chunk_obstack, '*');
329309577Sglebius	      p++;
330309577Sglebius
331309577Sglebius	      if (ISDIGIT (*p))
332309577Sglebius		{
333309577Sglebius		  char *end;
334309577Sglebius		  unsigned int argno2 = strtoul (p, &end, 10) - 1;
335309577Sglebius		  p = end;
336309577Sglebius		  gcc_assert (argno2 == argno - 1);
337309577Sglebius		  gcc_assert (!any_unnumbered);
338309577Sglebius		  gcc_assert (*p == '$');
339309577Sglebius
340309577Sglebius		  p++;
341309577Sglebius		  formatters[argno2] = formatters[argno];
342309577Sglebius		}
343309577Sglebius	      else
344309577Sglebius		{
345309577Sglebius		  gcc_assert (!any_numbered);
346309577Sglebius		  formatters[argno+1] = formatters[argno];
347309577Sglebius		  curarg++;
348309577Sglebius		}
349309577Sglebius	      gcc_assert (*p == 's');
350309577Sglebius	      obstack_1grow (&buffer->chunk_obstack, 's');
351309577Sglebius	      p++;
352309577Sglebius	    }
353309577Sglebius	}
354309577Sglebius      if (*p == '\0')
355309577Sglebius	break;
356309577Sglebius
357309577Sglebius      obstack_1grow (&buffer->chunk_obstack, '\0');
358309577Sglebius      gcc_assert (chunk < PP_NL_ARGMAX * 2);
359309577Sglebius      args[chunk++] = XOBFINISH (&buffer->chunk_obstack, const char *);
360309577Sglebius    }
361331986Sgordon
362331986Sgordon  obstack_1grow (&buffer->chunk_obstack, '\0');
363331986Sgordon  gcc_assert (chunk < PP_NL_ARGMAX * 2);
364331986Sgordon  args[chunk++] = XOBFINISH (&buffer->chunk_obstack, const char *);
365331986Sgordon  args[chunk] = 0;
366331986Sgordon
367331986Sgordon  /* Set output to the argument obstack, and switch line-wrapping and
368331986Sgordon     prefixing off.  */
369331986Sgordon  buffer->obstack = &buffer->chunk_obstack;
370331986Sgordon  old_wrapping_mode = pp_set_verbatim_wrapping (pp);
371331986Sgordon
372331986Sgordon  /* Second phase.  Replace each formatter with the formatted text it
373331986Sgordon     corresponds to.  */
374331986Sgordon
375331986Sgordon  for (argno = 0; formatters[argno]; argno++)
376331986Sgordon    {
377331986Sgordon      int precision = 0;
378331986Sgordon      bool wide = false;
379331986Sgordon      bool plus = false;
380331986Sgordon      bool hash = false;
381331986Sgordon      bool quote = false;
382331986Sgordon
383331986Sgordon      /* We do not attempt to enforce any ordering on the modifier
384331986Sgordon	 characters.  */
385309577Sglebius
386309577Sglebius      for (p = *formatters[argno];; p++)
387309577Sglebius	{
388309577Sglebius	  switch (*p)
389309577Sglebius	    {
390309577Sglebius	    case 'q':
391309577Sglebius	      gcc_assert (!quote);
392325322Sgordon	      quote = true;
393325322Sgordon	      continue;
394325322Sgordon
395325322Sgordon	    case '+':
396325322Sgordon	      gcc_assert (!plus);
397325322Sgordon	      plus = true;
398309577Sglebius	      continue;
399309577Sglebius
400309577Sglebius	    case '#':
401309577Sglebius	      gcc_assert (!hash);
402309577Sglebius	      hash = true;
403309577Sglebius	      continue;
404309577Sglebius
405309577Sglebius	    case 'w':
406309577Sglebius	      gcc_assert (!wide);
407309577Sglebius	      wide = true;
408309577Sglebius	      continue;
409309577Sglebius
410309577Sglebius	    case 'l':
411309577Sglebius	      /* We don't support precision beyond that of "long long".  */
412309577Sglebius	      gcc_assert (precision < 2);
413309577Sglebius	      precision++;
414309577Sglebius	      continue;
415309577Sglebius	    }
416309577Sglebius	  break;
417309577Sglebius	}
418309577Sglebius
419309577Sglebius      gcc_assert (!wide || precision == 0);
420309577Sglebius
421309577Sglebius      if (quote)
422309577Sglebius	pp_string (pp, open_quote);
423309577Sglebius
424309577Sglebius      switch (*p)
425309577Sglebius	{
426309577Sglebius	case 'c':
427309577Sglebius	  pp_character (pp, va_arg (*text->args_ptr, int));
428309577Sglebius	  break;
429309577Sglebius
430325322Sgordon	case 'd':
431309577Sglebius	case 'i':
432309577Sglebius	  if (wide)
433309577Sglebius	    pp_wide_integer (pp, va_arg (*text->args_ptr, HOST_WIDE_INT));
434325322Sgordon	  else
435325322Sgordon	    pp_integer_with_precision
436309577Sglebius	      (pp, *text->args_ptr, precision, int, "d");
437309577Sglebius	  break;
438309577Sglebius
439309577Sglebius	case 'o':
440309577Sglebius	  if (wide)
441309577Sglebius	    pp_scalar (pp, "%" HOST_WIDE_INT_PRINT "o",
442309577Sglebius		       va_arg (*text->args_ptr, unsigned HOST_WIDE_INT));
443309577Sglebius	  else
444309577Sglebius	    pp_integer_with_precision
445309577Sglebius	      (pp, *text->args_ptr, precision, unsigned, "o");
446331986Sgordon	  break;
447309577Sglebius
448309577Sglebius	case 's':
449309577Sglebius	  pp_string (pp, va_arg (*text->args_ptr, const char *));
450309577Sglebius	  break;
451309577Sglebius
452309577Sglebius	case 'p':
453309577Sglebius	  pp_pointer (pp, va_arg (*text->args_ptr, void *));
454309577Sglebius	  break;
455309577Sglebius
456309577Sglebius	case 'u':
457309577Sglebius	  if (wide)
458325322Sgordon	    pp_scalar (pp, HOST_WIDE_INT_PRINT_UNSIGNED,
459309577Sglebius		       va_arg (*text->args_ptr, unsigned HOST_WIDE_INT));
460309577Sglebius	  else
461309577Sglebius	    pp_integer_with_precision
462309577Sglebius	      (pp, *text->args_ptr, precision, unsigned, "u");
463309577Sglebius	  break;
464309577Sglebius
465309577Sglebius	case 'x':
466309577Sglebius	  if (wide)
467309577Sglebius	    pp_scalar (pp, HOST_WIDE_INT_PRINT_HEX,
468309577Sglebius		       va_arg (*text->args_ptr, unsigned HOST_WIDE_INT));
469325322Sgordon	  else
470325322Sgordon	    pp_integer_with_precision
471325322Sgordon	      (pp, *text->args_ptr, precision, unsigned, "x");
472325322Sgordon	  break;
473325322Sgordon
474325322Sgordon	case 'H':
475309577Sglebius	  {
476309577Sglebius	    location_t *locus = va_arg (*text->args_ptr, location_t *);
477309577Sglebius	    gcc_assert (text->locus != NULL);
478309577Sglebius	    *text->locus = *locus;
479309577Sglebius	  }
480325322Sgordon	  break;
481309577Sglebius
482325322Sgordon	case 'J':
483325322Sgordon	  {
484309577Sglebius	    tree t = va_arg (*text->args_ptr, tree);
485309577Sglebius	    gcc_assert (text->locus != NULL);
486309577Sglebius	    *text->locus = DECL_SOURCE_LOCATION (t);
487309577Sglebius	  }
488325322Sgordon	  break;
489325322Sgordon
490309577Sglebius	case '.':
491309577Sglebius	  {
492309577Sglebius	    int n;
493309577Sglebius	    const char *s;
494325322Sgordon
495309577Sglebius	    /* We handle '%.Ns' and '%.*s' or '%M$.*N$s'
496309577Sglebius	       (where M == N + 1).  The format string should be verified
497309577Sglebius	       already from the first phase.  */
498309577Sglebius	    p++;
499309577Sglebius	    if (ISDIGIT (*p))
500325322Sgordon	      {
501309577Sglebius		char *end;
502309577Sglebius		n = strtoul (p, &end, 10);
503309577Sglebius		p = end;
504309577Sglebius		gcc_assert (*p == 's');
505325322Sgordon	      }
506309577Sglebius	    else
507309577Sglebius	      {
508309577Sglebius		gcc_assert (*p == '*');
509309577Sglebius		p++;
510309577Sglebius		gcc_assert (*p == 's');
511309577Sglebius		n = va_arg (*text->args_ptr, int);
512309577Sglebius
513309577Sglebius		/* This consumes a second entry in the formatters array.  */
514309577Sglebius		gcc_assert (formatters[argno] == formatters[argno+1]);
515309577Sglebius		argno++;
516309577Sglebius	      }
517309577Sglebius
518325322Sgordon	    s = va_arg (*text->args_ptr, const char *);
519325322Sgordon	    pp_append_text (pp, s, s + n);
520325322Sgordon	  }
521325322Sgordon	  break;
522325322Sgordon
523325322Sgordon	default:
524309577Sglebius	  {
525309577Sglebius	    bool ok;
526309577Sglebius
527309577Sglebius	    gcc_assert (pp_format_decoder (pp));
528309577Sglebius	    ok = pp_format_decoder (pp) (pp, text, p,
529309577Sglebius					 precision, wide, plus, hash);
530309577Sglebius	    gcc_assert (ok);
531309577Sglebius	  }
532309577Sglebius	}
533309577Sglebius
534309577Sglebius      if (quote)
535309577Sglebius	pp_string (pp, close_quote);
536309577Sglebius
537309577Sglebius      obstack_1grow (&buffer->chunk_obstack, '\0');
538325322Sgordon      *formatters[argno] = XOBFINISH (&buffer->chunk_obstack, const char *);
539325322Sgordon    }
540325322Sgordon
541325322Sgordon#ifdef ENABLE_CHECKING
542325322Sgordon  for (; argno < PP_NL_ARGMAX; argno++)
543325322Sgordon    gcc_assert (!formatters[argno]);
544309577Sglebius#endif
545309577Sglebius
546309577Sglebius  /* Revert to normal obstack and wrapping mode.  */
547325322Sgordon  buffer->obstack = &buffer->formatted_obstack;
548309577Sglebius  buffer->line_length = 0;
549309577Sglebius  pp_wrapping_mode (pp) = old_wrapping_mode;
550309577Sglebius  pp_clear_state (pp);
551309577Sglebius}
552309577Sglebius
553309577Sglebius/* Format of a message pointed to by TEXT.  */
554309577Sglebiusvoid
555309577Sglebiuspp_base_output_formatted_text (pretty_printer *pp)
556309577Sglebius{
557309577Sglebius  unsigned int chunk;
558309577Sglebius  output_buffer *buffer = pp_buffer (pp);
559309577Sglebius  struct chunk_info *chunk_array = buffer->cur_chunk_array;
560309577Sglebius  const char **args = chunk_array->args;
561309577Sglebius
562309577Sglebius  gcc_assert (buffer->obstack == &buffer->formatted_obstack);
563309577Sglebius  gcc_assert (buffer->line_length == 0);
564309577Sglebius
565309577Sglebius  /* This is a third phase, first 2 phases done in pp_base_format_args.
566309577Sglebius     Now we actually print it.  */
567325322Sgordon  for (chunk = 0; args[chunk]; chunk++)
568309577Sglebius    pp_string (pp, args[chunk]);
569331986Sgordon
570325322Sgordon  /* Deallocate the chunk structure and everything after it (i.e. the
571309577Sglebius     associated series of formatted strings).  */
572309577Sglebius  buffer->cur_chunk_array = chunk_array->prev;
573309577Sglebius  obstack_free (&buffer->chunk_obstack, chunk_array);
574309577Sglebius}
575309577Sglebius
576309577Sglebius/* Helper subroutine of output_verbatim and verbatim. Do the appropriate
577309577Sglebius   settings needed by BUFFER for a verbatim formatting.  */
578309577Sglebiusvoid
579309577Sglebiuspp_base_format_verbatim (pretty_printer *pp, text_info *text)
580309577Sglebius{
581309577Sglebius  /* Set verbatim mode.  */
582325322Sgordon  pp_wrapping_mode_t oldmode = pp_set_verbatim_wrapping (pp);
583309577Sglebius
584309577Sglebius  /* Do the actual formatting.  */
585309577Sglebius  pp_format (pp, text);
586325322Sgordon  pp_output_formatted_text (pp);
587309577Sglebius
588309577Sglebius  /* Restore previous settings.  */
589309577Sglebius  pp_wrapping_mode (pp) = oldmode;
590309577Sglebius}
591309577Sglebius
592309577Sglebius/* Flush the content of BUFFER onto the attached stream.  */
593309577Sglebiusvoid
594309577Sglebiuspp_base_flush (pretty_printer *pp)
595309577Sglebius{
596309577Sglebius  pp_write_text_to_stream (pp);
597309577Sglebius  pp_clear_state (pp);
598309577Sglebius  fputc ('\n', pp->buffer->stream);
599309577Sglebius  fflush (pp->buffer->stream);
600309577Sglebius  pp_needs_newline (pp) = false;
601325322Sgordon}
602309577Sglebius
603331986Sgordon/* Sets the number of maximum characters per line PRETTY-PRINTER can
604325322Sgordon   output in line-wrapping mode.  A LENGTH value 0 suppresses
605309577Sglebius   line-wrapping.  */
606309577Sglebiusvoid
607309577Sglebiuspp_base_set_line_maximum_length (pretty_printer *pp, int length)
608309577Sglebius{
609309577Sglebius  pp_line_cutoff (pp) = length;
610309577Sglebius  pp_set_real_maximum_length (pp);
611309577Sglebius}
612309577Sglebius
613309577Sglebius/* Clear PRETTY-PRINTER output area text info.  */
614309577Sglebiusvoid
615309577Sglebiuspp_base_clear_output_area (pretty_printer *pp)
616309577Sglebius{
617309577Sglebius  obstack_free (pp->buffer->obstack, obstack_base (pp->buffer->obstack));
618309577Sglebius  pp->buffer->line_length = 0;
619309577Sglebius}
620309577Sglebius
621309577Sglebius/* Set PREFIX for PRETTY-PRINTER.  */
622309577Sglebiusvoid
623309577Sglebiuspp_base_set_prefix (pretty_printer *pp, const char *prefix)
624309577Sglebius{
625309577Sglebius  pp->prefix = prefix;
626309577Sglebius  pp_set_real_maximum_length (pp);
627309577Sglebius  pp->emitted_prefix = false;
628309577Sglebius  pp_indentation (pp) = 0;
629309577Sglebius}
630309577Sglebius
631309577Sglebius/* Free PRETTY-PRINTER's prefix, a previously malloc()'d string.  */
632309577Sglebiusvoid
633309577Sglebiuspp_base_destroy_prefix (pretty_printer *pp)
634309577Sglebius{
635309577Sglebius  if (pp->prefix != NULL)
636309577Sglebius    {
637309577Sglebius      free ((char *) pp->prefix);
638309577Sglebius      pp->prefix = NULL;
639309577Sglebius    }
640309577Sglebius}
641309577Sglebius
642309577Sglebius/* Write out PRETTY-PRINTER's prefix.  */
643309577Sglebiusvoid
644309577Sglebiuspp_base_emit_prefix (pretty_printer *pp)
645309577Sglebius{
646309577Sglebius  if (pp->prefix != NULL)
647309577Sglebius    {
648309577Sglebius      switch (pp_prefixing_rule (pp))
649309577Sglebius	{
650309577Sglebius	default:
651309577Sglebius	case DIAGNOSTICS_SHOW_PREFIX_NEVER:
652309577Sglebius	  break;
653309577Sglebius
654309577Sglebius	case DIAGNOSTICS_SHOW_PREFIX_ONCE:
655309577Sglebius	  if (pp->emitted_prefix)
656309577Sglebius	    {
657309577Sglebius	      pp_base_indent (pp);
658309577Sglebius	      break;
659309577Sglebius	    }
660309577Sglebius	  pp_indentation (pp) += 3;
661309577Sglebius	  /* Fall through.  */
662309577Sglebius
663309577Sglebius	case DIAGNOSTICS_SHOW_PREFIX_EVERY_LINE:
664309577Sglebius	  {
665309577Sglebius	    int prefix_length = strlen (pp->prefix);
666309577Sglebius	    pp_append_r (pp, pp->prefix, prefix_length);
667309577Sglebius	    pp->emitted_prefix = true;
668309577Sglebius	  }
669309577Sglebius	  break;
670309577Sglebius	}
671309577Sglebius    }
672309577Sglebius}
673309577Sglebius
674309577Sglebius/* Construct a PRETTY-PRINTER with PREFIX and of MAXIMUM_LENGTH
675309577Sglebius   characters per line.  */
676309577Sglebiusvoid
677309577Sglebiuspp_construct (pretty_printer *pp, const char *prefix, int maximum_length)
678309577Sglebius{
679309577Sglebius  memset (pp, 0, sizeof (pretty_printer));
680309577Sglebius  pp->buffer = XCNEW (output_buffer);
681309577Sglebius  obstack_init (&pp->buffer->chunk_obstack);
682309577Sglebius  obstack_init (&pp->buffer->formatted_obstack);
683309577Sglebius  pp->buffer->obstack = &pp->buffer->formatted_obstack;
684309577Sglebius  pp->buffer->stream = stderr;
685309577Sglebius  pp_line_cutoff (pp) = maximum_length;
686309577Sglebius  pp_prefixing_rule (pp) = DIAGNOSTICS_SHOW_PREFIX_ONCE;
687309577Sglebius  pp_set_prefix (pp, prefix);
688309577Sglebius}
689309577Sglebius
690325322Sgordon/* Append a string delimited by START and END to the output area of
691325322Sgordon   PRETTY-PRINTER.  No line wrapping is done.  However, if beginning a
692325322Sgordon   new line then emit PRETTY-PRINTER's prefix and skip any leading
693309577Sglebius   whitespace if appropriate.  The caller must ensure that it is
694309577Sglebius   safe to do so.  */
695309577Sglebiusvoid
696309577Sglebiuspp_base_append_text (pretty_printer *pp, const char *start, const char *end)
697325322Sgordon{
698325322Sgordon  /* Emit prefix and skip whitespace if we're starting a new line.  */
699309577Sglebius  if (pp->buffer->line_length == 0)
700    {
701      pp_emit_prefix (pp);
702      if (pp_is_wrapping_line (pp))
703	while (start != end && *start == ' ')
704	  ++start;
705    }
706  pp_append_r (pp, start, end - start);
707}
708
709/* Finishes constructing a NULL-terminated character string representing
710   the PRETTY-PRINTED text.  */
711const char *
712pp_base_formatted_text (pretty_printer *pp)
713{
714  obstack_1grow (pp->buffer->obstack, '\0');
715  return pp_formatted_text_data (pp);
716}
717
718/*  Return a pointer to the last character emitted in PRETTY-PRINTER's
719    output area.  A NULL pointer means no character available.  */
720const char *
721pp_base_last_position_in_text (const pretty_printer *pp)
722{
723  const char *p = NULL;
724  struct obstack *text = pp->buffer->obstack;
725
726  if (obstack_base (text) != obstack_next_free (text))
727    p = ((const char *) obstack_next_free (text)) - 1;
728  return p;
729}
730
731/* Return the amount of characters PRETTY-PRINTER can accept to
732   make a full line.  Meaningful only in line-wrapping mode.  */
733int
734pp_base_remaining_character_count_for_line (pretty_printer *pp)
735{
736  return pp->maximum_length - pp->buffer->line_length;
737}
738
739
740/* Format a message into BUFFER a la printf.  */
741void
742pp_printf (pretty_printer *pp, const char *msg, ...)
743{
744  text_info text;
745  va_list ap;
746
747  va_start (ap, msg);
748  text.err_no = errno;
749  text.args_ptr = &ap;
750  text.format_spec = msg;
751  text.locus = NULL;
752  pp_format (pp, &text);
753  pp_output_formatted_text (pp);
754  va_end (ap);
755}
756
757
758/* Output MESSAGE verbatim into BUFFER.  */
759void
760pp_verbatim (pretty_printer *pp, const char *msg, ...)
761{
762  text_info text;
763  va_list ap;
764
765  va_start (ap, msg);
766  text.err_no = errno;
767  text.args_ptr = &ap;
768  text.format_spec = msg;
769  text.locus = NULL;
770  pp_format_verbatim (pp, &text);
771  va_end (ap);
772}
773
774
775
776/* Have PRETTY-PRINTER start a new line.  */
777void
778pp_base_newline (pretty_printer *pp)
779{
780  obstack_1grow (pp->buffer->obstack, '\n');
781  pp->buffer->line_length = 0;
782}
783
784/* Have PRETTY-PRINTER add a CHARACTER.  */
785void
786pp_base_character (pretty_printer *pp, int c)
787{
788  if (pp_is_wrapping_line (pp)
789      && pp_remaining_character_count_for_line (pp) <= 0)
790    {
791      pp_newline (pp);
792      if (ISSPACE (c))
793        return;
794    }
795  obstack_1grow (pp->buffer->obstack, c);
796  ++pp->buffer->line_length;
797}
798
799/* Append a STRING to the output area of PRETTY-PRINTER; the STRING may
800   be line-wrapped if in appropriate mode.  */
801void
802pp_base_string (pretty_printer *pp, const char *str)
803{
804  pp_maybe_wrap_text (pp, str, str + (str ? strlen (str) : 0));
805}
806
807/* Maybe print out a whitespace if needed.  */
808
809void
810pp_base_maybe_space (pretty_printer *pp)
811{
812  if (pp_base (pp)->padding != pp_none)
813    {
814      pp_space (pp);
815      pp_base (pp)->padding = pp_none;
816    }
817}
818