1 /* Various declarations for language-independent pretty-print subroutines.
2 Copyright (C) 2003-2017 Free Software Foundation, Inc.
3 Contributed by Gabriel Dos Reis <gdr@integrable-solutions.net>
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"
35 /* Replacement for fputs() that handles ANSI escape codes on Windows NT.
36 Contributed by: Liu Hao (lh_mouse at 126 dot com)
38 XXX: This file is compiled into libcommon.a that will be self-contained.
39 It looks like that these functions can be put nowhere else. */
42 #define WIN32_LEAN_AND_MEAN 1
45 /* Write all bytes in [s,s+n) into the specified stream.
46 Errors are ignored. */
48 write_all (HANDLE h
, const char *s
, size_t n
)
59 if (!WriteFile (h
, s
+ n
- rem
, step
, &step
, NULL
))
65 /* Find the beginning of an escape sequence.
67 1. If the sequence begins with an ESC character (0x1B) and a second
68 character X in [0x40,0x5F], returns X and stores a pointer to
69 the third character into *head.
70 2. If the sequence begins with a character X in [0x80,0x9F], returns
71 (X-0x40) and stores a pointer to the second character into *head.
72 Stores the number of ESC character(s) in *prefix_len.
73 Returns 0 if no such sequence can be found. */
75 find_esc_head (int *prefix_len
, const char **head
, const char *str
)
83 c
= (unsigned char) *r
;
89 if (escaped
&& 0x40 <= c
&& c
<= 0x5F)
96 if (0x80 <= c
&& c
<= 0x9F)
108 /* Find the terminator of an escape sequence.
109 str should be the value stored in *head by a previous successful
110 call to find_esc_head().
111 Returns 0 if no such sequence can be found. */
113 find_esc_terminator (const char **term
, const char *str
)
120 c
= (unsigned char) *r
;
126 if (0x40 <= c
&& c
<= 0x7E)
136 /* Handle a sequence of codes. Sequences that are invalid, reserved,
137 unrecognized or unimplemented are ignored silently.
138 There isn't much we can do because of lameness of Windows consoles. */
140 eat_esc_sequence (HANDLE h
, int esc_code
,
141 const char *esc_head
, const char *esc_term
)
143 /* Numbers in an escape sequence cannot be negative, because
144 a minus sign in the middle of it would have terminated it. */
147 CONSOLE_SCREEN_BUFFER_INFO sb
;
149 /* ED and EL parameters. */
152 /* SGR parameters. */
153 WORD attrib_add
, attrib_rm
;
156 switch (MAKEWORD (esc_code
, *esc_term
))
159 Move the cursor up by n1 characters. */
160 case MAKEWORD ('[', 'A'):
161 if (esc_head
== esc_term
)
165 n1
= strtol (esc_head
, &eptr
, 10);
166 if (eptr
!= esc_term
)
170 if (GetConsoleScreenBufferInfo (h
, &sb
))
172 cr
= sb
.dwCursorPosition
;
173 /* Stop at the topmost boundary. */
178 SetConsoleCursorPosition (h
, cr
);
183 Move the cursor down by n1 characters. */
184 case MAKEWORD ('[', 'B'):
185 if (esc_head
== esc_term
)
189 n1
= strtol (esc_head
, &eptr
, 10);
190 if (eptr
!= esc_term
)
194 if (GetConsoleScreenBufferInfo (h
, &sb
))
196 cr
= sb
.dwCursorPosition
;
197 /* Stop at the bottommost boundary. */
198 if (sb
.dwSize
.Y
- cr
.Y
> n1
)
202 SetConsoleCursorPosition (h
, cr
);
207 Move the cursor right by n1 characters. */
208 case MAKEWORD ('[', 'C'):
209 if (esc_head
== esc_term
)
213 n1
= strtol (esc_head
, &eptr
, 10);
214 if (eptr
!= esc_term
)
218 if (GetConsoleScreenBufferInfo (h
, &sb
))
220 cr
= sb
.dwCursorPosition
;
221 /* Stop at the rightmost boundary. */
222 if (sb
.dwSize
.X
- cr
.X
> n1
)
226 SetConsoleCursorPosition (h
, cr
);
231 Move the cursor left by n1 characters. */
232 case MAKEWORD ('[', 'D'):
233 if (esc_head
== esc_term
)
237 n1
= strtol (esc_head
, &eptr
, 10);
238 if (eptr
!= esc_term
)
242 if (GetConsoleScreenBufferInfo (h
, &sb
))
244 cr
= sb
.dwCursorPosition
;
245 /* Stop at the leftmost boundary. */
250 SetConsoleCursorPosition (h
, cr
);
255 Move the cursor to the beginning of the n1-th line downwards. */
256 case MAKEWORD ('[', 'E'):
257 if (esc_head
== esc_term
)
261 n1
= strtol (esc_head
, &eptr
, 10);
262 if (eptr
!= esc_term
)
266 if (GetConsoleScreenBufferInfo (h
, &sb
))
268 cr
= sb
.dwCursorPosition
;
270 /* Stop at the bottommost boundary. */
271 if (sb
.dwSize
.Y
- cr
.Y
> n1
)
275 SetConsoleCursorPosition (h
, cr
);
280 Move the cursor to the beginning of the n1-th line upwards. */
281 case MAKEWORD ('[', 'F'):
282 if (esc_head
== esc_term
)
286 n1
= strtol (esc_head
, &eptr
, 10);
287 if (eptr
!= esc_term
)
291 if (GetConsoleScreenBufferInfo (h
, &sb
))
293 cr
= sb
.dwCursorPosition
;
295 /* Stop at the topmost boundary. */
300 SetConsoleCursorPosition (h
, cr
);
305 Move the cursor to the (1-based) n1-th column. */
306 case MAKEWORD ('[', 'G'):
307 if (esc_head
== esc_term
)
311 n1
= strtol (esc_head
, &eptr
, 10);
312 if (eptr
!= esc_term
)
316 if (GetConsoleScreenBufferInfo (h
, &sb
))
318 cr
= sb
.dwCursorPosition
;
320 /* Stop at the leftmost or rightmost boundary. */
323 else if (n1
> sb
.dwSize
.X
)
327 SetConsoleCursorPosition (h
, cr
);
331 /* ESC [ n1 ';' n2 'H'
333 Move the cursor to the (1-based) n1-th row and
334 (also 1-based) n2-th column. */
335 case MAKEWORD ('[', 'H'):
336 case MAKEWORD ('[', 'f'):
337 if (esc_head
== esc_term
)
339 /* Both parameters are omitted and set to 1 by default. */
343 else if (!(delim
= (char *) memchr (esc_head
, ';',
344 esc_term
- esc_head
)))
346 /* Only the first parameter is given. The second one is
347 set to 1 by default. */
348 n1
= strtol (esc_head
, &eptr
, 10);
349 if (eptr
!= esc_term
)
355 /* Both parameters are given. The first one shall be
356 terminated by the semicolon. */
357 n1
= strtol (esc_head
, &eptr
, 10);
360 n2
= strtol (delim
+ 1, &eptr
, 10);
361 if (eptr
!= esc_term
)
365 if (GetConsoleScreenBufferInfo (h
, &sb
))
367 cr
= sb
.dwCursorPosition
;
370 /* The cursor position shall be relative to the view coord of
371 the console window, which is usually smaller than the actual
372 buffer. FWIW, the 'appropriate' solution will be shrinking
373 the buffer to match the size of the console window,
374 destroying scrollback in the process. */
375 n1
+= sb
.srWindow
.Top
;
376 n2
+= sb
.srWindow
.Left
;
377 /* Stop at the topmost or bottommost boundary. */
380 else if (n1
> sb
.dwSize
.Y
)
384 /* Stop at the leftmost or rightmost boundary. */
387 else if (n2
> sb
.dwSize
.X
)
391 SetConsoleCursorPosition (h
, cr
);
397 case MAKEWORD ('[', 'J'):
398 if (esc_head
== esc_term
)
399 /* This is one of the very few codes whose parameters have
400 a default value of zero. */
404 n1
= strtol (esc_head
, &eptr
, 10);
405 if (eptr
!= esc_term
)
409 if (GetConsoleScreenBufferInfo (h
, &sb
))
411 /* The cursor is not necessarily in the console window, which
412 makes the behavior of this code harder to define. */
416 /* If the cursor is in or above the window, erase from
417 it to the bottom of the window; otherwise, do nothing. */
418 cr
= sb
.dwCursorPosition
;
419 cnt
= sb
.dwSize
.X
- sb
.dwCursorPosition
.X
;
420 rows
= sb
.srWindow
.Bottom
- sb
.dwCursorPosition
.Y
;
423 /* If the cursor is in or under the window, erase from
424 it to the top of the window; otherwise, do nothing. */
426 cr
.Y
= sb
.srWindow
.Top
;
427 cnt
= sb
.dwCursorPosition
.X
+ 1;
428 rows
= sb
.dwCursorPosition
.Y
- sb
.srWindow
.Top
;
431 /* Erase the entire window. */
432 cr
.X
= sb
.srWindow
.Left
;
433 cr
.Y
= sb
.srWindow
.Top
;
435 rows
= sb
.srWindow
.Bottom
- sb
.srWindow
.Top
+ 1;
438 /* Erase the entire buffer. */
447 cnt
+= rows
* sb
.dwSize
.X
;
448 FillConsoleOutputCharacterW (h
, L
' ', cnt
, cr
, &step
);
449 FillConsoleOutputAttribute (h
, sb
.wAttributes
, cnt
, cr
, &step
);
455 case MAKEWORD ('[', 'K'):
456 if (esc_head
== esc_term
)
457 /* This is one of the very few codes whose parameters have
458 a default value of zero. */
462 n1
= strtol (esc_head
, &eptr
, 10);
463 if (eptr
!= esc_term
)
467 if (GetConsoleScreenBufferInfo (h
, &sb
))
472 /* Erase from the cursor to the end. */
473 cr
= sb
.dwCursorPosition
;
474 cnt
= sb
.dwSize
.X
- sb
.dwCursorPosition
.X
;
477 /* Erase from the cursor to the beginning. */
478 cr
= sb
.dwCursorPosition
;
480 cnt
= sb
.dwCursorPosition
.X
+ 1;
483 /* Erase the entire line. */
484 cr
= sb
.dwCursorPosition
;
489 FillConsoleOutputCharacterW (h
, L
' ', cnt
, cr
, &step
);
490 FillConsoleOutputAttribute (h
, sb
.wAttributes
, cnt
, cr
, &step
);
494 /* ESC [ n1 ';' n2 'm'
495 Set SGR parameters. Zero or more parameters will follow. */
496 case MAKEWORD ('[', 'm'):
499 if (esc_head
== esc_term
)
501 /* When no parameter is given, reset the console. */
502 attrib_add
|= (FOREGROUND_RED
| FOREGROUND_GREEN
504 attrib_rm
= -1; /* Removes everything. */
510 /* Parse a parameter. */
511 n1
= strtol (param
, &eptr
, 10);
512 if (*eptr
!= ';' && eptr
!= esc_term
)
519 attrib_add
|= (FOREGROUND_RED
| FOREGROUND_GREEN
521 attrib_rm
= -1; /* Removes everything. */
525 attrib_add
|= FOREGROUND_INTENSITY
;
529 attrib_add
|= COMMON_LVB_UNDERSCORE
;
533 /* XXX: It is not BLINKING at all! */
534 attrib_add
|= BACKGROUND_INTENSITY
;
538 attrib_add
|= COMMON_LVB_REVERSE_VIDEO
;
542 attrib_add
&= ~FOREGROUND_INTENSITY
;
543 attrib_rm
|= FOREGROUND_INTENSITY
;
547 attrib_add
&= ~COMMON_LVB_UNDERSCORE
;
548 attrib_rm
|= COMMON_LVB_UNDERSCORE
;
552 /* XXX: It is not BLINKING at all! */
553 attrib_add
&= ~BACKGROUND_INTENSITY
;
554 attrib_rm
|= BACKGROUND_INTENSITY
;
558 attrib_add
&= ~COMMON_LVB_REVERSE_VIDEO
;
559 attrib_rm
|= COMMON_LVB_REVERSE_VIDEO
;
569 /* Foreground color. */
570 attrib_add
&= ~(FOREGROUND_RED
| FOREGROUND_GREEN
574 attrib_add
|= FOREGROUND_RED
;
576 attrib_add
|= FOREGROUND_GREEN
;
578 attrib_add
|= FOREGROUND_BLUE
;
579 attrib_rm
|= (FOREGROUND_RED
| FOREGROUND_GREEN
583 /* Reserved for extended foreground color.
584 Don't know how to handle parameters remaining.
588 /* Reset foreground color. */
590 attrib_add
|= (FOREGROUND_RED
| FOREGROUND_GREEN
592 attrib_rm
|= (FOREGROUND_RED
| FOREGROUND_GREEN
603 /* Background color. */
604 attrib_add
&= ~(BACKGROUND_RED
| BACKGROUND_GREEN
608 attrib_add
|= BACKGROUND_RED
;
610 attrib_add
|= BACKGROUND_GREEN
;
612 attrib_add
|= BACKGROUND_BLUE
;
613 attrib_rm
|= (BACKGROUND_RED
| BACKGROUND_GREEN
617 /* Reserved for extended background color.
618 Don't know how to handle parameters remaining.
622 /* Reset background color. */
624 attrib_add
&= ~(BACKGROUND_RED
| BACKGROUND_GREEN
626 attrib_rm
|= (BACKGROUND_RED
| BACKGROUND_GREEN
631 /* Prepare the next parameter. */
634 while (param
!= esc_term
);
637 /* 0xFFFF removes everything. If it is not the case,
638 care must be taken to preserve old attributes. */
639 if (attrib_rm
!= 0xFFFF && GetConsoleScreenBufferInfo (h
, &sb
))
641 attrib_add
|= sb
.wAttributes
& ~attrib_rm
;
643 SetConsoleTextAttribute (h
, attrib_add
);
649 mingw_ansi_fputs (const char *str
, FILE *fp
)
651 const char *read
= str
;
654 int esc_code
, prefix_len
;
655 const char *esc_head
, *esc_term
;
657 h
= (HANDLE
) _get_osfhandle (_fileno (fp
));
658 if (h
== INVALID_HANDLE_VALUE
)
661 /* Don't mess up stdio functions with Windows APIs. */
664 if (GetConsoleMode (h
, &mode
))
665 /* If it is a console, translate ANSI escape codes as needed. */
668 if ((esc_code
= find_esc_head (&prefix_len
, &esc_head
, read
)) == 0)
670 /* Write all remaining characters, then exit. */
671 write_all (h
, read
, strlen (read
));
674 if (find_esc_terminator (&esc_term
, esc_head
) == 0)
675 /* Ignore incomplete escape sequences at the moment.
676 FIXME: The escape state shall be cached for further calls
679 write_all (h
, read
, esc_head
- prefix_len
- read
);
680 eat_esc_sequence (h
, esc_code
, esc_head
, esc_term
);
684 /* If it is not a console, write everything as-is. */
685 write_all (h
, read
, strlen (read
));
687 _close ((intptr_t) h
);
691 #endif /* __MINGW32__ */
693 static void pp_quoted_string (pretty_printer
*, const char *, size_t = -1);
695 /* Overwrite the given location/range within this text_info's rich_location.
696 For use e.g. when implementing "+" in client format decoders. */
699 text_info::set_location (unsigned int idx
, location_t loc
, bool show_caret_p
)
701 gcc_checking_assert (m_richloc
);
702 m_richloc
->set_range (line_table
, idx
, loc
, show_caret_p
);
706 text_info::get_location (unsigned int index_of_location
) const
708 gcc_checking_assert (m_richloc
);
710 if (index_of_location
== 0)
711 return m_richloc
->get_loc ();
713 return UNKNOWN_LOCATION
;
716 // Default construct an output buffer.
718 output_buffer::output_buffer ()
719 : formatted_obstack (),
721 obstack (&formatted_obstack
),
728 obstack_init (&formatted_obstack
);
729 obstack_init (&chunk_obstack
);
732 // Release resources owned by an output buffer at the end of lifetime.
734 output_buffer::~output_buffer ()
736 obstack_free (&chunk_obstack
, NULL
);
737 obstack_free (&formatted_obstack
, NULL
);
741 /* Format an integer given by va_arg (ARG, type-specifier T) where
742 type-specifier is a precision modifier as indicated by PREC. F is
743 a string used to construct the appropriate format-specifier. */
744 #define pp_integer_with_precision(PP, ARG, PREC, T, F) \
749 pp_scalar (PP, "%" F, va_arg (ARG, T)); \
753 pp_scalar (PP, "%l" F, va_arg (ARG, long T)); \
757 pp_scalar (PP, "%" HOST_LONG_LONG_FORMAT F, va_arg (ARG, long long T)); \
766 /* Subroutine of pp_set_maximum_length. Set up PRETTY-PRINTER's
767 internal maximum characters per line. */
769 pp_set_real_maximum_length (pretty_printer
*pp
)
771 /* If we're told not to wrap lines then do the obvious thing. In case
772 we'll emit prefix only once per message, it is appropriate
773 not to increase unnecessarily the line-length cut-off. */
774 if (!pp_is_wrapping_line (pp
)
775 || pp_prefixing_rule (pp
) == DIAGNOSTICS_SHOW_PREFIX_ONCE
776 || pp_prefixing_rule (pp
) == DIAGNOSTICS_SHOW_PREFIX_NEVER
)
777 pp
->maximum_length
= pp_line_cutoff (pp
);
780 int prefix_length
= pp
->prefix
? strlen (pp
->prefix
) : 0;
781 /* If the prefix is ridiculously too long, output at least
783 if (pp_line_cutoff (pp
) - prefix_length
< 32)
784 pp
->maximum_length
= pp_line_cutoff (pp
) + 32;
786 pp
->maximum_length
= pp_line_cutoff (pp
);
790 /* Clear PRETTY-PRINTER's output state. */
792 pp_clear_state (pretty_printer
*pp
)
794 pp
->emitted_prefix
= false;
795 pp_indentation (pp
) = 0;
798 /* Flush the formatted text of PRETTY-PRINTER onto the attached stream. */
800 pp_write_text_to_stream (pretty_printer
*pp
)
802 const char *text
= pp_formatted_text (pp
);
804 mingw_ansi_fputs (text
, pp_buffer (pp
)->stream
);
806 fputs (text
, pp_buffer (pp
)->stream
);
808 pp_clear_output_area (pp
);
811 /* As pp_write_text_to_stream, but for GraphViz label output.
813 Flush the formatted text of pretty-printer PP onto the attached stream.
814 Replace characters in PPF that have special meaning in a GraphViz .dot
817 This routine is not very fast, but it doesn't have to be as this is only
818 be used by routines dumping intermediate representations in graph form. */
821 pp_write_text_as_dot_label_to_stream (pretty_printer
*pp
, bool for_record
)
823 const char *text
= pp_formatted_text (pp
);
824 const char *p
= text
;
825 FILE *fp
= pp_buffer (pp
)->stream
;
832 /* Print newlines as a left-aligned newline. */
838 /* The following characters are only special for record-shape nodes. */
845 escape_char
= for_record
;
848 /* The following characters always have to be escaped
849 for use in labels. */
851 /* There is a bug in some (f.i. 2.36.0) versions of graphiz
852 ( http://www.graphviz.org/mantisbt/view.php?id=2524 ) related to
853 backslash as last char in label. Let's avoid triggering it. */
854 gcc_assert (*(p
+ 1) != '\0');
871 pp_clear_output_area (pp
);
874 /* Wrap a text delimited by START and END into PRETTY-PRINTER. */
876 pp_wrap_text (pretty_printer
*pp
, const char *start
, const char *end
)
878 bool wrapping_line
= pp_is_wrapping_line (pp
);
882 /* Dump anything bordered by whitespaces. */
884 const char *p
= start
;
885 while (p
!= end
&& !ISBLANK (*p
) && *p
!= '\n')
888 && p
- start
>= pp_remaining_character_count_for_line (pp
))
890 pp_append_text (pp
, start
, p
);
894 if (start
!= end
&& ISBLANK (*start
))
899 if (start
!= end
&& *start
== '\n')
907 /* Same as pp_wrap_text but wrap text only when in line-wrapping mode. */
909 pp_maybe_wrap_text (pretty_printer
*pp
, const char *start
, const char *end
)
911 if (pp_is_wrapping_line (pp
))
912 pp_wrap_text (pp
, start
, end
);
914 pp_append_text (pp
, start
, end
);
917 /* Append to the output area of PRETTY-PRINTER a string specified by its
918 STARTing character and LENGTH. */
920 pp_append_r (pretty_printer
*pp
, const char *start
, int length
)
922 output_buffer_append_r (pp_buffer (pp
), start
, length
);
925 /* Insert enough spaces into the output area of PRETTY-PRINTER to bring
926 the column position to the current indentation level, assuming that a
927 newline has just been written to the buffer. */
929 pp_indent (pretty_printer
*pp
)
931 int n
= pp_indentation (pp
);
934 for (i
= 0; i
< n
; ++i
)
938 /* The following format specifiers are recognized as being client independent:
939 %d, %i: (signed) integer in base ten.
940 %u: unsigned integer in base ten.
941 %o: unsigned integer in base eight.
942 %x: unsigned integer in base sixteen.
943 %ld, %li, %lo, %lu, %lx: long versions of the above.
944 %lld, %lli, %llo, %llu, %llx: long long versions.
945 %wd, %wi, %wo, %wu, %wx: HOST_WIDE_INT versions.
948 %p: pointer (printed in a host-dependent manner).
949 %r: if pp_show_color(pp), switch to color identified by const char *.
950 %R: if pp_show_color(pp), reset color.
951 %m: strerror(text->err_no) - does not consume a value from args_ptr.
955 %': apostrophe (should only be used in untranslated messages;
956 translations should use appropriate punctuation directly).
957 %.*s: a substring the length of which is specified by an argument
959 %Ns: likewise, but length specified as constant in the format string.
960 Flag 'q': quote formatted text (must come immediately after '%').
961 %Z: Requires two arguments - array of int, and len. Prints elements
964 Arguments can be used sequentially, or through %N$ resp. *N$
965 notation Nth argument after the format string. If %N$ / *N$
966 notation is used, it must be used for all arguments, except %m, %%,
967 %<, %> and %', which may not have a number, as they do not consume
968 an argument. When %M$.*N$s is used, M must be N + 1. (This may
969 also be written %M$.*s, provided N is not otherwise used.) The
970 format string must have conversion specifiers with argument numbers
971 1 up to highest argument; each argument may only be used once.
972 A format string can have at most 30 arguments. */
974 /* Formatting phases 1 and 2: render TEXT->format_spec plus
975 TEXT->args_ptr into a series of chunks in pp_buffer (PP)->args[].
976 Phase 3 is in pp_output_formatted_text. */
979 pp_format (pretty_printer
*pp
, text_info
*text
)
981 output_buffer
*buffer
= pp_buffer (pp
);
984 struct chunk_info
*new_chunk_array
;
986 unsigned int curarg
= 0, chunk
= 0, argno
;
987 pp_wrapping_mode_t old_wrapping_mode
;
988 bool any_unnumbered
= false, any_numbered
= false;
989 const char **formatters
[PP_NL_ARGMAX
];
991 /* Allocate a new chunk structure. */
992 new_chunk_array
= XOBNEW (&buffer
->chunk_obstack
, struct chunk_info
);
993 new_chunk_array
->prev
= buffer
->cur_chunk_array
;
994 buffer
->cur_chunk_array
= new_chunk_array
;
995 args
= new_chunk_array
->args
;
997 /* Formatting phase 1: split up TEXT->format_spec into chunks in
998 pp_buffer (PP)->args[]. Even-numbered chunks are to be output
999 verbatim, odd-numbered chunks are format specifiers.
1000 %m, %%, %<, %>, and %' are replaced with the appropriate text at
1003 memset (formatters
, 0, sizeof formatters
);
1005 for (p
= text
->format_spec
; *p
; )
1007 while (*p
!= '\0' && *p
!= '%')
1009 obstack_1grow (&buffer
->chunk_obstack
, *p
);
1022 obstack_1grow (&buffer
->chunk_obstack
, '%');
1028 obstack_grow (&buffer
->chunk_obstack
,
1029 open_quote
, strlen (open_quote
));
1030 const char *colorstr
1031 = colorize_start (pp_show_color (pp
), "quote");
1032 obstack_grow (&buffer
->chunk_obstack
, colorstr
, strlen (colorstr
));
1039 const char *colorstr
= colorize_stop (pp_show_color (pp
));
1040 obstack_grow (&buffer
->chunk_obstack
, colorstr
, strlen (colorstr
));
1044 obstack_grow (&buffer
->chunk_obstack
,
1045 close_quote
, strlen (close_quote
));
1051 const char *colorstr
= colorize_stop (pp_show_color (pp
));
1052 obstack_grow (&buffer
->chunk_obstack
, colorstr
,
1060 const char *errstr
= xstrerror (text
->err_no
);
1061 obstack_grow (&buffer
->chunk_obstack
, errstr
, strlen (errstr
));
1067 /* Handled in phase 2. Terminate the plain chunk here. */
1068 obstack_1grow (&buffer
->chunk_obstack
, '\0');
1069 gcc_assert (chunk
< PP_NL_ARGMAX
* 2);
1070 args
[chunk
++] = XOBFINISH (&buffer
->chunk_obstack
, const char *);
1077 argno
= strtoul (p
, &end
, 10) - 1;
1079 gcc_assert (*p
== '$');
1082 any_numbered
= true;
1083 gcc_assert (!any_unnumbered
);
1088 any_unnumbered
= true;
1089 gcc_assert (!any_numbered
);
1091 gcc_assert (argno
< PP_NL_ARGMAX
);
1092 gcc_assert (!formatters
[argno
]);
1093 formatters
[argno
] = &args
[chunk
];
1096 obstack_1grow (&buffer
->chunk_obstack
, *p
);
1099 while (strchr ("qwl+#", p
[-1]));
1103 /* We handle '%.Ns' and '%.*s' or '%M$.*N$s'
1104 (where M == N + 1). */
1109 obstack_1grow (&buffer
->chunk_obstack
, *p
);
1112 while (ISDIGIT (p
[-1]));
1113 gcc_assert (p
[-1] == 's');
1117 gcc_assert (*p
== '*');
1118 obstack_1grow (&buffer
->chunk_obstack
, '*');
1124 unsigned int argno2
= strtoul (p
, &end
, 10) - 1;
1126 gcc_assert (argno2
== argno
- 1);
1127 gcc_assert (!any_unnumbered
);
1128 gcc_assert (*p
== '$');
1131 formatters
[argno2
] = formatters
[argno
];
1135 gcc_assert (!any_numbered
);
1136 formatters
[argno
+1] = formatters
[argno
];
1139 gcc_assert (*p
== 's');
1140 obstack_1grow (&buffer
->chunk_obstack
, 's');
1147 obstack_1grow (&buffer
->chunk_obstack
, '\0');
1148 gcc_assert (chunk
< PP_NL_ARGMAX
* 2);
1149 args
[chunk
++] = XOBFINISH (&buffer
->chunk_obstack
, const char *);
1152 obstack_1grow (&buffer
->chunk_obstack
, '\0');
1153 gcc_assert (chunk
< PP_NL_ARGMAX
* 2);
1154 args
[chunk
++] = XOBFINISH (&buffer
->chunk_obstack
, const char *);
1157 /* Set output to the argument obstack, and switch line-wrapping and
1159 buffer
->obstack
= &buffer
->chunk_obstack
;
1160 old_wrapping_mode
= pp_set_verbatim_wrapping (pp
);
1162 /* Second phase. Replace each formatter with the formatted text it
1165 for (argno
= 0; formatters
[argno
]; argno
++)
1173 /* We do not attempt to enforce any ordering on the modifier
1176 for (p
= *formatters
[argno
];; p
++)
1181 gcc_assert (!quote
);
1201 /* We don't support precision beyond that of "long long". */
1202 gcc_assert (precision
< 2);
1209 gcc_assert (!wide
|| precision
== 0);
1213 pp_string (pp
, open_quote
);
1214 pp_string (pp
, colorize_start (pp_show_color (pp
), "quote"));
1220 pp_string (pp
, colorize_start (pp_show_color (pp
),
1221 va_arg (*text
->args_ptr
,
1227 /* When quoting, print alphanumeric, punctuation, and the space
1228 character unchanged, and all others in hexadecimal with the
1229 "\x" prefix. Otherwise print them all unchanged. */
1230 int chr
= va_arg (*text
->args_ptr
, int);
1231 if (ISPRINT (chr
) || !quote
)
1232 pp_character (pp
, chr
);
1235 const char str
[2] = { chr
, '\0' };
1236 pp_quoted_string (pp
, str
, 1);
1244 pp_wide_integer (pp
, va_arg (*text
->args_ptr
, HOST_WIDE_INT
));
1246 pp_integer_with_precision
1247 (pp
, *text
->args_ptr
, precision
, int, "d");
1252 pp_scalar (pp
, "%" HOST_WIDE_INT_PRINT
"o",
1253 va_arg (*text
->args_ptr
, unsigned HOST_WIDE_INT
));
1255 pp_integer_with_precision
1256 (pp
, *text
->args_ptr
, precision
, unsigned, "o");
1261 pp_quoted_string (pp
, va_arg (*text
->args_ptr
, const char *));
1263 pp_string (pp
, va_arg (*text
->args_ptr
, const char *));
1267 pp_pointer (pp
, va_arg (*text
->args_ptr
, void *));
1272 pp_scalar (pp
, HOST_WIDE_INT_PRINT_UNSIGNED
,
1273 va_arg (*text
->args_ptr
, unsigned HOST_WIDE_INT
));
1275 pp_integer_with_precision
1276 (pp
, *text
->args_ptr
, precision
, unsigned, "u");
1281 int *v
= va_arg (*text
->args_ptr
, int *);
1282 unsigned len
= va_arg (*text
->args_ptr
, unsigned);
1284 for (unsigned i
= 0; i
< len
; ++i
)
1286 pp_scalar (pp
, "%i", v
[i
]);
1298 pp_scalar (pp
, HOST_WIDE_INT_PRINT_HEX
,
1299 va_arg (*text
->args_ptr
, unsigned HOST_WIDE_INT
));
1301 pp_integer_with_precision
1302 (pp
, *text
->args_ptr
, precision
, unsigned, "x");
1310 /* We handle '%.Ns' and '%.*s' or '%M$.*N$s'
1311 (where M == N + 1). The format string should be verified
1312 already from the first phase. */
1317 n
= strtoul (p
, &end
, 10);
1319 gcc_assert (*p
== 's');
1323 gcc_assert (*p
== '*');
1325 gcc_assert (*p
== 's');
1326 n
= va_arg (*text
->args_ptr
, int);
1328 /* This consumes a second entry in the formatters array. */
1329 gcc_assert (formatters
[argno
] == formatters
[argno
+1]);
1333 s
= va_arg (*text
->args_ptr
, const char *);
1335 /* Append the lesser of precision and strlen (s) characters
1336 from the array (which need not be a nul-terminated string).
1337 Negative precision is treated as if it were omitted. */
1338 size_t len
= n
< 0 ? strlen (s
) : strnlen (s
, n
);
1340 pp_append_text (pp
, s
, s
+ len
);
1348 gcc_assert (pp_format_decoder (pp
));
1349 ok
= pp_format_decoder (pp
) (pp
, text
, p
,
1350 precision
, wide
, plus
, hash
, quote
,
1358 pp_string (pp
, colorize_stop (pp_show_color (pp
)));
1359 pp_string (pp
, close_quote
);
1362 obstack_1grow (&buffer
->chunk_obstack
, '\0');
1363 *formatters
[argno
] = XOBFINISH (&buffer
->chunk_obstack
, const char *);
1367 for (; argno
< PP_NL_ARGMAX
; argno
++)
1368 gcc_assert (!formatters
[argno
]);
1370 /* If the client supplied a postprocessing object, call its "handle"
1372 if (pp
->m_format_postprocessor
)
1373 pp
->m_format_postprocessor
->handle (pp
);
1375 /* Revert to normal obstack and wrapping mode. */
1376 buffer
->obstack
= &buffer
->formatted_obstack
;
1377 buffer
->line_length
= 0;
1378 pp_wrapping_mode (pp
) = old_wrapping_mode
;
1379 pp_clear_state (pp
);
1382 /* Format of a message pointed to by TEXT. */
1384 pp_output_formatted_text (pretty_printer
*pp
)
1387 output_buffer
*buffer
= pp_buffer (pp
);
1388 struct chunk_info
*chunk_array
= buffer
->cur_chunk_array
;
1389 const char **args
= chunk_array
->args
;
1391 gcc_assert (buffer
->obstack
== &buffer
->formatted_obstack
);
1392 gcc_assert (buffer
->line_length
== 0);
1394 /* This is a third phase, first 2 phases done in pp_format_args.
1395 Now we actually print it. */
1396 for (chunk
= 0; args
[chunk
]; chunk
++)
1397 pp_string (pp
, args
[chunk
]);
1399 /* Deallocate the chunk structure and everything after it (i.e. the
1400 associated series of formatted strings). */
1401 buffer
->cur_chunk_array
= chunk_array
->prev
;
1402 obstack_free (&buffer
->chunk_obstack
, chunk_array
);
1405 /* Helper subroutine of output_verbatim and verbatim. Do the appropriate
1406 settings needed by BUFFER for a verbatim formatting. */
1408 pp_format_verbatim (pretty_printer
*pp
, text_info
*text
)
1410 /* Set verbatim mode. */
1411 pp_wrapping_mode_t oldmode
= pp_set_verbatim_wrapping (pp
);
1413 /* Do the actual formatting. */
1414 pp_format (pp
, text
);
1415 pp_output_formatted_text (pp
);
1417 /* Restore previous settings. */
1418 pp_wrapping_mode (pp
) = oldmode
;
1421 /* Flush the content of BUFFER onto the attached stream. This
1422 function does nothing unless pp->output_buffer->flush_p. */
1424 pp_flush (pretty_printer
*pp
)
1426 pp_clear_state (pp
);
1427 if (!pp
->buffer
->flush_p
)
1429 pp_write_text_to_stream (pp
);
1430 fflush (pp_buffer (pp
)->stream
);
1433 /* Flush the content of BUFFER onto the attached stream independently
1434 of the value of pp->output_buffer->flush_p. */
1436 pp_really_flush (pretty_printer
*pp
)
1438 pp_clear_state (pp
);
1439 pp_write_text_to_stream (pp
);
1440 fflush (pp_buffer (pp
)->stream
);
1443 /* Sets the number of maximum characters per line PRETTY-PRINTER can
1444 output in line-wrapping mode. A LENGTH value 0 suppresses
1447 pp_set_line_maximum_length (pretty_printer
*pp
, int length
)
1449 pp_line_cutoff (pp
) = length
;
1450 pp_set_real_maximum_length (pp
);
1453 /* Clear PRETTY-PRINTER output area text info. */
1455 pp_clear_output_area (pretty_printer
*pp
)
1457 obstack_free (pp_buffer (pp
)->obstack
,
1458 obstack_base (pp_buffer (pp
)->obstack
));
1459 pp_buffer (pp
)->line_length
= 0;
1462 /* Set PREFIX for PRETTY-PRINTER. */
1464 pp_set_prefix (pretty_printer
*pp
, const char *prefix
)
1466 pp
->prefix
= prefix
;
1467 pp_set_real_maximum_length (pp
);
1468 pp
->emitted_prefix
= false;
1469 pp_indentation (pp
) = 0;
1472 /* Free PRETTY-PRINTER's prefix, a previously malloc()'d string. */
1474 pp_destroy_prefix (pretty_printer
*pp
)
1476 if (pp
->prefix
!= NULL
)
1478 free (CONST_CAST (char *, pp
->prefix
));
1483 /* Write out PRETTY-PRINTER's prefix. */
1485 pp_emit_prefix (pretty_printer
*pp
)
1487 if (pp
->prefix
!= NULL
)
1489 switch (pp_prefixing_rule (pp
))
1492 case DIAGNOSTICS_SHOW_PREFIX_NEVER
:
1495 case DIAGNOSTICS_SHOW_PREFIX_ONCE
:
1496 if (pp
->emitted_prefix
)
1501 pp_indentation (pp
) += 3;
1504 case DIAGNOSTICS_SHOW_PREFIX_EVERY_LINE
:
1506 int prefix_length
= strlen (pp
->prefix
);
1507 pp_append_r (pp
, pp
->prefix
, prefix_length
);
1508 pp
->emitted_prefix
= true;
1515 /* Construct a PRETTY-PRINTER with PREFIX and of MAXIMUM_LENGTH
1516 characters per line. */
1518 pretty_printer::pretty_printer (const char *p
, int l
)
1519 : buffer (new (XCNEW (output_buffer
)) output_buffer ()),
1526 m_format_postprocessor (NULL
),
1529 translate_identifiers (true),
1532 pp_line_cutoff (this) = l
;
1533 /* By default, we emit prefixes once per message. */
1534 pp_prefixing_rule (this) = DIAGNOSTICS_SHOW_PREFIX_ONCE
;
1535 pp_set_prefix (this, p
);
1538 pretty_printer::~pretty_printer ()
1540 if (m_format_postprocessor
)
1541 delete m_format_postprocessor
;
1542 buffer
->~output_buffer ();
1546 /* Append a string delimited by START and END to the output area of
1547 PRETTY-PRINTER. No line wrapping is done. However, if beginning a
1548 new line then emit PRETTY-PRINTER's prefix and skip any leading
1549 whitespace if appropriate. The caller must ensure that it is
1552 pp_append_text (pretty_printer
*pp
, const char *start
, const char *end
)
1554 /* Emit prefix and skip whitespace if we're starting a new line. */
1555 if (pp_buffer (pp
)->line_length
== 0)
1557 pp_emit_prefix (pp
);
1558 if (pp_is_wrapping_line (pp
))
1559 while (start
!= end
&& *start
== ' ')
1562 pp_append_r (pp
, start
, end
- start
);
1565 /* Finishes constructing a NULL-terminated character string representing
1566 the PRETTY-PRINTED text. */
1568 pp_formatted_text (pretty_printer
*pp
)
1570 return output_buffer_formatted_text (pp_buffer (pp
));
1573 /* Return a pointer to the last character emitted in PRETTY-PRINTER's
1574 output area. A NULL pointer means no character available. */
1576 pp_last_position_in_text (const pretty_printer
*pp
)
1578 return output_buffer_last_position_in_text (pp_buffer (pp
));
1581 /* Return the amount of characters PRETTY-PRINTER can accept to
1582 make a full line. Meaningful only in line-wrapping mode. */
1584 pp_remaining_character_count_for_line (pretty_printer
*pp
)
1586 return pp
->maximum_length
- pp_buffer (pp
)->line_length
;
1590 /* Format a message into BUFFER a la printf. */
1592 pp_printf (pretty_printer
*pp
, const char *msg
, ...)
1598 text
.err_no
= errno
;
1599 text
.args_ptr
= &ap
;
1600 text
.format_spec
= msg
;
1601 pp_format (pp
, &text
);
1602 pp_output_formatted_text (pp
);
1607 /* Output MESSAGE verbatim into BUFFER. */
1609 pp_verbatim (pretty_printer
*pp
, const char *msg
, ...)
1615 text
.err_no
= errno
;
1616 text
.args_ptr
= &ap
;
1617 text
.format_spec
= msg
;
1618 pp_format_verbatim (pp
, &text
);
1624 /* Have PRETTY-PRINTER start a new line. */
1626 pp_newline (pretty_printer
*pp
)
1628 obstack_1grow (pp_buffer (pp
)->obstack
, '\n');
1629 pp_needs_newline (pp
) = false;
1630 pp_buffer (pp
)->line_length
= 0;
1633 /* Have PRETTY-PRINTER add a CHARACTER. */
1635 pp_character (pretty_printer
*pp
, int c
)
1637 if (pp_is_wrapping_line (pp
)
1638 && pp_remaining_character_count_for_line (pp
) <= 0)
1644 obstack_1grow (pp_buffer (pp
)->obstack
, c
);
1645 ++pp_buffer (pp
)->line_length
;
1648 /* Append a STRING to the output area of PRETTY-PRINTER; the STRING may
1649 be line-wrapped if in appropriate mode. */
1651 pp_string (pretty_printer
*pp
, const char *str
)
1653 gcc_checking_assert (str
);
1654 pp_maybe_wrap_text (pp
, str
, str
+ strlen (str
));
1657 /* Append the leading N characters of STRING to the output area of
1658 PRETTY-PRINTER, quoting in hexadecimal non-printable characters.
1659 Setting N = -1 is as if N were set to strlen (STRING). The STRING
1660 may be line-wrapped if in appropriate mode. */
1662 pp_quoted_string (pretty_printer
*pp
, const char *str
, size_t n
/* = -1 */)
1664 gcc_checking_assert (str
);
1666 const char *last
= str
;
1669 /* Compute the length if not specified. */
1670 if (n
== (size_t) -1)
1673 for (ps
= str
; n
; ++ps
, --n
)
1679 pp_maybe_wrap_text (pp
, last
, ps
- 1);
1681 /* Append the hexadecimal value of the character. Allocate a buffer
1682 that's large enough for a 32-bit char plus the hex prefix. */
1684 int n
= sprintf (buf
, "\\x%02x", (unsigned char)*ps
);
1685 pp_maybe_wrap_text (pp
, buf
, buf
+ n
);
1689 pp_maybe_wrap_text (pp
, last
, ps
);
1692 /* Maybe print out a whitespace if needed. */
1695 pp_maybe_space (pretty_printer
*pp
)
1697 if (pp
->padding
!= pp_none
)
1700 pp
->padding
= pp_none
;
1704 // Add a newline to the pretty printer PP and flush formatted text.
1707 pp_newline_and_flush (pretty_printer
*pp
)
1711 pp_needs_newline (pp
) = false;
1714 // Add a newline to the pretty printer PP, followed by indentation.
1717 pp_newline_and_indent (pretty_printer
*pp
, int n
)
1719 pp_indentation (pp
) += n
;
1722 pp_needs_newline (pp
) = false;
1725 // Add separator C, followed by a single whitespace.
1728 pp_separate_with (pretty_printer
*pp
, char c
)
1730 pp_character (pp
, c
);
1735 /* The string starting at P has LEN (at least 1) bytes left; if they
1736 start with a valid UTF-8 sequence, return the length of that
1737 sequence and set *VALUE to the value of that sequence, and
1738 otherwise return 0 and set *VALUE to (unsigned int) -1. */
1741 decode_utf8_char (const unsigned char *p
, size_t len
, unsigned int *value
)
1743 unsigned int t
= *p
;
1749 size_t utf8_len
= 0;
1752 for (t
= *p
; t
& 0x80; t
<<= 1)
1755 if (utf8_len
> len
|| utf8_len
< 2 || utf8_len
> 6)
1757 *value
= (unsigned int) -1;
1760 ch
= *p
& ((1 << (7 - utf8_len
)) - 1);
1761 for (i
= 1; i
< utf8_len
; i
++)
1763 unsigned int u
= p
[i
];
1764 if ((u
& 0xC0) != 0x80)
1766 *value
= (unsigned int) -1;
1769 ch
= (ch
<< 6) | (u
& 0x3F);
1771 if ( (ch
<= 0x7F && utf8_len
> 1)
1772 || (ch
<= 0x7FF && utf8_len
> 2)
1773 || (ch
<= 0xFFFF && utf8_len
> 3)
1774 || (ch
<= 0x1FFFFF && utf8_len
> 4)
1775 || (ch
<= 0x3FFFFFF && utf8_len
> 5)
1776 || (ch
>= 0xD800 && ch
<= 0xDFFF))
1778 *value
= (unsigned int) -1;
1791 /* Allocator for identifier_to_locale and corresponding function to
1794 void *(*identifier_to_locale_alloc
) (size_t) = xmalloc
;
1795 void (*identifier_to_locale_free
) (void *) = free
;
1797 /* Given IDENT, an identifier in the internal encoding, return a
1798 version of IDENT suitable for diagnostics in the locale character
1799 set: either IDENT itself, or a string, allocated using
1800 identifier_to_locale_alloc, converted to the locale character set
1801 and using escape sequences if not representable in the locale
1802 character set or containing control characters or invalid byte
1803 sequences. Existing backslashes in IDENT are not doubled, so the
1804 result may not uniquely specify the contents of an arbitrary byte
1805 sequence identifier. */
1808 identifier_to_locale (const char *ident
)
1810 const unsigned char *uid
= (const unsigned char *) ident
;
1811 size_t idlen
= strlen (ident
);
1812 bool valid_printable_utf8
= true;
1813 bool all_ascii
= true;
1816 for (i
= 0; i
< idlen
;)
1819 size_t utf8_len
= decode_utf8_char (&uid
[i
], idlen
- i
, &c
);
1820 if (utf8_len
== 0 || c
<= 0x1F || (c
>= 0x7F && c
<= 0x9F))
1822 valid_printable_utf8
= false;
1830 /* If IDENT contains invalid UTF-8 sequences (which may occur with
1831 attributes putting arbitrary byte sequences in identifiers), or
1832 control characters, we use octal escape sequences for all bytes
1833 outside printable ASCII. */
1834 if (!valid_printable_utf8
)
1836 char *ret
= (char *) identifier_to_locale_alloc (4 * idlen
+ 1);
1838 for (i
= 0; i
< idlen
; i
++)
1840 if (uid
[i
] > 0x1F && uid
[i
] < 0x7F)
1844 sprintf (p
, "\\%03o", uid
[i
]);
1852 /* Otherwise, if it is valid printable ASCII, or printable UTF-8
1853 with the locale character set being UTF-8, IDENT is used. */
1854 if (all_ascii
|| locale_utf8
)
1857 /* Otherwise IDENT is converted to the locale character set if
1859 #if defined ENABLE_NLS && defined HAVE_LANGINFO_CODESET && HAVE_ICONV
1860 if (locale_encoding
!= NULL
)
1862 iconv_t cd
= iconv_open (locale_encoding
, "UTF-8");
1863 bool conversion_ok
= true;
1865 if (cd
!= (iconv_t
) -1)
1867 size_t ret_alloc
= 4 * idlen
+ 1;
1870 /* Repeat the whole conversion process as needed with
1871 larger buffers so non-reversible transformations can
1872 always be detected. */
1873 ICONV_CONST
char *inbuf
= CONST_CAST (char *, ident
);
1875 size_t inbytesleft
= idlen
;
1876 size_t outbytesleft
= ret_alloc
- 1;
1879 ret
= (char *) identifier_to_locale_alloc (ret_alloc
);
1882 if (iconv (cd
, 0, 0, 0, 0) == (size_t) -1)
1884 conversion_ok
= false;
1888 iconv_ret
= iconv (cd
, &inbuf
, &inbytesleft
,
1889 &outbuf
, &outbytesleft
);
1890 if (iconv_ret
== (size_t) -1 || inbytesleft
!= 0)
1895 identifier_to_locale_free (ret
);
1901 conversion_ok
= false;
1905 else if (iconv_ret
!= 0)
1907 conversion_ok
= false;
1910 /* Return to initial shift state. */
1911 if (iconv (cd
, 0, 0, &outbuf
, &outbytesleft
) == (size_t) -1)
1916 identifier_to_locale_free (ret
);
1922 conversion_ok
= false;
1936 /* Otherwise, convert non-ASCII characters in IDENT to UCNs. */
1938 char *ret
= (char *) identifier_to_locale_alloc (10 * idlen
+ 1);
1940 for (i
= 0; i
< idlen
;)
1943 size_t utf8_len
= decode_utf8_char (&uid
[i
], idlen
- i
, &c
);
1948 sprintf (p
, "\\U%08x", c
);
1960 namespace selftest
{
1962 /* Smoketest for pretty_printer. */
1965 test_basic_printing ()
1968 pp_string (&pp
, "hello");
1970 pp_string (&pp
, "world");
1972 ASSERT_STREQ ("hello world", pp_formatted_text (&pp
));
1975 /* Helper function for testing pp_format.
1976 Verify that pp_format (FMT, ...) followed by pp_output_formatted_text
1977 prints EXPECTED, assuming that pp_show_color is SHOW_COLOR. */
1980 assert_pp_format_va (const location
&loc
, const char *expected
,
1981 bool show_color
, const char *fmt
, va_list *ap
)
1985 rich_location
rich_loc (line_table
, UNKNOWN_LOCATION
);
1987 ti
.format_spec
= fmt
;
1991 ti
.m_richloc
= &rich_loc
;
1993 pp_show_color (&pp
) = show_color
;
1994 pp_format (&pp
, &ti
);
1995 pp_output_formatted_text (&pp
);
1996 ASSERT_STREQ_AT (loc
, expected
, pp_formatted_text (&pp
));
1999 /* Verify that pp_format (FMT, ...) followed by pp_output_formatted_text
2000 prints EXPECTED, with show_color disabled. */
2003 assert_pp_format (const location
&loc
, const char *expected
,
2004 const char *fmt
, ...)
2009 assert_pp_format_va (loc
, expected
, false, fmt
, &ap
);
2013 /* As above, but with colorization enabled. */
2016 assert_pp_format_colored (const location
&loc
, const char *expected
,
2017 const char *fmt
, ...)
2019 /* The tests of colorization assume the default color scheme.
2020 If GCC_COLORS is set, then the colors have potentially been
2021 overridden; skip the test. */
2022 if (getenv ("GCC_COLORS"))
2028 assert_pp_format_va (loc
, expected
, true, fmt
, &ap
);
2032 /* Helper function for calling testing pp_format,
2033 by calling assert_pp_format with various numbers of arguments.
2034 These exist mostly to avoid having to write SELFTEST_LOCATION
2035 throughout test_pp_format. */
2037 #define ASSERT_PP_FORMAT_1(EXPECTED, FMT, ARG1) \
2038 SELFTEST_BEGIN_STMT \
2039 assert_pp_format ((SELFTEST_LOCATION), (EXPECTED), (FMT), \
2043 #define ASSERT_PP_FORMAT_2(EXPECTED, FMT, ARG1, ARG2) \
2044 SELFTEST_BEGIN_STMT \
2045 assert_pp_format ((SELFTEST_LOCATION), (EXPECTED), (FMT), \
2049 #define ASSERT_PP_FORMAT_3(EXPECTED, FMT, ARG1, ARG2, ARG3) \
2050 SELFTEST_BEGIN_STMT \
2051 assert_pp_format ((SELFTEST_LOCATION), (EXPECTED), (FMT), \
2052 (ARG1), (ARG2), (ARG3)); \
2055 /* Verify that pp_format works, for various format codes. */
2060 /* Avoid introducing locale-specific differences in the results
2061 by hardcoding open_quote and close_quote. */
2062 const char *old_open_quote
= open_quote
;
2063 const char *old_close_quote
= close_quote
;
2067 /* Verify that plain text is passed through unchanged. */
2068 assert_pp_format (SELFTEST_LOCATION
, "unformatted", "unformatted");
2070 /* Verify various individual format codes, in the order listed in the
2071 comment for pp_format above. For each code, we append a second
2072 argument with a known bit pattern (0x12345678), to ensure that we
2073 are consuming arguments correctly. */
2074 ASSERT_PP_FORMAT_2 ("-27 12345678", "%d %x", -27, 0x12345678);
2075 ASSERT_PP_FORMAT_2 ("-5 12345678", "%i %x", -5, 0x12345678);
2076 ASSERT_PP_FORMAT_2 ("10 12345678", "%u %x", 10, 0x12345678);
2077 ASSERT_PP_FORMAT_2 ("17 12345678", "%o %x", 15, 0x12345678);
2078 ASSERT_PP_FORMAT_2 ("cafebabe 12345678", "%x %x", 0xcafebabe, 0x12345678);
2079 ASSERT_PP_FORMAT_2 ("-27 12345678", "%ld %x", (long)-27, 0x12345678);
2080 ASSERT_PP_FORMAT_2 ("-5 12345678", "%li %x", (long)-5, 0x12345678);
2081 ASSERT_PP_FORMAT_2 ("10 12345678", "%lu %x", (long)10, 0x12345678);
2082 ASSERT_PP_FORMAT_2 ("17 12345678", "%lo %x", (long)15, 0x12345678);
2083 ASSERT_PP_FORMAT_2 ("cafebabe 12345678", "%lx %x", (long)0xcafebabe,
2085 ASSERT_PP_FORMAT_2 ("-27 12345678", "%lld %x", (long long)-27, 0x12345678);
2086 ASSERT_PP_FORMAT_2 ("-5 12345678", "%lli %x", (long long)-5, 0x12345678);
2087 ASSERT_PP_FORMAT_2 ("10 12345678", "%llu %x", (long long)10, 0x12345678);
2088 ASSERT_PP_FORMAT_2 ("17 12345678", "%llo %x", (long long)15, 0x12345678);
2089 ASSERT_PP_FORMAT_2 ("cafebabe 12345678", "%llx %x", (long long)0xcafebabe,
2091 ASSERT_PP_FORMAT_2 ("-27 12345678", "%wd %x", (HOST_WIDE_INT
)-27, 0x12345678);
2092 ASSERT_PP_FORMAT_2 ("-5 12345678", "%wi %x", (HOST_WIDE_INT
)-5, 0x12345678);
2093 ASSERT_PP_FORMAT_2 ("10 12345678", "%wu %x", (unsigned HOST_WIDE_INT
)10,
2095 ASSERT_PP_FORMAT_2 ("17 12345678", "%wo %x", (HOST_WIDE_INT
)15, 0x12345678);
2096 ASSERT_PP_FORMAT_2 ("0xcafebabe 12345678", "%wx %x", (HOST_WIDE_INT
)0xcafebabe,
2098 ASSERT_PP_FORMAT_2 ("A 12345678", "%c %x", 'A', 0x12345678);
2099 ASSERT_PP_FORMAT_2 ("hello world 12345678", "%s %x", "hello world",
2102 /* Not nul-terminated. */
2103 char arr
[5] = { '1', '2', '3', '4', '5' };
2104 ASSERT_PP_FORMAT_3 ("123 12345678", "%.*s %x", 3, arr
, 0x12345678);
2105 ASSERT_PP_FORMAT_3 ("1234 12345678", "%.*s %x", -1, "1234", 0x12345678);
2106 ASSERT_PP_FORMAT_3 ("12345 12345678", "%.*s %x", 7, "12345", 0x12345678);
2108 /* We can't test for %p; the pointer is printed in an implementation-defined
2110 ASSERT_PP_FORMAT_2 ("normal colored normal 12345678",
2111 "normal %rcolored%R normal %x",
2112 "error", 0x12345678);
2113 assert_pp_format_colored
2115 "normal \33[01;31m\33[Kcolored\33[m\33[K normal 12345678",
2116 "normal %rcolored%R normal %x", "error", 0x12345678);
2118 %m: strerror(text->err_no) - does not consume a value from args_ptr. */
2119 ASSERT_PP_FORMAT_1 ("% 12345678", "%% %x", 0x12345678);
2120 ASSERT_PP_FORMAT_1 ("` 12345678", "%< %x", 0x12345678);
2121 ASSERT_PP_FORMAT_1 ("' 12345678", "%> %x", 0x12345678);
2122 ASSERT_PP_FORMAT_1 ("' 12345678", "%' %x", 0x12345678);
2123 ASSERT_PP_FORMAT_3 ("abc 12345678", "%.*s %x", 3, "abcdef", 0x12345678);
2124 ASSERT_PP_FORMAT_2 ("abc 12345678", "%.3s %x", "abcdef", 0x12345678);
2126 /* Verify flag 'q'. */
2127 ASSERT_PP_FORMAT_2 ("`foo' 12345678", "%qs %x", "foo", 0x12345678);
2128 assert_pp_format_colored (SELFTEST_LOCATION
,
2129 "`\33[01m\33[Kfoo\33[m\33[K' 12345678", "%qs %x",
2133 int v
[] = { 1, 2, 3 };
2134 ASSERT_PP_FORMAT_3 ("1, 2, 3 12345678", "%Z %x", v
, 3, 0x12345678);
2137 ASSERT_PP_FORMAT_3 ("0 12345678", "%Z %x", v2
, 1, 0x12345678);
2139 /* Verify that combinations work, along with unformatted text. */
2140 assert_pp_format (SELFTEST_LOCATION
,
2141 "the quick brown fox jumps over the lazy dog",
2142 "the %s %s %s jumps over the %s %s",
2143 "quick", "brown", "fox", "lazy", "dog");
2144 assert_pp_format (SELFTEST_LOCATION
, "item 3 of 7", "item %i of %i", 3, 7);
2145 assert_pp_format (SELFTEST_LOCATION
, "problem with `bar' at line 10",
2146 "problem with %qs at line %i", "bar", 10);
2148 /* Restore old values of open_quote and close_quote. */
2149 open_quote
= old_open_quote
;
2150 close_quote
= old_close_quote
;
2153 /* Run all of the selftests within this file. */
2156 pretty_print_c_tests ()
2158 test_basic_printing ();
2162 } // namespace selftest
2164 #endif /* CHECKING_P */