1/* Various declarations for language-independent pretty-print subroutines.
2 Copyright (C) 2003-2017 Free Software Foundation, Inc.
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
9Software Foundation; either version 3, or (at your option) any later
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
18along with GCC; see the file COPYING3. If not see
19<http://www.gnu.org/licenses/>. */
20
21#include "config.h"
22#include "system.h"
23#include "coretypes.h"
24#include "intl.h"
25#include "pretty-print.h"
26#include "diagnostic-color.h"
27#include "selftest.h"
28
29#if HAVE_ICONV
30#include <iconv.h>
31#endif
32
33#ifdef __MINGW32__
34
35/* Replacement for fputs() that handles ANSI escape codes on Windows NT.
36 Contributed by: Liu Hao (lh_mouse at 126 dot com)
37
38 XXX: This file is compiled into libcommon.a that will be self-contained.
39 It looks like that these functions can be put nowhere else. */
40
41#include <io.h>
42#define WIN32_LEAN_AND_MEAN 1
43#include <windows.h>
44
45/* Write all bytes in [s,s+n) into the specified stream.
46 Errors are ignored. */
47static void
48write_all (HANDLE h, const char *s, size_t n)
49{
50 size_t rem = n;
51 DWORD step;
52
53 while (rem != 0)
54 {
55 if (rem <= UINT_MAX)
56 step = rem;
57 else
58 step = UINT_MAX;
59 if (!WriteFile (h, s + n - rem, step, &step, NULL))
60 break;
61 rem -= step;
62 }
63}
64
65/* Find the beginning of an escape sequence.
66 There are two cases:
67 1. If the sequence begins with an ESC character (0x1B) and a second
68 character X in [0x40,0x5F], returns X and stores a pointer to
69 the third character into *head.
70 2. If the sequence begins with a character X in [0x80,0x9F], returns
71 (X-0x40) and stores a pointer to the second character into *head.
72 Stores the number of ESC character(s) in *prefix_len.
73 Returns 0 if no such sequence can be found. */
74static int
75find_esc_head (int *prefix_len, const char **head, const char *str)
76{
77 int c;
78 const char *r = str;
79 int escaped = 0;
80
81 for (;;)
82 {
83 c = (unsigned char) *r;
84 if (c == 0)
85 {
86 /* Not found. */
87 return 0;
88 }
89 if (escaped && 0x40 <= c && c <= 0x5F)
90 {
91 /* Found (case 1). */
92 *prefix_len = 2;
93 *head = r + 1;
94 return c;
95 }
96 if (0x80 <= c && c <= 0x9F)
97 {
98 /* Found (case 2). */
99 *prefix_len = 1;
100 *head = r + 1;
101 return c - 0x40;
102 }
103 ++r;
104 escaped = c == 0x1B;
105 }
106}
107
108/* Find the terminator of an escape sequence.
109 str should be the value stored in *head by a previous successful
110 call to find_esc_head().
111 Returns 0 if no such sequence can be found. */
112static int
113find_esc_terminator (const char **term, const char *str)
114{
115 int c;
116 const char *r = str;
117
118 for (;;)
119 {
120 c = (unsigned char) *r;
121 if (c == 0)
122 {
123 /* Not found. */
124 return 0;
125 }
126 if (0x40 <= c && c <= 0x7E)
127 {
128 /* Found. */
129 *term = r;
130 return c;
131 }
132 ++r;
133 }
134}
135
136/* Handle a sequence of codes. Sequences that are invalid, reserved,
137 unrecognized or unimplemented are ignored silently.
138 There isn't much we can do because of lameness of Windows consoles. */
139static void
140eat_esc_sequence (HANDLE h, int esc_code,
141 const char *esc_head, const char *esc_term)
142{
143 /* Numbers in an escape sequence cannot be negative, because
144 a minus sign in the middle of it would have terminated it. */
145 long n1, n2;
146 char *eptr, *delim;
147 CONSOLE_SCREEN_BUFFER_INFO sb;
148 COORD cr;
149 /* ED and EL parameters. */
150 DWORD cnt, step;
151 long rows;
152 /* SGR parameters. */
153 WORD attrib_add, attrib_rm;
154 const char *param;
155
156 switch (MAKEWORD (esc_code, *esc_term))
157 {
158 /* ESC [ n1 'A'
159 Move the cursor up by n1 characters. */
160 case MAKEWORD ('[', 'A'):
161 if (esc_head == esc_term)
162 n1 = 1;
163 else
164 {
165 n1 = strtol (esc_head, &eptr, 10);
166 if (eptr != esc_term)
167 break;
168 }
169
170 if (GetConsoleScreenBufferInfo (h, &sb))
171 {
172 cr = sb.dwCursorPosition;
173 /* Stop at the topmost boundary. */
174 if (cr.Y > n1)
175 cr.Y -= n1;
176 else
177 cr.Y = 0;
178 SetConsoleCursorPosition (h, cr);
179 }
180 break;
181
182 /* ESC [ n1 'B'
183 Move the cursor down by n1 characters. */
184 case MAKEWORD ('[', 'B'):
185 if (esc_head == esc_term)
186 n1 = 1;
187 else
188 {
189 n1 = strtol (esc_head, &eptr, 10);
190 if (eptr != esc_term)
191 break;
192 }
193
194 if (GetConsoleScreenBufferInfo (h, &sb))
195 {
196 cr = sb.dwCursorPosition;
197 /* Stop at the bottommost boundary. */
198 if (sb.dwSize.Y - cr.Y > n1)
199 cr.Y += n1;
200 else
201 cr.Y = sb.dwSize.Y;
202 SetConsoleCursorPosition (h, cr);
203 }
204 break;
205
206 /* ESC [ n1 'C'
207 Move the cursor right by n1 characters. */
208 case MAKEWORD ('[', 'C'):
209 if (esc_head == esc_term)
210 n1 = 1;
211 else
212 {
213 n1 = strtol (esc_head, &eptr, 10);
214 if (eptr != esc_term)
215 break;
216 }
217
218 if (GetConsoleScreenBufferInfo (h, &sb))
219 {
220 cr = sb.dwCursorPosition;
221 /* Stop at the rightmost boundary. */
222 if (sb.dwSize.X - cr.X > n1)
223 cr.X += n1;
224 else
225 cr.X = sb.dwSize.X;
226 SetConsoleCursorPosition (h, cr);
227 }
228 break;
229
230 /* ESC [ n1 'D'
231 Move the cursor left by n1 characters. */
232 case MAKEWORD ('[', 'D'):
233 if (esc_head == esc_term)
234 n1 = 1;
235 else
236 {
237 n1 = strtol (esc_head, &eptr, 10);
238 if (eptr != esc_term)
239 break;
240 }
241
242 if (GetConsoleScreenBufferInfo (h, &sb))
243 {
244 cr = sb.dwCursorPosition;
245 /* Stop at the leftmost boundary. */
246 if (cr.X > n1)
247 cr.X -= n1;
248 else
249 cr.X = 0;
250 SetConsoleCursorPosition (h, cr);
251 }
252 break;
253
254 /* ESC [ n1 'E'
255 Move the cursor to the beginning of the n1-th line downwards. */
256 case MAKEWORD ('[', 'E'):
257 if (esc_head == esc_term)
258 n1 = 1;
259 else
260 {
261 n1 = strtol (esc_head, &eptr, 10);
262 if (eptr != esc_term)
263 break;
264 }
265
266 if (GetConsoleScreenBufferInfo (h, &sb))
267 {
268 cr = sb.dwCursorPosition;
269 cr.X = 0;
270 /* Stop at the bottommost boundary. */
271 if (sb.dwSize.Y - cr.Y > n1)
272 cr.Y += n1;
273 else
274 cr.Y = sb.dwSize.Y;
275 SetConsoleCursorPosition (h, cr);
276 }
277 break;
278
279 /* ESC [ n1 'F'
280 Move the cursor to the beginning of the n1-th line upwards. */
281 case MAKEWORD ('[', 'F'):
282 if (esc_head == esc_term)
283 n1 = 1;
284 else
285 {
286 n1 = strtol (esc_head, &eptr, 10);
287 if (eptr != esc_term)
288 break;
289 }
290
291 if (GetConsoleScreenBufferInfo (h, &sb))
292 {
293 cr = sb.dwCursorPosition;
294 cr.X = 0;
295 /* Stop at the topmost boundary. */
296 if (cr.Y > n1)
297 cr.Y -= n1;
298 else
299 cr.Y = 0;
300 SetConsoleCursorPosition (h, cr);
301 }
302 break;
303
304 /* ESC [ n1 'G'
305 Move the cursor to the (1-based) n1-th column. */
306 case MAKEWORD ('[', 'G'):
307 if (esc_head == esc_term)
308 n1 = 1;
309 else
310 {
311 n1 = strtol (esc_head, &eptr, 10);
312 if (eptr != esc_term)
313 break;
314 }
315
316 if (GetConsoleScreenBufferInfo (h, &sb))
317 {
318 cr = sb.dwCursorPosition;
319 n1 -= 1;
320 /* Stop at the leftmost or rightmost boundary. */
321 if (n1 < 0)
322 cr.X = 0;
323 else if (n1 > sb.dwSize.X)
324 cr.X = sb.dwSize.X;
325 else
326 cr.X = n1;
327 SetConsoleCursorPosition (h, cr);
328 }
329 break;
330
331 /* ESC [ n1 ';' n2 'H'
332 ESC [ n1 ';' n2 'f'
333 Move the cursor to the (1-based) n1-th row and
334 (also 1-based) n2-th column. */
335 case MAKEWORD ('[', 'H'):
336 case MAKEWORD ('[', 'f'):
337 if (esc_head == esc_term)
338 {
339 /* Both parameters are omitted and set to 1 by default. */
340 n1 = 1;
341 n2 = 1;
342 }
343 else if (!(delim = (char *) memchr (esc_head, ';',
344 esc_term - esc_head)))
345 {
346 /* Only the first parameter is given. The second one is
347 set to 1 by default. */
348 n1 = strtol (esc_head, &eptr, 10);
349 if (eptr != esc_term)
350 break;
351 n2 = 1;
352 }
353 else
354 {
355 /* Both parameters are given. The first one shall be
356 terminated by the semicolon. */
357 n1 = strtol (esc_head, &eptr, 10);
358 if (eptr != delim)
359 break;
360 n2 = strtol (delim + 1, &eptr, 10);
361 if (eptr != esc_term)
362 break;
363 }
364
365 if (GetConsoleScreenBufferInfo (h, &sb))
366 {
367 cr = sb.dwCursorPosition;
368 n1 -= 1;
369 n2 -= 1;
370 /* The cursor position shall be relative to the view coord of
371 the console window, which is usually smaller than the actual
372 buffer. FWIW, the 'appropriate' solution will be shrinking
373 the buffer to match the size of the console window,
374 destroying scrollback in the process. */
375 n1 += sb.srWindow.Top;
376 n2 += sb.srWindow.Left;
377 /* Stop at the topmost or bottommost boundary. */
378 if (n1 < 0)
379 cr.Y = 0;
380 else if (n1 > sb.dwSize.Y)
381 cr.Y = sb.dwSize.Y;
382 else
383 cr.Y = n1;
384 /* Stop at the leftmost or rightmost boundary. */
385 if (n2 < 0)
386 cr.X = 0;
387 else if (n2 > sb.dwSize.X)
388 cr.X = sb.dwSize.X;
389 else
390 cr.X = n2;
391 SetConsoleCursorPosition (h, cr);
392 }
393 break;
394
395 /* ESC [ n1 'J'
396 Erase display. */
397 case MAKEWORD ('[', 'J'):
398 if (esc_head == esc_term)
399 /* This is one of the very few codes whose parameters have
400 a default value of zero. */
401 n1 = 0;
402 else
403 {
404 n1 = strtol (esc_head, &eptr, 10);
405 if (eptr != esc_term)
406 break;
407 }
408
409 if (GetConsoleScreenBufferInfo (h, &sb))
410 {
411 /* The cursor is not necessarily in the console window, which
412 makes the behavior of this code harder to define. */
413 switch (n1)
414 {
415 case 0:
416 /* If the cursor is in or above the window, erase from
417 it to the bottom of the window; otherwise, do nothing. */
418 cr = sb.dwCursorPosition;
419 cnt = sb.dwSize.X - sb.dwCursorPosition.X;
420 rows = sb.srWindow.Bottom - sb.dwCursorPosition.Y;
421 break;
422 case 1:
423 /* If the cursor is in or under the window, erase from
424 it to the top of the window; otherwise, do nothing. */
425 cr.X = 0;
426 cr.Y = sb.srWindow.Top;
427 cnt = sb.dwCursorPosition.X + 1;
428 rows = sb.dwCursorPosition.Y - sb.srWindow.Top;
429 break;
430 case 2:
431 /* Erase the entire window. */
432 cr.X = sb.srWindow.Left;
433 cr.Y = sb.srWindow.Top;
434 cnt = 0;
435 rows = sb.srWindow.Bottom - sb.srWindow.Top + 1;
436 break;
437 default:
438 /* Erase the entire buffer. */
439 cr.X = 0;
440 cr.Y = 0;
441 cnt = 0;
442 rows = sb.dwSize.Y;
443 break;
444 }
445 if (rows < 0)
446 break;
447 cnt += rows * sb.dwSize.X;
448 FillConsoleOutputCharacterW (h, L' ', cnt, cr, &step);
449 FillConsoleOutputAttribute (h, sb.wAttributes, cnt, cr, &step);
450 }
451 break;
452
453 /* ESC [ n1 'K'
454 Erase line. */
455 case MAKEWORD ('[', 'K'):
456 if (esc_head == esc_term)
457 /* This is one of the very few codes whose parameters have
458 a default value of zero. */
459 n1 = 0;
460 else
461 {
462 n1 = strtol (esc_head, &eptr, 10);
463 if (eptr != esc_term)
464 break;
465 }
466
467 if (GetConsoleScreenBufferInfo (h, &sb))
468 {
469 switch (n1)
470 {
471 case 0:
472 /* Erase from the cursor to the end. */
473 cr = sb.dwCursorPosition;
474 cnt = sb.dwSize.X - sb.dwCursorPosition.X;
475 break;
476 case 1:
477 /* Erase from the cursor to the beginning. */
478 cr = sb.dwCursorPosition;
479 cr.X = 0;
480 cnt = sb.dwCursorPosition.X + 1;
481 break;
482 default:
483 /* Erase the entire line. */
484 cr = sb.dwCursorPosition;
485 cr.X = 0;
486 cnt = sb.dwSize.X;
487 break;
488 }
489 FillConsoleOutputCharacterW (h, L' ', cnt, cr, &step);
490 FillConsoleOutputAttribute (h, sb.wAttributes, cnt, cr, &step);
491 }
492 break;
493
494 /* ESC [ n1 ';' n2 'm'
495 Set SGR parameters. Zero or more parameters will follow. */
496 case MAKEWORD ('[', 'm'):
497 attrib_add = 0;
498 attrib_rm = 0;
499 if (esc_head == esc_term)
500 {
501 /* When no parameter is given, reset the console. */
502 attrib_add |= (FOREGROUND_RED | FOREGROUND_GREEN
503 | FOREGROUND_BLUE);
504 attrib_rm = -1; /* Removes everything. */
505 goto sgr_set_it;
506 }
507 param = esc_head;
508 do
509 {
510 /* Parse a parameter. */
511 n1 = strtol (param, &eptr, 10);
512 if (*eptr != ';' && eptr != esc_term)
513 goto sgr_set_it;
514
515 switch (n1)
516 {
517 case 0:
518 /* Reset. */
519 attrib_add |= (FOREGROUND_RED | FOREGROUND_GREEN
520 | FOREGROUND_BLUE);
521 attrib_rm = -1; /* Removes everything. */
522 break;
523 case 1:
524 /* Bold. */
525 attrib_add |= FOREGROUND_INTENSITY;
526 break;
527 case 4:
528 /* Underline. */
529 attrib_add |= COMMON_LVB_UNDERSCORE;
530 break;
531 case 5:
532 /* Blink. */
533 /* XXX: It is not BLINKING at all! */
534 attrib_add |= BACKGROUND_INTENSITY;
535 break;
536 case 7:
537 /* Reverse. */
538 attrib_add |= COMMON_LVB_REVERSE_VIDEO;
539 break;
540 case 22:
541 /* No bold. */
542 attrib_add &= ~FOREGROUND_INTENSITY;
543 attrib_rm |= FOREGROUND_INTENSITY;
544 break;
545 case 24:
546 /* No underline. */
547 attrib_add &= ~COMMON_LVB_UNDERSCORE;
548 attrib_rm |= COMMON_LVB_UNDERSCORE;
549 break;
550 case 25:
551 /* No blink. */
552 /* XXX: It is not BLINKING at all! */
553 attrib_add &= ~BACKGROUND_INTENSITY;
554 attrib_rm |= BACKGROUND_INTENSITY;
555 break;
556 case 27:
557 /* No reverse. */
558 attrib_add &= ~COMMON_LVB_REVERSE_VIDEO;
559 attrib_rm |= COMMON_LVB_REVERSE_VIDEO;
560 break;
561 case 30:
562 case 31:
563 case 32:
564 case 33:
565 case 34:
566 case 35:
567 case 36:
568 case 37:
569 /* Foreground color. */
570 attrib_add &= ~(FOREGROUND_RED | FOREGROUND_GREEN
571 | FOREGROUND_BLUE);
572 n1 -= 30;
573 if (n1 & 1)
574 attrib_add |= FOREGROUND_RED;
575 if (n1 & 2)
576 attrib_add |= FOREGROUND_GREEN;
577 if (n1 & 4)
578 attrib_add |= FOREGROUND_BLUE;
579 attrib_rm |= (FOREGROUND_RED | FOREGROUND_GREEN
580 | FOREGROUND_BLUE);
581 break;
582 case 38:
583 /* Reserved for extended foreground color.
584 Don't know how to handle parameters remaining.
585 Bail out. */
586 goto sgr_set_it;
587 case 39:
588 /* Reset foreground color. */
589 /* Set to grey. */
590 attrib_add |= (FOREGROUND_RED | FOREGROUND_GREEN
591 | FOREGROUND_BLUE);
592 attrib_rm |= (FOREGROUND_RED | FOREGROUND_GREEN
593 | FOREGROUND_BLUE);
594 break;
595 case 40:
596 case 41:
597 case 42:
598 case 43:
599 case 44:
600 case 45:
601 case 46:
602 case 47:
603 /* Background color. */
604 attrib_add &= ~(BACKGROUND_RED | BACKGROUND_GREEN
605 | BACKGROUND_BLUE);
606 n1 -= 40;
607 if (n1 & 1)
608 attrib_add |= BACKGROUND_RED;
609 if (n1 & 2)
610 attrib_add |= BACKGROUND_GREEN;
611 if (n1 & 4)
612 attrib_add |= BACKGROUND_BLUE;
613 attrib_rm |= (BACKGROUND_RED | BACKGROUND_GREEN
614 | BACKGROUND_BLUE);
615 break;
616 case 48:
617 /* Reserved for extended background color.
618 Don't know how to handle parameters remaining.
619 Bail out. */
620 goto sgr_set_it;
621 case 49:
622 /* Reset background color. */
623 /* Set to black. */
624 attrib_add &= ~(BACKGROUND_RED | BACKGROUND_GREEN
625 | BACKGROUND_BLUE);
626 attrib_rm |= (BACKGROUND_RED | BACKGROUND_GREEN
627 | BACKGROUND_BLUE);
628 break;
629 }
630
631 /* Prepare the next parameter. */
632 param = eptr + 1;
633 }
634 while (param != esc_term);
635
636sgr_set_it:
637 /* 0xFFFF removes everything. If it is not the case,
638 care must be taken to preserve old attributes. */
639 if (attrib_rm != 0xFFFF && GetConsoleScreenBufferInfo (h, &sb))
640 {
641 attrib_add |= sb.wAttributes & ~attrib_rm;
642 }
643 SetConsoleTextAttribute (h, attrib_add);
644 break;
645 }
646}
647
648int
649mingw_ansi_fputs (const char *str, FILE *fp)
650{
651 const char *read = str;
652 HANDLE h;
653 DWORD mode;
654 int esc_code, prefix_len;
655 const char *esc_head, *esc_term;
656
657 h = (HANDLE) _get_osfhandle (_fileno (fp));
658 if (h == INVALID_HANDLE_VALUE)
659 return EOF;
660
661 /* Don't mess up stdio functions with Windows APIs. */
662 fflush (fp);
663
664 if (GetConsoleMode (h, &mode))
665 /* If it is a console, translate ANSI escape codes as needed. */
666 for (;;)
667 {
668 if ((esc_code = find_esc_head (&prefix_len, &esc_head, read)) == 0)
669 {
670 /* Write all remaining characters, then exit. */
671 write_all (h, read, strlen (read));
672 break;
673 }
674 if (find_esc_terminator (&esc_term, esc_head) == 0)
675 /* Ignore incomplete escape sequences at the moment.
676 FIXME: The escape state shall be cached for further calls
677 to this function. */
678 break;
679 write_all (h, read, esc_head - prefix_len - read);
680 eat_esc_sequence (h, esc_code, esc_head, esc_term);
681 read = esc_term + 1;
682 }
683 else
684 /* If it is not a console, write everything as-is. */
685 write_all (h, read, strlen (read));
686
687 _close ((intptr_t) h);
688 return 1;
689}
690
691#endif /* __MINGW32__ */
692
693static void pp_quoted_string (pretty_printer *, const char *, size_t = -1);
694
695/* Overwrite the given location/range within this text_info's rich_location.
696 For use e.g. when implementing "+" in client format decoders. */
697
698void
699text_info::set_location (unsigned int idx, location_t loc, bool show_caret_p)
700{
701 gcc_checking_assert (m_richloc);
702 m_richloc->set_range (line_table, idx, loc, show_caret_p);
703}
704
705location_t
706text_info::get_location (unsigned int index_of_location) const
707{
708 gcc_checking_assert (m_richloc);
709
710 if (index_of_location == 0)
711 return m_richloc->get_loc ();
712 else
713 return UNKNOWN_LOCATION;
714}
715
716// Default construct an output buffer.
717
718output_buffer::output_buffer ()
719 : formatted_obstack (),
720 chunk_obstack (),
721 obstack (&formatted_obstack),
722 cur_chunk_array (),
723 stream (stderr),
724 line_length (),
725 digit_buffer (),
726 flush_p (true)
727{
728 obstack_init (&formatted_obstack);
729 obstack_init (&chunk_obstack);
730}
731
732// Release resources owned by an output buffer at the end of lifetime.
733
734output_buffer::~output_buffer ()
735{
736 obstack_free (&chunk_obstack, NULL);
737 obstack_free (&formatted_obstack, NULL);
738}
739
740
741/* Format an integer given by va_arg (ARG, type-specifier T) where
742 type-specifier is a precision modifier as indicated by PREC. F is
743 a string used to construct the appropriate format-specifier. */
744#define pp_integer_with_precision(PP, ARG, PREC, T, F) \
745 do \
746 switch (PREC) \
747 { \
748 case 0: \
749 pp_scalar (PP, "%" F, va_arg (ARG, T)); \
750 break; \
751 \
752 case 1: \
753 pp_scalar (PP, "%l" F, va_arg (ARG, long T)); \
754 break; \
755 \
756 case 2: \
757 pp_scalar (PP, "%" HOST_LONG_LONG_FORMAT F, va_arg (ARG, long long T)); \
758 break; \
759 \
760 default: \
761 break; \
762 } \
763 while (0)
764
765
766/* Subroutine of pp_set_maximum_length. Set up PRETTY-PRINTER's
767 internal maximum characters per line. */
768static void
769pp_set_real_maximum_length (pretty_printer *pp)
770{
771 /* If we're told not to wrap lines then do the obvious thing. In case
772 we'll emit prefix only once per message, it is appropriate
773 not to increase unnecessarily the line-length cut-off. */
774 if (!pp_is_wrapping_line (pp)
775 || pp_prefixing_rule (pp) == DIAGNOSTICS_SHOW_PREFIX_ONCE
776 || pp_prefixing_rule (pp) == DIAGNOSTICS_SHOW_PREFIX_NEVER)
777 pp->maximum_length = pp_line_cutoff (pp);
778 else
779 {
780 int prefix_length = pp->prefix ? strlen (pp->prefix) : 0;
781 /* If the prefix is ridiculously too long, output at least
782 32 characters. */
783 if (pp_line_cutoff (pp) - prefix_length < 32)
784 pp->maximum_length = pp_line_cutoff (pp) + 32;
785 else
786 pp->maximum_length = pp_line_cutoff (pp);
787 }
788}
789
790/* Clear PRETTY-PRINTER's output state. */
791static inline void
792pp_clear_state (pretty_printer *pp)
793{
794 pp->emitted_prefix = false;
795 pp_indentation (pp) = 0;
796}
797
798/* Flush the formatted text of PRETTY-PRINTER onto the attached stream. */
799void
800pp_write_text_to_stream (pretty_printer *pp)
801{
802 const char *text = pp_formatted_text (pp);
803#ifdef __MINGW32__
804 mingw_ansi_fputs (text, pp_buffer (pp)->stream);
805#else
806 fputs (text, pp_buffer (pp)->stream);
807#endif
808 pp_clear_output_area (pp);
809}
810
811/* As pp_write_text_to_stream, but for GraphViz label output.
812
813 Flush the formatted text of pretty-printer PP onto the attached stream.
814 Replace characters in PPF that have special meaning in a GraphViz .dot
815 file.
816
817 This routine is not very fast, but it doesn't have to be as this is only
818 be used by routines dumping intermediate representations in graph form. */
819
820void
821pp_write_text_as_dot_label_to_stream (pretty_printer *pp, bool for_record)
822{
823 const char *text = pp_formatted_text (pp);
824 const char *p = text;
825 FILE *fp = pp_buffer (pp)->stream;
826
827 for (;*p; p++)
828 {
829 bool escape_char;
830 switch (*p)
831 {
832 /* Print newlines as a left-aligned newline. */
833 case '\n':
834 fputs ("\\l", fp);
835 escape_char = true;
836 break;
837
838 /* The following characters are only special for record-shape nodes. */
839 case '|':
840 case '{':
841 case '}':
842 case '<':
843 case '>':
844 case ' ':
845 escape_char = for_record;
846 break;
847
848 /* The following characters always have to be escaped
849 for use in labels. */
850 case '\\':
851 /* There is a bug in some (f.i. 2.36.0) versions of graphiz
852 ( http://www.graphviz.org/mantisbt/view.php?id=2524 ) related to
853 backslash as last char in label. Let's avoid triggering it. */
854 gcc_assert (*(p + 1) != '\0');
855 /* Fall through. */
856 case '"':
857 escape_char = true;
858 break;
859
860 default:
861 escape_char = false;
862 break;
863 }
864
865 if (escape_char)
866 fputc ('\\', fp);
867
868 fputc (*p, fp);
869 }
870
871 pp_clear_output_area (pp);
872}
873
874/* Wrap a text delimited by START and END into PRETTY-PRINTER. */
875static void
876pp_wrap_text (pretty_printer *pp, const char *start, const char *end)
877{
878 bool wrapping_line = pp_is_wrapping_line (pp);
879
880 while (start != end)
881 {
882 /* Dump anything bordered by whitespaces. */
883 {
884 const char *p = start;
885 while (p != end && !ISBLANK (*p) && *p != '\n')
886 ++p;
887 if (wrapping_line
888 && p - start >= pp_remaining_character_count_for_line (pp))
889 pp_newline (pp);
890 pp_append_text (pp, start, p);
891 start = p;
892 }
893
894 if (start != end && ISBLANK (*start))
895 {
896 pp_space (pp);
897 ++start;
898 }
899 if (start != end && *start == '\n')
900 {
901 pp_newline (pp);
902 ++start;
903 }
904 }
905}
906
907/* Same as pp_wrap_text but wrap text only when in line-wrapping mode. */
908static inline void
909pp_maybe_wrap_text (pretty_printer *pp, const char *start, const char *end)
910{
911 if (pp_is_wrapping_line (pp))
912 pp_wrap_text (pp, start, end);
913 else
914 pp_append_text (pp, start, end);
915}
916
917/* Append to the output area of PRETTY-PRINTER a string specified by its
918 STARTing character and LENGTH. */
919static inline void
920pp_append_r (pretty_printer *pp, const char *start, int length)
921{
922 output_buffer_append_r (pp_buffer (pp), start, length);
923}
924
925/* Insert enough spaces into the output area of PRETTY-PRINTER to bring
926 the column position to the current indentation level, assuming that a
927 newline has just been written to the buffer. */
928void
929pp_indent (pretty_printer *pp)
930{
931 int n = pp_indentation (pp);
932 int i;
933
934 for (i = 0; i < n; ++i)
935 pp_space (pp);
936}
937
938/* The following format specifiers are recognized as being client independent:
939 %d, %i: (signed) integer in base ten.
940 %u: unsigned integer in base ten.
941 %o: unsigned integer in base eight.
942 %x: unsigned integer in base sixteen.
943 %ld, %li, %lo, %lu, %lx: long versions of the above.
944 %lld, %lli, %llo, %llu, %llx: long long versions.
945 %wd, %wi, %wo, %wu, %wx: HOST_WIDE_INT versions.
946 %c: character.
947 %s: string.
948 %p: pointer (printed in a host-dependent manner).
949 %r: if pp_show_color(pp), switch to color identified by const char *.
950 %R: if pp_show_color(pp), reset color.
951 %m: strerror(text->err_no) - does not consume a value from args_ptr.
952 %%: '%'.
953 %<: opening quote.
954 %>: closing quote.
955 %': apostrophe (should only be used in untranslated messages;
956 translations should use appropriate punctuation directly).
957 %.*s: a substring the length of which is specified by an argument
958 integer.
959 %Ns: likewise, but length specified as constant in the format string.
960 Flag 'q': quote formatted text (must come immediately after '%').
961 %Z: Requires two arguments - array of int, and len. Prints elements
962 of the array.
963
964 Arguments can be used sequentially, or through %N$ resp. *N$
965 notation Nth argument after the format string. If %N$ / *N$
966 notation is used, it must be used for all arguments, except %m, %%,
967 %<, %> and %', which may not have a number, as they do not consume
968 an argument. When %M$.*N$s is used, M must be N + 1. (This may
969 also be written %M$.*s, provided N is not otherwise used.) The
970 format string must have conversion specifiers with argument numbers
971 1 up to highest argument; each argument may only be used once.
972 A format string can have at most 30 arguments. */
973
974/* Formatting phases 1 and 2: render TEXT->format_spec plus
975 TEXT->args_ptr into a series of chunks in pp_buffer (PP)->args[].
976 Phase 3 is in pp_output_formatted_text. */
977
978void
979pp_format (pretty_printer *pp, text_info *text)
980{
981 output_buffer *buffer = pp_buffer (pp);
982 const char *p;
983 const char **args;
984 struct chunk_info *new_chunk_array;
985
986 unsigned int curarg = 0, chunk = 0, argno;
987 pp_wrapping_mode_t old_wrapping_mode;
988 bool any_unnumbered = false, any_numbered = false;
989 const char **formatters[PP_NL_ARGMAX];
990
991 /* Allocate a new chunk structure. */
992 new_chunk_array = XOBNEW (&buffer->chunk_obstack, struct chunk_info);
993 new_chunk_array->prev = buffer->cur_chunk_array;
994 buffer->cur_chunk_array = new_chunk_array;
995 args = new_chunk_array->args;
996
997 /* Formatting phase 1: split up TEXT->format_spec into chunks in
998 pp_buffer (PP)->args[]. Even-numbered chunks are to be output
999 verbatim, odd-numbered chunks are format specifiers.
1000 %m, %%, %<, %>, and %' are replaced with the appropriate text at
1001 this point. */
1002
1003 memset (formatters, 0, sizeof formatters);
1004
1005 for (p = text->format_spec; *p; )
1006 {
1007 while (*p != '\0' && *p != '%')
1008 {
1009 obstack_1grow (&buffer->chunk_obstack, *p);
1010 p++;
1011 }
1012
1013 if (*p == '\0')
1014 break;
1015
1016 switch (*++p)
1017 {
1018 case '\0':
1019 gcc_unreachable ();
1020
1021 case '%':
1022 obstack_1grow (&buffer->chunk_obstack, '%');
1023 p++;
1024 continue;
1025
1026 case '<':
1027 {
1028 obstack_grow (&buffer->chunk_obstack,
1029 open_quote, strlen (open_quote));
1030 const char *colorstr
1031 = colorize_start (pp_show_color (pp), "quote");
1032 obstack_grow (&buffer->chunk_obstack, colorstr, strlen (colorstr));
1033 p++;
1034 continue;
1035 }
1036
1037 case '>':
1038 {
1039 const char *colorstr = colorize_stop (pp_show_color (pp));
1040 obstack_grow (&buffer->chunk_obstack, colorstr, strlen (colorstr));
1041 }
1042 /* FALLTHRU */
1043 case '\'':
1044 obstack_grow (&buffer->chunk_obstack,
1045 close_quote, strlen (close_quote));
1046 p++;
1047 continue;
1048
1049 case 'R':
1050 {
1051 const char *colorstr = colorize_stop (pp_show_color (pp));
1052 obstack_grow (&buffer->chunk_obstack, colorstr,
1053 strlen (colorstr));
1054 p++;
1055 continue;
1056 }
1057
1058 case 'm':
1059 {
1060 const char *errstr = xstrerror (text->err_no);
1061 obstack_grow (&buffer->chunk_obstack, errstr, strlen (errstr));
1062 }
1063 p++;
1064 continue;
1065
1066 default:
1067 /* Handled in phase 2. Terminate the plain chunk here. */
1068 obstack_1grow (&buffer->chunk_obstack, '\0');
1069 gcc_assert (chunk < PP_NL_ARGMAX * 2);
1070 args[chunk++] = XOBFINISH (&buffer->chunk_obstack, const char *);
1071 break;
1072 }
1073
1074 if (ISDIGIT (*p))
1075 {
1076 char *end;
1077 argno = strtoul (p, &end, 10) - 1;
1078 p = end;
1079 gcc_assert (*p == '$');
1080 p++;
1081
1082 any_numbered = true;
1083 gcc_assert (!any_unnumbered);
1084 }
1085 else
1086 {
1087 argno = curarg++;
1088 any_unnumbered = true;
1089 gcc_assert (!any_numbered);
1090 }
1091 gcc_assert (argno < PP_NL_ARGMAX);
1092 gcc_assert (!formatters[argno]);
1093 formatters[argno] = &args[chunk];
1094 do
1095 {
1096 obstack_1grow (&buffer->chunk_obstack, *p);
1097 p++;
1098 }
1099 while (strchr ("qwl+#", p[-1]));
1100
1101 if (p[-1] == '.')
1102 {
1103 /* We handle '%.Ns' and '%.*s' or '%M$.*N$s'
1104 (where M == N + 1). */
1105 if (ISDIGIT (*p))
1106 {
1107 do
1108 {
1109 obstack_1grow (&buffer->chunk_obstack, *p);
1110 p++;
1111 }
1112 while (ISDIGIT (p[-1]));
1113 gcc_assert (p[-1] == 's');
1114 }
1115 else
1116 {
1117 gcc_assert (*p == '*');
1118 obstack_1grow (&buffer->chunk_obstack, '*');
1119 p++;
1120
1121 if (ISDIGIT (*p))
1122 {
1123 char *end;
1124 unsigned int argno2 = strtoul (p, &end, 10) - 1;
1125 p = end;
1126 gcc_assert (argno2 == argno - 1);
1127 gcc_assert (!any_unnumbered);
1128 gcc_assert (*p == '$');
1129
1130 p++;
1131 formatters[argno2] = formatters[argno];
1132 }
1133 else
1134 {
1135 gcc_assert (!any_numbered);
1136 formatters[argno+1] = formatters[argno];
1137 curarg++;
1138 }
1139 gcc_assert (*p == 's');
1140 obstack_1grow (&buffer->chunk_obstack, 's');
1141 p++;
1142 }
1143 }
1144 if (*p == '\0')
1145 break;
1146
1147 obstack_1grow (&buffer->chunk_obstack, '\0');
1148 gcc_assert (chunk < PP_NL_ARGMAX * 2);
1149 args[chunk++] = XOBFINISH (&buffer->chunk_obstack, const char *);
1150 }
1151
1152 obstack_1grow (&buffer->chunk_obstack, '\0');
1153 gcc_assert (chunk < PP_NL_ARGMAX * 2);
1154 args[chunk++] = XOBFINISH (&buffer->chunk_obstack, const char *);
1155 args[chunk] = 0;
1156
1157 /* Set output to the argument obstack, and switch line-wrapping and
1158 prefixing off. */
1159 buffer->obstack = &buffer->chunk_obstack;
1160 old_wrapping_mode = pp_set_verbatim_wrapping (pp);
1161
1162 /* Second phase. Replace each formatter with the formatted text it
1163 corresponds to. */
1164
1165 for (argno = 0; formatters[argno]; argno++)
1166 {
1167 int precision = 0;
1168 bool wide = false;
1169 bool plus = false;
1170 bool hash = false;
1171 bool quote = false;
1172
1173 /* We do not attempt to enforce any ordering on the modifier
1174 characters. */
1175
1176 for (p = *formatters[argno];; p++)
1177 {
1178 switch (*p)
1179 {
1180 case 'q':
1181 gcc_assert (!quote);
1182 quote = true;
1183 continue;
1184
1185 case '+':
1186 gcc_assert (!plus);
1187 plus = true;
1188 continue;
1189
1190 case '#':
1191 gcc_assert (!hash);
1192 hash = true;
1193 continue;
1194
1195 case 'w':
1196 gcc_assert (!wide);
1197 wide = true;
1198 continue;
1199
1200 case 'l':
1201 /* We don't support precision beyond that of "long long". */
1202 gcc_assert (precision < 2);
1203 precision++;
1204 continue;
1205 }
1206 break;
1207 }
1208
1209 gcc_assert (!wide || precision == 0);
1210
1211 if (quote)
1212 pp_begin_quote (pp, pp_show_color (pp));
1213
1214 switch (*p)
1215 {
1216 case 'r':
1217 pp_string (pp, colorize_start (pp_show_color (pp),
1218 va_arg (*text->args_ptr,
1219 const char *)));
1220 break;
1221
1222 case 'c':
1223 {
1224 /* When quoting, print alphanumeric, punctuation, and the space
1225 character unchanged, and all others in hexadecimal with the
1226 "\x" prefix. Otherwise print them all unchanged. */
1227 int chr = va_arg (*text->args_ptr, int);
1228 if (ISPRINT (chr) || !quote)
1229 pp_character (pp, chr);
1230 else
1231 {
1232 const char str [2] = { chr, '\0' };
1233 pp_quoted_string (pp, str, 1);
1234 }
1235 break;
1236 }
1237
1238 case 'd':
1239 case 'i':
1240 if (wide)
1241 pp_wide_integer (pp, va_arg (*text->args_ptr, HOST_WIDE_INT));
1242 else
1243 pp_integer_with_precision
1244 (pp, *text->args_ptr, precision, int, "d");
1245 break;
1246
1247 case 'o':
1248 if (wide)
1249 pp_scalar (pp, "%" HOST_WIDE_INT_PRINT "o",
1250 va_arg (*text->args_ptr, unsigned HOST_WIDE_INT));
1251 else
1252 pp_integer_with_precision
1253 (pp, *text->args_ptr, precision, unsigned, "o");
1254 break;
1255
1256 case 's':
1257 if (quote)
1258 pp_quoted_string (pp, va_arg (*text->args_ptr, const char *));
1259 else
1260 pp_string (pp, va_arg (*text->args_ptr, const char *));
1261 break;
1262
1263 case 'p':
1264 pp_pointer (pp, va_arg (*text->args_ptr, void *));
1265 break;
1266
1267 case 'u':
1268 if (wide)
1269 pp_scalar (pp, HOST_WIDE_INT_PRINT_UNSIGNED,
1270 va_arg (*text->args_ptr, unsigned HOST_WIDE_INT));
1271 else
1272 pp_integer_with_precision
1273 (pp, *text->args_ptr, precision, unsigned, "u");
1274 break;
1275
1276 case 'Z':
1277 {
1278 int *v = va_arg (*text->args_ptr, int *);
1279 unsigned len = va_arg (*text->args_ptr, unsigned);
1280
1281 for (unsigned i = 0; i < len; ++i)
1282 {
1283 pp_scalar (pp, "%i", v[i]);
1284 if (i < len - 1)
1285 {
1286 pp_comma (pp);
1287 pp_space (pp);
1288 }
1289 }
1290 break;
1291 }
1292
1293 case 'x':
1294 if (wide)
1295 pp_scalar (pp, HOST_WIDE_INT_PRINT_HEX,
1296 va_arg (*text->args_ptr, unsigned HOST_WIDE_INT));
1297 else
1298 pp_integer_with_precision
1299 (pp, *text->args_ptr, precision, unsigned, "x");
1300 break;
1301
1302 case '.':
1303 {
1304 int n;
1305 const char *s;
1306
1307 /* We handle '%.Ns' and '%.*s' or '%M$.*N$s'
1308 (where M == N + 1). The format string should be verified
1309 already from the first phase. */
1310 p++;
1311 if (ISDIGIT (*p))
1312 {
1313 char *end;
1314 n = strtoul (p, &end, 10);
1315 p = end;
1316 gcc_assert (*p == 's');
1317 }
1318 else
1319 {
1320 gcc_assert (*p == '*');
1321 p++;
1322 gcc_assert (*p == 's');
1323 n = va_arg (*text->args_ptr, int);
1324
1325 /* This consumes a second entry in the formatters array. */
1326 gcc_assert (formatters[argno] == formatters[argno+1]);
1327 argno++;
1328 }
1329
1330 s = va_arg (*text->args_ptr, const char *);
1331
1332 /* Append the lesser of precision and strlen (s) characters
1333 from the array (which need not be a nul-terminated string).
1334 Negative precision is treated as if it were omitted. */
1335 size_t len = n < 0 ? strlen (s) : strnlen (s, n);
1336
1337 pp_append_text (pp, s, s + len);
1338 }
1339 break;
1340
1341 default:
1342 {
1343 bool ok;
1344
1345 /* Call the format decoder.
1346 Pass the address of "quote" so that format decoders can
1347 potentially disable printing of the closing quote
1348 (e.g. when printing "'TYPEDEF' aka 'TYPE'" in the C family
1349 of frontends). */
1350 gcc_assert (pp_format_decoder (pp));
1351 ok = pp_format_decoder (pp) (pp, text, p,
1352 precision, wide, plus, hash, &quote,
1353 formatters[argno]);
1354 gcc_assert (ok);
1355 }
1356 }
1357
1358 if (quote)
1359 pp_end_quote (pp, pp_show_color (pp));
1360
1361 obstack_1grow (&buffer->chunk_obstack, '\0');
1362 *formatters[argno] = XOBFINISH (&buffer->chunk_obstack, const char *);
1363 }
1364
1365 if (CHECKING_P)
1366 for (; argno < PP_NL_ARGMAX; argno++)
1367 gcc_assert (!formatters[argno]);
1368
1369 /* If the client supplied a postprocessing object, call its "handle"
1370 hook here. */
1371 if (pp->m_format_postprocessor)
1372 pp->m_format_postprocessor->handle (pp);
1373
1374 /* Revert to normal obstack and wrapping mode. */
1375 buffer->obstack = &buffer->formatted_obstack;
1376 buffer->line_length = 0;
1377 pp_wrapping_mode (pp) = old_wrapping_mode;
1378 pp_clear_state (pp);
1379}
1380
1381/* Format of a message pointed to by TEXT. */
1382void
1383pp_output_formatted_text (pretty_printer *pp)
1384{
1385 unsigned int chunk;
1386 output_buffer *buffer = pp_buffer (pp);
1387 struct chunk_info *chunk_array = buffer->cur_chunk_array;
1388 const char **args = chunk_array->args;
1389
1390 gcc_assert (buffer->obstack == &buffer->formatted_obstack);
1391 gcc_assert (buffer->line_length == 0);
1392
1393 /* This is a third phase, first 2 phases done in pp_format_args.
1394 Now we actually print it. */
1395 for (chunk = 0; args[chunk]; chunk++)
1396 pp_string (pp, args[chunk]);
1397
1398 /* Deallocate the chunk structure and everything after it (i.e. the
1399 associated series of formatted strings). */
1400 buffer->cur_chunk_array = chunk_array->prev;
1401 obstack_free (&buffer->chunk_obstack, chunk_array);
1402}
1403
1404/* Helper subroutine of output_verbatim and verbatim. Do the appropriate
1405 settings needed by BUFFER for a verbatim formatting. */
1406void
1407pp_format_verbatim (pretty_printer *pp, text_info *text)
1408{
1409 /* Set verbatim mode. */
1410 pp_wrapping_mode_t oldmode = pp_set_verbatim_wrapping (pp);
1411
1412 /* Do the actual formatting. */
1413 pp_format (pp, text);
1414 pp_output_formatted_text (pp);
1415
1416 /* Restore previous settings. */
1417 pp_wrapping_mode (pp) = oldmode;
1418}
1419
1420/* Flush the content of BUFFER onto the attached stream. This
1421 function does nothing unless pp->output_buffer->flush_p. */
1422void
1423pp_flush (pretty_printer *pp)
1424{
1425 pp_clear_state (pp);
1426 if (!pp->buffer->flush_p)
1427 return;
1428 pp_write_text_to_stream (pp);
1429 fflush (pp_buffer (pp)->stream);
1430}
1431
1432/* Flush the content of BUFFER onto the attached stream independently
1433 of the value of pp->output_buffer->flush_p. */
1434void
1435pp_really_flush (pretty_printer *pp)
1436{
1437 pp_clear_state (pp);
1438 pp_write_text_to_stream (pp);
1439 fflush (pp_buffer (pp)->stream);
1440}
1441
1442/* Sets the number of maximum characters per line PRETTY-PRINTER can
1443 output in line-wrapping mode. A LENGTH value 0 suppresses
1444 line-wrapping. */
1445void
1446pp_set_line_maximum_length (pretty_printer *pp, int length)
1447{
1448 pp_line_cutoff (pp) = length;
1449 pp_set_real_maximum_length (pp);
1450}
1451
1452/* Clear PRETTY-PRINTER output area text info. */
1453void
1454pp_clear_output_area (pretty_printer *pp)
1455{
1456 obstack_free (pp_buffer (pp)->obstack,
1457 obstack_base (pp_buffer (pp)->obstack));
1458 pp_buffer (pp)->line_length = 0;
1459}
1460
1461/* Set PREFIX for PRETTY-PRINTER. */
1462void
1463pp_set_prefix (pretty_printer *pp, const char *prefix)
1464{
1465 pp->prefix = prefix;
1466 pp_set_real_maximum_length (pp);
1467 pp->emitted_prefix = false;
1468 pp_indentation (pp) = 0;
1469}
1470
1471/* Free PRETTY-PRINTER's prefix, a previously malloc()'d string. */
1472void
1473pp_destroy_prefix (pretty_printer *pp)
1474{
1475 if (pp->prefix != NULL)
1476 {
1477 free (CONST_CAST (char *, pp->prefix));
1478 pp->prefix = NULL;
1479 }
1480}
1481
1482/* Write out PRETTY-PRINTER's prefix. */
1483void
1484pp_emit_prefix (pretty_printer *pp)
1485{
1486 if (pp->prefix != NULL)
1487 {
1488 switch (pp_prefixing_rule (pp))
1489 {
1490 default:
1491 case DIAGNOSTICS_SHOW_PREFIX_NEVER:
1492 break;
1493
1494 case DIAGNOSTICS_SHOW_PREFIX_ONCE:
1495 if (pp->emitted_prefix)
1496 {
1497 pp_indent (pp);
1498 break;
1499 }
1500 pp_indentation (pp) += 3;
1501 /* Fall through. */
1502
1503 case DIAGNOSTICS_SHOW_PREFIX_EVERY_LINE:
1504 {
1505 int prefix_length = strlen (pp->prefix);
1506 pp_append_r (pp, pp->prefix, prefix_length);
1507 pp->emitted_prefix = true;
1508 }
1509 break;
1510 }
1511 }
1512}
1513
1514/* Construct a PRETTY-PRINTER with PREFIX and of MAXIMUM_LENGTH
1515 characters per line. */
1516
1517pretty_printer::pretty_printer (const char *p, int l)
1518 : buffer (new (XCNEW (output_buffer)) output_buffer ()),
1519 prefix (),
1520 padding (pp_none),
1521 maximum_length (),
1522 indent_skip (),
1523 wrapping (),
1524 format_decoder (),
1525 m_format_postprocessor (NULL),
1526 emitted_prefix (),
1527 need_newline (),
1528 translate_identifiers (true),
1529 show_color ()
1530{
1531 pp_line_cutoff (this) = l;
1532 /* By default, we emit prefixes once per message. */
1533 pp_prefixing_rule (this) = DIAGNOSTICS_SHOW_PREFIX_ONCE;
1534 pp_set_prefix (this, p);
1535}
1536
1537pretty_printer::~pretty_printer ()
1538{
1539 if (m_format_postprocessor)
1540 delete m_format_postprocessor;
1541 buffer->~output_buffer ();
1542 XDELETE (buffer);
1543}
1544
1545/* Append a string delimited by START and END to the output area of
1546 PRETTY-PRINTER. No line wrapping is done. However, if beginning a
1547 new line then emit PRETTY-PRINTER's prefix and skip any leading
1548 whitespace if appropriate. The caller must ensure that it is
1549 safe to do so. */
1550void
1551pp_append_text (pretty_printer *pp, const char *start, const char *end)
1552{
1553 /* Emit prefix and skip whitespace if we're starting a new line. */
1554 if (pp_buffer (pp)->line_length == 0)
1555 {
1556 pp_emit_prefix (pp);
1557 if (pp_is_wrapping_line (pp))
1558 while (start != end && *start == ' ')
1559 ++start;
1560 }
1561 pp_append_r (pp, start, end - start);
1562}
1563
1564/* Finishes constructing a NULL-terminated character string representing
1565 the PRETTY-PRINTED text. */
1566const char *
1567pp_formatted_text (pretty_printer *pp)
1568{
1569 return output_buffer_formatted_text (pp_buffer (pp));
1570}
1571
1572/* Return a pointer to the last character emitted in PRETTY-PRINTER's
1573 output area. A NULL pointer means no character available. */
1574const char *
1575pp_last_position_in_text (const pretty_printer *pp)
1576{
1577 return output_buffer_last_position_in_text (pp_buffer (pp));
1578}
1579
1580/* Return the amount of characters PRETTY-PRINTER can accept to
1581 make a full line. Meaningful only in line-wrapping mode. */
1582int
1583pp_remaining_character_count_for_line (pretty_printer *pp)
1584{
1585 return pp->maximum_length - pp_buffer (pp)->line_length;
1586}
1587
1588
1589/* Format a message into BUFFER a la printf. */
1590void
1591pp_printf (pretty_printer *pp, const char *msg, ...)
1592{
1593 text_info text;
1594 va_list ap;
1595
1596 va_start (ap, msg);
1597 text.err_no = errno;
1598 text.args_ptr = &ap;
1599 text.format_spec = msg;
1600 pp_format (pp, &text);
1601 pp_output_formatted_text (pp);
1602 va_end (ap);
1603}
1604
1605
1606/* Output MESSAGE verbatim into BUFFER. */
1607void
1608pp_verbatim (pretty_printer *pp, const char *msg, ...)
1609{
1610 text_info text;
1611 va_list ap;
1612
1613 va_start (ap, msg);
1614 text.err_no = errno;
1615 text.args_ptr = &ap;
1616 text.format_spec = msg;
1617 pp_format_verbatim (pp, &text);
1618 va_end (ap);
1619}
1620
1621
1622
1623/* Have PRETTY-PRINTER start a new line. */
1624void
1625pp_newline (pretty_printer *pp)
1626{
1627 obstack_1grow (pp_buffer (pp)->obstack, '\n');
1628 pp_needs_newline (pp) = false;
1629 pp_buffer (pp)->line_length = 0;
1630}
1631
1632/* Have PRETTY-PRINTER add a CHARACTER. */
1633void
1634pp_character (pretty_printer *pp, int c)
1635{
1636 if (pp_is_wrapping_line (pp)
1637 && pp_remaining_character_count_for_line (pp) <= 0)
1638 {
1639 pp_newline (pp);
1640 if (ISSPACE (c))
1641 return;
1642 }
1643 obstack_1grow (pp_buffer (pp)->obstack, c);
1644 ++pp_buffer (pp)->line_length;
1645}
1646
1647/* Append a STRING to the output area of PRETTY-PRINTER; the STRING may
1648 be line-wrapped if in appropriate mode. */
1649void
1650pp_string (pretty_printer *pp, const char *str)
1651{
1652 gcc_checking_assert (str);
1653 pp_maybe_wrap_text (pp, str, str + strlen (str));
1654}
1655
1656/* Append the leading N characters of STRING to the output area of
1657 PRETTY-PRINTER, quoting in hexadecimal non-printable characters.
1658 Setting N = -1 is as if N were set to strlen (STRING). The STRING
1659 may be line-wrapped if in appropriate mode. */
1660static void
1661pp_quoted_string (pretty_printer *pp, const char *str, size_t n /* = -1 */)
1662{
1663 gcc_checking_assert (str);
1664
1665 const char *last = str;
1666 const char *ps;
1667
1668 /* Compute the length if not specified. */
1669 if (n == (size_t) -1)
1670 n = strlen (str);
1671
1672 for (ps = str; n; ++ps, --n)
1673 {
1674 if (ISPRINT (*ps))
1675 continue;
1676
1677 if (last < ps)
1678 pp_maybe_wrap_text (pp, last, ps - 1);
1679
1680 /* Append the hexadecimal value of the character. Allocate a buffer
1681 that's large enough for a 32-bit char plus the hex prefix. */
1682 char buf [11];
1683 int n = sprintf (buf, "\\x%02x", (unsigned char)*ps);
1684 pp_maybe_wrap_text (pp, buf, buf + n);
1685 last = ps + 1;
1686 }
1687
1688 pp_maybe_wrap_text (pp, last, ps);
1689}
1690
1691/* Maybe print out a whitespace if needed. */
1692
1693void
1694pp_maybe_space (pretty_printer *pp)
1695{
1696 if (pp->padding != pp_none)
1697 {
1698 pp_space (pp);
1699 pp->padding = pp_none;
1700 }
1701}
1702
1703// Add a newline to the pretty printer PP and flush formatted text.
1704
1705void
1706pp_newline_and_flush (pretty_printer *pp)
1707{
1708 pp_newline (pp);
1709 pp_flush (pp);
1710 pp_needs_newline (pp) = false;
1711}
1712
1713// Add a newline to the pretty printer PP, followed by indentation.
1714
1715void
1716pp_newline_and_indent (pretty_printer *pp, int n)
1717{
1718 pp_indentation (pp) += n;
1719 pp_newline (pp);
1720 pp_indent (pp);
1721 pp_needs_newline (pp) = false;
1722}
1723
1724// Add separator C, followed by a single whitespace.
1725
1726void
1727pp_separate_with (pretty_printer *pp, char c)
1728{
1729 pp_character (pp, c);
1730 pp_space (pp);
1731}
1732
1733/* Add a localized open quote, and if SHOW_COLOR is true, begin colorizing
1734 using the "quote" color. */
1735
1736void
1737pp_begin_quote (pretty_printer *pp, bool show_color)
1738{
1739 pp_string (pp, open_quote);
1740 pp_string (pp, colorize_start (show_color, "quote"));
1741}
1742
1743/* If SHOW_COLOR is true, stop colorizing.
1744 Add a localized close quote. */
1745
1746void
1747pp_end_quote (pretty_printer *pp, bool show_color)
1748{
1749 pp_string (pp, colorize_stop (show_color));
1750 pp_string (pp, close_quote);
1751}
1752
1753
1754/* The string starting at P has LEN (at least 1) bytes left; if they
1755 start with a valid UTF-8 sequence, return the length of that
1756 sequence and set *VALUE to the value of that sequence, and
1757 otherwise return 0 and set *VALUE to (unsigned int) -1. */
1758
1759static int
1760decode_utf8_char (const unsigned char *p, size_t len, unsigned int *value)
1761{
1762 unsigned int t = *p;
1763
1764 if (len == 0)
1765 abort ();
1766 if (t & 0x80)
1767 {
1768 size_t utf8_len = 0;
1769 unsigned int ch;
1770 size_t i;
1771 for (t = *p; t & 0x80; t <<= 1)
1772 utf8_len++;
1773
1774 if (utf8_len > len || utf8_len < 2 || utf8_len > 6)
1775 {
1776 *value = (unsigned int) -1;
1777 return 0;
1778 }
1779 ch = *p & ((1 << (7 - utf8_len)) - 1);
1780 for (i = 1; i < utf8_len; i++)
1781 {
1782 unsigned int u = p[i];
1783 if ((u & 0xC0) != 0x80)
1784 {
1785 *value = (unsigned int) -1;
1786 return 0;
1787 }
1788 ch = (ch << 6) | (u & 0x3F);
1789 }
1790 if ( (ch <= 0x7F && utf8_len > 1)
1791 || (ch <= 0x7FF && utf8_len > 2)
1792 || (ch <= 0xFFFF && utf8_len > 3)
1793 || (ch <= 0x1FFFFF && utf8_len > 4)
1794 || (ch <= 0x3FFFFFF && utf8_len > 5)
1795 || (ch >= 0xD800 && ch <= 0xDFFF))
1796 {
1797 *value = (unsigned int) -1;
1798 return 0;
1799 }
1800 *value = ch;
1801 return utf8_len;
1802 }
1803 else
1804 {
1805 *value = t;
1806 return 1;
1807 }
1808}
1809
1810/* Allocator for identifier_to_locale and corresponding function to
1811 free memory. */
1812
1813void *(*identifier_to_locale_alloc) (size_t) = xmalloc;
1814void (*identifier_to_locale_free) (void *) = free;
1815
1816/* Given IDENT, an identifier in the internal encoding, return a
1817 version of IDENT suitable for diagnostics in the locale character
1818 set: either IDENT itself, or a string, allocated using
1819 identifier_to_locale_alloc, converted to the locale character set
1820 and using escape sequences if not representable in the locale
1821 character set or containing control characters or invalid byte
1822 sequences. Existing backslashes in IDENT are not doubled, so the
1823 result may not uniquely specify the contents of an arbitrary byte
1824 sequence identifier. */
1825
1826const char *
1827identifier_to_locale (const char *ident)
1828{
1829 const unsigned char *uid = (const unsigned char *) ident;
1830 size_t idlen = strlen (ident);
1831 bool valid_printable_utf8 = true;
1832 bool all_ascii = true;
1833 size_t i;
1834
1835 for (i = 0; i < idlen;)
1836 {
1837 unsigned int c;
1838 size_t utf8_len = decode_utf8_char (&uid[i], idlen - i, &c);
1839 if (utf8_len == 0 || c <= 0x1F || (c >= 0x7F && c <= 0x9F))
1840 {
1841 valid_printable_utf8 = false;
1842 break;
1843 }
1844 if (utf8_len > 1)
1845 all_ascii = false;
1846 i += utf8_len;
1847 }
1848
1849 /* If IDENT contains invalid UTF-8 sequences (which may occur with
1850 attributes putting arbitrary byte sequences in identifiers), or
1851 control characters, we use octal escape sequences for all bytes
1852 outside printable ASCII. */
1853 if (!valid_printable_utf8)
1854 {
1855 char *ret = (char *) identifier_to_locale_alloc (4 * idlen + 1);
1856 char *p = ret;
1857 for (i = 0; i < idlen; i++)
1858 {
1859 if (uid[i] > 0x1F && uid[i] < 0x7F)
1860 *p++ = uid[i];
1861 else
1862 {
1863 sprintf (p, "\\%03o", uid[i]);
1864 p += 4;
1865 }
1866 }
1867 *p = 0;
1868 return ret;
1869 }
1870
1871 /* Otherwise, if it is valid printable ASCII, or printable UTF-8
1872 with the locale character set being UTF-8, IDENT is used. */
1873 if (all_ascii || locale_utf8)
1874 return ident;
1875
1876 /* Otherwise IDENT is converted to the locale character set if
1877 possible. */
1878#if defined ENABLE_NLS && defined HAVE_LANGINFO_CODESET && HAVE_ICONV
1879 if (locale_encoding != NULL)
1880 {
1881 iconv_t cd = iconv_open (locale_encoding, "UTF-8");
1882 bool conversion_ok = true;
1883 char *ret = NULL;
1884 if (cd != (iconv_t) -1)
1885 {
1886 size_t ret_alloc = 4 * idlen + 1;
1887 for (;;)
1888 {
1889 /* Repeat the whole conversion process as needed with
1890 larger buffers so non-reversible transformations can
1891 always be detected. */
1892 ICONV_CONST char *inbuf = CONST_CAST (char *, ident);
1893 char *outbuf;
1894 size_t inbytesleft = idlen;
1895 size_t outbytesleft = ret_alloc - 1;
1896 size_t iconv_ret;
1897
1898 ret = (char *) identifier_to_locale_alloc (ret_alloc);
1899 outbuf = ret;
1900
1901 if (iconv (cd, 0, 0, 0, 0) == (size_t) -1)
1902 {
1903 conversion_ok = false;
1904 break;
1905 }
1906
1907 iconv_ret = iconv (cd, &inbuf, &inbytesleft,
1908 &outbuf, &outbytesleft);
1909 if (iconv_ret == (size_t) -1 || inbytesleft != 0)
1910 {
1911 if (errno == E2BIG)
1912 {
1913 ret_alloc *= 2;
1914 identifier_to_locale_free (ret);
1915 ret = NULL;
1916 continue;
1917 }
1918 else
1919 {
1920 conversion_ok = false;
1921 break;
1922 }
1923 }
1924 else if (iconv_ret != 0)
1925 {
1926 conversion_ok = false;
1927 break;
1928 }
1929 /* Return to initial shift state. */
1930 if (iconv (cd, 0, 0, &outbuf, &outbytesleft) == (size_t) -1)
1931 {
1932 if (errno == E2BIG)
1933 {
1934 ret_alloc *= 2;
1935 identifier_to_locale_free (ret);
1936 ret = NULL;
1937 continue;
1938 }
1939 else
1940 {
1941 conversion_ok = false;
1942 break;
1943 }
1944 }
1945 *outbuf = 0;
1946 break;
1947 }
1948 iconv_close (cd);
1949 if (conversion_ok)
1950 return ret;
1951 }
1952 }
1953#endif
1954
1955 /* Otherwise, convert non-ASCII characters in IDENT to UCNs. */
1956 {
1957 char *ret = (char *) identifier_to_locale_alloc (10 * idlen + 1);
1958 char *p = ret;
1959 for (i = 0; i < idlen;)
1960 {
1961 unsigned int c;
1962 size_t utf8_len = decode_utf8_char (&uid[i], idlen - i, &c);
1963 if (utf8_len == 1)
1964 *p++ = uid[i];
1965 else
1966 {
1967 sprintf (p, "\\U%08x", c);
1968 p += 10;
1969 }
1970 i += utf8_len;
1971 }
1972 *p = 0;
1973 return ret;
1974 }
1975}
1976
1977#if CHECKING_P
1978
1979namespace selftest {
1980
1981/* Smoketest for pretty_printer. */
1982
1983static void
1984test_basic_printing ()
1985{
1986 pretty_printer pp;
1987 pp_string (&pp, "hello");
1988 pp_space (&pp);
1989 pp_string (&pp, "world");
1990
1991 ASSERT_STREQ ("hello world", pp_formatted_text (&pp));
1992}
1993
1994/* Helper function for testing pp_format.
1995 Verify that pp_format (FMT, ...) followed by pp_output_formatted_text
1996 prints EXPECTED, assuming that pp_show_color is SHOW_COLOR. */
1997
1998static void
1999assert_pp_format_va (const location &loc, const char *expected,
2000 bool show_color, const char *fmt, va_list *ap)
2001{
2002 pretty_printer pp;
2003 text_info ti;
2004 rich_location rich_loc (line_table, UNKNOWN_LOCATION);
2005
2006 ti.format_spec = fmt;
2007 ti.args_ptr = ap;
2008 ti.err_no = 0;
2009 ti.x_data = NULL;
2010 ti.m_richloc = &rich_loc;
2011
2012 pp_show_color (&pp) = show_color;
2013 pp_format (&pp, &ti);
2014 pp_output_formatted_text (&pp);
2015 ASSERT_STREQ_AT (loc, expected, pp_formatted_text (&pp));
2016}
2017
2018/* Verify that pp_format (FMT, ...) followed by pp_output_formatted_text
2019 prints EXPECTED, with show_color disabled. */
2020
2021static void
2022assert_pp_format (const location &loc, const char *expected,
2023 const char *fmt, ...)
2024{
2025 va_list ap;
2026
2027 va_start (ap, fmt);
2028 assert_pp_format_va (loc, expected, false, fmt, &ap);
2029 va_end (ap);
2030}
2031
2032/* As above, but with colorization enabled. */
2033
2034static void
2035assert_pp_format_colored (const location &loc, const char *expected,
2036 const char *fmt, ...)
2037{
2038 /* The tests of colorization assume the default color scheme.
2039 If GCC_COLORS is set, then the colors have potentially been
2040 overridden; skip the test. */
2041 if (getenv ("GCC_COLORS"))
2042 return;
2043
2044 va_list ap;
2045
2046 va_start (ap, fmt);
2047 assert_pp_format_va (loc, expected, true, fmt, &ap);
2048 va_end (ap);
2049}
2050
2051/* Helper function for calling testing pp_format,
2052 by calling assert_pp_format with various numbers of arguments.
2053 These exist mostly to avoid having to write SELFTEST_LOCATION
2054 throughout test_pp_format. */
2055
2056#define ASSERT_PP_FORMAT_1(EXPECTED, FMT, ARG1) \
2057 SELFTEST_BEGIN_STMT \
2058 assert_pp_format ((SELFTEST_LOCATION), (EXPECTED), (FMT), \
2059 (ARG1)); \
2060 SELFTEST_END_STMT
2061
2062#define ASSERT_PP_FORMAT_2(EXPECTED, FMT, ARG1, ARG2) \
2063 SELFTEST_BEGIN_STMT \
2064 assert_pp_format ((SELFTEST_LOCATION), (EXPECTED), (FMT), \
2065 (ARG1), (ARG2)); \
2066 SELFTEST_END_STMT
2067
2068#define ASSERT_PP_FORMAT_3(EXPECTED, FMT, ARG1, ARG2, ARG3) \
2069 SELFTEST_BEGIN_STMT \
2070 assert_pp_format ((SELFTEST_LOCATION), (EXPECTED), (FMT), \
2071 (ARG1), (ARG2), (ARG3)); \
2072 SELFTEST_END_STMT
2073
2074/* Verify that pp_format works, for various format codes. */
2075
2076static void
2077test_pp_format ()
2078{
2079 /* Avoid introducing locale-specific differences in the results
2080 by hardcoding open_quote and close_quote. */
2081 const char *old_open_quote = open_quote;
2082 const char *old_close_quote = close_quote;
2083 open_quote = "`";
2084 close_quote = "'";
2085
2086 /* Verify that plain text is passed through unchanged. */
2087 assert_pp_format (SELFTEST_LOCATION, "unformatted", "unformatted");
2088
2089 /* Verify various individual format codes, in the order listed in the
2090 comment for pp_format above. For each code, we append a second
2091 argument with a known bit pattern (0x12345678), to ensure that we
2092 are consuming arguments correctly. */
2093 ASSERT_PP_FORMAT_2 ("-27 12345678", "%d %x", -27, 0x12345678);
2094 ASSERT_PP_FORMAT_2 ("-5 12345678", "%i %x", -5, 0x12345678);
2095 ASSERT_PP_FORMAT_2 ("10 12345678", "%u %x", 10, 0x12345678);
2096 ASSERT_PP_FORMAT_2 ("17 12345678", "%o %x", 15, 0x12345678);
2097 ASSERT_PP_FORMAT_2 ("cafebabe 12345678", "%x %x", 0xcafebabe, 0x12345678);
2098 ASSERT_PP_FORMAT_2 ("-27 12345678", "%ld %x", (long)-27, 0x12345678);
2099 ASSERT_PP_FORMAT_2 ("-5 12345678", "%li %x", (long)-5, 0x12345678);
2100 ASSERT_PP_FORMAT_2 ("10 12345678", "%lu %x", (long)10, 0x12345678);
2101 ASSERT_PP_FORMAT_2 ("17 12345678", "%lo %x", (long)15, 0x12345678);
2102 ASSERT_PP_FORMAT_2 ("cafebabe 12345678", "%lx %x", (long)0xcafebabe,
2103 0x12345678);
2104 ASSERT_PP_FORMAT_2 ("-27 12345678", "%lld %x", (long long)-27, 0x12345678);
2105 ASSERT_PP_FORMAT_2 ("-5 12345678", "%lli %x", (long long)-5, 0x12345678);
2106 ASSERT_PP_FORMAT_2 ("10 12345678", "%llu %x", (long long)10, 0x12345678);
2107 ASSERT_PP_FORMAT_2 ("17 12345678", "%llo %x", (long long)15, 0x12345678);
2108 ASSERT_PP_FORMAT_2 ("cafebabe 12345678", "%llx %x", (long long)0xcafebabe,
2109 0x12345678);
2110 ASSERT_PP_FORMAT_2 ("-27 12345678", "%wd %x", (HOST_WIDE_INT)-27, 0x12345678);
2111 ASSERT_PP_FORMAT_2 ("-5 12345678", "%wi %x", (HOST_WIDE_INT)-5, 0x12345678);
2112 ASSERT_PP_FORMAT_2 ("10 12345678", "%wu %x", (unsigned HOST_WIDE_INT)10,
2113 0x12345678);
2114 ASSERT_PP_FORMAT_2 ("17 12345678", "%wo %x", (HOST_WIDE_INT)15, 0x12345678);
2115 ASSERT_PP_FORMAT_2 ("0xcafebabe 12345678", "%wx %x", (HOST_WIDE_INT)0xcafebabe,
2116 0x12345678);
2117 ASSERT_PP_FORMAT_2 ("A 12345678", "%c %x", 'A', 0x12345678);
2118 ASSERT_PP_FORMAT_2 ("hello world 12345678", "%s %x", "hello world",
2119 0x12345678);
2120
2121 /* Not nul-terminated. */
2122 char arr[5] = { '1', '2', '3', '4', '5' };
2123 ASSERT_PP_FORMAT_3 ("123 12345678", "%.*s %x", 3, arr, 0x12345678);
2124 ASSERT_PP_FORMAT_3 ("1234 12345678", "%.*s %x", -1, "1234", 0x12345678);
2125 ASSERT_PP_FORMAT_3 ("12345 12345678", "%.*s %x", 7, "12345", 0x12345678);
2126
2127 /* We can't test for %p; the pointer is printed in an implementation-defined
2128 manner. */
2129 ASSERT_PP_FORMAT_2 ("normal colored normal 12345678",
2130 "normal %rcolored%R normal %x",
2131 "error", 0x12345678);
2132 assert_pp_format_colored
2133 (SELFTEST_LOCATION,
2134 "normal \33[01;31m\33[Kcolored\33[m\33[K normal 12345678",
2135 "normal %rcolored%R normal %x", "error", 0x12345678);
2136 /* TODO:
2137 %m: strerror(text->err_no) - does not consume a value from args_ptr. */
2138 ASSERT_PP_FORMAT_1 ("% 12345678", "%% %x", 0x12345678);
2139 ASSERT_PP_FORMAT_1 ("` 12345678", "%< %x", 0x12345678);
2140 ASSERT_PP_FORMAT_1 ("' 12345678", "%> %x", 0x12345678);
2141 ASSERT_PP_FORMAT_1 ("' 12345678", "%' %x", 0x12345678);
2142 ASSERT_PP_FORMAT_3 ("abc 12345678", "%.*s %x", 3, "abcdef", 0x12345678);
2143 ASSERT_PP_FORMAT_2 ("abc 12345678", "%.3s %x", "abcdef", 0x12345678);
2144
2145 /* Verify flag 'q'. */
2146 ASSERT_PP_FORMAT_2 ("`foo' 12345678", "%qs %x", "foo", 0x12345678);
2147 assert_pp_format_colored (SELFTEST_LOCATION,
2148 "`\33[01m\33[Kfoo\33[m\33[K' 12345678", "%qs %x",
2149 "foo", 0x12345678);
2150
2151 /* Verify %Z. */
2152 int v[] = { 1, 2, 3 };
2153 ASSERT_PP_FORMAT_3 ("1, 2, 3 12345678", "%Z %x", v, 3, 0x12345678);
2154
2155 int v2[] = { 0 };
2156 ASSERT_PP_FORMAT_3 ("0 12345678", "%Z %x", v2, 1, 0x12345678);
2157
2158 /* Verify that combinations work, along with unformatted text. */
2159 assert_pp_format (SELFTEST_LOCATION,
2160 "the quick brown fox jumps over the lazy dog",
2161 "the %s %s %s jumps over the %s %s",
2162 "quick", "brown", "fox", "lazy", "dog");
2163 assert_pp_format (SELFTEST_LOCATION, "item 3 of 7", "item %i of %i", 3, 7);
2164 assert_pp_format (SELFTEST_LOCATION, "problem with `bar' at line 10",
2165 "problem with %qs at line %i", "bar", 10);
2166
2167 /* Restore old values of open_quote and close_quote. */
2168 open_quote = old_open_quote;
2169 close_quote = old_close_quote;
2170}
2171
2172/* Run all of the selftests within this file. */
2173
2174void
2175pretty_print_c_tests ()
2176{
2177 test_basic_printing ();
2178 test_pp_format ();
2179}
2180
2181} // namespace selftest
2182
2183#endif /* CHECKING_P */
2184