]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/pretty-print.c
re PR sanitizer/71498 (ubsan bounds checking influenced by surrounding code)
[thirdparty/gcc.git] / gcc / pretty-print.c
CommitLineData
b6fe0bb8 1/* Various declarations for language-independent pretty-print subroutines.
818ab71a 2 Copyright (C) 2003-2016 Free Software Foundation, Inc.
b6fe0bb8
GDR
3 Contributed by Gabriel Dos Reis <gdr@integrable-solutions.net>
4
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify it under
8the terms of the GNU General Public License as published by the Free
9dcd6f09 9Software Foundation; either version 3, or (at your option) any later
b6fe0bb8
GDR
10version.
11
12GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13WARRANTY; without even the implied warranty of MERCHANTABILITY or
14FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15for more details.
16
17You should have received a copy of the GNU General Public License
9dcd6f09
NC
18along with GCC; see the file COPYING3. If not see
19<http://www.gnu.org/licenses/>. */
b6fe0bb8
GDR
20
21#include "config.h"
b6fe0bb8
GDR
22#include "system.h"
23#include "coretypes.h"
a668adb2 24#include "intl.h"
b6fe0bb8 25#include "pretty-print.h"
4b84d650 26#include "diagnostic-color.h"
4ccab56d 27#include "selftest.h"
a3af5087
JM
28
29#if HAVE_ICONV
30#include <iconv.h>
31#endif
b6fe0bb8 32
f79520bb 33/* Overwrite the given location/range within this text_info's rich_location.
8a645150
DM
34 For use e.g. when implementing "+" in client format decoders. */
35
36void
f79520bb 37text_info::set_location (unsigned int idx, location_t loc, bool show_caret_p)
8a645150
DM
38{
39 gcc_checking_assert (m_richloc);
f79520bb 40 m_richloc->set_range (line_table, idx, loc, show_caret_p);
8a645150
DM
41}
42
43location_t
44text_info::get_location (unsigned int index_of_location) const
45{
46 gcc_checking_assert (m_richloc);
47
48 if (index_of_location == 0)
49 return m_richloc->get_loc ();
50 else
51 return UNKNOWN_LOCATION;
52}
53
da6ca2b5
GDR
54// Default construct an output buffer.
55
56output_buffer::output_buffer ()
57 : formatted_obstack (),
58 chunk_obstack (),
59 obstack (&formatted_obstack),
60 cur_chunk_array (),
61 stream (stderr),
62 line_length (),
48749dbc
MLI
63 digit_buffer (),
64 flush_p (true)
da6ca2b5
GDR
65{
66 obstack_init (&formatted_obstack);
67 obstack_init (&chunk_obstack);
68}
69
025311c4
GDR
70// Release resources owned by an output buffer at the end of lifetime.
71
72output_buffer::~output_buffer ()
73{
65f5c720
RB
74 obstack_free (&chunk_obstack, NULL);
75 obstack_free (&formatted_obstack, NULL);
025311c4
GDR
76}
77
b6fe0bb8
GDR
78
79/* Format an integer given by va_arg (ARG, type-specifier T) where
80 type-specifier is a precision modifier as indicated by PREC. F is
81 a string used to construct the appropriate format-specifier. */
82#define pp_integer_with_precision(PP, ARG, PREC, T, F) \
83 do \
84 switch (PREC) \
85 { \
86 case 0: \
87 pp_scalar (PP, "%" F, va_arg (ARG, T)); \
88 break; \
89 \
90 case 1: \
91 pp_scalar (PP, "%l" F, va_arg (ARG, long T)); \
92 break; \
93 \
94 case 2: \
2a157700 95 pp_scalar (PP, "%" HOST_LONG_LONG_FORMAT F, va_arg (ARG, long long T)); \
b6fe0bb8
GDR
96 break; \
97 \
98 default: \
99 break; \
100 } \
101 while (0)
102
103
104/* Subroutine of pp_set_maximum_length. Set up PRETTY-PRINTER's
105 internal maximum characters per line. */
106static void
107pp_set_real_maximum_length (pretty_printer *pp)
108{
109 /* If we're told not to wrap lines then do the obvious thing. In case
110 we'll emit prefix only once per message, it is appropriate
111 not to increase unnecessarily the line-length cut-off. */
112 if (!pp_is_wrapping_line (pp)
113 || pp_prefixing_rule (pp) == DIAGNOSTICS_SHOW_PREFIX_ONCE
114 || pp_prefixing_rule (pp) == DIAGNOSTICS_SHOW_PREFIX_NEVER)
115 pp->maximum_length = pp_line_cutoff (pp);
116 else
117 {
118 int prefix_length = pp->prefix ? strlen (pp->prefix) : 0;
119 /* If the prefix is ridiculously too long, output at least
120 32 characters. */
121 if (pp_line_cutoff (pp) - prefix_length < 32)
122 pp->maximum_length = pp_line_cutoff (pp) + 32;
123 else
124 pp->maximum_length = pp_line_cutoff (pp);
125 }
126}
127
128/* Clear PRETTY-PRINTER's output state. */
129static inline void
130pp_clear_state (pretty_printer *pp)
131{
132 pp->emitted_prefix = false;
133 pp_indentation (pp) = 0;
134}
135
b6fe0bb8 136/* Flush the formatted text of PRETTY-PRINTER onto the attached stream. */
6de9cd9a 137void
b6fe0bb8
GDR
138pp_write_text_to_stream (pretty_printer *pp)
139{
140 const char *text = pp_formatted_text (pp);
025311c4 141 fputs (text, pp_buffer (pp)->stream);
b6fe0bb8
GDR
142 pp_clear_output_area (pp);
143}
144
7eba871a
SB
145/* As pp_write_text_to_stream, but for GraphViz label output.
146
147 Flush the formatted text of pretty-printer PP onto the attached stream.
148 Replace characters in PPF that have special meaning in a GraphViz .dot
149 file.
150
151 This routine is not very fast, but it doesn't have to be as this is only
152 be used by routines dumping intermediate representations in graph form. */
153
154void
155pp_write_text_as_dot_label_to_stream (pretty_printer *pp, bool for_record)
156{
157 const char *text = pp_formatted_text (pp);
158 const char *p = text;
025311c4 159 FILE *fp = pp_buffer (pp)->stream;
7eba871a 160
da3ebf2d 161 for (;*p; p++)
7eba871a 162 {
da3ebf2d 163 bool escape_char;
7eba871a
SB
164 switch (*p)
165 {
166 /* Print newlines as a left-aligned newline. */
167 case '\n':
da3ebf2d
TV
168 fputs ("\\l", fp);
169 escape_char = true;
7eba871a
SB
170 break;
171
795391fb 172 /* The following characters are only special for record-shape nodes. */
7eba871a 173 case '|':
795391fb
TV
174 case '{':
175 case '}':
176 case '<':
177 case '>':
178 case ' ':
da3ebf2d 179 escape_char = for_record;
7eba871a
SB
180 break;
181
182 /* The following characters always have to be escaped
183 for use in labels. */
b3de2446
TV
184 case '\\':
185 /* There is a bug in some (f.i. 2.36.0) versions of graphiz
186 ( http://www.graphviz.org/mantisbt/view.php?id=2524 ) related to
187 backslash as last char in label. Let's avoid triggering it. */
188 gcc_assert (*(p + 1) != '\0');
189 /* Fall through. */
7eba871a 190 case '"':
da3ebf2d
TV
191 escape_char = true;
192 break;
193
7eba871a 194 default:
da3ebf2d 195 escape_char = false;
7eba871a
SB
196 break;
197 }
da3ebf2d
TV
198
199 if (escape_char)
200 fputc ('\\', fp);
201
202 fputc (*p, fp);
7eba871a
SB
203 }
204
205 pp_clear_output_area (pp);
206}
207
b6fe0bb8
GDR
208/* Wrap a text delimited by START and END into PRETTY-PRINTER. */
209static void
210pp_wrap_text (pretty_printer *pp, const char *start, const char *end)
211{
212 bool wrapping_line = pp_is_wrapping_line (pp);
213
214 while (start != end)
215 {
216 /* Dump anything bordered by whitespaces. */
217 {
218 const char *p = start;
219 while (p != end && !ISBLANK (*p) && *p != '\n')
220 ++p;
221 if (wrapping_line
222 && p - start >= pp_remaining_character_count_for_line (pp))
223 pp_newline (pp);
224 pp_append_text (pp, start, p);
225 start = p;
226 }
227
228 if (start != end && ISBLANK (*start))
229 {
230 pp_space (pp);
231 ++start;
232 }
233 if (start != end && *start == '\n')
234 {
235 pp_newline (pp);
236 ++start;
237 }
238 }
239}
240
241/* Same as pp_wrap_text but wrap text only when in line-wrapping mode. */
242static inline void
243pp_maybe_wrap_text (pretty_printer *pp, const char *start, const char *end)
244{
245 if (pp_is_wrapping_line (pp))
246 pp_wrap_text (pp, start, end);
247 else
248 pp_append_text (pp, start, end);
249}
250
251/* Append to the output area of PRETTY-PRINTER a string specified by its
252 STARTing character and LENGTH. */
253static inline void
254pp_append_r (pretty_printer *pp, const char *start, int length)
255{
c4100eae 256 output_buffer_append_r (pp_buffer (pp), start, length);
b6fe0bb8
GDR
257}
258
4b780675
GDR
259/* Insert enough spaces into the output area of PRETTY-PRINTER to bring
260 the column position to the current indentation level, assuming that a
261 newline has just been written to the buffer. */
262void
b066401f 263pp_indent (pretty_printer *pp)
4b780675
GDR
264{
265 int n = pp_indentation (pp);
266 int i;
267
268 for (i = 0; i < n; ++i)
269 pp_space (pp);
270}
271
39ce81c9 272/* The following format specifiers are recognized as being client independent:
b6fe0bb8
GDR
273 %d, %i: (signed) integer in base ten.
274 %u: unsigned integer in base ten.
275 %o: unsigned integer in base eight.
276 %x: unsigned integer in base sixteen.
277 %ld, %li, %lo, %lu, %lx: long versions of the above.
278 %lld, %lli, %llo, %llu, %llx: long long versions.
279 %wd, %wi, %wo, %wu, %wx: HOST_WIDE_INT versions.
280 %c: character.
281 %s: string.
914bc2b9 282 %p: pointer (printed in a host-dependent manner).
4b84d650
JJ
283 %r: if pp_show_color(pp), switch to color identified by const char *.
284 %R: if pp_show_color(pp), reset color.
b6fe0bb8 285 %m: strerror(text->err_no) - does not consume a value from args_ptr.
a668adb2 286 %%: '%'.
ca09cd34
JM
287 %<: opening quote.
288 %>: closing quote.
289 %': apostrophe (should only be used in untranslated messages;
290 translations should use appropriate punctuation directly).
39ce81c9
ZW
291 %.*s: a substring the length of which is specified by an argument
292 integer.
293 %Ns: likewise, but length specified as constant in the format string.
39ce81c9
ZW
294 Flag 'q': quote formatted text (must come immediately after '%').
295
296 Arguments can be used sequentially, or through %N$ resp. *N$
297 notation Nth argument after the format string. If %N$ / *N$
298 notation is used, it must be used for all arguments, except %m, %%,
299 %<, %> and %', which may not have a number, as they do not consume
300 an argument. When %M$.*N$s is used, M must be N + 1. (This may
301 also be written %M$.*s, provided N is not otherwise used.) The
302 format string must have conversion specifiers with argument numbers
303 1 up to highest argument; each argument may only be used once.
304 A format string can have at most 30 arguments. */
305
306/* Formatting phases 1 and 2: render TEXT->format_spec plus
025311c4 307 TEXT->args_ptr into a series of chunks in pp_buffer (PP)->args[].
4ccab56d 308 Phase 3 is in pp_output_formatted_text. */
39ce81c9 309
b6fe0bb8 310void
b066401f 311pp_format (pretty_printer *pp, text_info *text)
b6fe0bb8 312{
025311c4 313 output_buffer *buffer = pp_buffer (pp);
39ce81c9
ZW
314 const char *p;
315 const char **args;
316 struct chunk_info *new_chunk_array;
317
318 unsigned int curarg = 0, chunk = 0, argno;
319 pp_wrapping_mode_t old_wrapping_mode;
320 bool any_unnumbered = false, any_numbered = false;
321 const char **formatters[PP_NL_ARGMAX];
322
323 /* Allocate a new chunk structure. */
324 new_chunk_array = XOBNEW (&buffer->chunk_obstack, struct chunk_info);
325 new_chunk_array->prev = buffer->cur_chunk_array;
326 buffer->cur_chunk_array = new_chunk_array;
327 args = new_chunk_array->args;
328
329 /* Formatting phase 1: split up TEXT->format_spec into chunks in
025311c4 330 pp_buffer (PP)->args[]. Even-numbered chunks are to be output
39ce81c9
ZW
331 verbatim, odd-numbered chunks are format specifiers.
332 %m, %%, %<, %>, and %' are replaced with the appropriate text at
333 this point. */
334
335 memset (formatters, 0, sizeof formatters);
b8698a0f 336
39ce81c9 337 for (p = text->format_spec; *p; )
b6fe0bb8 338 {
39ce81c9
ZW
339 while (*p != '\0' && *p != '%')
340 {
341 obstack_1grow (&buffer->chunk_obstack, *p);
342 p++;
343 }
b6fe0bb8 344
39ce81c9
ZW
345 if (*p == '\0')
346 break;
347
348 switch (*++p)
349 {
350 case '\0':
351 gcc_unreachable ();
b8698a0f 352
39ce81c9
ZW
353 case '%':
354 obstack_1grow (&buffer->chunk_obstack, '%');
355 p++;
356 continue;
b6fe0bb8 357
39ce81c9 358 case '<':
4b84d650
JJ
359 {
360 obstack_grow (&buffer->chunk_obstack,
361 open_quote, strlen (open_quote));
362 const char *colorstr
363 = colorize_start (pp_show_color (pp), "quote");
364 obstack_grow (&buffer->chunk_obstack, colorstr, strlen (colorstr));
365 p++;
366 continue;
367 }
39ce81c9
ZW
368
369 case '>':
4b84d650
JJ
370 {
371 const char *colorstr = colorize_stop (pp_show_color (pp));
372 obstack_grow (&buffer->chunk_obstack, colorstr, strlen (colorstr));
373 }
374 /* FALLTHRU */
39ce81c9
ZW
375 case '\'':
376 obstack_grow (&buffer->chunk_obstack,
241de8a0 377 close_quote, strlen (close_quote));
39ce81c9
ZW
378 p++;
379 continue;
380
4b84d650
JJ
381 case 'R':
382 {
383 const char *colorstr = colorize_stop (pp_show_color (pp));
384 obstack_grow (&buffer->chunk_obstack, colorstr,
385 strlen (colorstr));
386 p++;
387 continue;
388 }
389
39ce81c9
ZW
390 case 'm':
391 {
392 const char *errstr = xstrerror (text->err_no);
393 obstack_grow (&buffer->chunk_obstack, errstr, strlen (errstr));
394 }
395 p++;
396 continue;
397
398 default:
399 /* Handled in phase 2. Terminate the plain chunk here. */
400 obstack_1grow (&buffer->chunk_obstack, '\0');
401 gcc_assert (chunk < PP_NL_ARGMAX * 2);
402 args[chunk++] = XOBFINISH (&buffer->chunk_obstack, const char *);
403 break;
404 }
405
406 if (ISDIGIT (*p))
407 {
408 char *end;
409 argno = strtoul (p, &end, 10) - 1;
410 p = end;
411 gcc_assert (*p == '$');
412 p++;
413
414 any_numbered = true;
415 gcc_assert (!any_unnumbered);
416 }
417 else
418 {
419 argno = curarg++;
420 any_unnumbered = true;
421 gcc_assert (!any_numbered);
422 }
423 gcc_assert (argno < PP_NL_ARGMAX);
424 gcc_assert (!formatters[argno]);
425 formatters[argno] = &args[chunk];
426 do
427 {
428 obstack_1grow (&buffer->chunk_obstack, *p);
429 p++;
430 }
431 while (strchr ("qwl+#", p[-1]));
432
433 if (p[-1] == '.')
434 {
435 /* We handle '%.Ns' and '%.*s' or '%M$.*N$s'
436 (where M == N + 1). */
437 if (ISDIGIT (*p))
438 {
439 do
440 {
441 obstack_1grow (&buffer->chunk_obstack, *p);
442 p++;
443 }
444 while (ISDIGIT (p[-1]));
445 gcc_assert (p[-1] == 's');
446 }
447 else
448 {
449 gcc_assert (*p == '*');
450 obstack_1grow (&buffer->chunk_obstack, '*');
451 p++;
452
453 if (ISDIGIT (*p))
454 {
455 char *end;
456 unsigned int argno2 = strtoul (p, &end, 10) - 1;
457 p = end;
458 gcc_assert (argno2 == argno - 1);
459 gcc_assert (!any_unnumbered);
460 gcc_assert (*p == '$');
461
462 p++;
463 formatters[argno2] = formatters[argno];
464 }
465 else
466 {
467 gcc_assert (!any_numbered);
468 formatters[argno+1] = formatters[argno];
469 curarg++;
470 }
471 gcc_assert (*p == 's');
472 obstack_1grow (&buffer->chunk_obstack, 's');
473 p++;
474 }
475 }
476 if (*p == '\0')
b6fe0bb8
GDR
477 break;
478
39ce81c9
ZW
479 obstack_1grow (&buffer->chunk_obstack, '\0');
480 gcc_assert (chunk < PP_NL_ARGMAX * 2);
481 args[chunk++] = XOBFINISH (&buffer->chunk_obstack, const char *);
482 }
483
484 obstack_1grow (&buffer->chunk_obstack, '\0');
485 gcc_assert (chunk < PP_NL_ARGMAX * 2);
486 args[chunk++] = XOBFINISH (&buffer->chunk_obstack, const char *);
487 args[chunk] = 0;
b8698a0f 488
39ce81c9
ZW
489 /* Set output to the argument obstack, and switch line-wrapping and
490 prefixing off. */
491 buffer->obstack = &buffer->chunk_obstack;
492 old_wrapping_mode = pp_set_verbatim_wrapping (pp);
493
494 /* Second phase. Replace each formatter with the formatted text it
495 corresponds to. */
496
497 for (argno = 0; formatters[argno]; argno++)
498 {
499 int precision = 0;
500 bool wide = false;
501 bool plus = false;
502 bool hash = false;
503 bool quote = false;
504
505 /* We do not attempt to enforce any ordering on the modifier
506 characters. */
507
508 for (p = *formatters[argno];; p++)
a668adb2 509 {
39ce81c9
ZW
510 switch (*p)
511 {
512 case 'q':
513 gcc_assert (!quote);
514 quote = true;
515 continue;
516
517 case '+':
518 gcc_assert (!plus);
519 plus = true;
520 continue;
521
522 case '#':
523 gcc_assert (!hash);
524 hash = true;
525 continue;
526
527 case 'w':
528 gcc_assert (!wide);
529 wide = true;
530 continue;
531
532 case 'l':
533 /* We don't support precision beyond that of "long long". */
534 gcc_assert (precision < 2);
535 precision++;
536 continue;
537 }
538 break;
a668adb2 539 }
39ce81c9
ZW
540
541 gcc_assert (!wide || precision == 0);
542
543 if (quote)
4b84d650
JJ
544 {
545 pp_string (pp, open_quote);
546 pp_string (pp, colorize_start (pp_show_color (pp), "quote"));
547 }
39ce81c9
ZW
548
549 switch (*p)
b6fe0bb8 550 {
4b84d650
JJ
551 case 'r':
552 pp_string (pp, colorize_start (pp_show_color (pp),
553 va_arg (*text->args_ptr,
554 const char *)));
555 break;
556
b6fe0bb8
GDR
557 case 'c':
558 pp_character (pp, va_arg (*text->args_ptr, int));
559 break;
560
561 case 'd':
562 case 'i':
39ce81c9
ZW
563 if (wide)
564 pp_wide_integer (pp, va_arg (*text->args_ptr, HOST_WIDE_INT));
565 else
566 pp_integer_with_precision
567 (pp, *text->args_ptr, precision, int, "d");
b6fe0bb8
GDR
568 break;
569
570 case 'o':
39ce81c9
ZW
571 if (wide)
572 pp_scalar (pp, "%" HOST_WIDE_INT_PRINT "o",
573 va_arg (*text->args_ptr, unsigned HOST_WIDE_INT));
574 else
575 pp_integer_with_precision
576 (pp, *text->args_ptr, precision, unsigned, "o");
b6fe0bb8
GDR
577 break;
578
579 case 's':
580 pp_string (pp, va_arg (*text->args_ptr, const char *));
581 break;
582
39ce81c9
ZW
583 case 'p':
584 pp_pointer (pp, va_arg (*text->args_ptr, void *));
585 break;
b6fe0bb8
GDR
586
587 case 'u':
39ce81c9
ZW
588 if (wide)
589 pp_scalar (pp, HOST_WIDE_INT_PRINT_UNSIGNED,
590 va_arg (*text->args_ptr, unsigned HOST_WIDE_INT));
591 else
592 pp_integer_with_precision
593 (pp, *text->args_ptr, precision, unsigned, "u");
b6fe0bb8
GDR
594 break;
595
596 case 'x':
39ce81c9
ZW
597 if (wide)
598 pp_scalar (pp, HOST_WIDE_INT_PRINT_HEX,
599 va_arg (*text->args_ptr, unsigned HOST_WIDE_INT));
600 else
601 pp_integer_with_precision
602 (pp, *text->args_ptr, precision, unsigned, "x");
b6fe0bb8
GDR
603 break;
604
b6fe0bb8
GDR
605 case '.':
606 {
607 int n;
608 const char *s;
d5706a1e 609
39ce81c9
ZW
610 /* We handle '%.Ns' and '%.*s' or '%M$.*N$s'
611 (where M == N + 1). The format string should be verified
612 already from the first phase. */
613 p++;
614 if (ISDIGIT (*p))
615 {
616 char *end;
617 n = strtoul (p, &end, 10);
618 p = end;
619 gcc_assert (*p == 's');
620 }
621 else
622 {
623 gcc_assert (*p == '*');
624 p++;
625 gcc_assert (*p == 's');
626 n = va_arg (*text->args_ptr, int);
627
628 /* This consumes a second entry in the formatters array. */
629 gcc_assert (formatters[argno] == formatters[argno+1]);
630 argno++;
631 }
632
b6fe0bb8
GDR
633 s = va_arg (*text->args_ptr, const char *);
634 pp_append_text (pp, s, s + n);
635 }
636 break;
637
638 default:
0e61db61
NS
639 {
640 bool ok;
39ce81c9 641
0e61db61 642 gcc_assert (pp_format_decoder (pp));
39ce81c9
ZW
643 ok = pp_format_decoder (pp) (pp, text, p,
644 precision, wide, plus, hash);
0e61db61
NS
645 gcc_assert (ok);
646 }
b6fe0bb8 647 }
39ce81c9
ZW
648
649 if (quote)
4b84d650
JJ
650 {
651 pp_string (pp, colorize_stop (pp_show_color (pp)));
652 pp_string (pp, close_quote);
653 }
39ce81c9
ZW
654
655 obstack_1grow (&buffer->chunk_obstack, '\0');
656 *formatters[argno] = XOBFINISH (&buffer->chunk_obstack, const char *);
b6fe0bb8 657 }
39ce81c9 658
b2b29377
MM
659 if (CHECKING_P)
660 for (; argno < PP_NL_ARGMAX; argno++)
661 gcc_assert (!formatters[argno]);
39ce81c9
ZW
662
663 /* Revert to normal obstack and wrapping mode. */
664 buffer->obstack = &buffer->formatted_obstack;
665 buffer->line_length = 0;
666 pp_wrapping_mode (pp) = old_wrapping_mode;
667 pp_clear_state (pp);
668}
669
670/* Format of a message pointed to by TEXT. */
671void
b066401f 672pp_output_formatted_text (pretty_printer *pp)
39ce81c9
ZW
673{
674 unsigned int chunk;
675 output_buffer *buffer = pp_buffer (pp);
676 struct chunk_info *chunk_array = buffer->cur_chunk_array;
677 const char **args = chunk_array->args;
678
679 gcc_assert (buffer->obstack == &buffer->formatted_obstack);
680 gcc_assert (buffer->line_length == 0);
681
b066401f 682 /* This is a third phase, first 2 phases done in pp_format_args.
39ce81c9
ZW
683 Now we actually print it. */
684 for (chunk = 0; args[chunk]; chunk++)
685 pp_string (pp, args[chunk]);
686
687 /* Deallocate the chunk structure and everything after it (i.e. the
688 associated series of formatted strings). */
689 buffer->cur_chunk_array = chunk_array->prev;
690 obstack_free (&buffer->chunk_obstack, chunk_array);
b6fe0bb8
GDR
691}
692
693/* Helper subroutine of output_verbatim and verbatim. Do the appropriate
694 settings needed by BUFFER for a verbatim formatting. */
695void
b066401f 696pp_format_verbatim (pretty_printer *pp, text_info *text)
b6fe0bb8 697{
b6fe0bb8 698 /* Set verbatim mode. */
39ce81c9
ZW
699 pp_wrapping_mode_t oldmode = pp_set_verbatim_wrapping (pp);
700
b6fe0bb8 701 /* Do the actual formatting. */
39ce81c9
ZW
702 pp_format (pp, text);
703 pp_output_formatted_text (pp);
704
b6fe0bb8 705 /* Restore previous settings. */
39ce81c9 706 pp_wrapping_mode (pp) = oldmode;
b6fe0bb8
GDR
707}
708
48749dbc
MLI
709/* Flush the content of BUFFER onto the attached stream. This
710 function does nothing unless pp->output_buffer->flush_p. */
b6fe0bb8 711void
b066401f 712pp_flush (pretty_printer *pp)
b6fe0bb8 713{
48749dbc
MLI
714 pp_clear_state (pp);
715 if (!pp->buffer->flush_p)
716 return;
b6fe0bb8 717 pp_write_text_to_stream (pp);
48749dbc
MLI
718 fflush (pp_buffer (pp)->stream);
719}
720
721/* Flush the content of BUFFER onto the attached stream independently
722 of the value of pp->output_buffer->flush_p. */
723void
724pp_really_flush (pretty_printer *pp)
725{
b6fe0bb8 726 pp_clear_state (pp);
48749dbc 727 pp_write_text_to_stream (pp);
025311c4 728 fflush (pp_buffer (pp)->stream);
b6fe0bb8
GDR
729}
730
731/* Sets the number of maximum characters per line PRETTY-PRINTER can
732 output in line-wrapping mode. A LENGTH value 0 suppresses
733 line-wrapping. */
734void
b066401f 735pp_set_line_maximum_length (pretty_printer *pp, int length)
b6fe0bb8
GDR
736{
737 pp_line_cutoff (pp) = length;
738 pp_set_real_maximum_length (pp);
739}
740
741/* Clear PRETTY-PRINTER output area text info. */
742void
b066401f 743pp_clear_output_area (pretty_printer *pp)
b6fe0bb8 744{
025311c4
GDR
745 obstack_free (pp_buffer (pp)->obstack,
746 obstack_base (pp_buffer (pp)->obstack));
747 pp_buffer (pp)->line_length = 0;
b6fe0bb8
GDR
748}
749
750/* Set PREFIX for PRETTY-PRINTER. */
751void
b066401f 752pp_set_prefix (pretty_printer *pp, const char *prefix)
b6fe0bb8
GDR
753{
754 pp->prefix = prefix;
755 pp_set_real_maximum_length (pp);
756 pp->emitted_prefix = false;
757 pp_indentation (pp) = 0;
758}
759
760/* Free PRETTY-PRINTER's prefix, a previously malloc()'d string. */
761void
b066401f 762pp_destroy_prefix (pretty_printer *pp)
b6fe0bb8
GDR
763{
764 if (pp->prefix != NULL)
765 {
b1d5455a 766 free (CONST_CAST (char *, pp->prefix));
b6fe0bb8
GDR
767 pp->prefix = NULL;
768 }
769}
770
771/* Write out PRETTY-PRINTER's prefix. */
772void
b066401f 773pp_emit_prefix (pretty_printer *pp)
b6fe0bb8
GDR
774{
775 if (pp->prefix != NULL)
776 {
777 switch (pp_prefixing_rule (pp))
778 {
779 default:
780 case DIAGNOSTICS_SHOW_PREFIX_NEVER:
781 break;
782
783 case DIAGNOSTICS_SHOW_PREFIX_ONCE:
784 if (pp->emitted_prefix)
785 {
b066401f 786 pp_indent (pp);
b6fe0bb8
GDR
787 break;
788 }
789 pp_indentation (pp) += 3;
790 /* Fall through. */
791
792 case DIAGNOSTICS_SHOW_PREFIX_EVERY_LINE:
793 {
794 int prefix_length = strlen (pp->prefix);
795 pp_append_r (pp, pp->prefix, prefix_length);
796 pp->emitted_prefix = true;
797 }
798 break;
799 }
800 }
801}
802
803/* Construct a PRETTY-PRINTER with PREFIX and of MAXIMUM_LENGTH
804 characters per line. */
da6ca2b5
GDR
805
806pretty_printer::pretty_printer (const char *p, int l)
807 : buffer (new (XCNEW (output_buffer)) output_buffer ()),
808 prefix (),
809 padding (pp_none),
810 maximum_length (),
811 indent_skip (),
812 wrapping (),
813 format_decoder (),
814 emitted_prefix (),
815 need_newline (),
c3284718 816 translate_identifiers (true),
da6ca2b5 817 show_color ()
b6fe0bb8 818{
da6ca2b5
GDR
819 pp_line_cutoff (this) = l;
820 /* By default, we emit prefixes once per message. */
821 pp_prefixing_rule (this) = DIAGNOSTICS_SHOW_PREFIX_ONCE;
822 pp_set_prefix (this, p);
b6fe0bb8
GDR
823}
824
025311c4
GDR
825pretty_printer::~pretty_printer ()
826{
827 buffer->~output_buffer ();
828 XDELETE (buffer);
829}
830
b6fe0bb8
GDR
831/* Append a string delimited by START and END to the output area of
832 PRETTY-PRINTER. No line wrapping is done. However, if beginning a
833 new line then emit PRETTY-PRINTER's prefix and skip any leading
834 whitespace if appropriate. The caller must ensure that it is
835 safe to do so. */
836void
b066401f 837pp_append_text (pretty_printer *pp, const char *start, const char *end)
b6fe0bb8
GDR
838{
839 /* Emit prefix and skip whitespace if we're starting a new line. */
025311c4 840 if (pp_buffer (pp)->line_length == 0)
b6fe0bb8
GDR
841 {
842 pp_emit_prefix (pp);
843 if (pp_is_wrapping_line (pp))
844 while (start != end && *start == ' ')
845 ++start;
846 }
847 pp_append_r (pp, start, end - start);
848}
849
850/* Finishes constructing a NULL-terminated character string representing
851 the PRETTY-PRINTED text. */
852const char *
b066401f 853pp_formatted_text (pretty_printer *pp)
b6fe0bb8 854{
c4100eae 855 return output_buffer_formatted_text (pp_buffer (pp));
b6fe0bb8
GDR
856}
857
858/* Return a pointer to the last character emitted in PRETTY-PRINTER's
859 output area. A NULL pointer means no character available. */
860const char *
b066401f 861pp_last_position_in_text (const pretty_printer *pp)
b6fe0bb8 862{
c4100eae 863 return output_buffer_last_position_in_text (pp_buffer (pp));
b6fe0bb8
GDR
864}
865
866/* Return the amount of characters PRETTY-PRINTER can accept to
ba228239 867 make a full line. Meaningful only in line-wrapping mode. */
b6fe0bb8 868int
b066401f 869pp_remaining_character_count_for_line (pretty_printer *pp)
b6fe0bb8 870{
025311c4 871 return pp->maximum_length - pp_buffer (pp)->line_length;
b6fe0bb8
GDR
872}
873
874
875/* Format a message into BUFFER a la printf. */
876void
877pp_printf (pretty_printer *pp, const char *msg, ...)
878{
879 text_info text;
880 va_list ap;
881
882 va_start (ap, msg);
883 text.err_no = errno;
884 text.args_ptr = &ap;
885 text.format_spec = msg;
39ce81c9
ZW
886 pp_format (pp, &text);
887 pp_output_formatted_text (pp);
b6fe0bb8
GDR
888 va_end (ap);
889}
890
891
892/* Output MESSAGE verbatim into BUFFER. */
893void
894pp_verbatim (pretty_printer *pp, const char *msg, ...)
895{
896 text_info text;
897 va_list ap;
898
899 va_start (ap, msg);
900 text.err_no = errno;
901 text.args_ptr = &ap;
902 text.format_spec = msg;
903 pp_format_verbatim (pp, &text);
904 va_end (ap);
905}
906
907
908
909/* Have PRETTY-PRINTER start a new line. */
910void
b066401f 911pp_newline (pretty_printer *pp)
b6fe0bb8 912{
025311c4 913 obstack_1grow (pp_buffer (pp)->obstack, '\n');
c4669594 914 pp_needs_newline (pp) = false;
025311c4 915 pp_buffer (pp)->line_length = 0;
b6fe0bb8
GDR
916}
917
918/* Have PRETTY-PRINTER add a CHARACTER. */
919void
b066401f 920pp_character (pretty_printer *pp, int c)
b6fe0bb8
GDR
921{
922 if (pp_is_wrapping_line (pp)
923 && pp_remaining_character_count_for_line (pp) <= 0)
924 {
925 pp_newline (pp);
926 if (ISSPACE (c))
927 return;
928 }
025311c4
GDR
929 obstack_1grow (pp_buffer (pp)->obstack, c);
930 ++pp_buffer (pp)->line_length;
b6fe0bb8
GDR
931}
932
933/* Append a STRING to the output area of PRETTY-PRINTER; the STRING may
934 be line-wrapped if in appropriate mode. */
935void
b066401f 936pp_string (pretty_printer *pp, const char *str)
b6fe0bb8 937{
41d9f1e0
MLI
938 gcc_checking_assert (str);
939 pp_maybe_wrap_text (pp, str, str + strlen (str));
b6fe0bb8
GDR
940}
941
471854f8 942/* Maybe print out a whitespace if needed. */
b6fe0bb8 943
b9b44fb9 944void
b066401f 945pp_maybe_space (pretty_printer *pp)
b9b44fb9 946{
b066401f 947 if (pp->padding != pp_none)
b9b44fb9
GDR
948 {
949 pp_space (pp);
b066401f 950 pp->padding = pp_none;
b9b44fb9
GDR
951 }
952}
0fc80001
GDR
953
954// Add a newline to the pretty printer PP and flush formatted text.
955
956void
957pp_newline_and_flush (pretty_printer *pp)
958{
959 pp_newline (pp);
960 pp_flush (pp);
961 pp_needs_newline (pp) = false;
962}
963
964// Add a newline to the pretty printer PP, followed by indentation.
965
966void
967pp_newline_and_indent (pretty_printer *pp, int n)
968{
969 pp_indentation (pp) += n;
970 pp_newline (pp);
971 pp_indent (pp);
972 pp_needs_newline (pp) = false;
973}
974
975// Add separator C, followed by a single whitespace.
976
977void
978pp_separate_with (pretty_printer *pp, char c)
979{
980 pp_character (pp, c);
981 pp_space (pp);
982}
983
a3af5087
JM
984\f
985/* The string starting at P has LEN (at least 1) bytes left; if they
986 start with a valid UTF-8 sequence, return the length of that
987 sequence and set *VALUE to the value of that sequence, and
988 otherwise return 0 and set *VALUE to (unsigned int) -1. */
989
990static int
991decode_utf8_char (const unsigned char *p, size_t len, unsigned int *value)
992{
993 unsigned int t = *p;
994
995 if (len == 0)
996 abort ();
997 if (t & 0x80)
998 {
999 size_t utf8_len = 0;
1000 unsigned int ch;
1001 size_t i;
1002 for (t = *p; t & 0x80; t <<= 1)
1003 utf8_len++;
1004
1005 if (utf8_len > len || utf8_len < 2 || utf8_len > 6)
1006 {
1007 *value = (unsigned int) -1;
1008 return 0;
1009 }
1010 ch = *p & ((1 << (7 - utf8_len)) - 1);
1011 for (i = 1; i < utf8_len; i++)
1012 {
1013 unsigned int u = p[i];
1014 if ((u & 0xC0) != 0x80)
1015 {
1016 *value = (unsigned int) -1;
1017 return 0;
1018 }
1019 ch = (ch << 6) | (u & 0x3F);
1020 }
1021 if ( (ch <= 0x7F && utf8_len > 1)
1022 || (ch <= 0x7FF && utf8_len > 2)
1023 || (ch <= 0xFFFF && utf8_len > 3)
1024 || (ch <= 0x1FFFFF && utf8_len > 4)
1025 || (ch <= 0x3FFFFFF && utf8_len > 5)
1026 || (ch >= 0xD800 && ch <= 0xDFFF))
1027 {
1028 *value = (unsigned int) -1;
1029 return 0;
1030 }
1031 *value = ch;
1032 return utf8_len;
1033 }
1034 else
1035 {
1036 *value = t;
1037 return 1;
1038 }
1039}
1040
ab9b814d
JM
1041/* Allocator for identifier_to_locale and corresponding function to
1042 free memory. */
1043
1044void *(*identifier_to_locale_alloc) (size_t) = xmalloc;
1045void (*identifier_to_locale_free) (void *) = free;
1046
a3af5087
JM
1047/* Given IDENT, an identifier in the internal encoding, return a
1048 version of IDENT suitable for diagnostics in the locale character
ab9b814d
JM
1049 set: either IDENT itself, or a string, allocated using
1050 identifier_to_locale_alloc, converted to the locale character set
1051 and using escape sequences if not representable in the locale
1052 character set or containing control characters or invalid byte
1053 sequences. Existing backslashes in IDENT are not doubled, so the
1054 result may not uniquely specify the contents of an arbitrary byte
1055 sequence identifier. */
a3af5087
JM
1056
1057const char *
1058identifier_to_locale (const char *ident)
1059{
1060 const unsigned char *uid = (const unsigned char *) ident;
1061 size_t idlen = strlen (ident);
1062 bool valid_printable_utf8 = true;
1063 bool all_ascii = true;
1064 size_t i;
1065
1066 for (i = 0; i < idlen;)
1067 {
1068 unsigned int c;
1069 size_t utf8_len = decode_utf8_char (&uid[i], idlen - i, &c);
1070 if (utf8_len == 0 || c <= 0x1F || (c >= 0x7F && c <= 0x9F))
1071 {
1072 valid_printable_utf8 = false;
1073 break;
1074 }
1075 if (utf8_len > 1)
1076 all_ascii = false;
1077 i += utf8_len;
1078 }
1079
1080 /* If IDENT contains invalid UTF-8 sequences (which may occur with
1081 attributes putting arbitrary byte sequences in identifiers), or
1082 control characters, we use octal escape sequences for all bytes
1083 outside printable ASCII. */
1084 if (!valid_printable_utf8)
1085 {
ab9b814d 1086 char *ret = (char *) identifier_to_locale_alloc (4 * idlen + 1);
a3af5087
JM
1087 char *p = ret;
1088 for (i = 0; i < idlen; i++)
1089 {
1090 if (uid[i] > 0x1F && uid[i] < 0x7F)
1091 *p++ = uid[i];
1092 else
1093 {
1094 sprintf (p, "\\%03o", uid[i]);
1095 p += 4;
1096 }
1097 }
1098 *p = 0;
1099 return ret;
1100 }
1101
1102 /* Otherwise, if it is valid printable ASCII, or printable UTF-8
1103 with the locale character set being UTF-8, IDENT is used. */
1104 if (all_ascii || locale_utf8)
1105 return ident;
1106
1107 /* Otherwise IDENT is converted to the locale character set if
1108 possible. */
1109#if defined ENABLE_NLS && defined HAVE_LANGINFO_CODESET && HAVE_ICONV
1110 if (locale_encoding != NULL)
1111 {
1112 iconv_t cd = iconv_open (locale_encoding, "UTF-8");
1113 bool conversion_ok = true;
1114 char *ret = NULL;
1115 if (cd != (iconv_t) -1)
1116 {
1117 size_t ret_alloc = 4 * idlen + 1;
1118 for (;;)
1119 {
1120 /* Repeat the whole conversion process as needed with
1121 larger buffers so non-reversible transformations can
1122 always be detected. */
1123 ICONV_CONST char *inbuf = CONST_CAST (char *, ident);
1124 char *outbuf;
1125 size_t inbytesleft = idlen;
1126 size_t outbytesleft = ret_alloc - 1;
1127 size_t iconv_ret;
1128
ab9b814d 1129 ret = (char *) identifier_to_locale_alloc (ret_alloc);
a3af5087
JM
1130 outbuf = ret;
1131
1132 if (iconv (cd, 0, 0, 0, 0) == (size_t) -1)
1133 {
1134 conversion_ok = false;
1135 break;
1136 }
1137
1138 iconv_ret = iconv (cd, &inbuf, &inbytesleft,
1139 &outbuf, &outbytesleft);
1140 if (iconv_ret == (size_t) -1 || inbytesleft != 0)
1141 {
1142 if (errno == E2BIG)
1143 {
1144 ret_alloc *= 2;
ab9b814d 1145 identifier_to_locale_free (ret);
a3af5087
JM
1146 ret = NULL;
1147 continue;
1148 }
1149 else
1150 {
1151 conversion_ok = false;
1152 break;
1153 }
1154 }
1155 else if (iconv_ret != 0)
1156 {
1157 conversion_ok = false;
1158 break;
1159 }
1160 /* Return to initial shift state. */
1161 if (iconv (cd, 0, 0, &outbuf, &outbytesleft) == (size_t) -1)
1162 {
1163 if (errno == E2BIG)
1164 {
1165 ret_alloc *= 2;
ab9b814d 1166 identifier_to_locale_free (ret);
a3af5087
JM
1167 ret = NULL;
1168 continue;
1169 }
1170 else
1171 {
1172 conversion_ok = false;
1173 break;
1174 }
1175 }
1176 *outbuf = 0;
1177 break;
1178 }
1179 iconv_close (cd);
1180 if (conversion_ok)
1181 return ret;
1182 }
1183 }
1184#endif
1185
1186 /* Otherwise, convert non-ASCII characters in IDENT to UCNs. */
1187 {
ab9b814d 1188 char *ret = (char *) identifier_to_locale_alloc (10 * idlen + 1);
a3af5087
JM
1189 char *p = ret;
1190 for (i = 0; i < idlen;)
1191 {
1192 unsigned int c;
1193 size_t utf8_len = decode_utf8_char (&uid[i], idlen - i, &c);
1194 if (utf8_len == 1)
1195 *p++ = uid[i];
1196 else
1197 {
1198 sprintf (p, "\\U%08x", c);
1199 p += 10;
1200 }
1201 i += utf8_len;
1202 }
1203 *p = 0;
1204 return ret;
1205 }
1206}
4ccab56d
DM
1207
1208#if CHECKING_P
1209
1210namespace selftest {
1211
1212/* Smoketest for pretty_printer. */
1213
1214static void
1215test_basic_printing ()
1216{
1217 pretty_printer pp;
1218 pp_string (&pp, "hello");
1219 pp_space (&pp);
1220 pp_string (&pp, "world");
1221
1222 ASSERT_STREQ ("hello world", pp_formatted_text (&pp));
1223}
1224
1225/* Helper function for testing pp_format.
1226 Verify that pp_format (FMT, ...) followed by pp_output_formatted_text
1227 prints EXPECTED, assuming that pp_show_color is SHOW_COLOR. */
1228
1229static void
1230assert_pp_format_va (const char *expected, bool show_color, const char *fmt,
1231 va_list *ap)
1232{
1233 pretty_printer pp;
1234 text_info ti;
1235 rich_location rich_loc (line_table, UNKNOWN_LOCATION);
1236
1237 ti.format_spec = fmt;
1238 ti.args_ptr = ap;
1239 ti.err_no = 0;
1240 ti.x_data = NULL;
1241 ti.m_richloc = &rich_loc;
1242
1243 pp_show_color (&pp) = show_color;
1244 pp_format (&pp, &ti);
1245 pp_output_formatted_text (&pp);
1246 ASSERT_STREQ (expected, pp_formatted_text (&pp));
1247}
1248
1249/* Verify that pp_format (FMT, ...) followed by pp_output_formatted_text
1250 prints EXPECTED, with show_color disabled. */
1251
1252static void
1253assert_pp_format (const char *expected, const char *fmt, ...)
1254{
1255 va_list ap;
1256
1257 va_start (ap, fmt);
1258 assert_pp_format_va (expected, false, fmt, &ap);
1259 va_end (ap);
1260}
1261
1262/* As above, but with colorization enabled. */
1263
1264static void
1265assert_pp_format_colored (const char *expected, const char *fmt, ...)
1266{
1267 va_list ap;
1268
1269 va_start (ap, fmt);
1270 assert_pp_format_va (expected, true, fmt, &ap);
1271 va_end (ap);
1272}
1273
1274/* Verify that pp_format works, for various format codes. */
1275
1276static void
1277test_pp_format ()
1278{
1279 /* Avoid introducing locale-specific differences in the results
1280 by hardcoding open_quote and close_quote. */
1281 const char *old_open_quote = open_quote;
1282 const char *old_close_quote = close_quote;
1283 open_quote = "`";
1284 close_quote = "'";
1285
1286 /* Verify that plain text is passed through unchanged. */
1287 assert_pp_format ("unformatted", "unformatted");
1288
1289 /* Verify various individual format codes, in the order listed in the
1290 comment for pp_format above. For each code, we append a second
1291 argument with a known bit pattern (0x12345678), to ensure that we
1292 are consuming arguments correctly. */
1293 assert_pp_format ("-27 12345678", "%d %x", -27, 0x12345678);
1294 assert_pp_format ("-5 12345678", "%i %x", -5, 0x12345678);
1295 assert_pp_format ("10 12345678", "%u %x", 10, 0x12345678);
1296 assert_pp_format ("17 12345678", "%o %x", 15, 0x12345678);
1297 assert_pp_format ("cafebabe 12345678", "%x %x", 0xcafebabe, 0x12345678);
1298 assert_pp_format ("-27 12345678", "%ld %x", (long)-27, 0x12345678);
1299 assert_pp_format ("-5 12345678", "%li %x", (long)-5, 0x12345678);
1300 assert_pp_format ("10 12345678", "%lu %x", (long)10, 0x12345678);
1301 assert_pp_format ("17 12345678", "%lo %x", (long)15, 0x12345678);
1302 assert_pp_format ("cafebabe 12345678", "%lx %x", (long)0xcafebabe,
1303 0x12345678);
1304 assert_pp_format ("-27 12345678", "%lld %x", (long long)-27, 0x12345678);
1305 assert_pp_format ("-5 12345678", "%lli %x", (long long)-5, 0x12345678);
1306 assert_pp_format ("10 12345678", "%llu %x", (long long)10, 0x12345678);
1307 assert_pp_format ("17 12345678", "%llo %x", (long long)15, 0x12345678);
1308 assert_pp_format ("cafebabe 12345678", "%llx %x", (long long)0xcafebabe,
1309 0x12345678);
1310 assert_pp_format ("-27 12345678", "%wd %x", (HOST_WIDE_INT)-27, 0x12345678);
1311 assert_pp_format ("-5 12345678", "%wi %x", (HOST_WIDE_INT)-5, 0x12345678);
1312 assert_pp_format ("10 12345678", "%wu %x", (unsigned HOST_WIDE_INT)10,
1313 0x12345678);
1314 assert_pp_format ("17 12345678", "%wo %x", (HOST_WIDE_INT)15, 0x12345678);
1315 assert_pp_format ("0xcafebabe 12345678", "%wx %x", (HOST_WIDE_INT)0xcafebabe,
1316 0x12345678);
1317 assert_pp_format ("A 12345678", "%c %x", 'A', 0x12345678);
1318 assert_pp_format ("hello world 12345678", "%s %x", "hello world",
1319 0x12345678);
914bc2b9
DM
1320 /* We can't test for %p; the pointer is printed in an implementation-defined
1321 manner. */
4ccab56d
DM
1322 assert_pp_format ("normal colored normal 12345678",
1323 "normal %rcolored%R normal %x",
1324 "error", 0x12345678);
1325 /* The following assumes an empty value for GCC_COLORS. */
1326 assert_pp_format_colored
1327 ("normal \33[01;31m\33[Kcolored\33[m\33[K normal 12345678",
1328 "normal %rcolored%R normal %x", "error", 0x12345678);
1329 /* TODO:
1330 %m: strerror(text->err_no) - does not consume a value from args_ptr. */
1331 assert_pp_format ("% 12345678", "%% %x", 0x12345678);
1332 assert_pp_format ("` 12345678", "%< %x", 0x12345678);
1333 assert_pp_format ("' 12345678", "%> %x", 0x12345678);
1334 assert_pp_format ("' 12345678", "%' %x", 0x12345678);
1335 assert_pp_format ("abc 12345678", "%.*s %x", 3, "abcdef", 0x12345678);
1336 assert_pp_format ("abc 12345678", "%.3s %x", "abcdef", 0x12345678);
1337
1338 /* Verify flag 'q'. */
1339 assert_pp_format ("`foo' 12345678", "%qs %x", "foo", 0x12345678);
1340 assert_pp_format_colored ("`\33[01m\33[Kfoo\33[m\33[K' 12345678", "%qs %x",
1341 "foo", 0x12345678);
1342
1343 /* Verify that combinations work, along with unformatted text. */
1344 assert_pp_format ("the quick brown fox jumps over the lazy dog",
1345 "the %s %s %s jumps over the %s %s",
1346 "quick", "brown", "fox", "lazy", "dog");
1347 assert_pp_format ("item 3 of 7", "item %i of %i", 3, 7);
1348 assert_pp_format ("problem with `bar' at line 10",
1349 "problem with %qs at line %i", "bar", 10);
1350
1351 /* Restore old values of open_quote and close_quote. */
1352 open_quote = old_open_quote;
1353 close_quote = old_close_quote;
1354}
1355
1356/* Run all of the selftests within this file. */
1357
1358void
1359pretty_print_c_tests ()
1360{
1361 test_basic_printing ();
1362 test_pp_format ();
1363}
1364
1365} // namespace selftest
1366
1367#endif /* CHECKING_P */