[Ada] Missing range check on assignment to bit-packed array
[official-gcc.git] / gcc / pretty-print.c
blob6948971cecb2338f3ca6cf1c3532e5a7927d66f5
1 /* Various declarations for language-independent pretty-print subroutines.
2 Copyright (C) 2003-2019 Free Software Foundation, Inc.
3 Contributed by Gabriel Dos Reis <gdr@integrable-solutions.net>
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
10 version.
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
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"
29 #if HAVE_ICONV
30 #include <iconv.h>
31 #endif
33 #ifdef __MINGW32__
35 /* Replacement for fputs() that handles ANSI escape codes on Windows NT.
36 Contributed by: Liu Hao (lh_mouse at 126 dot com)
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. */
41 #include <io.h>
42 #define WIN32_LEAN_AND_MEAN 1
43 #include <windows.h>
45 /* Write all bytes in [s,s+n) into the specified stream.
46 Errors are ignored. */
47 static void
48 write_all (HANDLE h, const char *s, size_t n)
50 size_t rem = n;
51 DWORD step;
53 while (rem != 0)
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;
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. */
74 static int
75 find_esc_head (int *prefix_len, const char **head, const char *str)
77 int c;
78 const char *r = str;
79 int escaped = 0;
81 for (;;)
83 c = (unsigned char) *r;
84 if (c == 0)
86 /* Not found. */
87 return 0;
89 if (escaped && 0x40 <= c && c <= 0x5F)
91 /* Found (case 1). */
92 *prefix_len = 2;
93 *head = r + 1;
94 return c;
96 if (0x80 <= c && c <= 0x9F)
98 /* Found (case 2). */
99 *prefix_len = 1;
100 *head = r + 1;
101 return c - 0x40;
103 ++r;
104 escaped = c == 0x1B;
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. */
112 static int
113 find_esc_terminator (const char **term, const char *str)
115 int c;
116 const char *r = str;
118 for (;;)
120 c = (unsigned char) *r;
121 if (c == 0)
123 /* Not found. */
124 return 0;
126 if (0x40 <= c && c <= 0x7E)
128 /* Found. */
129 *term = r;
130 return c;
132 ++r;
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. */
139 static void
140 eat_esc_sequence (HANDLE h, int esc_code,
141 const char *esc_head, const char *esc_term)
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;
156 switch (MAKEWORD (esc_code, *esc_term))
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
165 n1 = strtol (esc_head, &eptr, 10);
166 if (eptr != esc_term)
167 break;
170 if (GetConsoleScreenBufferInfo (h, &sb))
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);
180 break;
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
189 n1 = strtol (esc_head, &eptr, 10);
190 if (eptr != esc_term)
191 break;
194 if (GetConsoleScreenBufferInfo (h, &sb))
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);
204 break;
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
213 n1 = strtol (esc_head, &eptr, 10);
214 if (eptr != esc_term)
215 break;
218 if (GetConsoleScreenBufferInfo (h, &sb))
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);
228 break;
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
237 n1 = strtol (esc_head, &eptr, 10);
238 if (eptr != esc_term)
239 break;
242 if (GetConsoleScreenBufferInfo (h, &sb))
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);
252 break;
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
261 n1 = strtol (esc_head, &eptr, 10);
262 if (eptr != esc_term)
263 break;
266 if (GetConsoleScreenBufferInfo (h, &sb))
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);
277 break;
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
286 n1 = strtol (esc_head, &eptr, 10);
287 if (eptr != esc_term)
288 break;
291 if (GetConsoleScreenBufferInfo (h, &sb))
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);
302 break;
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
311 n1 = strtol (esc_head, &eptr, 10);
312 if (eptr != esc_term)
313 break;
316 if (GetConsoleScreenBufferInfo (h, &sb))
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);
329 break;
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)
339 /* Both parameters are omitted and set to 1 by default. */
340 n1 = 1;
341 n2 = 1;
343 else if (!(delim = (char *) memchr (esc_head, ';',
344 esc_term - esc_head)))
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;
353 else
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;
365 if (GetConsoleScreenBufferInfo (h, &sb))
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);
393 break;
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
404 n1 = strtol (esc_head, &eptr, 10);
405 if (eptr != esc_term)
406 break;
409 if (GetConsoleScreenBufferInfo (h, &sb))
411 /* The cursor is not necessarily in the console window, which
412 makes the behavior of this code harder to define. */
413 switch (n1)
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;
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);
451 break;
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
462 n1 = strtol (esc_head, &eptr, 10);
463 if (eptr != esc_term)
464 break;
467 if (GetConsoleScreenBufferInfo (h, &sb))
469 switch (n1)
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;
489 FillConsoleOutputCharacterW (h, L' ', cnt, cr, &step);
490 FillConsoleOutputAttribute (h, sb.wAttributes, cnt, cr, &step);
492 break;
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)
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;
507 param = esc_head;
510 /* Parse a parameter. */
511 n1 = strtol (param, &eptr, 10);
512 if (*eptr != ';' && eptr != esc_term)
513 goto sgr_set_it;
515 switch (n1)
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;
631 /* Prepare the next parameter. */
632 param = eptr + 1;
634 while (param != esc_term);
636 sgr_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))
641 attrib_add |= sb.wAttributes & ~attrib_rm;
643 if (attrib_add & COMMON_LVB_REVERSE_VIDEO)
645 /* COMMON_LVB_REVERSE_VIDEO is only effective for DBCS.
646 * Swap foreground and background colors by hand.
648 attrib_add = (attrib_add & 0xFF00)
649 | ((attrib_add & 0x00F0) >> 4)
650 | ((attrib_add & 0x000F) << 4);
651 attrib_add &= ~COMMON_LVB_REVERSE_VIDEO;
653 SetConsoleTextAttribute (h, attrib_add);
654 break;
659 mingw_ansi_fputs (const char *str, FILE *fp)
661 const char *read = str;
662 HANDLE h;
663 DWORD mode;
664 int esc_code, prefix_len;
665 const char *esc_head, *esc_term;
667 h = (HANDLE) _get_osfhandle (_fileno (fp));
668 if (h == INVALID_HANDLE_VALUE)
669 return EOF;
671 /* Don't mess up stdio functions with Windows APIs. */
672 fflush (fp);
674 if (GetConsoleMode (h, &mode))
675 /* If it is a console, translate ANSI escape codes as needed. */
676 for (;;)
678 if ((esc_code = find_esc_head (&prefix_len, &esc_head, read)) == 0)
680 /* Write all remaining characters, then exit. */
681 write_all (h, read, strlen (read));
682 break;
684 if (find_esc_terminator (&esc_term, esc_head) == 0)
685 /* Ignore incomplete escape sequences at the moment.
686 FIXME: The escape state shall be cached for further calls
687 to this function. */
688 break;
689 write_all (h, read, esc_head - prefix_len - read);
690 eat_esc_sequence (h, esc_code, esc_head, esc_term);
691 read = esc_term + 1;
693 else
694 /* If it is not a console, write everything as-is. */
695 write_all (h, read, strlen (read));
697 return 1;
700 #endif /* __MINGW32__ */
702 static void pp_quoted_string (pretty_printer *, const char *, size_t = -1);
704 /* Overwrite the given location/range within this text_info's rich_location.
705 For use e.g. when implementing "+" in client format decoders. */
707 void
708 text_info::set_location (unsigned int idx, location_t loc,
709 enum range_display_kind range_display_kind)
711 gcc_checking_assert (m_richloc);
712 m_richloc->set_range (idx, loc, range_display_kind);
715 location_t
716 text_info::get_location (unsigned int index_of_location) const
718 gcc_checking_assert (m_richloc);
720 if (index_of_location == 0)
721 return m_richloc->get_loc ();
722 else
723 return UNKNOWN_LOCATION;
726 // Default construct an output buffer.
728 output_buffer::output_buffer ()
729 : formatted_obstack (),
730 chunk_obstack (),
731 obstack (&formatted_obstack),
732 cur_chunk_array (),
733 stream (stderr),
734 line_length (),
735 digit_buffer (),
736 flush_p (true)
738 obstack_init (&formatted_obstack);
739 obstack_init (&chunk_obstack);
742 // Release resources owned by an output buffer at the end of lifetime.
744 output_buffer::~output_buffer ()
746 obstack_free (&chunk_obstack, NULL);
747 obstack_free (&formatted_obstack, NULL);
751 /* Format an integer given by va_arg (ARG, type-specifier T) where
752 type-specifier is a precision modifier as indicated by PREC. F is
753 a string used to construct the appropriate format-specifier. */
754 #define pp_integer_with_precision(PP, ARG, PREC, T, F) \
755 do \
756 switch (PREC) \
758 case 0: \
759 pp_scalar (PP, "%" F, va_arg (ARG, T)); \
760 break; \
762 case 1: \
763 pp_scalar (PP, "%l" F, va_arg (ARG, long T)); \
764 break; \
766 case 2: \
767 pp_scalar (PP, "%" HOST_LONG_LONG_FORMAT F, va_arg (ARG, long long T)); \
768 break; \
770 default: \
771 break; \
773 while (0)
776 /* Subroutine of pp_set_maximum_length. Set up PRETTY-PRINTER's
777 internal maximum characters per line. */
778 static void
779 pp_set_real_maximum_length (pretty_printer *pp)
781 /* If we're told not to wrap lines then do the obvious thing. In case
782 we'll emit prefix only once per message, it is appropriate
783 not to increase unnecessarily the line-length cut-off. */
784 if (!pp_is_wrapping_line (pp)
785 || pp_prefixing_rule (pp) == DIAGNOSTICS_SHOW_PREFIX_ONCE
786 || pp_prefixing_rule (pp) == DIAGNOSTICS_SHOW_PREFIX_NEVER)
787 pp->maximum_length = pp_line_cutoff (pp);
788 else
790 int prefix_length = pp->prefix ? strlen (pp->prefix) : 0;
791 /* If the prefix is ridiculously too long, output at least
792 32 characters. */
793 if (pp_line_cutoff (pp) - prefix_length < 32)
794 pp->maximum_length = pp_line_cutoff (pp) + 32;
795 else
796 pp->maximum_length = pp_line_cutoff (pp);
800 /* Clear PRETTY-PRINTER's output state. */
801 static inline void
802 pp_clear_state (pretty_printer *pp)
804 pp->emitted_prefix = false;
805 pp_indentation (pp) = 0;
808 /* Print X to PP in decimal. */
809 template<unsigned int N, typename T>
810 void
811 pp_wide_integer (pretty_printer *pp, const poly_int_pod<N, T> &x)
813 if (x.is_constant ())
814 pp_wide_integer (pp, x.coeffs[0]);
815 else
817 pp_left_bracket (pp);
818 for (unsigned int i = 0; i < N; ++i)
820 if (i != 0)
821 pp_comma (pp);
822 pp_wide_integer (pp, x.coeffs[i]);
824 pp_right_bracket (pp);
828 template void pp_wide_integer (pretty_printer *, const poly_uint16_pod &);
829 template void pp_wide_integer (pretty_printer *, const poly_int64_pod &);
830 template void pp_wide_integer (pretty_printer *, const poly_uint64_pod &);
832 /* Flush the formatted text of PRETTY-PRINTER onto the attached stream. */
833 void
834 pp_write_text_to_stream (pretty_printer *pp)
836 const char *text = pp_formatted_text (pp);
837 #ifdef __MINGW32__
838 mingw_ansi_fputs (text, pp_buffer (pp)->stream);
839 #else
840 fputs (text, pp_buffer (pp)->stream);
841 #endif
842 pp_clear_output_area (pp);
845 /* As pp_write_text_to_stream, but for GraphViz label output.
847 Flush the formatted text of pretty-printer PP onto the attached stream.
848 Replace characters in PPF that have special meaning in a GraphViz .dot
849 file.
851 This routine is not very fast, but it doesn't have to be as this is only
852 be used by routines dumping intermediate representations in graph form. */
854 void
855 pp_write_text_as_dot_label_to_stream (pretty_printer *pp, bool for_record)
857 const char *text = pp_formatted_text (pp);
858 const char *p = text;
859 FILE *fp = pp_buffer (pp)->stream;
861 for (;*p; p++)
863 bool escape_char;
864 switch (*p)
866 /* Print newlines as a left-aligned newline. */
867 case '\n':
868 fputs ("\\l", fp);
869 escape_char = true;
870 break;
872 /* The following characters are only special for record-shape nodes. */
873 case '|':
874 case '{':
875 case '}':
876 case '<':
877 case '>':
878 case ' ':
879 escape_char = for_record;
880 break;
882 /* The following characters always have to be escaped
883 for use in labels. */
884 case '\\':
885 /* There is a bug in some (f.i. 2.36.0) versions of graphiz
886 ( http://www.graphviz.org/mantisbt/view.php?id=2524 ) related to
887 backslash as last char in label. Let's avoid triggering it. */
888 gcc_assert (*(p + 1) != '\0');
889 /* Fall through. */
890 case '"':
891 escape_char = true;
892 break;
894 default:
895 escape_char = false;
896 break;
899 if (escape_char)
900 fputc ('\\', fp);
902 fputc (*p, fp);
905 pp_clear_output_area (pp);
908 /* Wrap a text delimited by START and END into PRETTY-PRINTER. */
909 static void
910 pp_wrap_text (pretty_printer *pp, const char *start, const char *end)
912 bool wrapping_line = pp_is_wrapping_line (pp);
914 while (start != end)
916 /* Dump anything bordered by whitespaces. */
918 const char *p = start;
919 while (p != end && !ISBLANK (*p) && *p != '\n')
920 ++p;
921 if (wrapping_line
922 && p - start >= pp_remaining_character_count_for_line (pp))
923 pp_newline (pp);
924 pp_append_text (pp, start, p);
925 start = p;
928 if (start != end && ISBLANK (*start))
930 pp_space (pp);
931 ++start;
933 if (start != end && *start == '\n')
935 pp_newline (pp);
936 ++start;
941 /* Same as pp_wrap_text but wrap text only when in line-wrapping mode. */
942 static inline void
943 pp_maybe_wrap_text (pretty_printer *pp, const char *start, const char *end)
945 if (pp_is_wrapping_line (pp))
946 pp_wrap_text (pp, start, end);
947 else
948 pp_append_text (pp, start, end);
951 /* Append to the output area of PRETTY-PRINTER a string specified by its
952 STARTing character and LENGTH. */
953 static inline void
954 pp_append_r (pretty_printer *pp, const char *start, int length)
956 output_buffer_append_r (pp_buffer (pp), start, length);
959 /* Insert enough spaces into the output area of PRETTY-PRINTER to bring
960 the column position to the current indentation level, assuming that a
961 newline has just been written to the buffer. */
962 void
963 pp_indent (pretty_printer *pp)
965 int n = pp_indentation (pp);
966 int i;
968 for (i = 0; i < n; ++i)
969 pp_space (pp);
972 /* The following format specifiers are recognized as being client independent:
973 %d, %i: (signed) integer in base ten.
974 %u: unsigned integer in base ten.
975 %o: unsigned integer in base eight.
976 %x: unsigned integer in base sixteen.
977 %ld, %li, %lo, %lu, %lx: long versions of the above.
978 %lld, %lli, %llo, %llu, %llx: long long versions.
979 %wd, %wi, %wo, %wu, %wx: HOST_WIDE_INT versions.
980 %f: double
981 %c: character.
982 %s: string.
983 %p: pointer (printed in a host-dependent manner).
984 %r: if pp_show_color(pp), switch to color identified by const char *.
985 %R: if pp_show_color(pp), reset color.
986 %m: strerror(text->err_no) - does not consume a value from args_ptr.
987 %%: '%'.
988 %<: opening quote.
989 %>: closing quote.
990 %': apostrophe (should only be used in untranslated messages;
991 translations should use appropriate punctuation directly).
992 %.*s: a substring the length of which is specified by an argument
993 integer.
994 %Ns: likewise, but length specified as constant in the format string.
995 Flag 'q': quote formatted text (must come immediately after '%').
996 %Z: Requires two arguments - array of int, and len. Prints elements
997 of the array.
999 Arguments can be used sequentially, or through %N$ resp. *N$
1000 notation Nth argument after the format string. If %N$ / *N$
1001 notation is used, it must be used for all arguments, except %m, %%,
1002 %<, %> and %', which may not have a number, as they do not consume
1003 an argument. When %M$.*N$s is used, M must be N + 1. (This may
1004 also be written %M$.*s, provided N is not otherwise used.) The
1005 format string must have conversion specifiers with argument numbers
1006 1 up to highest argument; each argument may only be used once.
1007 A format string can have at most 30 arguments. */
1009 /* Formatting phases 1 and 2: render TEXT->format_spec plus
1010 TEXT->args_ptr into a series of chunks in pp_buffer (PP)->args[].
1011 Phase 3 is in pp_output_formatted_text. */
1013 void
1014 pp_format (pretty_printer *pp, text_info *text)
1016 output_buffer *buffer = pp_buffer (pp);
1017 const char *p;
1018 const char **args;
1019 struct chunk_info *new_chunk_array;
1021 unsigned int curarg = 0, chunk = 0, argno;
1022 pp_wrapping_mode_t old_wrapping_mode;
1023 bool any_unnumbered = false, any_numbered = false;
1024 const char **formatters[PP_NL_ARGMAX];
1026 /* Allocate a new chunk structure. */
1027 new_chunk_array = XOBNEW (&buffer->chunk_obstack, struct chunk_info);
1028 new_chunk_array->prev = buffer->cur_chunk_array;
1029 buffer->cur_chunk_array = new_chunk_array;
1030 args = new_chunk_array->args;
1032 /* Formatting phase 1: split up TEXT->format_spec into chunks in
1033 pp_buffer (PP)->args[]. Even-numbered chunks are to be output
1034 verbatim, odd-numbered chunks are format specifiers.
1035 %m, %%, %<, %>, and %' are replaced with the appropriate text at
1036 this point. */
1038 memset (formatters, 0, sizeof formatters);
1040 for (p = text->format_spec; *p; )
1042 while (*p != '\0' && *p != '%')
1044 obstack_1grow (&buffer->chunk_obstack, *p);
1045 p++;
1048 if (*p == '\0')
1049 break;
1051 switch (*++p)
1053 case '\0':
1054 gcc_unreachable ();
1056 case '%':
1057 obstack_1grow (&buffer->chunk_obstack, '%');
1058 p++;
1059 continue;
1061 case '<':
1063 obstack_grow (&buffer->chunk_obstack,
1064 open_quote, strlen (open_quote));
1065 const char *colorstr
1066 = colorize_start (pp_show_color (pp), "quote");
1067 obstack_grow (&buffer->chunk_obstack, colorstr, strlen (colorstr));
1068 p++;
1069 continue;
1072 case '>':
1074 const char *colorstr = colorize_stop (pp_show_color (pp));
1075 obstack_grow (&buffer->chunk_obstack, colorstr, strlen (colorstr));
1077 /* FALLTHRU */
1078 case '\'':
1079 obstack_grow (&buffer->chunk_obstack,
1080 close_quote, strlen (close_quote));
1081 p++;
1082 continue;
1084 case 'R':
1086 const char *colorstr = colorize_stop (pp_show_color (pp));
1087 obstack_grow (&buffer->chunk_obstack, colorstr,
1088 strlen (colorstr));
1089 p++;
1090 continue;
1093 case 'm':
1095 const char *errstr = xstrerror (text->err_no);
1096 obstack_grow (&buffer->chunk_obstack, errstr, strlen (errstr));
1098 p++;
1099 continue;
1101 default:
1102 /* Handled in phase 2. Terminate the plain chunk here. */
1103 obstack_1grow (&buffer->chunk_obstack, '\0');
1104 gcc_assert (chunk < PP_NL_ARGMAX * 2);
1105 args[chunk++] = XOBFINISH (&buffer->chunk_obstack, const char *);
1106 break;
1109 if (ISDIGIT (*p))
1111 char *end;
1112 argno = strtoul (p, &end, 10) - 1;
1113 p = end;
1114 gcc_assert (*p == '$');
1115 p++;
1117 any_numbered = true;
1118 gcc_assert (!any_unnumbered);
1120 else
1122 argno = curarg++;
1123 any_unnumbered = true;
1124 gcc_assert (!any_numbered);
1126 gcc_assert (argno < PP_NL_ARGMAX);
1127 gcc_assert (!formatters[argno]);
1128 formatters[argno] = &args[chunk];
1131 obstack_1grow (&buffer->chunk_obstack, *p);
1132 p++;
1134 while (strchr ("qwl+#", p[-1]));
1136 if (p[-1] == '.')
1138 /* We handle '%.Ns' and '%.*s' or '%M$.*N$s'
1139 (where M == N + 1). */
1140 if (ISDIGIT (*p))
1144 obstack_1grow (&buffer->chunk_obstack, *p);
1145 p++;
1147 while (ISDIGIT (p[-1]));
1148 gcc_assert (p[-1] == 's');
1150 else
1152 gcc_assert (*p == '*');
1153 obstack_1grow (&buffer->chunk_obstack, '*');
1154 p++;
1156 if (ISDIGIT (*p))
1158 char *end;
1159 unsigned int argno2 = strtoul (p, &end, 10) - 1;
1160 p = end;
1161 gcc_assert (argno2 == argno - 1);
1162 gcc_assert (!any_unnumbered);
1163 gcc_assert (*p == '$');
1165 p++;
1166 formatters[argno2] = formatters[argno];
1168 else
1170 gcc_assert (!any_numbered);
1171 formatters[argno+1] = formatters[argno];
1172 curarg++;
1174 gcc_assert (*p == 's');
1175 obstack_1grow (&buffer->chunk_obstack, 's');
1176 p++;
1179 if (*p == '\0')
1180 break;
1182 obstack_1grow (&buffer->chunk_obstack, '\0');
1183 gcc_assert (chunk < PP_NL_ARGMAX * 2);
1184 args[chunk++] = XOBFINISH (&buffer->chunk_obstack, const char *);
1187 obstack_1grow (&buffer->chunk_obstack, '\0');
1188 gcc_assert (chunk < PP_NL_ARGMAX * 2);
1189 args[chunk++] = XOBFINISH (&buffer->chunk_obstack, const char *);
1190 args[chunk] = 0;
1192 /* Set output to the argument obstack, and switch line-wrapping and
1193 prefixing off. */
1194 buffer->obstack = &buffer->chunk_obstack;
1195 old_wrapping_mode = pp_set_verbatim_wrapping (pp);
1197 /* Second phase. Replace each formatter with the formatted text it
1198 corresponds to. */
1200 for (argno = 0; formatters[argno]; argno++)
1202 int precision = 0;
1203 bool wide = false;
1204 bool plus = false;
1205 bool hash = false;
1206 bool quote = false;
1208 /* We do not attempt to enforce any ordering on the modifier
1209 characters. */
1211 for (p = *formatters[argno];; p++)
1213 switch (*p)
1215 case 'q':
1216 gcc_assert (!quote);
1217 quote = true;
1218 continue;
1220 case '+':
1221 gcc_assert (!plus);
1222 plus = true;
1223 continue;
1225 case '#':
1226 gcc_assert (!hash);
1227 hash = true;
1228 continue;
1230 case 'w':
1231 gcc_assert (!wide);
1232 wide = true;
1233 continue;
1235 case 'l':
1236 /* We don't support precision beyond that of "long long". */
1237 gcc_assert (precision < 2);
1238 precision++;
1239 continue;
1241 break;
1244 gcc_assert (!wide || precision == 0);
1246 if (quote)
1247 pp_begin_quote (pp, pp_show_color (pp));
1249 switch (*p)
1251 case 'r':
1252 pp_string (pp, colorize_start (pp_show_color (pp),
1253 va_arg (*text->args_ptr,
1254 const char *)));
1255 break;
1257 case 'c':
1259 /* When quoting, print alphanumeric, punctuation, and the space
1260 character unchanged, and all others in hexadecimal with the
1261 "\x" prefix. Otherwise print them all unchanged. */
1262 int chr = va_arg (*text->args_ptr, int);
1263 if (ISPRINT (chr) || !quote)
1264 pp_character (pp, chr);
1265 else
1267 const char str [2] = { chr, '\0' };
1268 pp_quoted_string (pp, str, 1);
1270 break;
1273 case 'd':
1274 case 'i':
1275 if (wide)
1276 pp_wide_integer (pp, va_arg (*text->args_ptr, HOST_WIDE_INT));
1277 else
1278 pp_integer_with_precision
1279 (pp, *text->args_ptr, precision, int, "d");
1280 break;
1282 case 'o':
1283 if (wide)
1284 pp_scalar (pp, "%" HOST_WIDE_INT_PRINT "o",
1285 va_arg (*text->args_ptr, unsigned HOST_WIDE_INT));
1286 else
1287 pp_integer_with_precision
1288 (pp, *text->args_ptr, precision, unsigned, "o");
1289 break;
1291 case 's':
1292 if (quote)
1293 pp_quoted_string (pp, va_arg (*text->args_ptr, const char *));
1294 else
1295 pp_string (pp, va_arg (*text->args_ptr, const char *));
1296 break;
1298 case 'p':
1299 pp_pointer (pp, va_arg (*text->args_ptr, void *));
1300 break;
1302 case 'u':
1303 if (wide)
1304 pp_scalar (pp, HOST_WIDE_INT_PRINT_UNSIGNED,
1305 va_arg (*text->args_ptr, unsigned HOST_WIDE_INT));
1306 else
1307 pp_integer_with_precision
1308 (pp, *text->args_ptr, precision, unsigned, "u");
1309 break;
1311 case 'f':
1312 pp_double (pp, va_arg (*text->args_ptr, double));
1313 break;
1315 case 'Z':
1317 int *v = va_arg (*text->args_ptr, int *);
1318 unsigned len = va_arg (*text->args_ptr, unsigned);
1320 for (unsigned i = 0; i < len; ++i)
1322 pp_scalar (pp, "%i", v[i]);
1323 if (i < len - 1)
1325 pp_comma (pp);
1326 pp_space (pp);
1329 break;
1332 case 'x':
1333 if (wide)
1334 pp_scalar (pp, HOST_WIDE_INT_PRINT_HEX,
1335 va_arg (*text->args_ptr, unsigned HOST_WIDE_INT));
1336 else
1337 pp_integer_with_precision
1338 (pp, *text->args_ptr, precision, unsigned, "x");
1339 break;
1341 case '.':
1343 int n;
1344 const char *s;
1346 /* We handle '%.Ns' and '%.*s' or '%M$.*N$s'
1347 (where M == N + 1). The format string should be verified
1348 already from the first phase. */
1349 p++;
1350 if (ISDIGIT (*p))
1352 char *end;
1353 n = strtoul (p, &end, 10);
1354 p = end;
1355 gcc_assert (*p == 's');
1357 else
1359 gcc_assert (*p == '*');
1360 p++;
1361 gcc_assert (*p == 's');
1362 n = va_arg (*text->args_ptr, int);
1364 /* This consumes a second entry in the formatters array. */
1365 gcc_assert (formatters[argno] == formatters[argno+1]);
1366 argno++;
1369 s = va_arg (*text->args_ptr, const char *);
1371 /* Append the lesser of precision and strlen (s) characters
1372 from the array (which need not be a nul-terminated string).
1373 Negative precision is treated as if it were omitted. */
1374 size_t len = n < 0 ? strlen (s) : strnlen (s, n);
1376 pp_append_text (pp, s, s + len);
1378 break;
1380 default:
1382 bool ok;
1384 /* Call the format decoder.
1385 Pass the address of "quote" so that format decoders can
1386 potentially disable printing of the closing quote
1387 (e.g. when printing "'TYPEDEF' aka 'TYPE'" in the C family
1388 of frontends). */
1389 gcc_assert (pp_format_decoder (pp));
1390 ok = pp_format_decoder (pp) (pp, text, p,
1391 precision, wide, plus, hash, &quote,
1392 formatters[argno]);
1393 gcc_assert (ok);
1397 if (quote)
1398 pp_end_quote (pp, pp_show_color (pp));
1400 obstack_1grow (&buffer->chunk_obstack, '\0');
1401 *formatters[argno] = XOBFINISH (&buffer->chunk_obstack, const char *);
1404 if (CHECKING_P)
1405 for (; argno < PP_NL_ARGMAX; argno++)
1406 gcc_assert (!formatters[argno]);
1408 /* If the client supplied a postprocessing object, call its "handle"
1409 hook here. */
1410 if (pp->m_format_postprocessor)
1411 pp->m_format_postprocessor->handle (pp);
1413 /* Revert to normal obstack and wrapping mode. */
1414 buffer->obstack = &buffer->formatted_obstack;
1415 buffer->line_length = 0;
1416 pp_wrapping_mode (pp) = old_wrapping_mode;
1417 pp_clear_state (pp);
1420 /* Format of a message pointed to by TEXT. */
1421 void
1422 pp_output_formatted_text (pretty_printer *pp)
1424 unsigned int chunk;
1425 output_buffer *buffer = pp_buffer (pp);
1426 struct chunk_info *chunk_array = buffer->cur_chunk_array;
1427 const char **args = chunk_array->args;
1429 gcc_assert (buffer->obstack == &buffer->formatted_obstack);
1430 gcc_assert (buffer->line_length == 0);
1432 /* This is a third phase, first 2 phases done in pp_format_args.
1433 Now we actually print it. */
1434 for (chunk = 0; args[chunk]; chunk++)
1435 pp_string (pp, args[chunk]);
1437 /* Deallocate the chunk structure and everything after it (i.e. the
1438 associated series of formatted strings). */
1439 buffer->cur_chunk_array = chunk_array->prev;
1440 obstack_free (&buffer->chunk_obstack, chunk_array);
1443 /* Helper subroutine of output_verbatim and verbatim. Do the appropriate
1444 settings needed by BUFFER for a verbatim formatting. */
1445 void
1446 pp_format_verbatim (pretty_printer *pp, text_info *text)
1448 /* Set verbatim mode. */
1449 pp_wrapping_mode_t oldmode = pp_set_verbatim_wrapping (pp);
1451 /* Do the actual formatting. */
1452 pp_format (pp, text);
1453 pp_output_formatted_text (pp);
1455 /* Restore previous settings. */
1456 pp_wrapping_mode (pp) = oldmode;
1459 /* Flush the content of BUFFER onto the attached stream. This
1460 function does nothing unless pp->output_buffer->flush_p. */
1461 void
1462 pp_flush (pretty_printer *pp)
1464 pp_clear_state (pp);
1465 if (!pp->buffer->flush_p)
1466 return;
1467 pp_write_text_to_stream (pp);
1468 fflush (pp_buffer (pp)->stream);
1471 /* Flush the content of BUFFER onto the attached stream independently
1472 of the value of pp->output_buffer->flush_p. */
1473 void
1474 pp_really_flush (pretty_printer *pp)
1476 pp_clear_state (pp);
1477 pp_write_text_to_stream (pp);
1478 fflush (pp_buffer (pp)->stream);
1481 /* Sets the number of maximum characters per line PRETTY-PRINTER can
1482 output in line-wrapping mode. A LENGTH value 0 suppresses
1483 line-wrapping. */
1484 void
1485 pp_set_line_maximum_length (pretty_printer *pp, int length)
1487 pp_line_cutoff (pp) = length;
1488 pp_set_real_maximum_length (pp);
1491 /* Clear PRETTY-PRINTER output area text info. */
1492 void
1493 pp_clear_output_area (pretty_printer *pp)
1495 obstack_free (pp_buffer (pp)->obstack,
1496 obstack_base (pp_buffer (pp)->obstack));
1497 pp_buffer (pp)->line_length = 0;
1500 /* Set PREFIX for PRETTY-PRINTER, taking ownership of PREFIX, which
1501 will eventually be free-ed. */
1503 void
1504 pp_set_prefix (pretty_printer *pp, char *prefix)
1506 free (pp->prefix);
1507 pp->prefix = prefix;
1508 pp_set_real_maximum_length (pp);
1509 pp->emitted_prefix = false;
1510 pp_indentation (pp) = 0;
1513 /* Take ownership of PP's prefix, setting it to NULL.
1514 This allows clients to save, overide, and then restore an existing
1515 prefix, without it being free-ed. */
1517 char *
1518 pp_take_prefix (pretty_printer *pp)
1520 char *result = pp->prefix;
1521 pp->prefix = NULL;
1522 return result;
1525 /* Free PRETTY-PRINTER's prefix, a previously malloc()'d string. */
1526 void
1527 pp_destroy_prefix (pretty_printer *pp)
1529 if (pp->prefix != NULL)
1531 free (pp->prefix);
1532 pp->prefix = NULL;
1536 /* Write out PRETTY-PRINTER's prefix. */
1537 void
1538 pp_emit_prefix (pretty_printer *pp)
1540 if (pp->prefix != NULL)
1542 switch (pp_prefixing_rule (pp))
1544 default:
1545 case DIAGNOSTICS_SHOW_PREFIX_NEVER:
1546 break;
1548 case DIAGNOSTICS_SHOW_PREFIX_ONCE:
1549 if (pp->emitted_prefix)
1551 pp_indent (pp);
1552 break;
1554 pp_indentation (pp) += 3;
1555 /* Fall through. */
1557 case DIAGNOSTICS_SHOW_PREFIX_EVERY_LINE:
1559 int prefix_length = strlen (pp->prefix);
1560 pp_append_r (pp, pp->prefix, prefix_length);
1561 pp->emitted_prefix = true;
1563 break;
1568 /* Construct a PRETTY-PRINTER of MAXIMUM_LENGTH characters per line. */
1570 pretty_printer::pretty_printer (int maximum_length)
1571 : buffer (new (XCNEW (output_buffer)) output_buffer ()),
1572 prefix (),
1573 padding (pp_none),
1574 maximum_length (),
1575 indent_skip (),
1576 wrapping (),
1577 format_decoder (),
1578 m_format_postprocessor (NULL),
1579 emitted_prefix (),
1580 need_newline (),
1581 translate_identifiers (true),
1582 show_color ()
1584 pp_line_cutoff (this) = maximum_length;
1585 /* By default, we emit prefixes once per message. */
1586 pp_prefixing_rule (this) = DIAGNOSTICS_SHOW_PREFIX_ONCE;
1587 pp_set_prefix (this, NULL);
1590 pretty_printer::~pretty_printer ()
1592 if (m_format_postprocessor)
1593 delete m_format_postprocessor;
1594 buffer->~output_buffer ();
1595 XDELETE (buffer);
1596 free (prefix);
1599 /* Append a string delimited by START and END to the output area of
1600 PRETTY-PRINTER. No line wrapping is done. However, if beginning a
1601 new line then emit PRETTY-PRINTER's prefix and skip any leading
1602 whitespace if appropriate. The caller must ensure that it is
1603 safe to do so. */
1604 void
1605 pp_append_text (pretty_printer *pp, const char *start, const char *end)
1607 /* Emit prefix and skip whitespace if we're starting a new line. */
1608 if (pp_buffer (pp)->line_length == 0)
1610 pp_emit_prefix (pp);
1611 if (pp_is_wrapping_line (pp))
1612 while (start != end && *start == ' ')
1613 ++start;
1615 pp_append_r (pp, start, end - start);
1618 /* Finishes constructing a NULL-terminated character string representing
1619 the PRETTY-PRINTED text. */
1620 const char *
1621 pp_formatted_text (pretty_printer *pp)
1623 return output_buffer_formatted_text (pp_buffer (pp));
1626 /* Return a pointer to the last character emitted in PRETTY-PRINTER's
1627 output area. A NULL pointer means no character available. */
1628 const char *
1629 pp_last_position_in_text (const pretty_printer *pp)
1631 return output_buffer_last_position_in_text (pp_buffer (pp));
1634 /* Return the amount of characters PRETTY-PRINTER can accept to
1635 make a full line. Meaningful only in line-wrapping mode. */
1637 pp_remaining_character_count_for_line (pretty_printer *pp)
1639 return pp->maximum_length - pp_buffer (pp)->line_length;
1643 /* Format a message into BUFFER a la printf. */
1644 void
1645 pp_printf (pretty_printer *pp, const char *msg, ...)
1647 text_info text;
1648 va_list ap;
1650 va_start (ap, msg);
1651 text.err_no = errno;
1652 text.args_ptr = &ap;
1653 text.format_spec = msg;
1654 pp_format (pp, &text);
1655 pp_output_formatted_text (pp);
1656 va_end (ap);
1660 /* Output MESSAGE verbatim into BUFFER. */
1661 void
1662 pp_verbatim (pretty_printer *pp, const char *msg, ...)
1664 text_info text;
1665 va_list ap;
1667 va_start (ap, msg);
1668 text.err_no = errno;
1669 text.args_ptr = &ap;
1670 text.format_spec = msg;
1671 pp_format_verbatim (pp, &text);
1672 va_end (ap);
1677 /* Have PRETTY-PRINTER start a new line. */
1678 void
1679 pp_newline (pretty_printer *pp)
1681 obstack_1grow (pp_buffer (pp)->obstack, '\n');
1682 pp_needs_newline (pp) = false;
1683 pp_buffer (pp)->line_length = 0;
1686 /* Have PRETTY-PRINTER add a CHARACTER. */
1687 void
1688 pp_character (pretty_printer *pp, int c)
1690 if (pp_is_wrapping_line (pp)
1691 && pp_remaining_character_count_for_line (pp) <= 0)
1693 pp_newline (pp);
1694 if (ISSPACE (c))
1695 return;
1697 obstack_1grow (pp_buffer (pp)->obstack, c);
1698 ++pp_buffer (pp)->line_length;
1701 /* Append a STRING to the output area of PRETTY-PRINTER; the STRING may
1702 be line-wrapped if in appropriate mode. */
1703 void
1704 pp_string (pretty_printer *pp, const char *str)
1706 gcc_checking_assert (str);
1707 pp_maybe_wrap_text (pp, str, str + strlen (str));
1710 /* Append the leading N characters of STRING to the output area of
1711 PRETTY-PRINTER, quoting in hexadecimal non-printable characters.
1712 Setting N = -1 is as if N were set to strlen (STRING). The STRING
1713 may be line-wrapped if in appropriate mode. */
1714 static void
1715 pp_quoted_string (pretty_printer *pp, const char *str, size_t n /* = -1 */)
1717 gcc_checking_assert (str);
1719 const char *last = str;
1720 const char *ps;
1722 /* Compute the length if not specified. */
1723 if (n == (size_t) -1)
1724 n = strlen (str);
1726 for (ps = str; n; ++ps, --n)
1728 if (ISPRINT (*ps))
1729 continue;
1731 if (last < ps)
1732 pp_maybe_wrap_text (pp, last, ps - 1);
1734 /* Append the hexadecimal value of the character. Allocate a buffer
1735 that's large enough for a 32-bit char plus the hex prefix. */
1736 char buf [11];
1737 int n = sprintf (buf, "\\x%02x", (unsigned char)*ps);
1738 pp_maybe_wrap_text (pp, buf, buf + n);
1739 last = ps + 1;
1742 pp_maybe_wrap_text (pp, last, ps);
1745 /* Maybe print out a whitespace if needed. */
1747 void
1748 pp_maybe_space (pretty_printer *pp)
1750 if (pp->padding != pp_none)
1752 pp_space (pp);
1753 pp->padding = pp_none;
1757 // Add a newline to the pretty printer PP and flush formatted text.
1759 void
1760 pp_newline_and_flush (pretty_printer *pp)
1762 pp_newline (pp);
1763 pp_flush (pp);
1764 pp_needs_newline (pp) = false;
1767 // Add a newline to the pretty printer PP, followed by indentation.
1769 void
1770 pp_newline_and_indent (pretty_printer *pp, int n)
1772 pp_indentation (pp) += n;
1773 pp_newline (pp);
1774 pp_indent (pp);
1775 pp_needs_newline (pp) = false;
1778 // Add separator C, followed by a single whitespace.
1780 void
1781 pp_separate_with (pretty_printer *pp, char c)
1783 pp_character (pp, c);
1784 pp_space (pp);
1787 /* Add a localized open quote, and if SHOW_COLOR is true, begin colorizing
1788 using the "quote" color. */
1790 void
1791 pp_begin_quote (pretty_printer *pp, bool show_color)
1793 pp_string (pp, open_quote);
1794 pp_string (pp, colorize_start (show_color, "quote"));
1797 /* If SHOW_COLOR is true, stop colorizing.
1798 Add a localized close quote. */
1800 void
1801 pp_end_quote (pretty_printer *pp, bool show_color)
1803 pp_string (pp, colorize_stop (show_color));
1804 pp_string (pp, close_quote);
1808 /* The string starting at P has LEN (at least 1) bytes left; if they
1809 start with a valid UTF-8 sequence, return the length of that
1810 sequence and set *VALUE to the value of that sequence, and
1811 otherwise return 0 and set *VALUE to (unsigned int) -1. */
1813 static int
1814 decode_utf8_char (const unsigned char *p, size_t len, unsigned int *value)
1816 unsigned int t = *p;
1818 if (len == 0)
1819 abort ();
1820 if (t & 0x80)
1822 size_t utf8_len = 0;
1823 unsigned int ch;
1824 size_t i;
1825 for (t = *p; t & 0x80; t <<= 1)
1826 utf8_len++;
1828 if (utf8_len > len || utf8_len < 2 || utf8_len > 6)
1830 *value = (unsigned int) -1;
1831 return 0;
1833 ch = *p & ((1 << (7 - utf8_len)) - 1);
1834 for (i = 1; i < utf8_len; i++)
1836 unsigned int u = p[i];
1837 if ((u & 0xC0) != 0x80)
1839 *value = (unsigned int) -1;
1840 return 0;
1842 ch = (ch << 6) | (u & 0x3F);
1844 if ( (ch <= 0x7F && utf8_len > 1)
1845 || (ch <= 0x7FF && utf8_len > 2)
1846 || (ch <= 0xFFFF && utf8_len > 3)
1847 || (ch <= 0x1FFFFF && utf8_len > 4)
1848 || (ch <= 0x3FFFFFF && utf8_len > 5)
1849 || (ch >= 0xD800 && ch <= 0xDFFF))
1851 *value = (unsigned int) -1;
1852 return 0;
1854 *value = ch;
1855 return utf8_len;
1857 else
1859 *value = t;
1860 return 1;
1864 /* Allocator for identifier_to_locale and corresponding function to
1865 free memory. */
1867 void *(*identifier_to_locale_alloc) (size_t) = xmalloc;
1868 void (*identifier_to_locale_free) (void *) = free;
1870 /* Given IDENT, an identifier in the internal encoding, return a
1871 version of IDENT suitable for diagnostics in the locale character
1872 set: either IDENT itself, or a string, allocated using
1873 identifier_to_locale_alloc, converted to the locale character set
1874 and using escape sequences if not representable in the locale
1875 character set or containing control characters or invalid byte
1876 sequences. Existing backslashes in IDENT are not doubled, so the
1877 result may not uniquely specify the contents of an arbitrary byte
1878 sequence identifier. */
1880 const char *
1881 identifier_to_locale (const char *ident)
1883 const unsigned char *uid = (const unsigned char *) ident;
1884 size_t idlen = strlen (ident);
1885 bool valid_printable_utf8 = true;
1886 bool all_ascii = true;
1887 size_t i;
1889 for (i = 0; i < idlen;)
1891 unsigned int c;
1892 size_t utf8_len = decode_utf8_char (&uid[i], idlen - i, &c);
1893 if (utf8_len == 0 || c <= 0x1F || (c >= 0x7F && c <= 0x9F))
1895 valid_printable_utf8 = false;
1896 break;
1898 if (utf8_len > 1)
1899 all_ascii = false;
1900 i += utf8_len;
1903 /* If IDENT contains invalid UTF-8 sequences (which may occur with
1904 attributes putting arbitrary byte sequences in identifiers), or
1905 control characters, we use octal escape sequences for all bytes
1906 outside printable ASCII. */
1907 if (!valid_printable_utf8)
1909 char *ret = (char *) identifier_to_locale_alloc (4 * idlen + 1);
1910 char *p = ret;
1911 for (i = 0; i < idlen; i++)
1913 if (uid[i] > 0x1F && uid[i] < 0x7F)
1914 *p++ = uid[i];
1915 else
1917 sprintf (p, "\\%03o", uid[i]);
1918 p += 4;
1921 *p = 0;
1922 return ret;
1925 /* Otherwise, if it is valid printable ASCII, or printable UTF-8
1926 with the locale character set being UTF-8, IDENT is used. */
1927 if (all_ascii || locale_utf8)
1928 return ident;
1930 /* Otherwise IDENT is converted to the locale character set if
1931 possible. */
1932 #if defined ENABLE_NLS && defined HAVE_LANGINFO_CODESET && HAVE_ICONV
1933 if (locale_encoding != NULL)
1935 iconv_t cd = iconv_open (locale_encoding, "UTF-8");
1936 bool conversion_ok = true;
1937 char *ret = NULL;
1938 if (cd != (iconv_t) -1)
1940 size_t ret_alloc = 4 * idlen + 1;
1941 for (;;)
1943 /* Repeat the whole conversion process as needed with
1944 larger buffers so non-reversible transformations can
1945 always be detected. */
1946 ICONV_CONST char *inbuf = CONST_CAST (char *, ident);
1947 char *outbuf;
1948 size_t inbytesleft = idlen;
1949 size_t outbytesleft = ret_alloc - 1;
1950 size_t iconv_ret;
1952 ret = (char *) identifier_to_locale_alloc (ret_alloc);
1953 outbuf = ret;
1955 if (iconv (cd, 0, 0, 0, 0) == (size_t) -1)
1957 conversion_ok = false;
1958 break;
1961 iconv_ret = iconv (cd, &inbuf, &inbytesleft,
1962 &outbuf, &outbytesleft);
1963 if (iconv_ret == (size_t) -1 || inbytesleft != 0)
1965 if (errno == E2BIG)
1967 ret_alloc *= 2;
1968 identifier_to_locale_free (ret);
1969 ret = NULL;
1970 continue;
1972 else
1974 conversion_ok = false;
1975 break;
1978 else if (iconv_ret != 0)
1980 conversion_ok = false;
1981 break;
1983 /* Return to initial shift state. */
1984 if (iconv (cd, 0, 0, &outbuf, &outbytesleft) == (size_t) -1)
1986 if (errno == E2BIG)
1988 ret_alloc *= 2;
1989 identifier_to_locale_free (ret);
1990 ret = NULL;
1991 continue;
1993 else
1995 conversion_ok = false;
1996 break;
1999 *outbuf = 0;
2000 break;
2002 iconv_close (cd);
2003 if (conversion_ok)
2004 return ret;
2007 #endif
2009 /* Otherwise, convert non-ASCII characters in IDENT to UCNs. */
2011 char *ret = (char *) identifier_to_locale_alloc (10 * idlen + 1);
2012 char *p = ret;
2013 for (i = 0; i < idlen;)
2015 unsigned int c;
2016 size_t utf8_len = decode_utf8_char (&uid[i], idlen - i, &c);
2017 if (utf8_len == 1)
2018 *p++ = uid[i];
2019 else
2021 sprintf (p, "\\U%08x", c);
2022 p += 10;
2024 i += utf8_len;
2026 *p = 0;
2027 return ret;
2031 #if CHECKING_P
2033 namespace selftest {
2035 /* Smoketest for pretty_printer. */
2037 static void
2038 test_basic_printing ()
2040 pretty_printer pp;
2041 pp_string (&pp, "hello");
2042 pp_space (&pp);
2043 pp_string (&pp, "world");
2045 ASSERT_STREQ ("hello world", pp_formatted_text (&pp));
2048 /* Helper function for testing pp_format.
2049 Verify that pp_format (FMT, ...) followed by pp_output_formatted_text
2050 prints EXPECTED, assuming that pp_show_color is SHOW_COLOR. */
2052 static void
2053 assert_pp_format_va (const location &loc, const char *expected,
2054 bool show_color, const char *fmt, va_list *ap)
2056 pretty_printer pp;
2057 text_info ti;
2058 rich_location rich_loc (line_table, UNKNOWN_LOCATION);
2060 ti.format_spec = fmt;
2061 ti.args_ptr = ap;
2062 ti.err_no = 0;
2063 ti.x_data = NULL;
2064 ti.m_richloc = &rich_loc;
2066 pp_show_color (&pp) = show_color;
2067 pp_format (&pp, &ti);
2068 pp_output_formatted_text (&pp);
2069 ASSERT_STREQ_AT (loc, expected, pp_formatted_text (&pp));
2072 /* Verify that pp_format (FMT, ...) followed by pp_output_formatted_text
2073 prints EXPECTED, with show_color disabled. */
2075 static void
2076 assert_pp_format (const location &loc, const char *expected,
2077 const char *fmt, ...)
2079 va_list ap;
2081 va_start (ap, fmt);
2082 assert_pp_format_va (loc, expected, false, fmt, &ap);
2083 va_end (ap);
2086 /* As above, but with colorization enabled. */
2088 static void
2089 assert_pp_format_colored (const location &loc, const char *expected,
2090 const char *fmt, ...)
2092 /* The tests of colorization assume the default color scheme.
2093 If GCC_COLORS is set, then the colors have potentially been
2094 overridden; skip the test. */
2095 if (getenv ("GCC_COLORS"))
2096 return;
2098 va_list ap;
2100 va_start (ap, fmt);
2101 assert_pp_format_va (loc, expected, true, fmt, &ap);
2102 va_end (ap);
2105 /* Helper function for calling testing pp_format,
2106 by calling assert_pp_format with various numbers of arguments.
2107 These exist mostly to avoid having to write SELFTEST_LOCATION
2108 throughout test_pp_format. */
2110 #define ASSERT_PP_FORMAT_1(EXPECTED, FMT, ARG1) \
2111 SELFTEST_BEGIN_STMT \
2112 assert_pp_format ((SELFTEST_LOCATION), (EXPECTED), (FMT), \
2113 (ARG1)); \
2114 SELFTEST_END_STMT
2116 #define ASSERT_PP_FORMAT_2(EXPECTED, FMT, ARG1, ARG2) \
2117 SELFTEST_BEGIN_STMT \
2118 assert_pp_format ((SELFTEST_LOCATION), (EXPECTED), (FMT), \
2119 (ARG1), (ARG2)); \
2120 SELFTEST_END_STMT
2122 #define ASSERT_PP_FORMAT_3(EXPECTED, FMT, ARG1, ARG2, ARG3) \
2123 SELFTEST_BEGIN_STMT \
2124 assert_pp_format ((SELFTEST_LOCATION), (EXPECTED), (FMT), \
2125 (ARG1), (ARG2), (ARG3)); \
2126 SELFTEST_END_STMT
2128 /* Verify that pp_format works, for various format codes. */
2130 static void
2131 test_pp_format ()
2133 /* Avoid introducing locale-specific differences in the results
2134 by hardcoding open_quote and close_quote. */
2135 auto_fix_quotes fix_quotes;
2137 /* Verify that plain text is passed through unchanged. */
2138 assert_pp_format (SELFTEST_LOCATION, "unformatted", "unformatted");
2140 /* Verify various individual format codes, in the order listed in the
2141 comment for pp_format above. For each code, we append a second
2142 argument with a known bit pattern (0x12345678), to ensure that we
2143 are consuming arguments correctly. */
2144 ASSERT_PP_FORMAT_2 ("-27 12345678", "%d %x", -27, 0x12345678);
2145 ASSERT_PP_FORMAT_2 ("-5 12345678", "%i %x", -5, 0x12345678);
2146 ASSERT_PP_FORMAT_2 ("10 12345678", "%u %x", 10, 0x12345678);
2147 ASSERT_PP_FORMAT_2 ("17 12345678", "%o %x", 15, 0x12345678);
2148 ASSERT_PP_FORMAT_2 ("cafebabe 12345678", "%x %x", 0xcafebabe, 0x12345678);
2149 ASSERT_PP_FORMAT_2 ("-27 12345678", "%ld %x", (long)-27, 0x12345678);
2150 ASSERT_PP_FORMAT_2 ("-5 12345678", "%li %x", (long)-5, 0x12345678);
2151 ASSERT_PP_FORMAT_2 ("10 12345678", "%lu %x", (long)10, 0x12345678);
2152 ASSERT_PP_FORMAT_2 ("17 12345678", "%lo %x", (long)15, 0x12345678);
2153 ASSERT_PP_FORMAT_2 ("cafebabe 12345678", "%lx %x", (long)0xcafebabe,
2154 0x12345678);
2155 ASSERT_PP_FORMAT_2 ("-27 12345678", "%lld %x", (long long)-27, 0x12345678);
2156 ASSERT_PP_FORMAT_2 ("-5 12345678", "%lli %x", (long long)-5, 0x12345678);
2157 ASSERT_PP_FORMAT_2 ("10 12345678", "%llu %x", (long long)10, 0x12345678);
2158 ASSERT_PP_FORMAT_2 ("17 12345678", "%llo %x", (long long)15, 0x12345678);
2159 ASSERT_PP_FORMAT_2 ("cafebabe 12345678", "%llx %x", (long long)0xcafebabe,
2160 0x12345678);
2161 ASSERT_PP_FORMAT_2 ("-27 12345678", "%wd %x", (HOST_WIDE_INT)-27, 0x12345678);
2162 ASSERT_PP_FORMAT_2 ("-5 12345678", "%wi %x", (HOST_WIDE_INT)-5, 0x12345678);
2163 ASSERT_PP_FORMAT_2 ("10 12345678", "%wu %x", (unsigned HOST_WIDE_INT)10,
2164 0x12345678);
2165 ASSERT_PP_FORMAT_2 ("17 12345678", "%wo %x", (HOST_WIDE_INT)15, 0x12345678);
2166 ASSERT_PP_FORMAT_2 ("0xcafebabe 12345678", "%wx %x", (HOST_WIDE_INT)0xcafebabe,
2167 0x12345678);
2168 ASSERT_PP_FORMAT_2 ("1.000000 12345678", "%f %x", 1.0, 0x12345678);
2169 ASSERT_PP_FORMAT_2 ("A 12345678", "%c %x", 'A', 0x12345678);
2170 ASSERT_PP_FORMAT_2 ("hello world 12345678", "%s %x", "hello world",
2171 0x12345678);
2173 /* Not nul-terminated. */
2174 char arr[5] = { '1', '2', '3', '4', '5' };
2175 ASSERT_PP_FORMAT_3 ("123 12345678", "%.*s %x", 3, arr, 0x12345678);
2176 ASSERT_PP_FORMAT_3 ("1234 12345678", "%.*s %x", -1, "1234", 0x12345678);
2177 ASSERT_PP_FORMAT_3 ("12345 12345678", "%.*s %x", 7, "12345", 0x12345678);
2179 /* We can't test for %p; the pointer is printed in an implementation-defined
2180 manner. */
2181 ASSERT_PP_FORMAT_2 ("normal colored normal 12345678",
2182 "normal %rcolored%R normal %x",
2183 "error", 0x12345678);
2184 assert_pp_format_colored
2185 (SELFTEST_LOCATION,
2186 "normal \33[01;31m\33[Kcolored\33[m\33[K normal 12345678",
2187 "normal %rcolored%R normal %x", "error", 0x12345678);
2188 /* TODO:
2189 %m: strerror(text->err_no) - does not consume a value from args_ptr. */
2190 ASSERT_PP_FORMAT_1 ("% 12345678", "%% %x", 0x12345678);
2191 ASSERT_PP_FORMAT_1 ("` 12345678", "%< %x", 0x12345678);
2192 ASSERT_PP_FORMAT_1 ("' 12345678", "%> %x", 0x12345678);
2193 ASSERT_PP_FORMAT_1 ("' 12345678", "%' %x", 0x12345678);
2194 ASSERT_PP_FORMAT_3 ("abc 12345678", "%.*s %x", 3, "abcdef", 0x12345678);
2195 ASSERT_PP_FORMAT_2 ("abc 12345678", "%.3s %x", "abcdef", 0x12345678);
2197 /* Verify flag 'q'. */
2198 ASSERT_PP_FORMAT_2 ("`foo' 12345678", "%qs %x", "foo", 0x12345678);
2199 assert_pp_format_colored (SELFTEST_LOCATION,
2200 "`\33[01m\33[Kfoo\33[m\33[K' 12345678", "%qs %x",
2201 "foo", 0x12345678);
2203 /* Verify %Z. */
2204 int v[] = { 1, 2, 3 };
2205 ASSERT_PP_FORMAT_3 ("1, 2, 3 12345678", "%Z %x", v, 3, 0x12345678);
2207 int v2[] = { 0 };
2208 ASSERT_PP_FORMAT_3 ("0 12345678", "%Z %x", v2, 1, 0x12345678);
2210 /* Verify that combinations work, along with unformatted text. */
2211 assert_pp_format (SELFTEST_LOCATION,
2212 "the quick brown fox jumps over the lazy dog",
2213 "the %s %s %s jumps over the %s %s",
2214 "quick", "brown", "fox", "lazy", "dog");
2215 assert_pp_format (SELFTEST_LOCATION, "item 3 of 7", "item %i of %i", 3, 7);
2216 assert_pp_format (SELFTEST_LOCATION, "problem with `bar' at line 10",
2217 "problem with %qs at line %i", "bar", 10);
2220 /* A subclass of pretty_printer for use by test_prefixes_and_wrapping. */
2222 class test_pretty_printer : public pretty_printer
2224 public:
2225 test_pretty_printer (enum diagnostic_prefixing_rule_t rule,
2226 int max_line_length)
2228 pp_set_prefix (this, xstrdup ("PREFIX: "));
2229 wrapping.rule = rule;
2230 pp_set_line_maximum_length (this, max_line_length);
2234 /* Verify that the various values of enum diagnostic_prefixing_rule_t work
2235 as expected, with and without line wrapping. */
2237 static void
2238 test_prefixes_and_wrapping ()
2240 /* Tests of the various prefixing rules, without wrapping.
2241 Newlines embedded in pp_string don't affect it; we have to
2242 explicitly call pp_newline. */
2244 test_pretty_printer pp (DIAGNOSTICS_SHOW_PREFIX_ONCE, 0);
2245 pp_string (&pp, "the quick brown fox");
2246 pp_newline (&pp);
2247 pp_string (&pp, "jumps over the lazy dog");
2248 pp_newline (&pp);
2249 ASSERT_STREQ (pp_formatted_text (&pp),
2250 "PREFIX: the quick brown fox\n"
2251 " jumps over the lazy dog\n");
2254 test_pretty_printer pp (DIAGNOSTICS_SHOW_PREFIX_NEVER, 0);
2255 pp_string (&pp, "the quick brown fox");
2256 pp_newline (&pp);
2257 pp_string (&pp, "jumps over the lazy dog");
2258 pp_newline (&pp);
2259 ASSERT_STREQ (pp_formatted_text (&pp),
2260 "the quick brown fox\n"
2261 "jumps over the lazy dog\n");
2264 test_pretty_printer pp (DIAGNOSTICS_SHOW_PREFIX_EVERY_LINE, 0);
2265 pp_string (&pp, "the quick brown fox");
2266 pp_newline (&pp);
2267 pp_string (&pp, "jumps over the lazy dog");
2268 pp_newline (&pp);
2269 ASSERT_STREQ (pp_formatted_text (&pp),
2270 "PREFIX: the quick brown fox\n"
2271 "PREFIX: jumps over the lazy dog\n");
2274 /* Tests of the various prefixing rules, with wrapping. */
2276 test_pretty_printer pp (DIAGNOSTICS_SHOW_PREFIX_ONCE, 20);
2277 pp_string (&pp, "the quick brown fox jumps over the lazy dog");
2278 pp_newline (&pp);
2279 pp_string (&pp, "able was I ere I saw elba");
2280 pp_newline (&pp);
2281 ASSERT_STREQ (pp_formatted_text (&pp),
2282 "PREFIX: the quick \n"
2283 " brown fox jumps \n"
2284 " over the lazy \n"
2285 " dog\n"
2286 " able was I ere I \n"
2287 " saw elba\n");
2290 test_pretty_printer pp (DIAGNOSTICS_SHOW_PREFIX_NEVER, 20);
2291 pp_string (&pp, "the quick brown fox jumps over the lazy dog");
2292 pp_newline (&pp);
2293 pp_string (&pp, "able was I ere I saw elba");
2294 pp_newline (&pp);
2295 ASSERT_STREQ (pp_formatted_text (&pp),
2296 "the quick brown fox \n"
2297 "jumps over the lazy \n"
2298 "dog\n"
2299 "able was I ere I \n"
2300 "saw elba\n");
2303 test_pretty_printer pp (DIAGNOSTICS_SHOW_PREFIX_EVERY_LINE, 20);
2304 pp_string (&pp, "the quick brown fox jumps over the lazy dog");
2305 pp_newline (&pp);
2306 pp_string (&pp, "able was I ere I saw elba");
2307 pp_newline (&pp);
2308 ASSERT_STREQ (pp_formatted_text (&pp),
2309 "PREFIX: the quick brown fox jumps over the lazy dog\n"
2310 "PREFIX: able was I ere I saw elba\n");
2315 /* Run all of the selftests within this file. */
2317 void
2318 pretty_print_c_tests ()
2320 test_basic_printing ();
2321 test_pp_format ();
2322 test_prefixes_and_wrapping ();
2325 } // namespace selftest
2327 #endif /* CHECKING_P */