1 /* Various declarations for language-independent pretty-print subroutines.
2 Copyright (C) 2003-2021 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 /* Write all bytes in [s,s+n) into the specified stream.
47 Errors are ignored. */
49 write_all (HANDLE h
, const char *s
, size_t n
)
60 if (!WriteFile (h
, s
+ n
- rem
, step
, &step
, NULL
))
66 /* Find the beginning of an escape sequence.
68 1. If the sequence begins with an ESC character (0x1B) and a second
69 character X in [0x40,0x5F], returns X and stores a pointer to
70 the third character into *head.
71 2. If the sequence begins with a character X in [0x80,0x9F], returns
72 (X-0x40) and stores a pointer to the second character into *head.
73 Stores the number of ESC character(s) in *prefix_len.
74 Returns 0 if no such sequence can be found. */
76 find_esc_head (int *prefix_len
, const char **head
, const char *str
)
84 c
= (unsigned char) *r
;
90 if (escaped
&& 0x40 <= c
&& c
<= 0x5F)
97 if (0x80 <= c
&& c
<= 0x9F)
109 /* Find the terminator of an escape sequence.
110 str should be the value stored in *head by a previous successful
111 call to find_esc_head().
112 Returns 0 if no such sequence can be found. */
114 find_esc_terminator (const char **term
, const char *str
)
121 c
= (unsigned char) *r
;
127 if (0x40 <= c
&& c
<= 0x7E)
137 /* Handle a sequence of codes. Sequences that are invalid, reserved,
138 unrecognized or unimplemented are ignored silently.
139 There isn't much we can do because of lameness of Windows consoles. */
141 eat_esc_sequence (HANDLE h
, int esc_code
,
142 const char *esc_head
, const char *esc_term
)
144 /* Numbers in an escape sequence cannot be negative, because
145 a minus sign in the middle of it would have terminated it. */
148 CONSOLE_SCREEN_BUFFER_INFO sb
;
150 /* ED and EL parameters. */
153 /* SGR parameters. */
154 WORD attrib_add
, attrib_rm
;
157 switch (MAKEWORD (esc_code
, *esc_term
))
160 Move the cursor up by n1 characters. */
161 case MAKEWORD ('[', 'A'):
162 if (esc_head
== esc_term
)
166 n1
= strtol (esc_head
, &eptr
, 10);
167 if (eptr
!= esc_term
)
171 if (GetConsoleScreenBufferInfo (h
, &sb
))
173 cr
= sb
.dwCursorPosition
;
174 /* Stop at the topmost boundary. */
179 SetConsoleCursorPosition (h
, cr
);
184 Move the cursor down by n1 characters. */
185 case MAKEWORD ('[', 'B'):
186 if (esc_head
== esc_term
)
190 n1
= strtol (esc_head
, &eptr
, 10);
191 if (eptr
!= esc_term
)
195 if (GetConsoleScreenBufferInfo (h
, &sb
))
197 cr
= sb
.dwCursorPosition
;
198 /* Stop at the bottommost boundary. */
199 if (sb
.dwSize
.Y
- cr
.Y
> n1
)
203 SetConsoleCursorPosition (h
, cr
);
208 Move the cursor right by n1 characters. */
209 case MAKEWORD ('[', 'C'):
210 if (esc_head
== esc_term
)
214 n1
= strtol (esc_head
, &eptr
, 10);
215 if (eptr
!= esc_term
)
219 if (GetConsoleScreenBufferInfo (h
, &sb
))
221 cr
= sb
.dwCursorPosition
;
222 /* Stop at the rightmost boundary. */
223 if (sb
.dwSize
.X
- cr
.X
> n1
)
227 SetConsoleCursorPosition (h
, cr
);
232 Move the cursor left by n1 characters. */
233 case MAKEWORD ('[', 'D'):
234 if (esc_head
== esc_term
)
238 n1
= strtol (esc_head
, &eptr
, 10);
239 if (eptr
!= esc_term
)
243 if (GetConsoleScreenBufferInfo (h
, &sb
))
245 cr
= sb
.dwCursorPosition
;
246 /* Stop at the leftmost boundary. */
251 SetConsoleCursorPosition (h
, cr
);
256 Move the cursor to the beginning of the n1-th line downwards. */
257 case MAKEWORD ('[', 'E'):
258 if (esc_head
== esc_term
)
262 n1
= strtol (esc_head
, &eptr
, 10);
263 if (eptr
!= esc_term
)
267 if (GetConsoleScreenBufferInfo (h
, &sb
))
269 cr
= sb
.dwCursorPosition
;
271 /* Stop at the bottommost boundary. */
272 if (sb
.dwSize
.Y
- cr
.Y
> n1
)
276 SetConsoleCursorPosition (h
, cr
);
281 Move the cursor to the beginning of the n1-th line upwards. */
282 case MAKEWORD ('[', 'F'):
283 if (esc_head
== esc_term
)
287 n1
= strtol (esc_head
, &eptr
, 10);
288 if (eptr
!= esc_term
)
292 if (GetConsoleScreenBufferInfo (h
, &sb
))
294 cr
= sb
.dwCursorPosition
;
296 /* Stop at the topmost boundary. */
301 SetConsoleCursorPosition (h
, cr
);
306 Move the cursor to the (1-based) n1-th column. */
307 case MAKEWORD ('[', 'G'):
308 if (esc_head
== esc_term
)
312 n1
= strtol (esc_head
, &eptr
, 10);
313 if (eptr
!= esc_term
)
317 if (GetConsoleScreenBufferInfo (h
, &sb
))
319 cr
= sb
.dwCursorPosition
;
321 /* Stop at the leftmost or rightmost boundary. */
324 else if (n1
> sb
.dwSize
.X
)
328 SetConsoleCursorPosition (h
, cr
);
332 /* ESC [ n1 ';' n2 'H'
334 Move the cursor to the (1-based) n1-th row and
335 (also 1-based) n2-th column. */
336 case MAKEWORD ('[', 'H'):
337 case MAKEWORD ('[', 'f'):
338 if (esc_head
== esc_term
)
340 /* Both parameters are omitted and set to 1 by default. */
344 else if (!(delim
= (char *) memchr (esc_head
, ';',
345 esc_term
- esc_head
)))
347 /* Only the first parameter is given. The second one is
348 set to 1 by default. */
349 n1
= strtol (esc_head
, &eptr
, 10);
350 if (eptr
!= esc_term
)
356 /* Both parameters are given. The first one shall be
357 terminated by the semicolon. */
358 n1
= strtol (esc_head
, &eptr
, 10);
361 n2
= strtol (delim
+ 1, &eptr
, 10);
362 if (eptr
!= esc_term
)
366 if (GetConsoleScreenBufferInfo (h
, &sb
))
368 cr
= sb
.dwCursorPosition
;
371 /* The cursor position shall be relative to the view coord of
372 the console window, which is usually smaller than the actual
373 buffer. FWIW, the 'appropriate' solution will be shrinking
374 the buffer to match the size of the console window,
375 destroying scrollback in the process. */
376 n1
+= sb
.srWindow
.Top
;
377 n2
+= sb
.srWindow
.Left
;
378 /* Stop at the topmost or bottommost boundary. */
381 else if (n1
> sb
.dwSize
.Y
)
385 /* Stop at the leftmost or rightmost boundary. */
388 else if (n2
> sb
.dwSize
.X
)
392 SetConsoleCursorPosition (h
, cr
);
398 case MAKEWORD ('[', 'J'):
399 if (esc_head
== esc_term
)
400 /* This is one of the very few codes whose parameters have
401 a default value of zero. */
405 n1
= strtol (esc_head
, &eptr
, 10);
406 if (eptr
!= esc_term
)
410 if (GetConsoleScreenBufferInfo (h
, &sb
))
412 /* The cursor is not necessarily in the console window, which
413 makes the behavior of this code harder to define. */
417 /* If the cursor is in or above the window, erase from
418 it to the bottom of the window; otherwise, do nothing. */
419 cr
= sb
.dwCursorPosition
;
420 cnt
= sb
.dwSize
.X
- sb
.dwCursorPosition
.X
;
421 rows
= sb
.srWindow
.Bottom
- sb
.dwCursorPosition
.Y
;
424 /* If the cursor is in or under the window, erase from
425 it to the top of the window; otherwise, do nothing. */
427 cr
.Y
= sb
.srWindow
.Top
;
428 cnt
= sb
.dwCursorPosition
.X
+ 1;
429 rows
= sb
.dwCursorPosition
.Y
- sb
.srWindow
.Top
;
432 /* Erase the entire window. */
433 cr
.X
= sb
.srWindow
.Left
;
434 cr
.Y
= sb
.srWindow
.Top
;
436 rows
= sb
.srWindow
.Bottom
- sb
.srWindow
.Top
+ 1;
439 /* Erase the entire buffer. */
448 cnt
+= rows
* sb
.dwSize
.X
;
449 FillConsoleOutputCharacterW (h
, L
' ', cnt
, cr
, &step
);
450 FillConsoleOutputAttribute (h
, sb
.wAttributes
, cnt
, cr
, &step
);
456 case MAKEWORD ('[', 'K'):
457 if (esc_head
== esc_term
)
458 /* This is one of the very few codes whose parameters have
459 a default value of zero. */
463 n1
= strtol (esc_head
, &eptr
, 10);
464 if (eptr
!= esc_term
)
468 if (GetConsoleScreenBufferInfo (h
, &sb
))
473 /* Erase from the cursor to the end. */
474 cr
= sb
.dwCursorPosition
;
475 cnt
= sb
.dwSize
.X
- sb
.dwCursorPosition
.X
;
478 /* Erase from the cursor to the beginning. */
479 cr
= sb
.dwCursorPosition
;
481 cnt
= sb
.dwCursorPosition
.X
+ 1;
484 /* Erase the entire line. */
485 cr
= sb
.dwCursorPosition
;
490 FillConsoleOutputCharacterW (h
, L
' ', cnt
, cr
, &step
);
491 FillConsoleOutputAttribute (h
, sb
.wAttributes
, cnt
, cr
, &step
);
495 /* ESC [ n1 ';' n2 'm'
496 Set SGR parameters. Zero or more parameters will follow. */
497 case MAKEWORD ('[', 'm'):
500 if (esc_head
== esc_term
)
502 /* When no parameter is given, reset the console. */
503 attrib_add
|= (FOREGROUND_RED
| FOREGROUND_GREEN
505 attrib_rm
= -1; /* Removes everything. */
511 /* Parse a parameter. */
512 n1
= strtol (param
, &eptr
, 10);
513 if (*eptr
!= ';' && eptr
!= esc_term
)
520 attrib_add
|= (FOREGROUND_RED
| FOREGROUND_GREEN
522 attrib_rm
= -1; /* Removes everything. */
526 attrib_add
|= FOREGROUND_INTENSITY
;
530 attrib_add
|= COMMON_LVB_UNDERSCORE
;
534 /* XXX: It is not BLINKING at all! */
535 attrib_add
|= BACKGROUND_INTENSITY
;
539 attrib_add
|= COMMON_LVB_REVERSE_VIDEO
;
543 attrib_add
&= ~FOREGROUND_INTENSITY
;
544 attrib_rm
|= FOREGROUND_INTENSITY
;
548 attrib_add
&= ~COMMON_LVB_UNDERSCORE
;
549 attrib_rm
|= COMMON_LVB_UNDERSCORE
;
553 /* XXX: It is not BLINKING at all! */
554 attrib_add
&= ~BACKGROUND_INTENSITY
;
555 attrib_rm
|= BACKGROUND_INTENSITY
;
559 attrib_add
&= ~COMMON_LVB_REVERSE_VIDEO
;
560 attrib_rm
|= COMMON_LVB_REVERSE_VIDEO
;
570 /* Foreground color. */
571 attrib_add
&= ~(FOREGROUND_RED
| FOREGROUND_GREEN
575 attrib_add
|= FOREGROUND_RED
;
577 attrib_add
|= FOREGROUND_GREEN
;
579 attrib_add
|= FOREGROUND_BLUE
;
580 attrib_rm
|= (FOREGROUND_RED
| FOREGROUND_GREEN
584 /* Reserved for extended foreground color.
585 Don't know how to handle parameters remaining.
589 /* Reset foreground color. */
591 attrib_add
|= (FOREGROUND_RED
| FOREGROUND_GREEN
593 attrib_rm
|= (FOREGROUND_RED
| FOREGROUND_GREEN
604 /* Background color. */
605 attrib_add
&= ~(BACKGROUND_RED
| BACKGROUND_GREEN
609 attrib_add
|= BACKGROUND_RED
;
611 attrib_add
|= BACKGROUND_GREEN
;
613 attrib_add
|= BACKGROUND_BLUE
;
614 attrib_rm
|= (BACKGROUND_RED
| BACKGROUND_GREEN
618 /* Reserved for extended background color.
619 Don't know how to handle parameters remaining.
623 /* Reset background color. */
625 attrib_add
&= ~(BACKGROUND_RED
| BACKGROUND_GREEN
627 attrib_rm
|= (BACKGROUND_RED
| BACKGROUND_GREEN
632 /* Prepare the next parameter. */
635 while (param
!= esc_term
);
638 /* 0xFFFF removes everything. If it is not the case,
639 care must be taken to preserve old attributes. */
640 if (attrib_rm
!= 0xFFFF && GetConsoleScreenBufferInfo (h
, &sb
))
642 attrib_add
|= sb
.wAttributes
& ~attrib_rm
;
644 if (attrib_add
& COMMON_LVB_REVERSE_VIDEO
)
646 /* COMMON_LVB_REVERSE_VIDEO is only effective for DBCS.
647 * Swap foreground and background colors by hand.
649 attrib_add
= (attrib_add
& 0xFF00)
650 | ((attrib_add
& 0x00F0) >> 4)
651 | ((attrib_add
& 0x000F) << 4);
652 attrib_add
&= ~COMMON_LVB_REVERSE_VIDEO
;
654 SetConsoleTextAttribute (h
, attrib_add
);
660 mingw_ansi_fputs (const char *str
, FILE *fp
)
662 const char *read
= str
;
665 int esc_code
, prefix_len
;
666 const char *esc_head
, *esc_term
;
668 h
= (HANDLE
) _get_osfhandle (_fileno (fp
));
669 if (h
== INVALID_HANDLE_VALUE
)
672 /* Don't mess up stdio functions with Windows APIs. */
675 if (GetConsoleMode (h
, &mode
))
676 /* If it is a console, translate ANSI escape codes as needed. */
679 if ((esc_code
= find_esc_head (&prefix_len
, &esc_head
, read
)) == 0)
681 /* Write all remaining characters, then exit. */
682 write_all (h
, read
, strlen (read
));
685 if (find_esc_terminator (&esc_term
, esc_head
) == 0)
686 /* Ignore incomplete escape sequences at the moment.
687 FIXME: The escape state shall be cached for further calls
690 write_all (h
, read
, esc_head
- prefix_len
- read
);
691 eat_esc_sequence (h
, esc_code
, esc_head
, esc_term
);
695 /* If it is not a console, write everything as-is. */
696 write_all (h
, read
, strlen (read
));
701 #endif /* __MINGW32__ */
704 decode_utf8_char (const unsigned char *, size_t len
, unsigned int *);
705 static void pp_quoted_string (pretty_printer
*, const char *, size_t = -1);
707 /* Overwrite the given location/range within this text_info's rich_location.
708 For use e.g. when implementing "+" in client format decoders. */
711 text_info::set_location (unsigned int idx
, location_t loc
,
712 enum range_display_kind range_display_kind
)
714 gcc_checking_assert (m_richloc
);
715 m_richloc
->set_range (idx
, loc
, range_display_kind
);
719 text_info::get_location (unsigned int index_of_location
) const
721 gcc_checking_assert (m_richloc
);
723 if (index_of_location
== 0)
724 return m_richloc
->get_loc ();
726 return UNKNOWN_LOCATION
;
729 // Default construct an output buffer.
731 output_buffer::output_buffer ()
732 : formatted_obstack (),
734 obstack (&formatted_obstack
),
741 obstack_init (&formatted_obstack
);
742 obstack_init (&chunk_obstack
);
745 // Release resources owned by an output buffer at the end of lifetime.
747 output_buffer::~output_buffer ()
749 obstack_free (&chunk_obstack
, NULL
);
750 obstack_free (&formatted_obstack
, NULL
);
754 /* Format an integer given by va_arg (ARG, type-specifier T) where
755 type-specifier is a precision modifier as indicated by PREC. F is
756 a string used to construct the appropriate format-specifier. */
757 #define pp_integer_with_precision(PP, ARG, PREC, T, F) \
762 pp_scalar (PP, "%" F, va_arg (ARG, T)); \
766 pp_scalar (PP, "%l" F, va_arg (ARG, long T)); \
770 pp_scalar (PP, "%" HOST_LONG_LONG_FORMAT F, va_arg (ARG, long long T)); \
779 /* Subroutine of pp_set_maximum_length. Set up PRETTY-PRINTER's
780 internal maximum characters per line. */
782 pp_set_real_maximum_length (pretty_printer
*pp
)
784 /* If we're told not to wrap lines then do the obvious thing. In case
785 we'll emit prefix only once per message, it is appropriate
786 not to increase unnecessarily the line-length cut-off. */
787 if (!pp_is_wrapping_line (pp
)
788 || pp_prefixing_rule (pp
) == DIAGNOSTICS_SHOW_PREFIX_ONCE
789 || pp_prefixing_rule (pp
) == DIAGNOSTICS_SHOW_PREFIX_NEVER
)
790 pp
->maximum_length
= pp_line_cutoff (pp
);
793 int prefix_length
= pp
->prefix
? strlen (pp
->prefix
) : 0;
794 /* If the prefix is ridiculously too long, output at least
796 if (pp_line_cutoff (pp
) - prefix_length
< 32)
797 pp
->maximum_length
= pp_line_cutoff (pp
) + 32;
799 pp
->maximum_length
= pp_line_cutoff (pp
);
803 /* Clear PRETTY-PRINTER's output state. */
805 pp_clear_state (pretty_printer
*pp
)
807 pp
->emitted_prefix
= false;
808 pp_indentation (pp
) = 0;
811 /* Print X to PP in decimal. */
812 template<unsigned int N
, typename T
>
814 pp_wide_integer (pretty_printer
*pp
, const poly_int_pod
<N
, T
> &x
)
816 if (x
.is_constant ())
817 pp_wide_integer (pp
, x
.coeffs
[0]);
820 pp_left_bracket (pp
);
821 for (unsigned int i
= 0; i
< N
; ++i
)
825 pp_wide_integer (pp
, x
.coeffs
[i
]);
827 pp_right_bracket (pp
);
831 template void pp_wide_integer (pretty_printer
*, const poly_uint16_pod
&);
832 template void pp_wide_integer (pretty_printer
*, const poly_int64_pod
&);
833 template void pp_wide_integer (pretty_printer
*, const poly_uint64_pod
&);
835 /* Flush the formatted text of PRETTY-PRINTER onto the attached stream. */
837 pp_write_text_to_stream (pretty_printer
*pp
)
839 const char *text
= pp_formatted_text (pp
);
841 mingw_ansi_fputs (text
, pp_buffer (pp
)->stream
);
843 fputs (text
, pp_buffer (pp
)->stream
);
845 pp_clear_output_area (pp
);
848 /* As pp_write_text_to_stream, but for GraphViz label output.
850 Flush the formatted text of pretty-printer PP onto the attached stream.
851 Replace characters in PPF that have special meaning in a GraphViz .dot
854 This routine is not very fast, but it doesn't have to be as this is only
855 be used by routines dumping intermediate representations in graph form. */
858 pp_write_text_as_dot_label_to_stream (pretty_printer
*pp
, bool for_record
)
860 const char *text
= pp_formatted_text (pp
);
861 const char *p
= text
;
862 FILE *fp
= pp_buffer (pp
)->stream
;
869 /* Print newlines as a left-aligned newline. */
875 /* The following characters are only special for record-shape nodes. */
882 escape_char
= for_record
;
885 /* The following characters always have to be escaped
886 for use in labels. */
888 /* There is a bug in some (f.i. 2.36.0) versions of graphiz
889 ( http://www.graphviz.org/mantisbt/view.php?id=2524 ) related to
890 backslash as last char in label. Let's avoid triggering it. */
891 gcc_assert (*(p
+ 1) != '\0');
908 pp_clear_output_area (pp
);
911 /* As pp_write_text_to_stream, but for GraphViz HTML-like strings.
913 Flush the formatted text of pretty-printer PP onto the attached stream,
914 escaping these characters
916 using XML escape sequences.
918 http://www.graphviz.org/doc/info/lang.html#html states:
919 special XML escape sequences for ", &, <, and > may be necessary in
920 order to embed these characters in attribute values or raw text
921 This doesn't list "'" (which would normally be escaped in XML
922 as "'" or in HTML as "'");.
924 Experiments show that escaping "'" doesn't seem to be necessary. */
927 pp_write_text_as_html_like_dot_to_stream (pretty_printer
*pp
)
929 const char *text
= pp_formatted_text (pp
);
930 const char *p
= text
;
931 FILE *fp
= pp_buffer (pp
)->stream
;
938 fputs (""", fp
);
956 pp_clear_output_area (pp
);
959 /* Wrap a text delimited by START and END into PRETTY-PRINTER. */
961 pp_wrap_text (pretty_printer
*pp
, const char *start
, const char *end
)
963 bool wrapping_line
= pp_is_wrapping_line (pp
);
967 /* Dump anything bordered by whitespaces. */
969 const char *p
= start
;
970 while (p
!= end
&& !ISBLANK (*p
) && *p
!= '\n')
973 && p
- start
>= pp_remaining_character_count_for_line (pp
))
975 pp_append_text (pp
, start
, p
);
979 if (start
!= end
&& ISBLANK (*start
))
984 if (start
!= end
&& *start
== '\n')
992 /* Same as pp_wrap_text but wrap text only when in line-wrapping mode. */
994 pp_maybe_wrap_text (pretty_printer
*pp
, const char *start
, const char *end
)
996 if (pp_is_wrapping_line (pp
))
997 pp_wrap_text (pp
, start
, end
);
999 pp_append_text (pp
, start
, end
);
1002 /* Append to the output area of PRETTY-PRINTER a string specified by its
1003 STARTing character and LENGTH. */
1005 pp_append_r (pretty_printer
*pp
, const char *start
, int length
)
1007 output_buffer_append_r (pp_buffer (pp
), start
, length
);
1010 /* Insert enough spaces into the output area of PRETTY-PRINTER to bring
1011 the column position to the current indentation level, assuming that a
1012 newline has just been written to the buffer. */
1014 pp_indent (pretty_printer
*pp
)
1016 int n
= pp_indentation (pp
);
1019 for (i
= 0; i
< n
; ++i
)
1023 static const char *get_end_url_string (pretty_printer
*);
1025 /* The following format specifiers are recognized as being client independent:
1026 %d, %i: (signed) integer in base ten.
1027 %u: unsigned integer in base ten.
1028 %o: unsigned integer in base eight.
1029 %x: unsigned integer in base sixteen.
1030 %ld, %li, %lo, %lu, %lx: long versions of the above.
1031 %lld, %lli, %llo, %llu, %llx: long long versions.
1032 %wd, %wi, %wo, %wu, %wx: HOST_WIDE_INT versions.
1036 %p: pointer (printed in a host-dependent manner).
1037 %r: if pp_show_color(pp), switch to color identified by const char *.
1038 %R: if pp_show_color(pp), reset color.
1039 %m: strerror(text->err_no) - does not consume a value from args_ptr.
1043 %{: URL start. Consumes a const char * argument for the URL.
1044 %}: URL end. Does not consume any arguments.
1045 %': apostrophe (should only be used in untranslated messages;
1046 translations should use appropriate punctuation directly).
1047 %@: diagnostic_event_id_ptr, for which event_id->known_p () must be true.
1048 %.*s: a substring the length of which is specified by an argument
1050 %Ns: likewise, but length specified as constant in the format string.
1051 Flag 'q': quote formatted text (must come immediately after '%').
1052 %Z: Requires two arguments - array of int, and len. Prints elements
1055 Arguments can be used sequentially, or through %N$ resp. *N$
1056 notation Nth argument after the format string. If %N$ / *N$
1057 notation is used, it must be used for all arguments, except %m, %%,
1058 %<, %>, %} and %', which may not have a number, as they do not consume
1059 an argument. When %M$.*N$s is used, M must be N + 1. (This may
1060 also be written %M$.*s, provided N is not otherwise used.) The
1061 format string must have conversion specifiers with argument numbers
1062 1 up to highest argument; each argument may only be used once.
1063 A format string can have at most 30 arguments. */
1065 /* Formatting phases 1 and 2: render TEXT->format_spec plus
1066 TEXT->args_ptr into a series of chunks in pp_buffer (PP)->args[].
1067 Phase 3 is in pp_output_formatted_text. */
1070 pp_format (pretty_printer
*pp
, text_info
*text
)
1072 output_buffer
*buffer
= pp_buffer (pp
);
1075 struct chunk_info
*new_chunk_array
;
1077 unsigned int curarg
= 0, chunk
= 0, argno
;
1078 pp_wrapping_mode_t old_wrapping_mode
;
1079 bool any_unnumbered
= false, any_numbered
= false;
1080 const char **formatters
[PP_NL_ARGMAX
];
1082 /* Allocate a new chunk structure. */
1083 new_chunk_array
= XOBNEW (&buffer
->chunk_obstack
, struct chunk_info
);
1084 new_chunk_array
->prev
= buffer
->cur_chunk_array
;
1085 buffer
->cur_chunk_array
= new_chunk_array
;
1086 args
= new_chunk_array
->args
;
1088 /* Formatting phase 1: split up TEXT->format_spec into chunks in
1089 pp_buffer (PP)->args[]. Even-numbered chunks are to be output
1090 verbatim, odd-numbered chunks are format specifiers.
1091 %m, %%, %<, %>, %} and %' are replaced with the appropriate text at
1094 memset (formatters
, 0, sizeof formatters
);
1096 for (p
= text
->format_spec
; *p
; )
1098 while (*p
!= '\0' && *p
!= '%')
1100 obstack_1grow (&buffer
->chunk_obstack
, *p
);
1113 obstack_1grow (&buffer
->chunk_obstack
, '%');
1119 obstack_grow (&buffer
->chunk_obstack
,
1120 open_quote
, strlen (open_quote
));
1121 const char *colorstr
1122 = colorize_start (pp_show_color (pp
), "quote");
1123 obstack_grow (&buffer
->chunk_obstack
, colorstr
, strlen (colorstr
));
1130 const char *colorstr
= colorize_stop (pp_show_color (pp
));
1131 obstack_grow (&buffer
->chunk_obstack
, colorstr
, strlen (colorstr
));
1135 obstack_grow (&buffer
->chunk_obstack
,
1136 close_quote
, strlen (close_quote
));
1142 const char *endurlstr
= get_end_url_string (pp
);
1143 obstack_grow (&buffer
->chunk_obstack
, endurlstr
,
1144 strlen (endurlstr
));
1151 const char *colorstr
= colorize_stop (pp_show_color (pp
));
1152 obstack_grow (&buffer
->chunk_obstack
, colorstr
,
1160 const char *errstr
= xstrerror (text
->err_no
);
1161 obstack_grow (&buffer
->chunk_obstack
, errstr
, strlen (errstr
));
1167 /* Handled in phase 2. Terminate the plain chunk here. */
1168 obstack_1grow (&buffer
->chunk_obstack
, '\0');
1169 gcc_assert (chunk
< PP_NL_ARGMAX
* 2);
1170 args
[chunk
++] = XOBFINISH (&buffer
->chunk_obstack
, const char *);
1177 argno
= strtoul (p
, &end
, 10) - 1;
1179 gcc_assert (*p
== '$');
1182 any_numbered
= true;
1183 gcc_assert (!any_unnumbered
);
1188 any_unnumbered
= true;
1189 gcc_assert (!any_numbered
);
1191 gcc_assert (argno
< PP_NL_ARGMAX
);
1192 gcc_assert (!formatters
[argno
]);
1193 formatters
[argno
] = &args
[chunk
];
1196 obstack_1grow (&buffer
->chunk_obstack
, *p
);
1199 while (strchr ("qwl+#", p
[-1]));
1203 /* We handle '%.Ns' and '%.*s' or '%M$.*N$s'
1204 (where M == N + 1). */
1209 obstack_1grow (&buffer
->chunk_obstack
, *p
);
1212 while (ISDIGIT (p
[-1]));
1213 gcc_assert (p
[-1] == 's');
1217 gcc_assert (*p
== '*');
1218 obstack_1grow (&buffer
->chunk_obstack
, '*');
1224 unsigned int argno2
= strtoul (p
, &end
, 10) - 1;
1226 gcc_assert (argno2
== argno
- 1);
1227 gcc_assert (!any_unnumbered
);
1228 gcc_assert (*p
== '$');
1231 formatters
[argno2
] = formatters
[argno
];
1235 gcc_assert (!any_numbered
);
1236 formatters
[argno
+1] = formatters
[argno
];
1239 gcc_assert (*p
== 's');
1240 obstack_1grow (&buffer
->chunk_obstack
, 's');
1247 obstack_1grow (&buffer
->chunk_obstack
, '\0');
1248 gcc_assert (chunk
< PP_NL_ARGMAX
* 2);
1249 args
[chunk
++] = XOBFINISH (&buffer
->chunk_obstack
, const char *);
1252 obstack_1grow (&buffer
->chunk_obstack
, '\0');
1253 gcc_assert (chunk
< PP_NL_ARGMAX
* 2);
1254 args
[chunk
++] = XOBFINISH (&buffer
->chunk_obstack
, const char *);
1257 /* Set output to the argument obstack, and switch line-wrapping and
1259 buffer
->obstack
= &buffer
->chunk_obstack
;
1260 const int old_line_length
= buffer
->line_length
;
1261 old_wrapping_mode
= pp_set_verbatim_wrapping (pp
);
1263 /* Second phase. Replace each formatter with the formatted text it
1266 for (argno
= 0; formatters
[argno
]; argno
++)
1274 /* We do not attempt to enforce any ordering on the modifier
1277 for (p
= *formatters
[argno
];; p
++)
1282 gcc_assert (!quote
);
1302 /* We don't support precision beyond that of "long long". */
1303 gcc_assert (precision
< 2);
1310 gcc_assert (!wide
|| precision
== 0);
1313 pp_begin_quote (pp
, pp_show_color (pp
));
1318 pp_string (pp
, colorize_start (pp_show_color (pp
),
1319 va_arg (*text
->args_ptr
,
1325 /* When quoting, print alphanumeric, punctuation, and the space
1326 character unchanged, and all others in hexadecimal with the
1327 "\x" prefix. Otherwise print them all unchanged. */
1328 int chr
= va_arg (*text
->args_ptr
, int);
1329 if (ISPRINT (chr
) || !quote
)
1330 pp_character (pp
, chr
);
1333 const char str
[2] = { chr
, '\0' };
1334 pp_quoted_string (pp
, str
, 1);
1342 pp_wide_integer (pp
, va_arg (*text
->args_ptr
, HOST_WIDE_INT
));
1344 pp_integer_with_precision
1345 (pp
, *text
->args_ptr
, precision
, int, "d");
1350 pp_scalar (pp
, "%" HOST_WIDE_INT_PRINT
"o",
1351 va_arg (*text
->args_ptr
, unsigned HOST_WIDE_INT
));
1353 pp_integer_with_precision
1354 (pp
, *text
->args_ptr
, precision
, unsigned, "o");
1359 pp_quoted_string (pp
, va_arg (*text
->args_ptr
, const char *));
1361 pp_string (pp
, va_arg (*text
->args_ptr
, const char *));
1365 pp_pointer (pp
, va_arg (*text
->args_ptr
, void *));
1370 pp_scalar (pp
, HOST_WIDE_INT_PRINT_UNSIGNED
,
1371 va_arg (*text
->args_ptr
, unsigned HOST_WIDE_INT
));
1373 pp_integer_with_precision
1374 (pp
, *text
->args_ptr
, precision
, unsigned, "u");
1378 pp_double (pp
, va_arg (*text
->args_ptr
, double));
1383 int *v
= va_arg (*text
->args_ptr
, int *);
1384 unsigned len
= va_arg (*text
->args_ptr
, unsigned);
1386 for (unsigned i
= 0; i
< len
; ++i
)
1388 pp_scalar (pp
, "%i", v
[i
]);
1400 pp_scalar (pp
, HOST_WIDE_INT_PRINT_HEX
,
1401 va_arg (*text
->args_ptr
, unsigned HOST_WIDE_INT
));
1403 pp_integer_with_precision
1404 (pp
, *text
->args_ptr
, precision
, unsigned, "x");
1412 /* We handle '%.Ns' and '%.*s' or '%M$.*N$s'
1413 (where M == N + 1). The format string should be verified
1414 already from the first phase. */
1419 n
= strtoul (p
, &end
, 10);
1421 gcc_assert (*p
== 's');
1425 gcc_assert (*p
== '*');
1427 gcc_assert (*p
== 's');
1428 n
= va_arg (*text
->args_ptr
, int);
1430 /* This consumes a second entry in the formatters array. */
1431 gcc_assert (formatters
[argno
] == formatters
[argno
+1]);
1435 s
= va_arg (*text
->args_ptr
, const char *);
1437 /* Append the lesser of precision and strlen (s) characters
1438 from the array (which need not be a nul-terminated string).
1439 Negative precision is treated as if it were omitted. */
1440 size_t len
= n
< 0 ? strlen (s
) : strnlen (s
, n
);
1442 pp_append_text (pp
, s
, s
+ len
);
1448 /* diagnostic_event_id_t *. */
1449 diagnostic_event_id_ptr event_id
1450 = va_arg (*text
->args_ptr
, diagnostic_event_id_ptr
);
1451 gcc_assert (event_id
->known_p ());
1453 pp_string (pp
, colorize_start (pp_show_color (pp
), "path"));
1454 pp_character (pp
, '(');
1455 pp_decimal_int (pp
, event_id
->one_based ());
1456 pp_character (pp
, ')');
1457 pp_string (pp
, colorize_stop (pp_show_color (pp
)));
1462 pp_begin_url (pp
, va_arg (*text
->args_ptr
, const char *));
1469 /* Call the format decoder.
1470 Pass the address of "quote" so that format decoders can
1471 potentially disable printing of the closing quote
1472 (e.g. when printing "'TYPEDEF' aka 'TYPE'" in the C family
1474 gcc_assert (pp_format_decoder (pp
));
1475 ok
= pp_format_decoder (pp
) (pp
, text
, p
,
1476 precision
, wide
, plus
, hash
, "e
,
1483 pp_end_quote (pp
, pp_show_color (pp
));
1485 obstack_1grow (&buffer
->chunk_obstack
, '\0');
1486 *formatters
[argno
] = XOBFINISH (&buffer
->chunk_obstack
, const char *);
1490 for (; argno
< PP_NL_ARGMAX
; argno
++)
1491 gcc_assert (!formatters
[argno
]);
1493 /* If the client supplied a postprocessing object, call its "handle"
1495 if (pp
->m_format_postprocessor
)
1496 pp
->m_format_postprocessor
->handle (pp
);
1498 /* Revert to normal obstack and wrapping mode. */
1499 buffer
->obstack
= &buffer
->formatted_obstack
;
1500 buffer
->line_length
= old_line_length
;
1501 pp_wrapping_mode (pp
) = old_wrapping_mode
;
1502 pp_clear_state (pp
);
1505 /* Format of a message pointed to by TEXT. */
1507 pp_output_formatted_text (pretty_printer
*pp
)
1510 output_buffer
*buffer
= pp_buffer (pp
);
1511 struct chunk_info
*chunk_array
= buffer
->cur_chunk_array
;
1512 const char **args
= chunk_array
->args
;
1514 gcc_assert (buffer
->obstack
== &buffer
->formatted_obstack
);
1516 /* This is a third phase, first 2 phases done in pp_format_args.
1517 Now we actually print it. */
1518 for (chunk
= 0; args
[chunk
]; chunk
++)
1519 pp_string (pp
, args
[chunk
]);
1521 /* Deallocate the chunk structure and everything after it (i.e. the
1522 associated series of formatted strings). */
1523 buffer
->cur_chunk_array
= chunk_array
->prev
;
1524 obstack_free (&buffer
->chunk_obstack
, chunk_array
);
1527 /* Helper subroutine of output_verbatim and verbatim. Do the appropriate
1528 settings needed by BUFFER for a verbatim formatting. */
1530 pp_format_verbatim (pretty_printer
*pp
, text_info
*text
)
1532 /* Set verbatim mode. */
1533 pp_wrapping_mode_t oldmode
= pp_set_verbatim_wrapping (pp
);
1535 /* Do the actual formatting. */
1536 pp_format (pp
, text
);
1537 pp_output_formatted_text (pp
);
1539 /* Restore previous settings. */
1540 pp_wrapping_mode (pp
) = oldmode
;
1543 /* Flush the content of BUFFER onto the attached stream. This
1544 function does nothing unless pp->output_buffer->flush_p. */
1546 pp_flush (pretty_printer
*pp
)
1548 pp_clear_state (pp
);
1549 if (!pp
->buffer
->flush_p
)
1551 pp_write_text_to_stream (pp
);
1552 fflush (pp_buffer (pp
)->stream
);
1555 /* Flush the content of BUFFER onto the attached stream independently
1556 of the value of pp->output_buffer->flush_p. */
1558 pp_really_flush (pretty_printer
*pp
)
1560 pp_clear_state (pp
);
1561 pp_write_text_to_stream (pp
);
1562 fflush (pp_buffer (pp
)->stream
);
1565 /* Sets the number of maximum characters per line PRETTY-PRINTER can
1566 output in line-wrapping mode. A LENGTH value 0 suppresses
1569 pp_set_line_maximum_length (pretty_printer
*pp
, int length
)
1571 pp_line_cutoff (pp
) = length
;
1572 pp_set_real_maximum_length (pp
);
1575 /* Clear PRETTY-PRINTER output area text info. */
1577 pp_clear_output_area (pretty_printer
*pp
)
1579 obstack_free (pp_buffer (pp
)->obstack
,
1580 obstack_base (pp_buffer (pp
)->obstack
));
1581 pp_buffer (pp
)->line_length
= 0;
1584 /* Set PREFIX for PRETTY-PRINTER, taking ownership of PREFIX, which
1585 will eventually be free-ed. */
1588 pp_set_prefix (pretty_printer
*pp
, char *prefix
)
1591 pp
->prefix
= prefix
;
1592 pp_set_real_maximum_length (pp
);
1593 pp
->emitted_prefix
= false;
1594 pp_indentation (pp
) = 0;
1597 /* Take ownership of PP's prefix, setting it to NULL.
1598 This allows clients to save, override, and then restore an existing
1599 prefix, without it being free-ed. */
1602 pp_take_prefix (pretty_printer
*pp
)
1604 char *result
= pp
->prefix
;
1609 /* Free PRETTY-PRINTER's prefix, a previously malloc()'d string. */
1611 pp_destroy_prefix (pretty_printer
*pp
)
1613 if (pp
->prefix
!= NULL
)
1620 /* Write out PRETTY-PRINTER's prefix. */
1622 pp_emit_prefix (pretty_printer
*pp
)
1624 if (pp
->prefix
!= NULL
)
1626 switch (pp_prefixing_rule (pp
))
1629 case DIAGNOSTICS_SHOW_PREFIX_NEVER
:
1632 case DIAGNOSTICS_SHOW_PREFIX_ONCE
:
1633 if (pp
->emitted_prefix
)
1638 pp_indentation (pp
) += 3;
1641 case DIAGNOSTICS_SHOW_PREFIX_EVERY_LINE
:
1643 int prefix_length
= strlen (pp
->prefix
);
1644 pp_append_r (pp
, pp
->prefix
, prefix_length
);
1645 pp
->emitted_prefix
= true;
1652 /* Construct a PRETTY-PRINTER of MAXIMUM_LENGTH characters per line. */
1654 pretty_printer::pretty_printer (int maximum_length
)
1655 : buffer (new (XCNEW (output_buffer
)) output_buffer ()),
1662 m_format_postprocessor (NULL
),
1665 translate_identifiers (true),
1667 url_format (URL_FORMAT_NONE
)
1669 pp_line_cutoff (this) = maximum_length
;
1670 /* By default, we emit prefixes once per message. */
1671 pp_prefixing_rule (this) = DIAGNOSTICS_SHOW_PREFIX_ONCE
;
1672 pp_set_prefix (this, NULL
);
1675 /* Copy constructor for pretty_printer. */
1677 pretty_printer::pretty_printer (const pretty_printer
&other
)
1678 : buffer (new (XCNEW (output_buffer
)) output_buffer ()),
1680 padding (other
.padding
),
1681 maximum_length (other
.maximum_length
),
1682 indent_skip (other
.indent_skip
),
1683 wrapping (other
.wrapping
),
1684 format_decoder (other
.format_decoder
),
1685 m_format_postprocessor (NULL
),
1686 emitted_prefix (other
.emitted_prefix
),
1687 need_newline (other
.need_newline
),
1688 translate_identifiers (other
.translate_identifiers
),
1689 show_color (other
.show_color
),
1690 url_format (other
.url_format
)
1692 pp_line_cutoff (this) = maximum_length
;
1693 /* By default, we emit prefixes once per message. */
1694 pp_prefixing_rule (this) = pp_prefixing_rule (&other
);
1695 pp_set_prefix (this, NULL
);
1697 if (other
.m_format_postprocessor
)
1698 m_format_postprocessor
= other
.m_format_postprocessor
->clone ();
1701 pretty_printer::~pretty_printer ()
1703 if (m_format_postprocessor
)
1704 delete m_format_postprocessor
;
1705 buffer
->~output_buffer ();
1710 /* Base class implementation of pretty_printer::clone vfunc. */
1713 pretty_printer::clone () const
1715 return new pretty_printer (*this);
1718 /* Append a string delimited by START and END to the output area of
1719 PRETTY-PRINTER. No line wrapping is done. However, if beginning a
1720 new line then emit PRETTY-PRINTER's prefix and skip any leading
1721 whitespace if appropriate. The caller must ensure that it is
1724 pp_append_text (pretty_printer
*pp
, const char *start
, const char *end
)
1726 /* Emit prefix and skip whitespace if we're starting a new line. */
1727 if (pp_buffer (pp
)->line_length
== 0)
1729 pp_emit_prefix (pp
);
1730 if (pp_is_wrapping_line (pp
))
1731 while (start
!= end
&& *start
== ' ')
1734 pp_append_r (pp
, start
, end
- start
);
1737 /* Finishes constructing a NULL-terminated character string representing
1738 the PRETTY-PRINTED text. */
1740 pp_formatted_text (pretty_printer
*pp
)
1742 return output_buffer_formatted_text (pp_buffer (pp
));
1745 /* Return a pointer to the last character emitted in PRETTY-PRINTER's
1746 output area. A NULL pointer means no character available. */
1748 pp_last_position_in_text (const pretty_printer
*pp
)
1750 return output_buffer_last_position_in_text (pp_buffer (pp
));
1753 /* Return the amount of characters PRETTY-PRINTER can accept to
1754 make a full line. Meaningful only in line-wrapping mode. */
1756 pp_remaining_character_count_for_line (pretty_printer
*pp
)
1758 return pp
->maximum_length
- pp_buffer (pp
)->line_length
;
1762 /* Format a message into BUFFER a la printf. */
1764 pp_printf (pretty_printer
*pp
, const char *msg
, ...)
1770 text
.err_no
= errno
;
1771 text
.args_ptr
= &ap
;
1772 text
.format_spec
= msg
;
1773 pp_format (pp
, &text
);
1774 pp_output_formatted_text (pp
);
1779 /* Output MESSAGE verbatim into BUFFER. */
1781 pp_verbatim (pretty_printer
*pp
, const char *msg
, ...)
1787 text
.err_no
= errno
;
1788 text
.args_ptr
= &ap
;
1789 text
.format_spec
= msg
;
1790 pp_format_verbatim (pp
, &text
);
1796 /* Have PRETTY-PRINTER start a new line. */
1798 pp_newline (pretty_printer
*pp
)
1800 obstack_1grow (pp_buffer (pp
)->obstack
, '\n');
1801 pp_needs_newline (pp
) = false;
1802 pp_buffer (pp
)->line_length
= 0;
1805 /* Have PRETTY-PRINTER add a CHARACTER. */
1807 pp_character (pretty_printer
*pp
, int c
)
1809 if (pp_is_wrapping_line (pp
)
1810 /* If printing UTF-8, don't wrap in the middle of a sequence. */
1811 && (((unsigned int) c
) & 0xC0) != 0x80
1812 && pp_remaining_character_count_for_line (pp
) <= 0)
1818 obstack_1grow (pp_buffer (pp
)->obstack
, c
);
1819 ++pp_buffer (pp
)->line_length
;
1822 /* Append a STRING to the output area of PRETTY-PRINTER; the STRING may
1823 be line-wrapped if in appropriate mode. */
1825 pp_string (pretty_printer
*pp
, const char *str
)
1827 gcc_checking_assert (str
);
1828 pp_maybe_wrap_text (pp
, str
, str
+ strlen (str
));
1831 /* Append the leading N characters of STRING to the output area of
1832 PRETTY-PRINTER, quoting in hexadecimal non-printable characters.
1833 Setting N = -1 is as if N were set to strlen (STRING). The STRING
1834 may be line-wrapped if in appropriate mode. */
1836 pp_quoted_string (pretty_printer
*pp
, const char *str
, size_t n
/* = -1 */)
1838 gcc_checking_assert (str
);
1840 const char *last
= str
;
1843 /* Compute the length if not specified. */
1844 if (n
== (size_t) -1)
1847 for (ps
= str
; n
; ++ps
, --n
)
1852 /* Don't escape a valid UTF-8 extended char. */
1853 const unsigned char *ups
= (const unsigned char *) ps
;
1856 unsigned int extended_char
;
1857 const int valid_utf8_len
= decode_utf8_char (ups
, n
, &extended_char
);
1858 if (valid_utf8_len
> 0)
1860 ps
+= valid_utf8_len
- 1;
1861 n
-= valid_utf8_len
- 1;
1867 pp_maybe_wrap_text (pp
, last
, ps
);
1869 /* Append the hexadecimal value of the character. Allocate a buffer
1870 that's large enough for a 32-bit char plus the hex prefix. */
1872 int n
= sprintf (buf
, "\\x%02x", (unsigned char)*ps
);
1873 pp_maybe_wrap_text (pp
, buf
, buf
+ n
);
1877 pp_maybe_wrap_text (pp
, last
, ps
);
1880 /* Maybe print out a whitespace if needed. */
1883 pp_maybe_space (pretty_printer
*pp
)
1885 if (pp
->padding
!= pp_none
)
1888 pp
->padding
= pp_none
;
1892 // Add a newline to the pretty printer PP and flush formatted text.
1895 pp_newline_and_flush (pretty_printer
*pp
)
1899 pp_needs_newline (pp
) = false;
1902 // Add a newline to the pretty printer PP, followed by indentation.
1905 pp_newline_and_indent (pretty_printer
*pp
, int n
)
1907 pp_indentation (pp
) += n
;
1910 pp_needs_newline (pp
) = false;
1913 // Add separator C, followed by a single whitespace.
1916 pp_separate_with (pretty_printer
*pp
, char c
)
1918 pp_character (pp
, c
);
1922 /* Add a localized open quote, and if SHOW_COLOR is true, begin colorizing
1923 using the "quote" color. */
1926 pp_begin_quote (pretty_printer
*pp
, bool show_color
)
1928 pp_string (pp
, open_quote
);
1929 pp_string (pp
, colorize_start (show_color
, "quote"));
1932 /* If SHOW_COLOR is true, stop colorizing.
1933 Add a localized close quote. */
1936 pp_end_quote (pretty_printer
*pp
, bool show_color
)
1938 pp_string (pp
, colorize_stop (show_color
));
1939 pp_string (pp
, close_quote
);
1943 /* The string starting at P has LEN (at least 1) bytes left; if they
1944 start with a valid UTF-8 sequence, return the length of that
1945 sequence and set *VALUE to the value of that sequence, and
1946 otherwise return 0 and set *VALUE to (unsigned int) -1. */
1949 decode_utf8_char (const unsigned char *p
, size_t len
, unsigned int *value
)
1951 unsigned int t
= *p
;
1957 size_t utf8_len
= 0;
1960 for (t
= *p
; t
& 0x80; t
<<= 1)
1963 if (utf8_len
> len
|| utf8_len
< 2 || utf8_len
> 6)
1965 *value
= (unsigned int) -1;
1968 ch
= *p
& ((1 << (7 - utf8_len
)) - 1);
1969 for (i
= 1; i
< utf8_len
; i
++)
1971 unsigned int u
= p
[i
];
1972 if ((u
& 0xC0) != 0x80)
1974 *value
= (unsigned int) -1;
1977 ch
= (ch
<< 6) | (u
& 0x3F);
1979 if ( (ch
<= 0x7F && utf8_len
> 1)
1980 || (ch
<= 0x7FF && utf8_len
> 2)
1981 || (ch
<= 0xFFFF && utf8_len
> 3)
1982 || (ch
<= 0x1FFFFF && utf8_len
> 4)
1983 || (ch
<= 0x3FFFFFF && utf8_len
> 5)
1984 || (ch
>= 0xD800 && ch
<= 0xDFFF))
1986 *value
= (unsigned int) -1;
1999 /* Allocator for identifier_to_locale and corresponding function to
2002 void *(*identifier_to_locale_alloc
) (size_t) = xmalloc
;
2003 void (*identifier_to_locale_free
) (void *) = free
;
2005 /* Given IDENT, an identifier in the internal encoding, return a
2006 version of IDENT suitable for diagnostics in the locale character
2007 set: either IDENT itself, or a string, allocated using
2008 identifier_to_locale_alloc, converted to the locale character set
2009 and using escape sequences if not representable in the locale
2010 character set or containing control characters or invalid byte
2011 sequences. Existing backslashes in IDENT are not doubled, so the
2012 result may not uniquely specify the contents of an arbitrary byte
2013 sequence identifier. */
2016 identifier_to_locale (const char *ident
)
2018 const unsigned char *uid
= (const unsigned char *) ident
;
2019 size_t idlen
= strlen (ident
);
2020 bool valid_printable_utf8
= true;
2021 bool all_ascii
= true;
2024 for (i
= 0; i
< idlen
;)
2027 size_t utf8_len
= decode_utf8_char (&uid
[i
], idlen
- i
, &c
);
2028 if (utf8_len
== 0 || c
<= 0x1F || (c
>= 0x7F && c
<= 0x9F))
2030 valid_printable_utf8
= false;
2038 /* If IDENT contains invalid UTF-8 sequences (which may occur with
2039 attributes putting arbitrary byte sequences in identifiers), or
2040 control characters, we use octal escape sequences for all bytes
2041 outside printable ASCII. */
2042 if (!valid_printable_utf8
)
2044 char *ret
= (char *) identifier_to_locale_alloc (4 * idlen
+ 1);
2046 for (i
= 0; i
< idlen
; i
++)
2048 if (uid
[i
] > 0x1F && uid
[i
] < 0x7F)
2052 sprintf (p
, "\\%03o", uid
[i
]);
2060 /* Otherwise, if it is valid printable ASCII, or printable UTF-8
2061 with the locale character set being UTF-8, IDENT is used. */
2062 if (all_ascii
|| locale_utf8
)
2065 /* Otherwise IDENT is converted to the locale character set if
2067 #if defined ENABLE_NLS && defined HAVE_LANGINFO_CODESET && HAVE_ICONV
2068 if (locale_encoding
!= NULL
)
2070 iconv_t cd
= iconv_open (locale_encoding
, "UTF-8");
2071 bool conversion_ok
= true;
2073 if (cd
!= (iconv_t
) -1)
2075 size_t ret_alloc
= 4 * idlen
+ 1;
2078 /* Repeat the whole conversion process as needed with
2079 larger buffers so non-reversible transformations can
2080 always be detected. */
2081 ICONV_CONST
char *inbuf
= CONST_CAST (char *, ident
);
2083 size_t inbytesleft
= idlen
;
2084 size_t outbytesleft
= ret_alloc
- 1;
2087 ret
= (char *) identifier_to_locale_alloc (ret_alloc
);
2090 if (iconv (cd
, 0, 0, 0, 0) == (size_t) -1)
2092 conversion_ok
= false;
2096 iconv_ret
= iconv (cd
, &inbuf
, &inbytesleft
,
2097 &outbuf
, &outbytesleft
);
2098 if (iconv_ret
== (size_t) -1 || inbytesleft
!= 0)
2103 identifier_to_locale_free (ret
);
2109 conversion_ok
= false;
2113 else if (iconv_ret
!= 0)
2115 conversion_ok
= false;
2118 /* Return to initial shift state. */
2119 if (iconv (cd
, 0, 0, &outbuf
, &outbytesleft
) == (size_t) -1)
2124 identifier_to_locale_free (ret
);
2130 conversion_ok
= false;
2144 /* Otherwise, convert non-ASCII characters in IDENT to UCNs. */
2146 char *ret
= (char *) identifier_to_locale_alloc (10 * idlen
+ 1);
2148 for (i
= 0; i
< idlen
;)
2151 size_t utf8_len
= decode_utf8_char (&uid
[i
], idlen
- i
, &c
);
2156 sprintf (p
, "\\U%08x", c
);
2166 /* Support for encoding URLs.
2167 See egmontkob/Hyperlinks_in_Terminal_Emulators.md
2168 ( https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda ).
2170 > A hyperlink is opened upon encountering an OSC 8 escape sequence with
2171 > the target URI. The syntax is
2173 > OSC 8 ; params ; URI ST
2175 > A hyperlink is closed with the same escape sequence, omitting the
2176 > parameters and the URI but keeping the separators:
2180 > OSC (operating system command) is typically ESC ].
2182 Use BEL instead of ST, as that is currently rendered better in some
2183 terminal emulators that don't support OSC 8, like konsole. */
2185 /* If URL-printing is enabled, write an "open URL" escape sequence to PP
2186 for the given URL. */
2189 pp_begin_url (pretty_printer
*pp
, const char *url
)
2191 switch (pp
->url_format
)
2193 case URL_FORMAT_NONE
:
2196 pp_string (pp
, "\33]8;;");
2197 pp_string (pp
, url
);
2198 pp_string (pp
, "\33\\");
2200 case URL_FORMAT_BEL
:
2201 pp_string (pp
, "\33]8;;");
2202 pp_string (pp
, url
);
2203 pp_string (pp
, "\a");
2210 /* Helper function for pp_end_url and pp_format, return the "close URL" escape
2214 get_end_url_string (pretty_printer
*pp
)
2216 switch (pp
->url_format
)
2218 case URL_FORMAT_NONE
:
2221 return "\33]8;;\33\\";
2222 case URL_FORMAT_BEL
:
2229 /* If URL-printing is enabled, write a "close URL" escape sequence to PP. */
2232 pp_end_url (pretty_printer
*pp
)
2234 if (pp
->url_format
!= URL_FORMAT_NONE
)
2235 pp_string (pp
, get_end_url_string (pp
));
2240 namespace selftest
{
2242 /* Smoketest for pretty_printer. */
2245 test_basic_printing ()
2248 pp_string (&pp
, "hello");
2250 pp_string (&pp
, "world");
2252 ASSERT_STREQ ("hello world", pp_formatted_text (&pp
));
2255 /* Helper function for testing pp_format.
2256 Verify that pp_format (FMT, ...) followed by pp_output_formatted_text
2257 prints EXPECTED, assuming that pp_show_color is SHOW_COLOR. */
2260 assert_pp_format_va (const location
&loc
, const char *expected
,
2261 bool show_color
, const char *fmt
, va_list *ap
)
2265 rich_location
rich_loc (line_table
, UNKNOWN_LOCATION
);
2267 ti
.format_spec
= fmt
;
2271 ti
.m_richloc
= &rich_loc
;
2273 pp_show_color (&pp
) = show_color
;
2274 pp_format (&pp
, &ti
);
2275 pp_output_formatted_text (&pp
);
2276 ASSERT_STREQ_AT (loc
, expected
, pp_formatted_text (&pp
));
2279 /* Verify that pp_format (FMT, ...) followed by pp_output_formatted_text
2280 prints EXPECTED, with show_color disabled. */
2283 assert_pp_format (const location
&loc
, const char *expected
,
2284 const char *fmt
, ...)
2289 assert_pp_format_va (loc
, expected
, false, fmt
, &ap
);
2293 /* As above, but with colorization enabled. */
2296 assert_pp_format_colored (const location
&loc
, const char *expected
,
2297 const char *fmt
, ...)
2299 /* The tests of colorization assume the default color scheme.
2300 If GCC_COLORS is set, then the colors have potentially been
2301 overridden; skip the test. */
2302 if (getenv ("GCC_COLORS"))
2308 assert_pp_format_va (loc
, expected
, true, fmt
, &ap
);
2312 /* Helper function for calling testing pp_format,
2313 by calling assert_pp_format with various numbers of arguments.
2314 These exist mostly to avoid having to write SELFTEST_LOCATION
2315 throughout test_pp_format. */
2317 #define ASSERT_PP_FORMAT_1(EXPECTED, FMT, ARG1) \
2318 SELFTEST_BEGIN_STMT \
2319 assert_pp_format ((SELFTEST_LOCATION), (EXPECTED), (FMT), \
2323 #define ASSERT_PP_FORMAT_2(EXPECTED, FMT, ARG1, ARG2) \
2324 SELFTEST_BEGIN_STMT \
2325 assert_pp_format ((SELFTEST_LOCATION), (EXPECTED), (FMT), \
2329 #define ASSERT_PP_FORMAT_3(EXPECTED, FMT, ARG1, ARG2, ARG3) \
2330 SELFTEST_BEGIN_STMT \
2331 assert_pp_format ((SELFTEST_LOCATION), (EXPECTED), (FMT), \
2332 (ARG1), (ARG2), (ARG3)); \
2335 /* Verify that pp_format works, for various format codes. */
2340 /* Avoid introducing locale-specific differences in the results
2341 by hardcoding open_quote and close_quote. */
2342 auto_fix_quotes fix_quotes
;
2344 /* Verify that plain text is passed through unchanged. */
2345 assert_pp_format (SELFTEST_LOCATION
, "unformatted", "unformatted");
2347 /* Verify various individual format codes, in the order listed in the
2348 comment for pp_format above. For each code, we append a second
2349 argument with a known bit pattern (0x12345678), to ensure that we
2350 are consuming arguments correctly. */
2351 ASSERT_PP_FORMAT_2 ("-27 12345678", "%d %x", -27, 0x12345678);
2352 ASSERT_PP_FORMAT_2 ("-5 12345678", "%i %x", -5, 0x12345678);
2353 ASSERT_PP_FORMAT_2 ("10 12345678", "%u %x", 10, 0x12345678);
2354 ASSERT_PP_FORMAT_2 ("17 12345678", "%o %x", 15, 0x12345678);
2355 ASSERT_PP_FORMAT_2 ("cafebabe 12345678", "%x %x", 0xcafebabe, 0x12345678);
2356 ASSERT_PP_FORMAT_2 ("-27 12345678", "%ld %x", (long)-27, 0x12345678);
2357 ASSERT_PP_FORMAT_2 ("-5 12345678", "%li %x", (long)-5, 0x12345678);
2358 ASSERT_PP_FORMAT_2 ("10 12345678", "%lu %x", (long)10, 0x12345678);
2359 ASSERT_PP_FORMAT_2 ("17 12345678", "%lo %x", (long)15, 0x12345678);
2360 ASSERT_PP_FORMAT_2 ("cafebabe 12345678", "%lx %x", (long)0xcafebabe,
2362 ASSERT_PP_FORMAT_2 ("-27 12345678", "%lld %x", (long long)-27, 0x12345678);
2363 ASSERT_PP_FORMAT_2 ("-5 12345678", "%lli %x", (long long)-5, 0x12345678);
2364 ASSERT_PP_FORMAT_2 ("10 12345678", "%llu %x", (long long)10, 0x12345678);
2365 ASSERT_PP_FORMAT_2 ("17 12345678", "%llo %x", (long long)15, 0x12345678);
2366 ASSERT_PP_FORMAT_2 ("cafebabe 12345678", "%llx %x", (long long)0xcafebabe,
2368 ASSERT_PP_FORMAT_2 ("-27 12345678", "%wd %x", (HOST_WIDE_INT
)-27, 0x12345678);
2369 ASSERT_PP_FORMAT_2 ("-5 12345678", "%wi %x", (HOST_WIDE_INT
)-5, 0x12345678);
2370 ASSERT_PP_FORMAT_2 ("10 12345678", "%wu %x", (unsigned HOST_WIDE_INT
)10,
2372 ASSERT_PP_FORMAT_2 ("17 12345678", "%wo %x", (HOST_WIDE_INT
)15, 0x12345678);
2373 ASSERT_PP_FORMAT_2 ("0xcafebabe 12345678", "%wx %x", (HOST_WIDE_INT
)0xcafebabe,
2375 ASSERT_PP_FORMAT_2 ("1.000000 12345678", "%f %x", 1.0, 0x12345678);
2376 ASSERT_PP_FORMAT_2 ("A 12345678", "%c %x", 'A', 0x12345678);
2377 ASSERT_PP_FORMAT_2 ("hello world 12345678", "%s %x", "hello world",
2380 /* Not nul-terminated. */
2381 char arr
[5] = { '1', '2', '3', '4', '5' };
2382 ASSERT_PP_FORMAT_3 ("123 12345678", "%.*s %x", 3, arr
, 0x12345678);
2383 ASSERT_PP_FORMAT_3 ("1234 12345678", "%.*s %x", -1, "1234", 0x12345678);
2384 ASSERT_PP_FORMAT_3 ("12345 12345678", "%.*s %x", 7, "12345", 0x12345678);
2386 /* We can't test for %p; the pointer is printed in an implementation-defined
2388 ASSERT_PP_FORMAT_2 ("normal colored normal 12345678",
2389 "normal %rcolored%R normal %x",
2390 "error", 0x12345678);
2391 assert_pp_format_colored
2393 "normal \33[01;31m\33[Kcolored\33[m\33[K normal 12345678",
2394 "normal %rcolored%R normal %x", "error", 0x12345678);
2396 %m: strerror(text->err_no) - does not consume a value from args_ptr. */
2397 ASSERT_PP_FORMAT_1 ("% 12345678", "%% %x", 0x12345678);
2398 ASSERT_PP_FORMAT_1 ("` 12345678", "%< %x", 0x12345678);
2399 ASSERT_PP_FORMAT_1 ("' 12345678", "%> %x", 0x12345678);
2400 ASSERT_PP_FORMAT_1 ("' 12345678", "%' %x", 0x12345678);
2401 ASSERT_PP_FORMAT_3 ("abc 12345678", "%.*s %x", 3, "abcdef", 0x12345678);
2402 ASSERT_PP_FORMAT_2 ("abc 12345678", "%.3s %x", "abcdef", 0x12345678);
2404 /* Verify flag 'q'. */
2405 ASSERT_PP_FORMAT_2 ("`foo' 12345678", "%qs %x", "foo", 0x12345678);
2406 assert_pp_format_colored (SELFTEST_LOCATION
,
2407 "`\33[01m\33[Kfoo\33[m\33[K' 12345678", "%qs %x",
2411 diagnostic_event_id_t
first (2);
2412 diagnostic_event_id_t
second (7);
2414 ASSERT_PP_FORMAT_2 ("first `free' at (3); second `free' at (8)",
2415 "first %<free%> at %@; second %<free%> at %@",
2417 assert_pp_format_colored
2419 "first `\e[01m\e[Kfree\e[m\e[K' at \e[01;36m\e[K(3)\e[m\e[K;"
2420 " second `\e[01m\e[Kfree\e[m\e[K' at \e[01;36m\e[K(8)\e[m\e[K",
2421 "first %<free%> at %@; second %<free%> at %@",
2426 int v
[] = { 1, 2, 3 };
2427 ASSERT_PP_FORMAT_3 ("1, 2, 3 12345678", "%Z %x", v
, 3, 0x12345678);
2430 ASSERT_PP_FORMAT_3 ("0 12345678", "%Z %x", v2
, 1, 0x12345678);
2432 /* Verify that combinations work, along with unformatted text. */
2433 assert_pp_format (SELFTEST_LOCATION
,
2434 "the quick brown fox jumps over the lazy dog",
2435 "the %s %s %s jumps over the %s %s",
2436 "quick", "brown", "fox", "lazy", "dog");
2437 assert_pp_format (SELFTEST_LOCATION
, "item 3 of 7", "item %i of %i", 3, 7);
2438 assert_pp_format (SELFTEST_LOCATION
, "problem with `bar' at line 10",
2439 "problem with %qs at line %i", "bar", 10);
2442 /* A subclass of pretty_printer for use by test_prefixes_and_wrapping. */
2444 class test_pretty_printer
: public pretty_printer
2447 test_pretty_printer (enum diagnostic_prefixing_rule_t rule
,
2448 int max_line_length
)
2450 pp_set_prefix (this, xstrdup ("PREFIX: "));
2451 wrapping
.rule
= rule
;
2452 pp_set_line_maximum_length (this, max_line_length
);
2456 /* Verify that the various values of enum diagnostic_prefixing_rule_t work
2457 as expected, with and without line wrapping. */
2460 test_prefixes_and_wrapping ()
2462 /* Tests of the various prefixing rules, without wrapping.
2463 Newlines embedded in pp_string don't affect it; we have to
2464 explicitly call pp_newline. */
2466 test_pretty_printer
pp (DIAGNOSTICS_SHOW_PREFIX_ONCE
, 0);
2467 pp_string (&pp
, "the quick brown fox");
2469 pp_string (&pp
, "jumps over the lazy dog");
2471 ASSERT_STREQ (pp_formatted_text (&pp
),
2472 "PREFIX: the quick brown fox\n"
2473 " jumps over the lazy dog\n");
2476 test_pretty_printer
pp (DIAGNOSTICS_SHOW_PREFIX_NEVER
, 0);
2477 pp_string (&pp
, "the quick brown fox");
2479 pp_string (&pp
, "jumps over the lazy dog");
2481 ASSERT_STREQ (pp_formatted_text (&pp
),
2482 "the quick brown fox\n"
2483 "jumps over the lazy dog\n");
2486 test_pretty_printer
pp (DIAGNOSTICS_SHOW_PREFIX_EVERY_LINE
, 0);
2487 pp_string (&pp
, "the quick brown fox");
2489 pp_string (&pp
, "jumps over the lazy dog");
2491 ASSERT_STREQ (pp_formatted_text (&pp
),
2492 "PREFIX: the quick brown fox\n"
2493 "PREFIX: jumps over the lazy dog\n");
2496 /* Tests of the various prefixing rules, with wrapping. */
2498 test_pretty_printer
pp (DIAGNOSTICS_SHOW_PREFIX_ONCE
, 20);
2499 pp_string (&pp
, "the quick brown fox jumps over the lazy dog");
2501 pp_string (&pp
, "able was I ere I saw elba");
2503 ASSERT_STREQ (pp_formatted_text (&pp
),
2504 "PREFIX: the quick \n"
2505 " brown fox jumps \n"
2508 " able was I ere I \n"
2512 test_pretty_printer
pp (DIAGNOSTICS_SHOW_PREFIX_NEVER
, 20);
2513 pp_string (&pp
, "the quick brown fox jumps over the lazy dog");
2515 pp_string (&pp
, "able was I ere I saw elba");
2517 ASSERT_STREQ (pp_formatted_text (&pp
),
2518 "the quick brown fox \n"
2519 "jumps over the lazy \n"
2521 "able was I ere I \n"
2525 test_pretty_printer
pp (DIAGNOSTICS_SHOW_PREFIX_EVERY_LINE
, 20);
2526 pp_string (&pp
, "the quick brown fox jumps over the lazy dog");
2528 pp_string (&pp
, "able was I ere I saw elba");
2530 ASSERT_STREQ (pp_formatted_text (&pp
),
2531 "PREFIX: the quick brown fox jumps over the lazy dog\n"
2532 "PREFIX: able was I ere I saw elba\n");
2537 /* Verify that URL-printing works as expected. */
2544 pp
.url_format
= URL_FORMAT_NONE
;
2545 pp_begin_url (&pp
, "http://example.com");
2546 pp_string (&pp
, "This is a link");
2548 ASSERT_STREQ ("This is a link",
2549 pp_formatted_text (&pp
));
2554 pp
.url_format
= URL_FORMAT_ST
;
2555 pp_begin_url (&pp
, "http://example.com");
2556 pp_string (&pp
, "This is a link");
2558 ASSERT_STREQ ("\33]8;;http://example.com\33\\This is a link\33]8;;\33\\",
2559 pp_formatted_text (&pp
));
2564 pp
.url_format
= URL_FORMAT_BEL
;
2565 pp_begin_url (&pp
, "http://example.com");
2566 pp_string (&pp
, "This is a link");
2568 ASSERT_STREQ ("\33]8;;http://example.com\aThis is a link\33]8;;\a",
2569 pp_formatted_text (&pp
));
2573 /* Test multibyte awareness. */
2574 static void test_utf8 ()
2577 /* Check that pp_quoted_string leaves valid UTF-8 alone. */
2580 const char *s
= "\xf0\x9f\x98\x82";
2581 pp_quoted_string (&pp
, s
);
2582 ASSERT_STREQ (pp_formatted_text (&pp
), s
);
2585 /* Check that pp_quoted_string escapes non-UTF-8 nonprintable bytes. */
2588 pp_quoted_string (&pp
, "\xf0!\x9f\x98\x82");
2589 ASSERT_STREQ (pp_formatted_text (&pp
),
2590 "\\xf0!\\x9f\\x98\\x82");
2593 /* Check that pp_character will line-wrap at the beginning of a UTF-8
2594 sequence, but not in the middle. */
2596 pretty_printer
pp (3);
2597 const char s
[] = "---\xf0\x9f\x98\x82";
2598 for (int i
= 0; i
!= sizeof (s
) - 1; ++i
)
2599 pp_character (&pp
, s
[i
]);
2601 for (int i
= 1; i
!= sizeof (s
) - 1; ++i
)
2602 pp_character (&pp
, s
[i
]);
2603 pp_character (&pp
, '-');
2604 ASSERT_STREQ (pp_formatted_text (&pp
),
2606 "\xf0\x9f\x98\x82\n"
2607 "--\xf0\x9f\x98\x82\n"
2613 /* Run all of the selftests within this file. */
2616 pretty_print_c_tests ()
2618 test_basic_printing ();
2620 test_prefixes_and_wrapping ();
2625 } // namespace selftest
2627 #endif /* CHECKING_P */