1 /* Various declarations for language-independent pretty-print subroutines.
2 Copyright (C) 2003-2022 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
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
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/>. */
23 #include "coretypes.h"
25 #include "pretty-print.h"
26 #include "diagnostic-color.h"
27 #include "diagnostic-event-id.h"
36 /* Replacement for fputs() that handles ANSI escape codes on Windows NT.
37 Contributed by: Liu Hao (lh_mouse at 126 dot com)
39 XXX: This file is compiled into libcommon.a that will be self-contained.
40 It looks like that these functions can be put nowhere else. */
43 #define WIN32_LEAN_AND_MEAN 1
46 /* These symbols might be missing in some versions of mingw */
47 #ifndef COMMON_LVB_UNDERSCORE
48 #define COMMON_LVB_UNDERSCORE 0x8000
50 #ifndef COMMON_LVB_REVERSE_VIDEO
51 #define COMMON_LVB_REVERSE_VIDEO 0x4000
55 /* Write all bytes in [s,s+n) into the specified stream.
56 Errors are ignored. */
58 write_all (HANDLE h
, const char *s
, size_t n
)
69 if (!WriteFile (h
, s
+ n
- rem
, step
, &step
, NULL
))
75 /* Find the beginning of an escape sequence.
77 1. If the sequence begins with an ESC character (0x1B) and a second
78 character X in [0x40,0x5F], returns X and stores a pointer to
79 the third character into *head.
80 2. If the sequence begins with a character X in [0x80,0x9F], returns
81 (X-0x40) and stores a pointer to the second character into *head.
82 Stores the number of ESC character(s) in *prefix_len.
83 Returns 0 if no such sequence can be found. */
85 find_esc_head (int *prefix_len
, const char **head
, const char *str
)
93 c
= (unsigned char) *r
;
99 if (escaped
&& 0x40 <= c
&& c
<= 0x5F)
101 /* Found (case 1). */
106 if (0x80 <= c
&& c
<= 0x9F)
108 /* Found (case 2). */
118 /* Find the terminator of an escape sequence.
119 str should be the value stored in *head by a previous successful
120 call to find_esc_head().
121 Returns 0 if no such sequence can be found. */
123 find_esc_terminator (const char **term
, const char *str
)
130 c
= (unsigned char) *r
;
136 if (0x40 <= c
&& c
<= 0x7E)
146 /* Handle a sequence of codes. Sequences that are invalid, reserved,
147 unrecognized or unimplemented are ignored silently.
148 There isn't much we can do because of lameness of Windows consoles. */
150 eat_esc_sequence (HANDLE h
, int esc_code
,
151 const char *esc_head
, const char *esc_term
)
153 /* Numbers in an escape sequence cannot be negative, because
154 a minus sign in the middle of it would have terminated it. */
157 CONSOLE_SCREEN_BUFFER_INFO sb
;
159 /* ED and EL parameters. */
162 /* SGR parameters. */
163 WORD attrib_add
, attrib_rm
;
166 switch (MAKEWORD (esc_code
, *esc_term
))
169 Move the cursor up by n1 characters. */
170 case MAKEWORD ('[', 'A'):
171 if (esc_head
== esc_term
)
175 n1
= strtol (esc_head
, &eptr
, 10);
176 if (eptr
!= esc_term
)
180 if (GetConsoleScreenBufferInfo (h
, &sb
))
182 cr
= sb
.dwCursorPosition
;
183 /* Stop at the topmost boundary. */
188 SetConsoleCursorPosition (h
, cr
);
193 Move the cursor down by n1 characters. */
194 case MAKEWORD ('[', 'B'):
195 if (esc_head
== esc_term
)
199 n1
= strtol (esc_head
, &eptr
, 10);
200 if (eptr
!= esc_term
)
204 if (GetConsoleScreenBufferInfo (h
, &sb
))
206 cr
= sb
.dwCursorPosition
;
207 /* Stop at the bottommost boundary. */
208 if (sb
.dwSize
.Y
- cr
.Y
> n1
)
212 SetConsoleCursorPosition (h
, cr
);
217 Move the cursor right by n1 characters. */
218 case MAKEWORD ('[', 'C'):
219 if (esc_head
== esc_term
)
223 n1
= strtol (esc_head
, &eptr
, 10);
224 if (eptr
!= esc_term
)
228 if (GetConsoleScreenBufferInfo (h
, &sb
))
230 cr
= sb
.dwCursorPosition
;
231 /* Stop at the rightmost boundary. */
232 if (sb
.dwSize
.X
- cr
.X
> n1
)
236 SetConsoleCursorPosition (h
, cr
);
241 Move the cursor left by n1 characters. */
242 case MAKEWORD ('[', 'D'):
243 if (esc_head
== esc_term
)
247 n1
= strtol (esc_head
, &eptr
, 10);
248 if (eptr
!= esc_term
)
252 if (GetConsoleScreenBufferInfo (h
, &sb
))
254 cr
= sb
.dwCursorPosition
;
255 /* Stop at the leftmost boundary. */
260 SetConsoleCursorPosition (h
, cr
);
265 Move the cursor to the beginning of the n1-th line downwards. */
266 case MAKEWORD ('[', 'E'):
267 if (esc_head
== esc_term
)
271 n1
= strtol (esc_head
, &eptr
, 10);
272 if (eptr
!= esc_term
)
276 if (GetConsoleScreenBufferInfo (h
, &sb
))
278 cr
= sb
.dwCursorPosition
;
280 /* Stop at the bottommost boundary. */
281 if (sb
.dwSize
.Y
- cr
.Y
> n1
)
285 SetConsoleCursorPosition (h
, cr
);
290 Move the cursor to the beginning of the n1-th line upwards. */
291 case MAKEWORD ('[', 'F'):
292 if (esc_head
== esc_term
)
296 n1
= strtol (esc_head
, &eptr
, 10);
297 if (eptr
!= esc_term
)
301 if (GetConsoleScreenBufferInfo (h
, &sb
))
303 cr
= sb
.dwCursorPosition
;
305 /* Stop at the topmost boundary. */
310 SetConsoleCursorPosition (h
, cr
);
315 Move the cursor to the (1-based) n1-th column. */
316 case MAKEWORD ('[', 'G'):
317 if (esc_head
== esc_term
)
321 n1
= strtol (esc_head
, &eptr
, 10);
322 if (eptr
!= esc_term
)
326 if (GetConsoleScreenBufferInfo (h
, &sb
))
328 cr
= sb
.dwCursorPosition
;
330 /* Stop at the leftmost or rightmost boundary. */
333 else if (n1
> sb
.dwSize
.X
)
337 SetConsoleCursorPosition (h
, cr
);
341 /* ESC [ n1 ';' n2 'H'
343 Move the cursor to the (1-based) n1-th row and
344 (also 1-based) n2-th column. */
345 case MAKEWORD ('[', 'H'):
346 case MAKEWORD ('[', 'f'):
347 if (esc_head
== esc_term
)
349 /* Both parameters are omitted and set to 1 by default. */
353 else if (!(delim
= (char *) memchr (esc_head
, ';',
354 esc_term
- esc_head
)))
356 /* Only the first parameter is given. The second one is
357 set to 1 by default. */
358 n1
= strtol (esc_head
, &eptr
, 10);
359 if (eptr
!= esc_term
)
365 /* Both parameters are given. The first one shall be
366 terminated by the semicolon. */
367 n1
= strtol (esc_head
, &eptr
, 10);
370 n2
= strtol (delim
+ 1, &eptr
, 10);
371 if (eptr
!= esc_term
)
375 if (GetConsoleScreenBufferInfo (h
, &sb
))
377 cr
= sb
.dwCursorPosition
;
380 /* The cursor position shall be relative to the view coord of
381 the console window, which is usually smaller than the actual
382 buffer. FWIW, the 'appropriate' solution will be shrinking
383 the buffer to match the size of the console window,
384 destroying scrollback in the process. */
385 n1
+= sb
.srWindow
.Top
;
386 n2
+= sb
.srWindow
.Left
;
387 /* Stop at the topmost or bottommost boundary. */
390 else if (n1
> sb
.dwSize
.Y
)
394 /* Stop at the leftmost or rightmost boundary. */
397 else if (n2
> sb
.dwSize
.X
)
401 SetConsoleCursorPosition (h
, cr
);
407 case MAKEWORD ('[', 'J'):
408 if (esc_head
== esc_term
)
409 /* This is one of the very few codes whose parameters have
410 a default value of zero. */
414 n1
= strtol (esc_head
, &eptr
, 10);
415 if (eptr
!= esc_term
)
419 if (GetConsoleScreenBufferInfo (h
, &sb
))
421 /* The cursor is not necessarily in the console window, which
422 makes the behavior of this code harder to define. */
426 /* If the cursor is in or above the window, erase from
427 it to the bottom of the window; otherwise, do nothing. */
428 cr
= sb
.dwCursorPosition
;
429 cnt
= sb
.dwSize
.X
- sb
.dwCursorPosition
.X
;
430 rows
= sb
.srWindow
.Bottom
- sb
.dwCursorPosition
.Y
;
433 /* If the cursor is in or under the window, erase from
434 it to the top of the window; otherwise, do nothing. */
436 cr
.Y
= sb
.srWindow
.Top
;
437 cnt
= sb
.dwCursorPosition
.X
+ 1;
438 rows
= sb
.dwCursorPosition
.Y
- sb
.srWindow
.Top
;
441 /* Erase the entire window. */
442 cr
.X
= sb
.srWindow
.Left
;
443 cr
.Y
= sb
.srWindow
.Top
;
445 rows
= sb
.srWindow
.Bottom
- sb
.srWindow
.Top
+ 1;
448 /* Erase the entire buffer. */
457 cnt
+= rows
* sb
.dwSize
.X
;
458 FillConsoleOutputCharacterW (h
, L
' ', cnt
, cr
, &step
);
459 FillConsoleOutputAttribute (h
, sb
.wAttributes
, cnt
, cr
, &step
);
465 case MAKEWORD ('[', 'K'):
466 if (esc_head
== esc_term
)
467 /* This is one of the very few codes whose parameters have
468 a default value of zero. */
472 n1
= strtol (esc_head
, &eptr
, 10);
473 if (eptr
!= esc_term
)
477 if (GetConsoleScreenBufferInfo (h
, &sb
))
482 /* Erase from the cursor to the end. */
483 cr
= sb
.dwCursorPosition
;
484 cnt
= sb
.dwSize
.X
- sb
.dwCursorPosition
.X
;
487 /* Erase from the cursor to the beginning. */
488 cr
= sb
.dwCursorPosition
;
490 cnt
= sb
.dwCursorPosition
.X
+ 1;
493 /* Erase the entire line. */
494 cr
= sb
.dwCursorPosition
;
499 FillConsoleOutputCharacterW (h
, L
' ', cnt
, cr
, &step
);
500 FillConsoleOutputAttribute (h
, sb
.wAttributes
, cnt
, cr
, &step
);
504 /* ESC [ n1 ';' n2 'm'
505 Set SGR parameters. Zero or more parameters will follow. */
506 case MAKEWORD ('[', 'm'):
509 if (esc_head
== esc_term
)
511 /* When no parameter is given, reset the console. */
512 attrib_add
|= (FOREGROUND_RED
| FOREGROUND_GREEN
514 attrib_rm
= -1; /* Removes everything. */
520 /* Parse a parameter. */
521 n1
= strtol (param
, &eptr
, 10);
522 if (*eptr
!= ';' && eptr
!= esc_term
)
529 attrib_add
|= (FOREGROUND_RED
| FOREGROUND_GREEN
531 attrib_rm
= -1; /* Removes everything. */
535 attrib_add
|= FOREGROUND_INTENSITY
;
539 attrib_add
|= COMMON_LVB_UNDERSCORE
;
543 /* XXX: It is not BLINKING at all! */
544 attrib_add
|= BACKGROUND_INTENSITY
;
548 attrib_add
|= COMMON_LVB_REVERSE_VIDEO
;
552 attrib_add
&= ~FOREGROUND_INTENSITY
;
553 attrib_rm
|= FOREGROUND_INTENSITY
;
557 attrib_add
&= ~COMMON_LVB_UNDERSCORE
;
558 attrib_rm
|= COMMON_LVB_UNDERSCORE
;
562 /* XXX: It is not BLINKING at all! */
563 attrib_add
&= ~BACKGROUND_INTENSITY
;
564 attrib_rm
|= BACKGROUND_INTENSITY
;
568 attrib_add
&= ~COMMON_LVB_REVERSE_VIDEO
;
569 attrib_rm
|= COMMON_LVB_REVERSE_VIDEO
;
579 /* Foreground color. */
580 attrib_add
&= ~(FOREGROUND_RED
| FOREGROUND_GREEN
584 attrib_add
|= FOREGROUND_RED
;
586 attrib_add
|= FOREGROUND_GREEN
;
588 attrib_add
|= FOREGROUND_BLUE
;
589 attrib_rm
|= (FOREGROUND_RED
| FOREGROUND_GREEN
593 /* Reserved for extended foreground color.
594 Don't know how to handle parameters remaining.
598 /* Reset foreground color. */
600 attrib_add
|= (FOREGROUND_RED
| FOREGROUND_GREEN
602 attrib_rm
|= (FOREGROUND_RED
| FOREGROUND_GREEN
613 /* Background color. */
614 attrib_add
&= ~(BACKGROUND_RED
| BACKGROUND_GREEN
618 attrib_add
|= BACKGROUND_RED
;
620 attrib_add
|= BACKGROUND_GREEN
;
622 attrib_add
|= BACKGROUND_BLUE
;
623 attrib_rm
|= (BACKGROUND_RED
| BACKGROUND_GREEN
627 /* Reserved for extended background color.
628 Don't know how to handle parameters remaining.
632 /* Reset background color. */
634 attrib_add
&= ~(BACKGROUND_RED
| BACKGROUND_GREEN
636 attrib_rm
|= (BACKGROUND_RED
| BACKGROUND_GREEN
641 /* Prepare the next parameter. */
644 while (param
!= esc_term
);
647 /* 0xFFFF removes everything. If it is not the case,
648 care must be taken to preserve old attributes. */
649 if (attrib_rm
!= 0xFFFF && GetConsoleScreenBufferInfo (h
, &sb
))
651 attrib_add
|= sb
.wAttributes
& ~attrib_rm
;
653 if (attrib_add
& COMMON_LVB_REVERSE_VIDEO
)
655 /* COMMON_LVB_REVERSE_VIDEO is only effective for DBCS.
656 * Swap foreground and background colors by hand.
658 attrib_add
= (attrib_add
& 0xFF00)
659 | ((attrib_add
& 0x00F0) >> 4)
660 | ((attrib_add
& 0x000F) << 4);
661 attrib_add
&= ~COMMON_LVB_REVERSE_VIDEO
;
663 SetConsoleTextAttribute (h
, attrib_add
);
669 mingw_ansi_fputs (const char *str
, FILE *fp
)
671 const char *read
= str
;
674 int esc_code
, prefix_len
;
675 const char *esc_head
, *esc_term
;
677 h
= (HANDLE
) _get_osfhandle (_fileno (fp
));
678 if (h
== INVALID_HANDLE_VALUE
)
681 /* Don't mess up stdio functions with Windows APIs. */
684 if (GetConsoleMode (h
, &mode
))
685 /* If it is a console, translate ANSI escape codes as needed. */
688 if ((esc_code
= find_esc_head (&prefix_len
, &esc_head
, read
)) == 0)
690 /* Write all remaining characters, then exit. */
691 write_all (h
, read
, strlen (read
));
694 if (find_esc_terminator (&esc_term
, esc_head
) == 0)
695 /* Ignore incomplete escape sequences at the moment.
696 FIXME: The escape state shall be cached for further calls
699 write_all (h
, read
, esc_head
- prefix_len
- read
);
700 eat_esc_sequence (h
, esc_code
, esc_head
, esc_term
);
704 /* If it is not a console, write everything as-is. */
705 write_all (h
, read
, strlen (read
));
710 #endif /* __MINGW32__ */
713 decode_utf8_char (const unsigned char *, size_t len
, unsigned int *);
714 static void pp_quoted_string (pretty_printer
*, const char *, size_t = -1);
716 /* Overwrite the given location/range within this text_info's rich_location.
717 For use e.g. when implementing "+" in client format decoders. */
720 text_info::set_location (unsigned int idx
, location_t loc
,
721 enum range_display_kind range_display_kind
)
723 gcc_checking_assert (m_richloc
);
724 m_richloc
->set_range (idx
, loc
, range_display_kind
);
728 text_info::get_location (unsigned int index_of_location
) const
730 gcc_checking_assert (m_richloc
);
732 if (index_of_location
== 0)
733 return m_richloc
->get_loc ();
735 return UNKNOWN_LOCATION
;
738 // Default construct an output buffer.
740 output_buffer::output_buffer ()
741 : formatted_obstack (),
743 obstack (&formatted_obstack
),
750 obstack_init (&formatted_obstack
);
751 obstack_init (&chunk_obstack
);
754 // Release resources owned by an output buffer at the end of lifetime.
756 output_buffer::~output_buffer ()
758 obstack_free (&chunk_obstack
, NULL
);
759 obstack_free (&formatted_obstack
, NULL
);
763 /* Format an integer given by va_arg (ARG, type-specifier T) where
764 type-specifier is a precision modifier as indicated by PREC. F is
765 a string used to construct the appropriate format-specifier. */
766 #define pp_integer_with_precision(PP, ARG, PREC, T, F) \
771 pp_scalar (PP, "%" F, va_arg (ARG, T)); \
775 pp_scalar (PP, "%l" F, va_arg (ARG, long T)); \
779 pp_scalar (PP, "%" HOST_LONG_LONG_FORMAT F, va_arg (ARG, long long T)); \
788 /* Subroutine of pp_set_maximum_length. Set up PRETTY-PRINTER's
789 internal maximum characters per line. */
791 pp_set_real_maximum_length (pretty_printer
*pp
)
793 /* If we're told not to wrap lines then do the obvious thing. In case
794 we'll emit prefix only once per message, it is appropriate
795 not to increase unnecessarily the line-length cut-off. */
796 if (!pp_is_wrapping_line (pp
)
797 || pp_prefixing_rule (pp
) == DIAGNOSTICS_SHOW_PREFIX_ONCE
798 || pp_prefixing_rule (pp
) == DIAGNOSTICS_SHOW_PREFIX_NEVER
)
799 pp
->maximum_length
= pp_line_cutoff (pp
);
802 int prefix_length
= pp
->prefix
? strlen (pp
->prefix
) : 0;
803 /* If the prefix is ridiculously too long, output at least
805 if (pp_line_cutoff (pp
) - prefix_length
< 32)
806 pp
->maximum_length
= pp_line_cutoff (pp
) + 32;
808 pp
->maximum_length
= pp_line_cutoff (pp
);
812 /* Clear PRETTY-PRINTER's output state. */
814 pp_clear_state (pretty_printer
*pp
)
816 pp
->emitted_prefix
= false;
817 pp_indentation (pp
) = 0;
820 /* Print X to PP in decimal. */
822 template<unsigned int N
, typename T
>
824 pp_wide_integer (pretty_printer
*pp
, const poly_int_pod
<N
, T
> &x
)
826 if (x
.is_constant ())
827 pp_wide_integer (pp
, x
.coeffs
[0]);
830 pp_left_bracket (pp
);
831 for (unsigned int i
= 0; i
< N
; ++i
)
835 pp_wide_integer (pp
, x
.coeffs
[i
]);
837 pp_right_bracket (pp
);
841 template void pp_wide_integer (pretty_printer
*, const poly_uint16_pod
&);
842 template void pp_wide_integer (pretty_printer
*, const poly_int64_pod
&);
843 template void pp_wide_integer (pretty_printer
*, const poly_uint64_pod
&);
846 /* Flush the formatted text of PRETTY-PRINTER onto the attached stream. */
848 pp_write_text_to_stream (pretty_printer
*pp
)
850 const char *text
= pp_formatted_text (pp
);
852 mingw_ansi_fputs (text
, pp_buffer (pp
)->stream
);
854 fputs (text
, pp_buffer (pp
)->stream
);
856 pp_clear_output_area (pp
);
859 /* As pp_write_text_to_stream, but for GraphViz label output.
861 Flush the formatted text of pretty-printer PP onto the attached stream.
862 Replace characters in PPF that have special meaning in a GraphViz .dot
865 This routine is not very fast, but it doesn't have to be as this is only
866 be used by routines dumping intermediate representations in graph form. */
869 pp_write_text_as_dot_label_to_stream (pretty_printer
*pp
, bool for_record
)
871 const char *text
= pp_formatted_text (pp
);
872 const char *p
= text
;
873 FILE *fp
= pp_buffer (pp
)->stream
;
880 /* Print newlines as a left-aligned newline. */
886 /* The following characters are only special for record-shape nodes. */
893 escape_char
= for_record
;
896 /* The following characters always have to be escaped
897 for use in labels. */
899 /* There is a bug in some (f.i. 2.36.0) versions of graphiz
900 ( http://www.graphviz.org/mantisbt/view.php?id=2524 ) related to
901 backslash as last char in label. Let's avoid triggering it. */
902 gcc_assert (*(p
+ 1) != '\0');
919 pp_clear_output_area (pp
);
922 /* As pp_write_text_to_stream, but for GraphViz HTML-like strings.
924 Flush the formatted text of pretty-printer PP onto the attached stream,
925 escaping these characters
927 using XML escape sequences.
929 http://www.graphviz.org/doc/info/lang.html#html states:
930 special XML escape sequences for ", &, <, and > may be necessary in
931 order to embed these characters in attribute values or raw text
932 This doesn't list "'" (which would normally be escaped in XML
933 as "'" or in HTML as "'");.
935 Experiments show that escaping "'" doesn't seem to be necessary. */
938 pp_write_text_as_html_like_dot_to_stream (pretty_printer
*pp
)
940 const char *text
= pp_formatted_text (pp
);
941 const char *p
= text
;
942 FILE *fp
= pp_buffer (pp
)->stream
;
949 fputs (""", fp
);
967 pp_clear_output_area (pp
);
970 /* Wrap a text delimited by START and END into PRETTY-PRINTER. */
972 pp_wrap_text (pretty_printer
*pp
, const char *start
, const char *end
)
974 bool wrapping_line
= pp_is_wrapping_line (pp
);
978 /* Dump anything bordered by whitespaces. */
980 const char *p
= start
;
981 while (p
!= end
&& !ISBLANK (*p
) && *p
!= '\n')
984 && p
- start
>= pp_remaining_character_count_for_line (pp
))
986 pp_append_text (pp
, start
, p
);
990 if (start
!= end
&& ISBLANK (*start
))
995 if (start
!= end
&& *start
== '\n')
1003 /* Same as pp_wrap_text but wrap text only when in line-wrapping mode. */
1005 pp_maybe_wrap_text (pretty_printer
*pp
, const char *start
, const char *end
)
1007 if (pp_is_wrapping_line (pp
))
1008 pp_wrap_text (pp
, start
, end
);
1010 pp_append_text (pp
, start
, end
);
1013 /* Append to the output area of PRETTY-PRINTER a string specified by its
1014 STARTing character and LENGTH. */
1016 pp_append_r (pretty_printer
*pp
, const char *start
, int length
)
1018 output_buffer_append_r (pp_buffer (pp
), start
, length
);
1021 /* Insert enough spaces into the output area of PRETTY-PRINTER to bring
1022 the column position to the current indentation level, assuming that a
1023 newline has just been written to the buffer. */
1025 pp_indent (pretty_printer
*pp
)
1027 int n
= pp_indentation (pp
);
1030 for (i
= 0; i
< n
; ++i
)
1034 static const char *get_end_url_string (pretty_printer
*);
1036 /* The following format specifiers are recognized as being client independent:
1037 %d, %i: (signed) integer in base ten.
1038 %u: unsigned integer in base ten.
1039 %o: unsigned integer in base eight.
1040 %x: unsigned integer in base sixteen.
1041 %ld, %li, %lo, %lu, %lx: long versions of the above.
1042 %lld, %lli, %llo, %llu, %llx: long long versions.
1043 %wd, %wi, %wo, %wu, %wx: HOST_WIDE_INT versions.
1047 %p: pointer (printed in a host-dependent manner).
1048 %r: if pp_show_color(pp), switch to color identified by const char *.
1049 %R: if pp_show_color(pp), reset color.
1050 %m: strerror(text->err_no) - does not consume a value from args_ptr.
1054 %{: URL start. Consumes a const char * argument for the URL.
1055 %}: URL end. Does not consume any arguments.
1056 %': apostrophe (should only be used in untranslated messages;
1057 translations should use appropriate punctuation directly).
1058 %@: diagnostic_event_id_ptr, for which event_id->known_p () must be true.
1059 %.*s: a substring the length of which is specified by an argument
1061 %Ns: likewise, but length specified as constant in the format string.
1062 Flag 'q': quote formatted text (must come immediately after '%').
1063 %Z: Requires two arguments - array of int, and len. Prints elements
1066 Arguments can be used sequentially, or through %N$ resp. *N$
1067 notation Nth argument after the format string. If %N$ / *N$
1068 notation is used, it must be used for all arguments, except %m, %%,
1069 %<, %>, %} and %', which may not have a number, as they do not consume
1070 an argument. When %M$.*N$s is used, M must be N + 1. (This may
1071 also be written %M$.*s, provided N is not otherwise used.) The
1072 format string must have conversion specifiers with argument numbers
1073 1 up to highest argument; each argument may only be used once.
1074 A format string can have at most 30 arguments. */
1076 /* Formatting phases 1 and 2: render TEXT->format_spec plus
1077 TEXT->args_ptr into a series of chunks in pp_buffer (PP)->args[].
1078 Phase 3 is in pp_output_formatted_text. */
1081 pp_format (pretty_printer
*pp
, text_info
*text
)
1083 output_buffer
*buffer
= pp_buffer (pp
);
1086 struct chunk_info
*new_chunk_array
;
1088 unsigned int curarg
= 0, chunk
= 0, argno
;
1089 pp_wrapping_mode_t old_wrapping_mode
;
1090 bool any_unnumbered
= false, any_numbered
= false;
1091 const char **formatters
[PP_NL_ARGMAX
];
1093 /* Allocate a new chunk structure. */
1094 new_chunk_array
= XOBNEW (&buffer
->chunk_obstack
, struct chunk_info
);
1095 new_chunk_array
->prev
= buffer
->cur_chunk_array
;
1096 buffer
->cur_chunk_array
= new_chunk_array
;
1097 args
= new_chunk_array
->args
;
1099 /* Formatting phase 1: split up TEXT->format_spec into chunks in
1100 pp_buffer (PP)->args[]. Even-numbered chunks are to be output
1101 verbatim, odd-numbered chunks are format specifiers.
1102 %m, %%, %<, %>, %} and %' are replaced with the appropriate text at
1105 memset (formatters
, 0, sizeof formatters
);
1107 for (p
= text
->format_spec
; *p
; )
1109 while (*p
!= '\0' && *p
!= '%')
1111 obstack_1grow (&buffer
->chunk_obstack
, *p
);
1124 obstack_1grow (&buffer
->chunk_obstack
, '%');
1130 obstack_grow (&buffer
->chunk_obstack
,
1131 open_quote
, strlen (open_quote
));
1132 const char *colorstr
1133 = colorize_start (pp_show_color (pp
), "quote");
1134 obstack_grow (&buffer
->chunk_obstack
, colorstr
, strlen (colorstr
));
1141 const char *colorstr
= colorize_stop (pp_show_color (pp
));
1142 obstack_grow (&buffer
->chunk_obstack
, colorstr
, strlen (colorstr
));
1146 obstack_grow (&buffer
->chunk_obstack
,
1147 close_quote
, strlen (close_quote
));
1153 const char *endurlstr
= get_end_url_string (pp
);
1154 obstack_grow (&buffer
->chunk_obstack
, endurlstr
,
1155 strlen (endurlstr
));
1162 const char *colorstr
= colorize_stop (pp_show_color (pp
));
1163 obstack_grow (&buffer
->chunk_obstack
, colorstr
,
1171 const char *errstr
= xstrerror (text
->err_no
);
1172 obstack_grow (&buffer
->chunk_obstack
, errstr
, strlen (errstr
));
1178 /* Handled in phase 2. Terminate the plain chunk here. */
1179 obstack_1grow (&buffer
->chunk_obstack
, '\0');
1180 gcc_assert (chunk
< PP_NL_ARGMAX
* 2);
1181 args
[chunk
++] = XOBFINISH (&buffer
->chunk_obstack
, const char *);
1188 argno
= strtoul (p
, &end
, 10) - 1;
1190 gcc_assert (*p
== '$');
1193 any_numbered
= true;
1194 gcc_assert (!any_unnumbered
);
1199 any_unnumbered
= true;
1200 gcc_assert (!any_numbered
);
1202 gcc_assert (argno
< PP_NL_ARGMAX
);
1203 gcc_assert (!formatters
[argno
]);
1204 formatters
[argno
] = &args
[chunk
];
1207 obstack_1grow (&buffer
->chunk_obstack
, *p
);
1210 while (strchr ("qwl+#", p
[-1]));
1214 /* We handle '%.Ns' and '%.*s' or '%M$.*N$s'
1215 (where M == N + 1). */
1220 obstack_1grow (&buffer
->chunk_obstack
, *p
);
1223 while (ISDIGIT (p
[-1]));
1224 gcc_assert (p
[-1] == 's');
1228 gcc_assert (*p
== '*');
1229 obstack_1grow (&buffer
->chunk_obstack
, '*');
1235 unsigned int argno2
= strtoul (p
, &end
, 10) - 1;
1237 gcc_assert (argno2
== argno
- 1);
1238 gcc_assert (!any_unnumbered
);
1239 gcc_assert (*p
== '$');
1242 formatters
[argno2
] = formatters
[argno
];
1246 gcc_assert (!any_numbered
);
1247 formatters
[argno
+1] = formatters
[argno
];
1250 gcc_assert (*p
== 's');
1251 obstack_1grow (&buffer
->chunk_obstack
, 's');
1258 obstack_1grow (&buffer
->chunk_obstack
, '\0');
1259 gcc_assert (chunk
< PP_NL_ARGMAX
* 2);
1260 args
[chunk
++] = XOBFINISH (&buffer
->chunk_obstack
, const char *);
1263 obstack_1grow (&buffer
->chunk_obstack
, '\0');
1264 gcc_assert (chunk
< PP_NL_ARGMAX
* 2);
1265 args
[chunk
++] = XOBFINISH (&buffer
->chunk_obstack
, const char *);
1268 /* Set output to the argument obstack, and switch line-wrapping and
1270 buffer
->obstack
= &buffer
->chunk_obstack
;
1271 const int old_line_length
= buffer
->line_length
;
1272 old_wrapping_mode
= pp_set_verbatim_wrapping (pp
);
1274 /* Second phase. Replace each formatter with the formatted text it
1277 for (argno
= 0; formatters
[argno
]; argno
++)
1285 /* We do not attempt to enforce any ordering on the modifier
1288 for (p
= *formatters
[argno
];; p
++)
1293 gcc_assert (!quote
);
1313 /* We don't support precision beyond that of "long long". */
1314 gcc_assert (precision
< 2);
1321 gcc_assert (!wide
|| precision
== 0);
1324 pp_begin_quote (pp
, pp_show_color (pp
));
1329 pp_string (pp
, colorize_start (pp_show_color (pp
),
1330 va_arg (*text
->args_ptr
,
1336 /* When quoting, print alphanumeric, punctuation, and the space
1337 character unchanged, and all others in hexadecimal with the
1338 "\x" prefix. Otherwise print them all unchanged. */
1339 int chr
= va_arg (*text
->args_ptr
, int);
1340 if (ISPRINT (chr
) || !quote
)
1341 pp_character (pp
, chr
);
1344 const char str
[2] = { chr
, '\0' };
1345 pp_quoted_string (pp
, str
, 1);
1353 pp_wide_integer (pp
, va_arg (*text
->args_ptr
, HOST_WIDE_INT
));
1355 pp_integer_with_precision
1356 (pp
, *text
->args_ptr
, precision
, int, "d");
1361 pp_scalar (pp
, "%" HOST_WIDE_INT_PRINT
"o",
1362 va_arg (*text
->args_ptr
, unsigned HOST_WIDE_INT
));
1364 pp_integer_with_precision
1365 (pp
, *text
->args_ptr
, precision
, unsigned, "o");
1370 pp_quoted_string (pp
, va_arg (*text
->args_ptr
, const char *));
1372 pp_string (pp
, va_arg (*text
->args_ptr
, const char *));
1376 pp_pointer (pp
, va_arg (*text
->args_ptr
, void *));
1381 pp_scalar (pp
, HOST_WIDE_INT_PRINT_UNSIGNED
,
1382 va_arg (*text
->args_ptr
, unsigned HOST_WIDE_INT
));
1384 pp_integer_with_precision
1385 (pp
, *text
->args_ptr
, precision
, unsigned, "u");
1389 pp_double (pp
, va_arg (*text
->args_ptr
, double));
1394 int *v
= va_arg (*text
->args_ptr
, int *);
1395 unsigned len
= va_arg (*text
->args_ptr
, unsigned);
1397 for (unsigned i
= 0; i
< len
; ++i
)
1399 pp_scalar (pp
, "%i", v
[i
]);
1411 pp_scalar (pp
, HOST_WIDE_INT_PRINT_HEX
,
1412 va_arg (*text
->args_ptr
, unsigned HOST_WIDE_INT
));
1414 pp_integer_with_precision
1415 (pp
, *text
->args_ptr
, precision
, unsigned, "x");
1423 /* We handle '%.Ns' and '%.*s' or '%M$.*N$s'
1424 (where M == N + 1). The format string should be verified
1425 already from the first phase. */
1430 n
= strtoul (p
, &end
, 10);
1432 gcc_assert (*p
== 's');
1436 gcc_assert (*p
== '*');
1438 gcc_assert (*p
== 's');
1439 n
= va_arg (*text
->args_ptr
, int);
1441 /* This consumes a second entry in the formatters array. */
1442 gcc_assert (formatters
[argno
] == formatters
[argno
+1]);
1446 s
= va_arg (*text
->args_ptr
, const char *);
1448 /* Append the lesser of precision and strlen (s) characters
1449 from the array (which need not be a nul-terminated string).
1450 Negative precision is treated as if it were omitted. */
1451 size_t len
= n
< 0 ? strlen (s
) : strnlen (s
, n
);
1453 pp_append_text (pp
, s
, s
+ len
);
1459 /* diagnostic_event_id_t *. */
1460 diagnostic_event_id_ptr event_id
1461 = va_arg (*text
->args_ptr
, diagnostic_event_id_ptr
);
1462 gcc_assert (event_id
->known_p ());
1464 pp_string (pp
, colorize_start (pp_show_color (pp
), "path"));
1465 pp_character (pp
, '(');
1466 pp_decimal_int (pp
, event_id
->one_based ());
1467 pp_character (pp
, ')');
1468 pp_string (pp
, colorize_stop (pp_show_color (pp
)));
1473 pp_begin_url (pp
, va_arg (*text
->args_ptr
, const char *));
1480 /* Call the format decoder.
1481 Pass the address of "quote" so that format decoders can
1482 potentially disable printing of the closing quote
1483 (e.g. when printing "'TYPEDEF' aka 'TYPE'" in the C family
1485 gcc_assert (pp_format_decoder (pp
));
1486 ok
= pp_format_decoder (pp
) (pp
, text
, p
,
1487 precision
, wide
, plus
, hash
, "e
,
1494 pp_end_quote (pp
, pp_show_color (pp
));
1496 obstack_1grow (&buffer
->chunk_obstack
, '\0');
1497 *formatters
[argno
] = XOBFINISH (&buffer
->chunk_obstack
, const char *);
1501 for (; argno
< PP_NL_ARGMAX
; argno
++)
1502 gcc_assert (!formatters
[argno
]);
1504 /* If the client supplied a postprocessing object, call its "handle"
1506 if (pp
->m_format_postprocessor
)
1507 pp
->m_format_postprocessor
->handle (pp
);
1509 /* Revert to normal obstack and wrapping mode. */
1510 buffer
->obstack
= &buffer
->formatted_obstack
;
1511 buffer
->line_length
= old_line_length
;
1512 pp_wrapping_mode (pp
) = old_wrapping_mode
;
1513 pp_clear_state (pp
);
1516 /* Format of a message pointed to by TEXT. */
1518 pp_output_formatted_text (pretty_printer
*pp
)
1521 output_buffer
*buffer
= pp_buffer (pp
);
1522 struct chunk_info
*chunk_array
= buffer
->cur_chunk_array
;
1523 const char **args
= chunk_array
->args
;
1525 gcc_assert (buffer
->obstack
== &buffer
->formatted_obstack
);
1527 /* This is a third phase, first 2 phases done in pp_format_args.
1528 Now we actually print it. */
1529 for (chunk
= 0; args
[chunk
]; chunk
++)
1530 pp_string (pp
, args
[chunk
]);
1532 /* Deallocate the chunk structure and everything after it (i.e. the
1533 associated series of formatted strings). */
1534 buffer
->cur_chunk_array
= chunk_array
->prev
;
1535 obstack_free (&buffer
->chunk_obstack
, chunk_array
);
1538 /* Helper subroutine of output_verbatim and verbatim. Do the appropriate
1539 settings needed by BUFFER for a verbatim formatting. */
1541 pp_format_verbatim (pretty_printer
*pp
, text_info
*text
)
1543 /* Set verbatim mode. */
1544 pp_wrapping_mode_t oldmode
= pp_set_verbatim_wrapping (pp
);
1546 /* Do the actual formatting. */
1547 pp_format (pp
, text
);
1548 pp_output_formatted_text (pp
);
1550 /* Restore previous settings. */
1551 pp_wrapping_mode (pp
) = oldmode
;
1554 /* Flush the content of BUFFER onto the attached stream. This
1555 function does nothing unless pp->output_buffer->flush_p. */
1557 pp_flush (pretty_printer
*pp
)
1559 pp_clear_state (pp
);
1560 if (!pp
->buffer
->flush_p
)
1562 pp_write_text_to_stream (pp
);
1563 fflush (pp_buffer (pp
)->stream
);
1566 /* Flush the content of BUFFER onto the attached stream independently
1567 of the value of pp->output_buffer->flush_p. */
1569 pp_really_flush (pretty_printer
*pp
)
1571 pp_clear_state (pp
);
1572 pp_write_text_to_stream (pp
);
1573 fflush (pp_buffer (pp
)->stream
);
1576 /* Sets the number of maximum characters per line PRETTY-PRINTER can
1577 output in line-wrapping mode. A LENGTH value 0 suppresses
1580 pp_set_line_maximum_length (pretty_printer
*pp
, int length
)
1582 pp_line_cutoff (pp
) = length
;
1583 pp_set_real_maximum_length (pp
);
1586 /* Clear PRETTY-PRINTER output area text info. */
1588 pp_clear_output_area (pretty_printer
*pp
)
1590 obstack_free (pp_buffer (pp
)->obstack
,
1591 obstack_base (pp_buffer (pp
)->obstack
));
1592 pp_buffer (pp
)->line_length
= 0;
1595 /* Set PREFIX for PRETTY-PRINTER, taking ownership of PREFIX, which
1596 will eventually be free-ed. */
1599 pp_set_prefix (pretty_printer
*pp
, char *prefix
)
1602 pp
->prefix
= prefix
;
1603 pp_set_real_maximum_length (pp
);
1604 pp
->emitted_prefix
= false;
1605 pp_indentation (pp
) = 0;
1608 /* Take ownership of PP's prefix, setting it to NULL.
1609 This allows clients to save, override, and then restore an existing
1610 prefix, without it being free-ed. */
1613 pp_take_prefix (pretty_printer
*pp
)
1615 char *result
= pp
->prefix
;
1620 /* Free PRETTY-PRINTER's prefix, a previously malloc()'d string. */
1622 pp_destroy_prefix (pretty_printer
*pp
)
1624 if (pp
->prefix
!= NULL
)
1631 /* Write out PRETTY-PRINTER's prefix. */
1633 pp_emit_prefix (pretty_printer
*pp
)
1635 if (pp
->prefix
!= NULL
)
1637 switch (pp_prefixing_rule (pp
))
1640 case DIAGNOSTICS_SHOW_PREFIX_NEVER
:
1643 case DIAGNOSTICS_SHOW_PREFIX_ONCE
:
1644 if (pp
->emitted_prefix
)
1649 pp_indentation (pp
) += 3;
1652 case DIAGNOSTICS_SHOW_PREFIX_EVERY_LINE
:
1654 int prefix_length
= strlen (pp
->prefix
);
1655 pp_append_r (pp
, pp
->prefix
, prefix_length
);
1656 pp
->emitted_prefix
= true;
1663 /* Construct a PRETTY-PRINTER of MAXIMUM_LENGTH characters per line. */
1665 pretty_printer::pretty_printer (int maximum_length
)
1666 : buffer (new (XCNEW (output_buffer
)) output_buffer ()),
1673 m_format_postprocessor (NULL
),
1676 translate_identifiers (true),
1678 url_format (URL_FORMAT_NONE
)
1680 pp_line_cutoff (this) = maximum_length
;
1681 /* By default, we emit prefixes once per message. */
1682 pp_prefixing_rule (this) = DIAGNOSTICS_SHOW_PREFIX_ONCE
;
1683 pp_set_prefix (this, NULL
);
1686 /* Copy constructor for pretty_printer. */
1688 pretty_printer::pretty_printer (const pretty_printer
&other
)
1689 : buffer (new (XCNEW (output_buffer
)) output_buffer ()),
1691 padding (other
.padding
),
1692 maximum_length (other
.maximum_length
),
1693 indent_skip (other
.indent_skip
),
1694 wrapping (other
.wrapping
),
1695 format_decoder (other
.format_decoder
),
1696 m_format_postprocessor (NULL
),
1697 emitted_prefix (other
.emitted_prefix
),
1698 need_newline (other
.need_newline
),
1699 translate_identifiers (other
.translate_identifiers
),
1700 show_color (other
.show_color
),
1701 url_format (other
.url_format
)
1703 pp_line_cutoff (this) = maximum_length
;
1704 /* By default, we emit prefixes once per message. */
1705 pp_prefixing_rule (this) = pp_prefixing_rule (&other
);
1706 pp_set_prefix (this, NULL
);
1708 if (other
.m_format_postprocessor
)
1709 m_format_postprocessor
= other
.m_format_postprocessor
->clone ();
1712 pretty_printer::~pretty_printer ()
1714 if (m_format_postprocessor
)
1715 delete m_format_postprocessor
;
1716 buffer
->~output_buffer ();
1721 /* Base class implementation of pretty_printer::clone vfunc. */
1724 pretty_printer::clone () const
1726 return new pretty_printer (*this);
1729 /* Append a string delimited by START and END to the output area of
1730 PRETTY-PRINTER. No line wrapping is done. However, if beginning a
1731 new line then emit PRETTY-PRINTER's prefix and skip any leading
1732 whitespace if appropriate. The caller must ensure that it is
1735 pp_append_text (pretty_printer
*pp
, const char *start
, const char *end
)
1737 /* Emit prefix and skip whitespace if we're starting a new line. */
1738 if (pp_buffer (pp
)->line_length
== 0)
1740 pp_emit_prefix (pp
);
1741 if (pp_is_wrapping_line (pp
))
1742 while (start
!= end
&& *start
== ' ')
1745 pp_append_r (pp
, start
, end
- start
);
1748 /* Finishes constructing a NULL-terminated character string representing
1749 the PRETTY-PRINTED text. */
1751 pp_formatted_text (pretty_printer
*pp
)
1753 return output_buffer_formatted_text (pp_buffer (pp
));
1756 /* Return a pointer to the last character emitted in PRETTY-PRINTER's
1757 output area. A NULL pointer means no character available. */
1759 pp_last_position_in_text (const pretty_printer
*pp
)
1761 return output_buffer_last_position_in_text (pp_buffer (pp
));
1764 /* Return the amount of characters PRETTY-PRINTER can accept to
1765 make a full line. Meaningful only in line-wrapping mode. */
1767 pp_remaining_character_count_for_line (pretty_printer
*pp
)
1769 return pp
->maximum_length
- pp_buffer (pp
)->line_length
;
1773 /* Format a message into BUFFER a la printf. */
1775 pp_printf (pretty_printer
*pp
, const char *msg
, ...)
1781 text
.err_no
= errno
;
1782 text
.args_ptr
= &ap
;
1783 text
.format_spec
= msg
;
1784 pp_format (pp
, &text
);
1785 pp_output_formatted_text (pp
);
1790 /* Output MESSAGE verbatim into BUFFER. */
1792 pp_verbatim (pretty_printer
*pp
, const char *msg
, ...)
1798 text
.err_no
= errno
;
1799 text
.args_ptr
= &ap
;
1800 text
.format_spec
= msg
;
1801 pp_format_verbatim (pp
, &text
);
1807 /* Have PRETTY-PRINTER start a new line. */
1809 pp_newline (pretty_printer
*pp
)
1811 obstack_1grow (pp_buffer (pp
)->obstack
, '\n');
1812 pp_needs_newline (pp
) = false;
1813 pp_buffer (pp
)->line_length
= 0;
1816 /* Have PRETTY-PRINTER add a CHARACTER. */
1818 pp_character (pretty_printer
*pp
, int c
)
1820 if (pp_is_wrapping_line (pp
)
1821 /* If printing UTF-8, don't wrap in the middle of a sequence. */
1822 && (((unsigned int) c
) & 0xC0) != 0x80
1823 && pp_remaining_character_count_for_line (pp
) <= 0)
1829 obstack_1grow (pp_buffer (pp
)->obstack
, c
);
1830 ++pp_buffer (pp
)->line_length
;
1833 /* Append a STRING to the output area of PRETTY-PRINTER; the STRING may
1834 be line-wrapped if in appropriate mode. */
1836 pp_string (pretty_printer
*pp
, const char *str
)
1838 gcc_checking_assert (str
);
1839 pp_maybe_wrap_text (pp
, str
, str
+ strlen (str
));
1842 /* Append the leading N characters of STRING to the output area of
1843 PRETTY-PRINTER, quoting in hexadecimal non-printable characters.
1844 Setting N = -1 is as if N were set to strlen (STRING). The STRING
1845 may be line-wrapped if in appropriate mode. */
1847 pp_quoted_string (pretty_printer
*pp
, const char *str
, size_t n
/* = -1 */)
1849 gcc_checking_assert (str
);
1851 const char *last
= str
;
1854 /* Compute the length if not specified. */
1855 if (n
== (size_t) -1)
1858 for (ps
= str
; n
; ++ps
, --n
)
1863 /* Don't escape a valid UTF-8 extended char. */
1864 const unsigned char *ups
= (const unsigned char *) ps
;
1867 unsigned int extended_char
;
1868 const int valid_utf8_len
= decode_utf8_char (ups
, n
, &extended_char
);
1869 if (valid_utf8_len
> 0)
1871 ps
+= valid_utf8_len
- 1;
1872 n
-= valid_utf8_len
- 1;
1878 pp_maybe_wrap_text (pp
, last
, ps
);
1880 /* Append the hexadecimal value of the character. Allocate a buffer
1881 that's large enough for a 32-bit char plus the hex prefix. */
1883 int n
= sprintf (buf
, "\\x%02x", (unsigned char)*ps
);
1884 pp_maybe_wrap_text (pp
, buf
, buf
+ n
);
1888 pp_maybe_wrap_text (pp
, last
, ps
);
1891 /* Maybe print out a whitespace if needed. */
1894 pp_maybe_space (pretty_printer
*pp
)
1896 if (pp
->padding
!= pp_none
)
1899 pp
->padding
= pp_none
;
1903 // Add a newline to the pretty printer PP and flush formatted text.
1906 pp_newline_and_flush (pretty_printer
*pp
)
1910 pp_needs_newline (pp
) = false;
1913 // Add a newline to the pretty printer PP, followed by indentation.
1916 pp_newline_and_indent (pretty_printer
*pp
, int n
)
1918 pp_indentation (pp
) += n
;
1921 pp_needs_newline (pp
) = false;
1924 // Add separator C, followed by a single whitespace.
1927 pp_separate_with (pretty_printer
*pp
, char c
)
1929 pp_character (pp
, c
);
1933 /* Add a localized open quote, and if SHOW_COLOR is true, begin colorizing
1934 using the "quote" color. */
1937 pp_begin_quote (pretty_printer
*pp
, bool show_color
)
1939 pp_string (pp
, open_quote
);
1940 pp_string (pp
, colorize_start (show_color
, "quote"));
1943 /* If SHOW_COLOR is true, stop colorizing.
1944 Add a localized close quote. */
1947 pp_end_quote (pretty_printer
*pp
, bool show_color
)
1949 pp_string (pp
, colorize_stop (show_color
));
1950 pp_string (pp
, close_quote
);
1954 /* The string starting at P has LEN (at least 1) bytes left; if they
1955 start with a valid UTF-8 sequence, return the length of that
1956 sequence and set *VALUE to the value of that sequence, and
1957 otherwise return 0 and set *VALUE to (unsigned int) -1. */
1960 decode_utf8_char (const unsigned char *p
, size_t len
, unsigned int *value
)
1962 unsigned int t
= *p
;
1968 size_t utf8_len
= 0;
1971 for (t
= *p
; t
& 0x80; t
<<= 1)
1974 if (utf8_len
> len
|| utf8_len
< 2 || utf8_len
> 6)
1976 *value
= (unsigned int) -1;
1979 ch
= *p
& ((1 << (7 - utf8_len
)) - 1);
1980 for (i
= 1; i
< utf8_len
; i
++)
1982 unsigned int u
= p
[i
];
1983 if ((u
& 0xC0) != 0x80)
1985 *value
= (unsigned int) -1;
1988 ch
= (ch
<< 6) | (u
& 0x3F);
1990 if ( (ch
<= 0x7F && utf8_len
> 1)
1991 || (ch
<= 0x7FF && utf8_len
> 2)
1992 || (ch
<= 0xFFFF && utf8_len
> 3)
1993 || (ch
<= 0x1FFFFF && utf8_len
> 4)
1994 || (ch
<= 0x3FFFFFF && utf8_len
> 5)
1995 || (ch
>= 0xD800 && ch
<= 0xDFFF))
1997 *value
= (unsigned int) -1;
2010 /* Allocator for identifier_to_locale and corresponding function to
2013 void *(*identifier_to_locale_alloc
) (size_t) = xmalloc
;
2014 void (*identifier_to_locale_free
) (void *) = free
;
2016 /* Given IDENT, an identifier in the internal encoding, return a
2017 version of IDENT suitable for diagnostics in the locale character
2018 set: either IDENT itself, or a string, allocated using
2019 identifier_to_locale_alloc, converted to the locale character set
2020 and using escape sequences if not representable in the locale
2021 character set or containing control characters or invalid byte
2022 sequences. Existing backslashes in IDENT are not doubled, so the
2023 result may not uniquely specify the contents of an arbitrary byte
2024 sequence identifier. */
2027 identifier_to_locale (const char *ident
)
2029 const unsigned char *uid
= (const unsigned char *) ident
;
2030 size_t idlen
= strlen (ident
);
2031 bool valid_printable_utf8
= true;
2032 bool all_ascii
= true;
2035 for (i
= 0; i
< idlen
;)
2038 size_t utf8_len
= decode_utf8_char (&uid
[i
], idlen
- i
, &c
);
2039 if (utf8_len
== 0 || c
<= 0x1F || (c
>= 0x7F && c
<= 0x9F))
2041 valid_printable_utf8
= false;
2049 /* If IDENT contains invalid UTF-8 sequences (which may occur with
2050 attributes putting arbitrary byte sequences in identifiers), or
2051 control characters, we use octal escape sequences for all bytes
2052 outside printable ASCII. */
2053 if (!valid_printable_utf8
)
2055 char *ret
= (char *) identifier_to_locale_alloc (4 * idlen
+ 1);
2057 for (i
= 0; i
< idlen
; i
++)
2059 if (uid
[i
] > 0x1F && uid
[i
] < 0x7F)
2063 sprintf (p
, "\\%03o", uid
[i
]);
2071 /* Otherwise, if it is valid printable ASCII, or printable UTF-8
2072 with the locale character set being UTF-8, IDENT is used. */
2073 if (all_ascii
|| locale_utf8
)
2076 /* Otherwise IDENT is converted to the locale character set if
2078 #if defined ENABLE_NLS && defined HAVE_LANGINFO_CODESET && HAVE_ICONV
2079 if (locale_encoding
!= NULL
)
2081 iconv_t cd
= iconv_open (locale_encoding
, "UTF-8");
2082 bool conversion_ok
= true;
2084 if (cd
!= (iconv_t
) -1)
2086 size_t ret_alloc
= 4 * idlen
+ 1;
2089 /* Repeat the whole conversion process as needed with
2090 larger buffers so non-reversible transformations can
2091 always be detected. */
2092 ICONV_CONST
char *inbuf
= CONST_CAST (char *, ident
);
2094 size_t inbytesleft
= idlen
;
2095 size_t outbytesleft
= ret_alloc
- 1;
2098 ret
= (char *) identifier_to_locale_alloc (ret_alloc
);
2101 if (iconv (cd
, 0, 0, 0, 0) == (size_t) -1)
2103 conversion_ok
= false;
2107 iconv_ret
= iconv (cd
, &inbuf
, &inbytesleft
,
2108 &outbuf
, &outbytesleft
);
2109 if (iconv_ret
== (size_t) -1 || inbytesleft
!= 0)
2114 identifier_to_locale_free (ret
);
2120 conversion_ok
= false;
2124 else if (iconv_ret
!= 0)
2126 conversion_ok
= false;
2129 /* Return to initial shift state. */
2130 if (iconv (cd
, 0, 0, &outbuf
, &outbytesleft
) == (size_t) -1)
2135 identifier_to_locale_free (ret
);
2141 conversion_ok
= false;
2155 /* Otherwise, convert non-ASCII characters in IDENT to UCNs. */
2157 char *ret
= (char *) identifier_to_locale_alloc (10 * idlen
+ 1);
2159 for (i
= 0; i
< idlen
;)
2162 size_t utf8_len
= decode_utf8_char (&uid
[i
], idlen
- i
, &c
);
2167 sprintf (p
, "\\U%08x", c
);
2177 /* Support for encoding URLs.
2178 See egmontkob/Hyperlinks_in_Terminal_Emulators.md
2179 ( https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda ).
2181 > A hyperlink is opened upon encountering an OSC 8 escape sequence with
2182 > the target URI. The syntax is
2184 > OSC 8 ; params ; URI ST
2186 > A hyperlink is closed with the same escape sequence, omitting the
2187 > parameters and the URI but keeping the separators:
2191 > OSC (operating system command) is typically ESC ].
2193 Use BEL instead of ST, as that is currently rendered better in some
2194 terminal emulators that don't support OSC 8, like konsole. */
2196 /* If URL-printing is enabled, write an "open URL" escape sequence to PP
2197 for the given URL. */
2200 pp_begin_url (pretty_printer
*pp
, const char *url
)
2202 switch (pp
->url_format
)
2204 case URL_FORMAT_NONE
:
2207 pp_string (pp
, "\33]8;;");
2208 pp_string (pp
, url
);
2209 pp_string (pp
, "\33\\");
2211 case URL_FORMAT_BEL
:
2212 pp_string (pp
, "\33]8;;");
2213 pp_string (pp
, url
);
2214 pp_string (pp
, "\a");
2221 /* Helper function for pp_end_url and pp_format, return the "close URL" escape
2225 get_end_url_string (pretty_printer
*pp
)
2227 switch (pp
->url_format
)
2229 case URL_FORMAT_NONE
:
2232 return "\33]8;;\33\\";
2233 case URL_FORMAT_BEL
:
2240 /* If URL-printing is enabled, write a "close URL" escape sequence to PP. */
2243 pp_end_url (pretty_printer
*pp
)
2245 if (pp
->url_format
!= URL_FORMAT_NONE
)
2246 pp_string (pp
, get_end_url_string (pp
));
2251 namespace selftest
{
2253 /* Smoketest for pretty_printer. */
2256 test_basic_printing ()
2259 pp_string (&pp
, "hello");
2261 pp_string (&pp
, "world");
2263 ASSERT_STREQ ("hello world", pp_formatted_text (&pp
));
2266 /* Helper function for testing pp_format.
2267 Verify that pp_format (FMT, ...) followed by pp_output_formatted_text
2268 prints EXPECTED, assuming that pp_show_color is SHOW_COLOR. */
2271 assert_pp_format_va (const location
&loc
, const char *expected
,
2272 bool show_color
, const char *fmt
, va_list *ap
)
2276 rich_location
rich_loc (line_table
, UNKNOWN_LOCATION
);
2278 ti
.format_spec
= fmt
;
2282 ti
.m_richloc
= &rich_loc
;
2284 pp_show_color (&pp
) = show_color
;
2285 pp_format (&pp
, &ti
);
2286 pp_output_formatted_text (&pp
);
2287 ASSERT_STREQ_AT (loc
, expected
, pp_formatted_text (&pp
));
2290 /* Verify that pp_format (FMT, ...) followed by pp_output_formatted_text
2291 prints EXPECTED, with show_color disabled. */
2294 assert_pp_format (const location
&loc
, const char *expected
,
2295 const char *fmt
, ...)
2300 assert_pp_format_va (loc
, expected
, false, fmt
, &ap
);
2304 /* As above, but with colorization enabled. */
2307 assert_pp_format_colored (const location
&loc
, const char *expected
,
2308 const char *fmt
, ...)
2310 /* The tests of colorization assume the default color scheme.
2311 If GCC_COLORS is set, then the colors have potentially been
2312 overridden; skip the test. */
2313 if (getenv ("GCC_COLORS"))
2319 assert_pp_format_va (loc
, expected
, true, fmt
, &ap
);
2323 /* Helper function for calling testing pp_format,
2324 by calling assert_pp_format with various numbers of arguments.
2325 These exist mostly to avoid having to write SELFTEST_LOCATION
2326 throughout test_pp_format. */
2328 #define ASSERT_PP_FORMAT_1(EXPECTED, FMT, ARG1) \
2329 SELFTEST_BEGIN_STMT \
2330 assert_pp_format ((SELFTEST_LOCATION), (EXPECTED), (FMT), \
2334 #define ASSERT_PP_FORMAT_2(EXPECTED, FMT, ARG1, ARG2) \
2335 SELFTEST_BEGIN_STMT \
2336 assert_pp_format ((SELFTEST_LOCATION), (EXPECTED), (FMT), \
2340 #define ASSERT_PP_FORMAT_3(EXPECTED, FMT, ARG1, ARG2, ARG3) \
2341 SELFTEST_BEGIN_STMT \
2342 assert_pp_format ((SELFTEST_LOCATION), (EXPECTED), (FMT), \
2343 (ARG1), (ARG2), (ARG3)); \
2346 /* Verify that pp_format works, for various format codes. */
2351 /* Avoid introducing locale-specific differences in the results
2352 by hardcoding open_quote and close_quote. */
2353 auto_fix_quotes fix_quotes
;
2355 /* Verify that plain text is passed through unchanged. */
2356 assert_pp_format (SELFTEST_LOCATION
, "unformatted", "unformatted");
2358 /* Verify various individual format codes, in the order listed in the
2359 comment for pp_format above. For each code, we append a second
2360 argument with a known bit pattern (0x12345678), to ensure that we
2361 are consuming arguments correctly. */
2362 ASSERT_PP_FORMAT_2 ("-27 12345678", "%d %x", -27, 0x12345678);
2363 ASSERT_PP_FORMAT_2 ("-5 12345678", "%i %x", -5, 0x12345678);
2364 ASSERT_PP_FORMAT_2 ("10 12345678", "%u %x", 10, 0x12345678);
2365 ASSERT_PP_FORMAT_2 ("17 12345678", "%o %x", 15, 0x12345678);
2366 ASSERT_PP_FORMAT_2 ("cafebabe 12345678", "%x %x", 0xcafebabe, 0x12345678);
2367 ASSERT_PP_FORMAT_2 ("-27 12345678", "%ld %x", (long)-27, 0x12345678);
2368 ASSERT_PP_FORMAT_2 ("-5 12345678", "%li %x", (long)-5, 0x12345678);
2369 ASSERT_PP_FORMAT_2 ("10 12345678", "%lu %x", (long)10, 0x12345678);
2370 ASSERT_PP_FORMAT_2 ("17 12345678", "%lo %x", (long)15, 0x12345678);
2371 ASSERT_PP_FORMAT_2 ("cafebabe 12345678", "%lx %x", (long)0xcafebabe,
2373 ASSERT_PP_FORMAT_2 ("-27 12345678", "%lld %x", (long long)-27, 0x12345678);
2374 ASSERT_PP_FORMAT_2 ("-5 12345678", "%lli %x", (long long)-5, 0x12345678);
2375 ASSERT_PP_FORMAT_2 ("10 12345678", "%llu %x", (long long)10, 0x12345678);
2376 ASSERT_PP_FORMAT_2 ("17 12345678", "%llo %x", (long long)15, 0x12345678);
2377 ASSERT_PP_FORMAT_2 ("cafebabe 12345678", "%llx %x", (long long)0xcafebabe,
2379 ASSERT_PP_FORMAT_2 ("-27 12345678", "%wd %x", (HOST_WIDE_INT
)-27, 0x12345678);
2380 ASSERT_PP_FORMAT_2 ("-5 12345678", "%wi %x", (HOST_WIDE_INT
)-5, 0x12345678);
2381 ASSERT_PP_FORMAT_2 ("10 12345678", "%wu %x", (unsigned HOST_WIDE_INT
)10,
2383 ASSERT_PP_FORMAT_2 ("17 12345678", "%wo %x", (HOST_WIDE_INT
)15, 0x12345678);
2384 ASSERT_PP_FORMAT_2 ("0xcafebabe 12345678", "%wx %x", (HOST_WIDE_INT
)0xcafebabe,
2386 ASSERT_PP_FORMAT_2 ("1.000000 12345678", "%f %x", 1.0, 0x12345678);
2387 ASSERT_PP_FORMAT_2 ("A 12345678", "%c %x", 'A', 0x12345678);
2388 ASSERT_PP_FORMAT_2 ("hello world 12345678", "%s %x", "hello world",
2391 /* Not nul-terminated. */
2392 char arr
[5] = { '1', '2', '3', '4', '5' };
2393 ASSERT_PP_FORMAT_3 ("123 12345678", "%.*s %x", 3, arr
, 0x12345678);
2394 ASSERT_PP_FORMAT_3 ("1234 12345678", "%.*s %x", -1, "1234", 0x12345678);
2395 ASSERT_PP_FORMAT_3 ("12345 12345678", "%.*s %x", 7, "12345", 0x12345678);
2397 /* We can't test for %p; the pointer is printed in an implementation-defined
2399 ASSERT_PP_FORMAT_2 ("normal colored normal 12345678",
2400 "normal %rcolored%R normal %x",
2401 "error", 0x12345678);
2402 assert_pp_format_colored
2404 "normal \33[01;31m\33[Kcolored\33[m\33[K normal 12345678",
2405 "normal %rcolored%R normal %x", "error", 0x12345678);
2407 %m: strerror(text->err_no) - does not consume a value from args_ptr. */
2408 ASSERT_PP_FORMAT_1 ("% 12345678", "%% %x", 0x12345678);
2409 ASSERT_PP_FORMAT_1 ("` 12345678", "%< %x", 0x12345678);
2410 ASSERT_PP_FORMAT_1 ("' 12345678", "%> %x", 0x12345678);
2411 ASSERT_PP_FORMAT_1 ("' 12345678", "%' %x", 0x12345678);
2412 ASSERT_PP_FORMAT_3 ("abc 12345678", "%.*s %x", 3, "abcdef", 0x12345678);
2413 ASSERT_PP_FORMAT_2 ("abc 12345678", "%.3s %x", "abcdef", 0x12345678);
2415 /* Verify flag 'q'. */
2416 ASSERT_PP_FORMAT_2 ("`foo' 12345678", "%qs %x", "foo", 0x12345678);
2417 assert_pp_format_colored (SELFTEST_LOCATION
,
2418 "`\33[01m\33[Kfoo\33[m\33[K' 12345678", "%qs %x",
2422 diagnostic_event_id_t
first (2);
2423 diagnostic_event_id_t
second (7);
2425 ASSERT_PP_FORMAT_2 ("first `free' at (3); second `free' at (8)",
2426 "first %<free%> at %@; second %<free%> at %@",
2428 assert_pp_format_colored
2430 "first `\e[01m\e[Kfree\e[m\e[K' at \e[01;36m\e[K(3)\e[m\e[K;"
2431 " second `\e[01m\e[Kfree\e[m\e[K' at \e[01;36m\e[K(8)\e[m\e[K",
2432 "first %<free%> at %@; second %<free%> at %@",
2437 int v
[] = { 1, 2, 3 };
2438 ASSERT_PP_FORMAT_3 ("1, 2, 3 12345678", "%Z %x", v
, 3, 0x12345678);
2441 ASSERT_PP_FORMAT_3 ("0 12345678", "%Z %x", v2
, 1, 0x12345678);
2443 /* Verify that combinations work, along with unformatted text. */
2444 assert_pp_format (SELFTEST_LOCATION
,
2445 "the quick brown fox jumps over the lazy dog",
2446 "the %s %s %s jumps over the %s %s",
2447 "quick", "brown", "fox", "lazy", "dog");
2448 assert_pp_format (SELFTEST_LOCATION
, "item 3 of 7", "item %i of %i", 3, 7);
2449 assert_pp_format (SELFTEST_LOCATION
, "problem with `bar' at line 10",
2450 "problem with %qs at line %i", "bar", 10);
2453 /* A subclass of pretty_printer for use by test_prefixes_and_wrapping. */
2455 class test_pretty_printer
: public pretty_printer
2458 test_pretty_printer (enum diagnostic_prefixing_rule_t rule
,
2459 int max_line_length
)
2461 pp_set_prefix (this, xstrdup ("PREFIX: "));
2462 wrapping
.rule
= rule
;
2463 pp_set_line_maximum_length (this, max_line_length
);
2467 /* Verify that the various values of enum diagnostic_prefixing_rule_t work
2468 as expected, with and without line wrapping. */
2471 test_prefixes_and_wrapping ()
2473 /* Tests of the various prefixing rules, without wrapping.
2474 Newlines embedded in pp_string don't affect it; we have to
2475 explicitly call pp_newline. */
2477 test_pretty_printer
pp (DIAGNOSTICS_SHOW_PREFIX_ONCE
, 0);
2478 pp_string (&pp
, "the quick brown fox");
2480 pp_string (&pp
, "jumps over the lazy dog");
2482 ASSERT_STREQ (pp_formatted_text (&pp
),
2483 "PREFIX: the quick brown fox\n"
2484 " jumps over the lazy dog\n");
2487 test_pretty_printer
pp (DIAGNOSTICS_SHOW_PREFIX_NEVER
, 0);
2488 pp_string (&pp
, "the quick brown fox");
2490 pp_string (&pp
, "jumps over the lazy dog");
2492 ASSERT_STREQ (pp_formatted_text (&pp
),
2493 "the quick brown fox\n"
2494 "jumps over the lazy dog\n");
2497 test_pretty_printer
pp (DIAGNOSTICS_SHOW_PREFIX_EVERY_LINE
, 0);
2498 pp_string (&pp
, "the quick brown fox");
2500 pp_string (&pp
, "jumps over the lazy dog");
2502 ASSERT_STREQ (pp_formatted_text (&pp
),
2503 "PREFIX: the quick brown fox\n"
2504 "PREFIX: jumps over the lazy dog\n");
2507 /* Tests of the various prefixing rules, with wrapping. */
2509 test_pretty_printer
pp (DIAGNOSTICS_SHOW_PREFIX_ONCE
, 20);
2510 pp_string (&pp
, "the quick brown fox jumps over the lazy dog");
2512 pp_string (&pp
, "able was I ere I saw elba");
2514 ASSERT_STREQ (pp_formatted_text (&pp
),
2515 "PREFIX: the quick \n"
2516 " brown fox jumps \n"
2519 " able was I ere I \n"
2523 test_pretty_printer
pp (DIAGNOSTICS_SHOW_PREFIX_NEVER
, 20);
2524 pp_string (&pp
, "the quick brown fox jumps over the lazy dog");
2526 pp_string (&pp
, "able was I ere I saw elba");
2528 ASSERT_STREQ (pp_formatted_text (&pp
),
2529 "the quick brown fox \n"
2530 "jumps over the lazy \n"
2532 "able was I ere I \n"
2536 test_pretty_printer
pp (DIAGNOSTICS_SHOW_PREFIX_EVERY_LINE
, 20);
2537 pp_string (&pp
, "the quick brown fox jumps over the lazy dog");
2539 pp_string (&pp
, "able was I ere I saw elba");
2541 ASSERT_STREQ (pp_formatted_text (&pp
),
2542 "PREFIX: the quick brown fox jumps over the lazy dog\n"
2543 "PREFIX: able was I ere I saw elba\n");
2548 /* Verify that URL-printing works as expected. */
2555 pp
.url_format
= URL_FORMAT_NONE
;
2556 pp_begin_url (&pp
, "http://example.com");
2557 pp_string (&pp
, "This is a link");
2559 ASSERT_STREQ ("This is a link",
2560 pp_formatted_text (&pp
));
2565 pp
.url_format
= URL_FORMAT_ST
;
2566 pp_begin_url (&pp
, "http://example.com");
2567 pp_string (&pp
, "This is a link");
2569 ASSERT_STREQ ("\33]8;;http://example.com\33\\This is a link\33]8;;\33\\",
2570 pp_formatted_text (&pp
));
2575 pp
.url_format
= URL_FORMAT_BEL
;
2576 pp_begin_url (&pp
, "http://example.com");
2577 pp_string (&pp
, "This is a link");
2579 ASSERT_STREQ ("\33]8;;http://example.com\aThis is a link\33]8;;\a",
2580 pp_formatted_text (&pp
));
2584 /* Test multibyte awareness. */
2585 static void test_utf8 ()
2588 /* Check that pp_quoted_string leaves valid UTF-8 alone. */
2591 const char *s
= "\xf0\x9f\x98\x82";
2592 pp_quoted_string (&pp
, s
);
2593 ASSERT_STREQ (pp_formatted_text (&pp
), s
);
2596 /* Check that pp_quoted_string escapes non-UTF-8 nonprintable bytes. */
2599 pp_quoted_string (&pp
, "\xf0!\x9f\x98\x82");
2600 ASSERT_STREQ (pp_formatted_text (&pp
),
2601 "\\xf0!\\x9f\\x98\\x82");
2604 /* Check that pp_character will line-wrap at the beginning of a UTF-8
2605 sequence, but not in the middle. */
2607 pretty_printer
pp (3);
2608 const char s
[] = "---\xf0\x9f\x98\x82";
2609 for (int i
= 0; i
!= sizeof (s
) - 1; ++i
)
2610 pp_character (&pp
, s
[i
]);
2612 for (int i
= 1; i
!= sizeof (s
) - 1; ++i
)
2613 pp_character (&pp
, s
[i
]);
2614 pp_character (&pp
, '-');
2615 ASSERT_STREQ (pp_formatted_text (&pp
),
2617 "\xf0\x9f\x98\x82\n"
2618 "--\xf0\x9f\x98\x82\n"
2624 /* Run all of the selftests within this file. */
2627 pretty_print_cc_tests ()
2629 test_basic_printing ();
2631 test_prefixes_and_wrapping ();
2636 } // namespace selftest
2638 #endif /* CHECKING_P */