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