]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/pretty-print.c
pretty-print.c (mingw_ansi_fputs): Do not call _close() on the handle returned by...
[thirdparty/gcc.git] / gcc / pretty-print.c
CommitLineData
b6fe0bb8 1/* Various declarations for language-independent pretty-print subroutines.
85ec4feb 2 Copyright (C) 2003-2018 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 }
643 SetConsoleTextAttribute (h, attrib_add);
644 break;
645 }
646}
647
648int
649mingw_ansi_fputs (const char *str, FILE *fp)
650{
651 const char *read = str;
652 HANDLE h;
653 DWORD mode;
654 int esc_code, prefix_len;
655 const char *esc_head, *esc_term;
656
657 h = (HANDLE) _get_osfhandle (_fileno (fp));
658 if (h == INVALID_HANDLE_VALUE)
659 return EOF;
660
661 /* Don't mess up stdio functions with Windows APIs. */
662 fflush (fp);
663
664 if (GetConsoleMode (h, &mode))
665 /* If it is a console, translate ANSI escape codes as needed. */
666 for (;;)
667 {
668 if ((esc_code = find_esc_head (&prefix_len, &esc_head, read)) == 0)
669 {
670 /* Write all remaining characters, then exit. */
671 write_all (h, read, strlen (read));
672 break;
673 }
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
677 to this function. */
678 break;
679 write_all (h, read, esc_head - prefix_len - read);
680 eat_esc_sequence (h, esc_code, esc_head, esc_term);
681 read = esc_term + 1;
682 }
683 else
684 /* If it is not a console, write everything as-is. */
685 write_all (h, read, strlen (read));
686
db0d1bae
LH
687 return 1;
688}
689
690#endif /* __MINGW32__ */
691
3f0177e7
MS
692static void pp_quoted_string (pretty_printer *, const char *, size_t = -1);
693
f79520bb 694/* Overwrite the given location/range within this text_info's rich_location.
8a645150
DM
695 For use e.g. when implementing "+" in client format decoders. */
696
697void
f79520bb 698text_info::set_location (unsigned int idx, location_t loc, bool show_caret_p)
8a645150
DM
699{
700 gcc_checking_assert (m_richloc);
181463c2 701 m_richloc->set_range (idx, loc, show_caret_p);
8a645150
DM
702}
703
704location_t
705text_info::get_location (unsigned int index_of_location) const
706{
707 gcc_checking_assert (m_richloc);
708
709 if (index_of_location == 0)
710 return m_richloc->get_loc ();
711 else
712 return UNKNOWN_LOCATION;
713}
714
da6ca2b5
GDR
715// Default construct an output buffer.
716
717output_buffer::output_buffer ()
718 : formatted_obstack (),
719 chunk_obstack (),
720 obstack (&formatted_obstack),
721 cur_chunk_array (),
722 stream (stderr),
723 line_length (),
48749dbc
MLI
724 digit_buffer (),
725 flush_p (true)
da6ca2b5
GDR
726{
727 obstack_init (&formatted_obstack);
728 obstack_init (&chunk_obstack);
729}
730
025311c4
GDR
731// Release resources owned by an output buffer at the end of lifetime.
732
733output_buffer::~output_buffer ()
734{
65f5c720
RB
735 obstack_free (&chunk_obstack, NULL);
736 obstack_free (&formatted_obstack, NULL);
025311c4
GDR
737}
738
b6fe0bb8
GDR
739
740/* Format an integer given by va_arg (ARG, type-specifier T) where
741 type-specifier is a precision modifier as indicated by PREC. F is
742 a string used to construct the appropriate format-specifier. */
743#define pp_integer_with_precision(PP, ARG, PREC, T, F) \
744 do \
745 switch (PREC) \
746 { \
747 case 0: \
748 pp_scalar (PP, "%" F, va_arg (ARG, T)); \
749 break; \
750 \
751 case 1: \
752 pp_scalar (PP, "%l" F, va_arg (ARG, long T)); \
753 break; \
754 \
755 case 2: \
2a157700 756 pp_scalar (PP, "%" HOST_LONG_LONG_FORMAT F, va_arg (ARG, long long T)); \
b6fe0bb8
GDR
757 break; \
758 \
759 default: \
760 break; \
761 } \
762 while (0)
763
764
765/* Subroutine of pp_set_maximum_length. Set up PRETTY-PRINTER's
766 internal maximum characters per line. */
767static void
768pp_set_real_maximum_length (pretty_printer *pp)
769{
770 /* If we're told not to wrap lines then do the obvious thing. In case
771 we'll emit prefix only once per message, it is appropriate
772 not to increase unnecessarily the line-length cut-off. */
773 if (!pp_is_wrapping_line (pp)
774 || pp_prefixing_rule (pp) == DIAGNOSTICS_SHOW_PREFIX_ONCE
775 || pp_prefixing_rule (pp) == DIAGNOSTICS_SHOW_PREFIX_NEVER)
776 pp->maximum_length = pp_line_cutoff (pp);
777 else
778 {
779 int prefix_length = pp->prefix ? strlen (pp->prefix) : 0;
780 /* If the prefix is ridiculously too long, output at least
781 32 characters. */
782 if (pp_line_cutoff (pp) - prefix_length < 32)
783 pp->maximum_length = pp_line_cutoff (pp) + 32;
784 else
785 pp->maximum_length = pp_line_cutoff (pp);
786 }
787}
788
789/* Clear PRETTY-PRINTER's output state. */
790static inline void
791pp_clear_state (pretty_printer *pp)
792{
793 pp->emitted_prefix = false;
794 pp_indentation (pp) = 0;
795}
796
dc3f3805
RS
797/* Print X to PP in decimal. */
798template<unsigned int N, typename T>
799void
800pp_wide_integer (pretty_printer *pp, const poly_int_pod<N, T> &x)
801{
802 if (x.is_constant ())
803 pp_wide_integer (pp, x.coeffs[0]);
804 else
805 {
806 pp_left_bracket (pp);
807 for (unsigned int i = 0; i < N; ++i)
808 {
809 if (i != 0)
810 pp_comma (pp);
811 pp_wide_integer (pp, x.coeffs[i]);
812 }
813 pp_right_bracket (pp);
814 }
815}
816
817template void pp_wide_integer (pretty_printer *, const poly_uint16_pod &);
818template void pp_wide_integer (pretty_printer *, const poly_int64_pod &);
819template void pp_wide_integer (pretty_printer *, const poly_uint64_pod &);
820
b6fe0bb8 821/* Flush the formatted text of PRETTY-PRINTER onto the attached stream. */
6de9cd9a 822void
b6fe0bb8
GDR
823pp_write_text_to_stream (pretty_printer *pp)
824{
825 const char *text = pp_formatted_text (pp);
db0d1bae
LH
826#ifdef __MINGW32__
827 mingw_ansi_fputs (text, pp_buffer (pp)->stream);
828#else
025311c4 829 fputs (text, pp_buffer (pp)->stream);
db0d1bae 830#endif
b6fe0bb8
GDR
831 pp_clear_output_area (pp);
832}
833
7eba871a
SB
834/* As pp_write_text_to_stream, but for GraphViz label output.
835
836 Flush the formatted text of pretty-printer PP onto the attached stream.
837 Replace characters in PPF that have special meaning in a GraphViz .dot
838 file.
839
840 This routine is not very fast, but it doesn't have to be as this is only
841 be used by routines dumping intermediate representations in graph form. */
842
843void
844pp_write_text_as_dot_label_to_stream (pretty_printer *pp, bool for_record)
845{
846 const char *text = pp_formatted_text (pp);
847 const char *p = text;
025311c4 848 FILE *fp = pp_buffer (pp)->stream;
7eba871a 849
da3ebf2d 850 for (;*p; p++)
7eba871a 851 {
da3ebf2d 852 bool escape_char;
7eba871a
SB
853 switch (*p)
854 {
855 /* Print newlines as a left-aligned newline. */
856 case '\n':
da3ebf2d
TV
857 fputs ("\\l", fp);
858 escape_char = true;
7eba871a
SB
859 break;
860
795391fb 861 /* The following characters are only special for record-shape nodes. */
7eba871a 862 case '|':
795391fb
TV
863 case '{':
864 case '}':
865 case '<':
866 case '>':
867 case ' ':
da3ebf2d 868 escape_char = for_record;
7eba871a
SB
869 break;
870
871 /* The following characters always have to be escaped
872 for use in labels. */
b3de2446
TV
873 case '\\':
874 /* There is a bug in some (f.i. 2.36.0) versions of graphiz
875 ( http://www.graphviz.org/mantisbt/view.php?id=2524 ) related to
876 backslash as last char in label. Let's avoid triggering it. */
877 gcc_assert (*(p + 1) != '\0');
878 /* Fall through. */
7eba871a 879 case '"':
da3ebf2d
TV
880 escape_char = true;
881 break;
882
7eba871a 883 default:
da3ebf2d 884 escape_char = false;
7eba871a
SB
885 break;
886 }
da3ebf2d
TV
887
888 if (escape_char)
889 fputc ('\\', fp);
890
891 fputc (*p, fp);
7eba871a
SB
892 }
893
894 pp_clear_output_area (pp);
895}
896
b6fe0bb8
GDR
897/* Wrap a text delimited by START and END into PRETTY-PRINTER. */
898static void
899pp_wrap_text (pretty_printer *pp, const char *start, const char *end)
900{
901 bool wrapping_line = pp_is_wrapping_line (pp);
902
903 while (start != end)
904 {
905 /* Dump anything bordered by whitespaces. */
906 {
907 const char *p = start;
908 while (p != end && !ISBLANK (*p) && *p != '\n')
909 ++p;
910 if (wrapping_line
911 && p - start >= pp_remaining_character_count_for_line (pp))
912 pp_newline (pp);
913 pp_append_text (pp, start, p);
914 start = p;
915 }
916
917 if (start != end && ISBLANK (*start))
918 {
919 pp_space (pp);
920 ++start;
921 }
922 if (start != end && *start == '\n')
923 {
924 pp_newline (pp);
925 ++start;
926 }
927 }
928}
929
930/* Same as pp_wrap_text but wrap text only when in line-wrapping mode. */
931static inline void
932pp_maybe_wrap_text (pretty_printer *pp, const char *start, const char *end)
933{
934 if (pp_is_wrapping_line (pp))
935 pp_wrap_text (pp, start, end);
936 else
937 pp_append_text (pp, start, end);
938}
939
940/* Append to the output area of PRETTY-PRINTER a string specified by its
941 STARTing character and LENGTH. */
942static inline void
943pp_append_r (pretty_printer *pp, const char *start, int length)
944{
c4100eae 945 output_buffer_append_r (pp_buffer (pp), start, length);
b6fe0bb8
GDR
946}
947
4b780675
GDR
948/* Insert enough spaces into the output area of PRETTY-PRINTER to bring
949 the column position to the current indentation level, assuming that a
950 newline has just been written to the buffer. */
951void
b066401f 952pp_indent (pretty_printer *pp)
4b780675
GDR
953{
954 int n = pp_indentation (pp);
955 int i;
956
957 for (i = 0; i < n; ++i)
958 pp_space (pp);
959}
960
39ce81c9 961/* The following format specifiers are recognized as being client independent:
b6fe0bb8
GDR
962 %d, %i: (signed) integer in base ten.
963 %u: unsigned integer in base ten.
964 %o: unsigned integer in base eight.
965 %x: unsigned integer in base sixteen.
966 %ld, %li, %lo, %lu, %lx: long versions of the above.
967 %lld, %lli, %llo, %llu, %llx: long long versions.
968 %wd, %wi, %wo, %wu, %wx: HOST_WIDE_INT versions.
969 %c: character.
970 %s: string.
914bc2b9 971 %p: pointer (printed in a host-dependent manner).
4b84d650
JJ
972 %r: if pp_show_color(pp), switch to color identified by const char *.
973 %R: if pp_show_color(pp), reset color.
b6fe0bb8 974 %m: strerror(text->err_no) - does not consume a value from args_ptr.
a668adb2 975 %%: '%'.
ca09cd34
JM
976 %<: opening quote.
977 %>: closing quote.
978 %': apostrophe (should only be used in untranslated messages;
979 translations should use appropriate punctuation directly).
39ce81c9
ZW
980 %.*s: a substring the length of which is specified by an argument
981 integer.
982 %Ns: likewise, but length specified as constant in the format string.
39ce81c9 983 Flag 'q': quote formatted text (must come immediately after '%').
975672f3
PK
984 %Z: Requires two arguments - array of int, and len. Prints elements
985 of the array.
39ce81c9
ZW
986
987 Arguments can be used sequentially, or through %N$ resp. *N$
988 notation Nth argument after the format string. If %N$ / *N$
989 notation is used, it must be used for all arguments, except %m, %%,
990 %<, %> and %', which may not have a number, as they do not consume
991 an argument. When %M$.*N$s is used, M must be N + 1. (This may
992 also be written %M$.*s, provided N is not otherwise used.) The
993 format string must have conversion specifiers with argument numbers
994 1 up to highest argument; each argument may only be used once.
995 A format string can have at most 30 arguments. */
996
997/* Formatting phases 1 and 2: render TEXT->format_spec plus
025311c4 998 TEXT->args_ptr into a series of chunks in pp_buffer (PP)->args[].
4ccab56d 999 Phase 3 is in pp_output_formatted_text. */
39ce81c9 1000
b6fe0bb8 1001void
b066401f 1002pp_format (pretty_printer *pp, text_info *text)
b6fe0bb8 1003{
025311c4 1004 output_buffer *buffer = pp_buffer (pp);
39ce81c9
ZW
1005 const char *p;
1006 const char **args;
1007 struct chunk_info *new_chunk_array;
1008
1009 unsigned int curarg = 0, chunk = 0, argno;
1010 pp_wrapping_mode_t old_wrapping_mode;
1011 bool any_unnumbered = false, any_numbered = false;
1012 const char **formatters[PP_NL_ARGMAX];
1013
1014 /* Allocate a new chunk structure. */
1015 new_chunk_array = XOBNEW (&buffer->chunk_obstack, struct chunk_info);
1016 new_chunk_array->prev = buffer->cur_chunk_array;
1017 buffer->cur_chunk_array = new_chunk_array;
1018 args = new_chunk_array->args;
1019
1020 /* Formatting phase 1: split up TEXT->format_spec into chunks in
025311c4 1021 pp_buffer (PP)->args[]. Even-numbered chunks are to be output
39ce81c9
ZW
1022 verbatim, odd-numbered chunks are format specifiers.
1023 %m, %%, %<, %>, and %' are replaced with the appropriate text at
1024 this point. */
1025
1026 memset (formatters, 0, sizeof formatters);
b8698a0f 1027
39ce81c9 1028 for (p = text->format_spec; *p; )
b6fe0bb8 1029 {
39ce81c9
ZW
1030 while (*p != '\0' && *p != '%')
1031 {
1032 obstack_1grow (&buffer->chunk_obstack, *p);
1033 p++;
1034 }
b6fe0bb8 1035
39ce81c9
ZW
1036 if (*p == '\0')
1037 break;
1038
1039 switch (*++p)
1040 {
1041 case '\0':
1042 gcc_unreachable ();
b8698a0f 1043
39ce81c9
ZW
1044 case '%':
1045 obstack_1grow (&buffer->chunk_obstack, '%');
1046 p++;
1047 continue;
b6fe0bb8 1048
39ce81c9 1049 case '<':
4b84d650
JJ
1050 {
1051 obstack_grow (&buffer->chunk_obstack,
1052 open_quote, strlen (open_quote));
1053 const char *colorstr
1054 = colorize_start (pp_show_color (pp), "quote");
1055 obstack_grow (&buffer->chunk_obstack, colorstr, strlen (colorstr));
1056 p++;
1057 continue;
1058 }
39ce81c9
ZW
1059
1060 case '>':
4b84d650
JJ
1061 {
1062 const char *colorstr = colorize_stop (pp_show_color (pp));
1063 obstack_grow (&buffer->chunk_obstack, colorstr, strlen (colorstr));
1064 }
1065 /* FALLTHRU */
39ce81c9
ZW
1066 case '\'':
1067 obstack_grow (&buffer->chunk_obstack,
241de8a0 1068 close_quote, strlen (close_quote));
39ce81c9
ZW
1069 p++;
1070 continue;
1071
4b84d650
JJ
1072 case 'R':
1073 {
1074 const char *colorstr = colorize_stop (pp_show_color (pp));
1075 obstack_grow (&buffer->chunk_obstack, colorstr,
1076 strlen (colorstr));
1077 p++;
1078 continue;
1079 }
1080
39ce81c9
ZW
1081 case 'm':
1082 {
1083 const char *errstr = xstrerror (text->err_no);
1084 obstack_grow (&buffer->chunk_obstack, errstr, strlen (errstr));
1085 }
1086 p++;
1087 continue;
1088
1089 default:
1090 /* Handled in phase 2. Terminate the plain chunk here. */
1091 obstack_1grow (&buffer->chunk_obstack, '\0');
1092 gcc_assert (chunk < PP_NL_ARGMAX * 2);
1093 args[chunk++] = XOBFINISH (&buffer->chunk_obstack, const char *);
1094 break;
1095 }
1096
1097 if (ISDIGIT (*p))
1098 {
1099 char *end;
1100 argno = strtoul (p, &end, 10) - 1;
1101 p = end;
1102 gcc_assert (*p == '$');
1103 p++;
1104
1105 any_numbered = true;
1106 gcc_assert (!any_unnumbered);
1107 }
1108 else
1109 {
1110 argno = curarg++;
1111 any_unnumbered = true;
1112 gcc_assert (!any_numbered);
1113 }
1114 gcc_assert (argno < PP_NL_ARGMAX);
1115 gcc_assert (!formatters[argno]);
1116 formatters[argno] = &args[chunk];
1117 do
1118 {
1119 obstack_1grow (&buffer->chunk_obstack, *p);
1120 p++;
1121 }
1122 while (strchr ("qwl+#", p[-1]));
1123
1124 if (p[-1] == '.')
1125 {
1126 /* We handle '%.Ns' and '%.*s' or '%M$.*N$s'
1127 (where M == N + 1). */
1128 if (ISDIGIT (*p))
1129 {
1130 do
1131 {
1132 obstack_1grow (&buffer->chunk_obstack, *p);
1133 p++;
1134 }
1135 while (ISDIGIT (p[-1]));
1136 gcc_assert (p[-1] == 's');
1137 }
1138 else
1139 {
1140 gcc_assert (*p == '*');
1141 obstack_1grow (&buffer->chunk_obstack, '*');
1142 p++;
1143
1144 if (ISDIGIT (*p))
1145 {
1146 char *end;
1147 unsigned int argno2 = strtoul (p, &end, 10) - 1;
1148 p = end;
1149 gcc_assert (argno2 == argno - 1);
1150 gcc_assert (!any_unnumbered);
1151 gcc_assert (*p == '$');
1152
1153 p++;
1154 formatters[argno2] = formatters[argno];
1155 }
1156 else
1157 {
1158 gcc_assert (!any_numbered);
1159 formatters[argno+1] = formatters[argno];
1160 curarg++;
1161 }
1162 gcc_assert (*p == 's');
1163 obstack_1grow (&buffer->chunk_obstack, 's');
1164 p++;
1165 }
1166 }
1167 if (*p == '\0')
b6fe0bb8
GDR
1168 break;
1169
39ce81c9
ZW
1170 obstack_1grow (&buffer->chunk_obstack, '\0');
1171 gcc_assert (chunk < PP_NL_ARGMAX * 2);
1172 args[chunk++] = XOBFINISH (&buffer->chunk_obstack, const char *);
1173 }
1174
1175 obstack_1grow (&buffer->chunk_obstack, '\0');
1176 gcc_assert (chunk < PP_NL_ARGMAX * 2);
1177 args[chunk++] = XOBFINISH (&buffer->chunk_obstack, const char *);
1178 args[chunk] = 0;
b8698a0f 1179
39ce81c9
ZW
1180 /* Set output to the argument obstack, and switch line-wrapping and
1181 prefixing off. */
1182 buffer->obstack = &buffer->chunk_obstack;
1183 old_wrapping_mode = pp_set_verbatim_wrapping (pp);
1184
1185 /* Second phase. Replace each formatter with the formatted text it
1186 corresponds to. */
1187
1188 for (argno = 0; formatters[argno]; argno++)
1189 {
1190 int precision = 0;
1191 bool wide = false;
1192 bool plus = false;
1193 bool hash = false;
1194 bool quote = false;
1195
1196 /* We do not attempt to enforce any ordering on the modifier
1197 characters. */
1198
1199 for (p = *formatters[argno];; p++)
a668adb2 1200 {
39ce81c9
ZW
1201 switch (*p)
1202 {
1203 case 'q':
1204 gcc_assert (!quote);
1205 quote = true;
1206 continue;
1207
1208 case '+':
1209 gcc_assert (!plus);
1210 plus = true;
1211 continue;
1212
1213 case '#':
1214 gcc_assert (!hash);
1215 hash = true;
1216 continue;
1217
1218 case 'w':
1219 gcc_assert (!wide);
1220 wide = true;
1221 continue;
1222
1223 case 'l':
1224 /* We don't support precision beyond that of "long long". */
1225 gcc_assert (precision < 2);
1226 precision++;
1227 continue;
1228 }
1229 break;
a668adb2 1230 }
39ce81c9
ZW
1231
1232 gcc_assert (!wide || precision == 0);
1233
1234 if (quote)
ce95abc4 1235 pp_begin_quote (pp, pp_show_color (pp));
39ce81c9
ZW
1236
1237 switch (*p)
b6fe0bb8 1238 {
4b84d650
JJ
1239 case 'r':
1240 pp_string (pp, colorize_start (pp_show_color (pp),
1241 va_arg (*text->args_ptr,
1242 const char *)));
1243 break;
1244
b6fe0bb8 1245 case 'c':
3f0177e7
MS
1246 {
1247 /* When quoting, print alphanumeric, punctuation, and the space
1248 character unchanged, and all others in hexadecimal with the
1249 "\x" prefix. Otherwise print them all unchanged. */
1250 int chr = va_arg (*text->args_ptr, int);
1251 if (ISPRINT (chr) || !quote)
1252 pp_character (pp, chr);
1253 else
1254 {
1255 const char str [2] = { chr, '\0' };
1256 pp_quoted_string (pp, str, 1);
1257 }
1258 break;
1259 }
b6fe0bb8
GDR
1260
1261 case 'd':
1262 case 'i':
39ce81c9
ZW
1263 if (wide)
1264 pp_wide_integer (pp, va_arg (*text->args_ptr, HOST_WIDE_INT));
1265 else
1266 pp_integer_with_precision
1267 (pp, *text->args_ptr, precision, int, "d");
b6fe0bb8
GDR
1268 break;
1269
1270 case 'o':
39ce81c9
ZW
1271 if (wide)
1272 pp_scalar (pp, "%" HOST_WIDE_INT_PRINT "o",
1273 va_arg (*text->args_ptr, unsigned HOST_WIDE_INT));
1274 else
1275 pp_integer_with_precision
1276 (pp, *text->args_ptr, precision, unsigned, "o");
b6fe0bb8
GDR
1277 break;
1278
1279 case 's':
3f0177e7
MS
1280 if (quote)
1281 pp_quoted_string (pp, va_arg (*text->args_ptr, const char *));
1282 else
1283 pp_string (pp, va_arg (*text->args_ptr, const char *));
b6fe0bb8
GDR
1284 break;
1285
39ce81c9
ZW
1286 case 'p':
1287 pp_pointer (pp, va_arg (*text->args_ptr, void *));
1288 break;
b6fe0bb8
GDR
1289
1290 case 'u':
39ce81c9
ZW
1291 if (wide)
1292 pp_scalar (pp, HOST_WIDE_INT_PRINT_UNSIGNED,
1293 va_arg (*text->args_ptr, unsigned HOST_WIDE_INT));
1294 else
1295 pp_integer_with_precision
1296 (pp, *text->args_ptr, precision, unsigned, "u");
b6fe0bb8
GDR
1297 break;
1298
975672f3
PK
1299 case 'Z':
1300 {
1301 int *v = va_arg (*text->args_ptr, int *);
1302 unsigned len = va_arg (*text->args_ptr, unsigned);
1303
1304 for (unsigned i = 0; i < len; ++i)
1305 {
1306 pp_scalar (pp, "%i", v[i]);
1307 if (i < len - 1)
1308 {
1309 pp_comma (pp);
1310 pp_space (pp);
1311 }
1312 }
1313 break;
1314 }
1315
b6fe0bb8 1316 case 'x':
39ce81c9
ZW
1317 if (wide)
1318 pp_scalar (pp, HOST_WIDE_INT_PRINT_HEX,
1319 va_arg (*text->args_ptr, unsigned HOST_WIDE_INT));
1320 else
1321 pp_integer_with_precision
1322 (pp, *text->args_ptr, precision, unsigned, "x");
b6fe0bb8
GDR
1323 break;
1324
b6fe0bb8
GDR
1325 case '.':
1326 {
1327 int n;
1328 const char *s;
d5706a1e 1329
39ce81c9
ZW
1330 /* We handle '%.Ns' and '%.*s' or '%M$.*N$s'
1331 (where M == N + 1). The format string should be verified
1332 already from the first phase. */
1333 p++;
1334 if (ISDIGIT (*p))
1335 {
1336 char *end;
1337 n = strtoul (p, &end, 10);
1338 p = end;
1339 gcc_assert (*p == 's');
1340 }
1341 else
1342 {
1343 gcc_assert (*p == '*');
1344 p++;
1345 gcc_assert (*p == 's');
1346 n = va_arg (*text->args_ptr, int);
1347
1348 /* This consumes a second entry in the formatters array. */
1349 gcc_assert (formatters[argno] == formatters[argno+1]);
1350 argno++;
1351 }
1352
b6fe0bb8 1353 s = va_arg (*text->args_ptr, const char *);
0a8923fa 1354
86ef85d3
MS
1355 /* Append the lesser of precision and strlen (s) characters
1356 from the array (which need not be a nul-terminated string).
1357 Negative precision is treated as if it were omitted. */
1358 size_t len = n < 0 ? strlen (s) : strnlen (s, n);
0a8923fa
MS
1359
1360 pp_append_text (pp, s, s + len);
b6fe0bb8
GDR
1361 }
1362 break;
1363
1364 default:
0e61db61
NS
1365 {
1366 bool ok;
39ce81c9 1367
ce95abc4
DM
1368 /* Call the format decoder.
1369 Pass the address of "quote" so that format decoders can
1370 potentially disable printing of the closing quote
1371 (e.g. when printing "'TYPEDEF' aka 'TYPE'" in the C family
1372 of frontends). */
0e61db61 1373 gcc_assert (pp_format_decoder (pp));
39ce81c9 1374 ok = pp_format_decoder (pp) (pp, text, p,
ce95abc4 1375 precision, wide, plus, hash, &quote,
f012c8ef 1376 formatters[argno]);
0e61db61
NS
1377 gcc_assert (ok);
1378 }
b6fe0bb8 1379 }
39ce81c9
ZW
1380
1381 if (quote)
ce95abc4 1382 pp_end_quote (pp, pp_show_color (pp));
39ce81c9
ZW
1383
1384 obstack_1grow (&buffer->chunk_obstack, '\0');
1385 *formatters[argno] = XOBFINISH (&buffer->chunk_obstack, const char *);
b6fe0bb8 1386 }
39ce81c9 1387
b2b29377
MM
1388 if (CHECKING_P)
1389 for (; argno < PP_NL_ARGMAX; argno++)
1390 gcc_assert (!formatters[argno]);
39ce81c9 1391
f012c8ef
DM
1392 /* If the client supplied a postprocessing object, call its "handle"
1393 hook here. */
1394 if (pp->m_format_postprocessor)
1395 pp->m_format_postprocessor->handle (pp);
1396
39ce81c9
ZW
1397 /* Revert to normal obstack and wrapping mode. */
1398 buffer->obstack = &buffer->formatted_obstack;
1399 buffer->line_length = 0;
1400 pp_wrapping_mode (pp) = old_wrapping_mode;
1401 pp_clear_state (pp);
1402}
1403
1404/* Format of a message pointed to by TEXT. */
1405void
b066401f 1406pp_output_formatted_text (pretty_printer *pp)
39ce81c9
ZW
1407{
1408 unsigned int chunk;
1409 output_buffer *buffer = pp_buffer (pp);
1410 struct chunk_info *chunk_array = buffer->cur_chunk_array;
1411 const char **args = chunk_array->args;
1412
1413 gcc_assert (buffer->obstack == &buffer->formatted_obstack);
1414 gcc_assert (buffer->line_length == 0);
1415
b066401f 1416 /* This is a third phase, first 2 phases done in pp_format_args.
39ce81c9
ZW
1417 Now we actually print it. */
1418 for (chunk = 0; args[chunk]; chunk++)
1419 pp_string (pp, args[chunk]);
1420
1421 /* Deallocate the chunk structure and everything after it (i.e. the
1422 associated series of formatted strings). */
1423 buffer->cur_chunk_array = chunk_array->prev;
1424 obstack_free (&buffer->chunk_obstack, chunk_array);
b6fe0bb8
GDR
1425}
1426
1427/* Helper subroutine of output_verbatim and verbatim. Do the appropriate
1428 settings needed by BUFFER for a verbatim formatting. */
1429void
b066401f 1430pp_format_verbatim (pretty_printer *pp, text_info *text)
b6fe0bb8 1431{
b6fe0bb8 1432 /* Set verbatim mode. */
39ce81c9
ZW
1433 pp_wrapping_mode_t oldmode = pp_set_verbatim_wrapping (pp);
1434
b6fe0bb8 1435 /* Do the actual formatting. */
39ce81c9
ZW
1436 pp_format (pp, text);
1437 pp_output_formatted_text (pp);
1438
b6fe0bb8 1439 /* Restore previous settings. */
39ce81c9 1440 pp_wrapping_mode (pp) = oldmode;
b6fe0bb8
GDR
1441}
1442
48749dbc
MLI
1443/* Flush the content of BUFFER onto the attached stream. This
1444 function does nothing unless pp->output_buffer->flush_p. */
b6fe0bb8 1445void
b066401f 1446pp_flush (pretty_printer *pp)
b6fe0bb8 1447{
48749dbc
MLI
1448 pp_clear_state (pp);
1449 if (!pp->buffer->flush_p)
1450 return;
b6fe0bb8 1451 pp_write_text_to_stream (pp);
48749dbc
MLI
1452 fflush (pp_buffer (pp)->stream);
1453}
1454
1455/* Flush the content of BUFFER onto the attached stream independently
1456 of the value of pp->output_buffer->flush_p. */
1457void
1458pp_really_flush (pretty_printer *pp)
1459{
b6fe0bb8 1460 pp_clear_state (pp);
48749dbc 1461 pp_write_text_to_stream (pp);
025311c4 1462 fflush (pp_buffer (pp)->stream);
b6fe0bb8
GDR
1463}
1464
1465/* Sets the number of maximum characters per line PRETTY-PRINTER can
1466 output in line-wrapping mode. A LENGTH value 0 suppresses
1467 line-wrapping. */
1468void
b066401f 1469pp_set_line_maximum_length (pretty_printer *pp, int length)
b6fe0bb8
GDR
1470{
1471 pp_line_cutoff (pp) = length;
1472 pp_set_real_maximum_length (pp);
1473}
1474
1475/* Clear PRETTY-PRINTER output area text info. */
1476void
b066401f 1477pp_clear_output_area (pretty_printer *pp)
b6fe0bb8 1478{
025311c4
GDR
1479 obstack_free (pp_buffer (pp)->obstack,
1480 obstack_base (pp_buffer (pp)->obstack));
1481 pp_buffer (pp)->line_length = 0;
b6fe0bb8
GDR
1482}
1483
653fee19
DM
1484/* Set PREFIX for PRETTY-PRINTER, taking ownership of PREFIX, which
1485 will eventually be free-ed. */
1486
b6fe0bb8 1487void
653fee19 1488pp_set_prefix (pretty_printer *pp, char *prefix)
b6fe0bb8 1489{
653fee19 1490 free (pp->prefix);
b6fe0bb8
GDR
1491 pp->prefix = prefix;
1492 pp_set_real_maximum_length (pp);
1493 pp->emitted_prefix = false;
1494 pp_indentation (pp) = 0;
1495}
1496
653fee19
DM
1497/* Take ownership of PP's prefix, setting it to NULL.
1498 This allows clients to save, overide, and then restore an existing
1499 prefix, without it being free-ed. */
1500
1501char *
1502pp_take_prefix (pretty_printer *pp)
1503{
1504 char *result = pp->prefix;
1505 pp->prefix = NULL;
1506 return result;
1507}
1508
b6fe0bb8
GDR
1509/* Free PRETTY-PRINTER's prefix, a previously malloc()'d string. */
1510void
b066401f 1511pp_destroy_prefix (pretty_printer *pp)
b6fe0bb8
GDR
1512{
1513 if (pp->prefix != NULL)
1514 {
653fee19 1515 free (pp->prefix);
b6fe0bb8
GDR
1516 pp->prefix = NULL;
1517 }
1518}
1519
1520/* Write out PRETTY-PRINTER's prefix. */
1521void
b066401f 1522pp_emit_prefix (pretty_printer *pp)
b6fe0bb8
GDR
1523{
1524 if (pp->prefix != NULL)
1525 {
1526 switch (pp_prefixing_rule (pp))
1527 {
1528 default:
1529 case DIAGNOSTICS_SHOW_PREFIX_NEVER:
1530 break;
1531
1532 case DIAGNOSTICS_SHOW_PREFIX_ONCE:
1533 if (pp->emitted_prefix)
1534 {
b066401f 1535 pp_indent (pp);
b6fe0bb8
GDR
1536 break;
1537 }
1538 pp_indentation (pp) += 3;
1539 /* Fall through. */
1540
1541 case DIAGNOSTICS_SHOW_PREFIX_EVERY_LINE:
1542 {
1543 int prefix_length = strlen (pp->prefix);
1544 pp_append_r (pp, pp->prefix, prefix_length);
1545 pp->emitted_prefix = true;
1546 }
1547 break;
1548 }
1549 }
1550}
1551
653fee19 1552/* Construct a PRETTY-PRINTER of MAXIMUM_LENGTH characters per line. */
da6ca2b5 1553
653fee19 1554pretty_printer::pretty_printer (int maximum_length)
da6ca2b5
GDR
1555 : buffer (new (XCNEW (output_buffer)) output_buffer ()),
1556 prefix (),
1557 padding (pp_none),
1558 maximum_length (),
1559 indent_skip (),
1560 wrapping (),
1561 format_decoder (),
f012c8ef 1562 m_format_postprocessor (NULL),
da6ca2b5
GDR
1563 emitted_prefix (),
1564 need_newline (),
c3284718 1565 translate_identifiers (true),
da6ca2b5 1566 show_color ()
b6fe0bb8 1567{
653fee19 1568 pp_line_cutoff (this) = maximum_length;
da6ca2b5
GDR
1569 /* By default, we emit prefixes once per message. */
1570 pp_prefixing_rule (this) = DIAGNOSTICS_SHOW_PREFIX_ONCE;
653fee19 1571 pp_set_prefix (this, NULL);
b6fe0bb8
GDR
1572}
1573
025311c4
GDR
1574pretty_printer::~pretty_printer ()
1575{
f012c8ef
DM
1576 if (m_format_postprocessor)
1577 delete m_format_postprocessor;
025311c4
GDR
1578 buffer->~output_buffer ();
1579 XDELETE (buffer);
653fee19 1580 free (prefix);
025311c4
GDR
1581}
1582
b6fe0bb8
GDR
1583/* Append a string delimited by START and END to the output area of
1584 PRETTY-PRINTER. No line wrapping is done. However, if beginning a
1585 new line then emit PRETTY-PRINTER's prefix and skip any leading
1586 whitespace if appropriate. The caller must ensure that it is
1587 safe to do so. */
1588void
b066401f 1589pp_append_text (pretty_printer *pp, const char *start, const char *end)
b6fe0bb8
GDR
1590{
1591 /* Emit prefix and skip whitespace if we're starting a new line. */
025311c4 1592 if (pp_buffer (pp)->line_length == 0)
b6fe0bb8
GDR
1593 {
1594 pp_emit_prefix (pp);
1595 if (pp_is_wrapping_line (pp))
1596 while (start != end && *start == ' ')
1597 ++start;
1598 }
1599 pp_append_r (pp, start, end - start);
1600}
1601
1602/* Finishes constructing a NULL-terminated character string representing
1603 the PRETTY-PRINTED text. */
1604const char *
b066401f 1605pp_formatted_text (pretty_printer *pp)
b6fe0bb8 1606{
c4100eae 1607 return output_buffer_formatted_text (pp_buffer (pp));
b6fe0bb8
GDR
1608}
1609
1610/* Return a pointer to the last character emitted in PRETTY-PRINTER's
1611 output area. A NULL pointer means no character available. */
1612const char *
b066401f 1613pp_last_position_in_text (const pretty_printer *pp)
b6fe0bb8 1614{
c4100eae 1615 return output_buffer_last_position_in_text (pp_buffer (pp));
b6fe0bb8
GDR
1616}
1617
1618/* Return the amount of characters PRETTY-PRINTER can accept to
ba228239 1619 make a full line. Meaningful only in line-wrapping mode. */
b6fe0bb8 1620int
b066401f 1621pp_remaining_character_count_for_line (pretty_printer *pp)
b6fe0bb8 1622{
025311c4 1623 return pp->maximum_length - pp_buffer (pp)->line_length;
b6fe0bb8
GDR
1624}
1625
1626
1627/* Format a message into BUFFER a la printf. */
1628void
1629pp_printf (pretty_printer *pp, const char *msg, ...)
1630{
1631 text_info text;
1632 va_list ap;
1633
1634 va_start (ap, msg);
1635 text.err_no = errno;
1636 text.args_ptr = &ap;
1637 text.format_spec = msg;
39ce81c9
ZW
1638 pp_format (pp, &text);
1639 pp_output_formatted_text (pp);
b6fe0bb8
GDR
1640 va_end (ap);
1641}
1642
1643
1644/* Output MESSAGE verbatim into BUFFER. */
1645void
1646pp_verbatim (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;
1655 pp_format_verbatim (pp, &text);
1656 va_end (ap);
1657}
1658
1659
1660
1661/* Have PRETTY-PRINTER start a new line. */
1662void
b066401f 1663pp_newline (pretty_printer *pp)
b6fe0bb8 1664{
025311c4 1665 obstack_1grow (pp_buffer (pp)->obstack, '\n');
c4669594 1666 pp_needs_newline (pp) = false;
025311c4 1667 pp_buffer (pp)->line_length = 0;
b6fe0bb8
GDR
1668}
1669
1670/* Have PRETTY-PRINTER add a CHARACTER. */
1671void
b066401f 1672pp_character (pretty_printer *pp, int c)
b6fe0bb8
GDR
1673{
1674 if (pp_is_wrapping_line (pp)
1675 && pp_remaining_character_count_for_line (pp) <= 0)
1676 {
1677 pp_newline (pp);
1678 if (ISSPACE (c))
1679 return;
1680 }
025311c4
GDR
1681 obstack_1grow (pp_buffer (pp)->obstack, c);
1682 ++pp_buffer (pp)->line_length;
b6fe0bb8
GDR
1683}
1684
1685/* Append a STRING to the output area of PRETTY-PRINTER; the STRING may
1686 be line-wrapped if in appropriate mode. */
1687void
b066401f 1688pp_string (pretty_printer *pp, const char *str)
b6fe0bb8 1689{
41d9f1e0
MLI
1690 gcc_checking_assert (str);
1691 pp_maybe_wrap_text (pp, str, str + strlen (str));
b6fe0bb8
GDR
1692}
1693
3f0177e7
MS
1694/* Append the leading N characters of STRING to the output area of
1695 PRETTY-PRINTER, quoting in hexadecimal non-printable characters.
1696 Setting N = -1 is as if N were set to strlen (STRING). The STRING
1697 may be line-wrapped if in appropriate mode. */
1698static void
1699pp_quoted_string (pretty_printer *pp, const char *str, size_t n /* = -1 */)
1700{
1701 gcc_checking_assert (str);
1702
1703 const char *last = str;
1704 const char *ps;
1705
1706 /* Compute the length if not specified. */
1707 if (n == (size_t) -1)
1708 n = strlen (str);
1709
1710 for (ps = str; n; ++ps, --n)
1711 {
1712 if (ISPRINT (*ps))
1713 continue;
1714
1715 if (last < ps)
1716 pp_maybe_wrap_text (pp, last, ps - 1);
1717
1718 /* Append the hexadecimal value of the character. Allocate a buffer
1719 that's large enough for a 32-bit char plus the hex prefix. */
1720 char buf [11];
1721 int n = sprintf (buf, "\\x%02x", (unsigned char)*ps);
1722 pp_maybe_wrap_text (pp, buf, buf + n);
1723 last = ps + 1;
1724 }
1725
1726 pp_maybe_wrap_text (pp, last, ps);
1727}
1728
471854f8 1729/* Maybe print out a whitespace if needed. */
b6fe0bb8 1730
b9b44fb9 1731void
b066401f 1732pp_maybe_space (pretty_printer *pp)
b9b44fb9 1733{
b066401f 1734 if (pp->padding != pp_none)
b9b44fb9
GDR
1735 {
1736 pp_space (pp);
b066401f 1737 pp->padding = pp_none;
b9b44fb9
GDR
1738 }
1739}
0fc80001
GDR
1740
1741// Add a newline to the pretty printer PP and flush formatted text.
1742
1743void
1744pp_newline_and_flush (pretty_printer *pp)
1745{
1746 pp_newline (pp);
1747 pp_flush (pp);
1748 pp_needs_newline (pp) = false;
1749}
1750
1751// Add a newline to the pretty printer PP, followed by indentation.
1752
1753void
1754pp_newline_and_indent (pretty_printer *pp, int n)
1755{
1756 pp_indentation (pp) += n;
1757 pp_newline (pp);
1758 pp_indent (pp);
1759 pp_needs_newline (pp) = false;
1760}
1761
1762// Add separator C, followed by a single whitespace.
1763
1764void
1765pp_separate_with (pretty_printer *pp, char c)
1766{
1767 pp_character (pp, c);
1768 pp_space (pp);
1769}
1770
ce95abc4
DM
1771/* Add a localized open quote, and if SHOW_COLOR is true, begin colorizing
1772 using the "quote" color. */
1773
1774void
1775pp_begin_quote (pretty_printer *pp, bool show_color)
1776{
1777 pp_string (pp, open_quote);
1778 pp_string (pp, colorize_start (show_color, "quote"));
1779}
1780
1781/* If SHOW_COLOR is true, stop colorizing.
1782 Add a localized close quote. */
1783
1784void
1785pp_end_quote (pretty_printer *pp, bool show_color)
1786{
1787 pp_string (pp, colorize_stop (show_color));
1788 pp_string (pp, close_quote);
1789}
1790
a3af5087
JM
1791\f
1792/* The string starting at P has LEN (at least 1) bytes left; if they
1793 start with a valid UTF-8 sequence, return the length of that
1794 sequence and set *VALUE to the value of that sequence, and
1795 otherwise return 0 and set *VALUE to (unsigned int) -1. */
1796
1797static int
1798decode_utf8_char (const unsigned char *p, size_t len, unsigned int *value)
1799{
1800 unsigned int t = *p;
1801
1802 if (len == 0)
1803 abort ();
1804 if (t & 0x80)
1805 {
1806 size_t utf8_len = 0;
1807 unsigned int ch;
1808 size_t i;
1809 for (t = *p; t & 0x80; t <<= 1)
1810 utf8_len++;
1811
1812 if (utf8_len > len || utf8_len < 2 || utf8_len > 6)
1813 {
1814 *value = (unsigned int) -1;
1815 return 0;
1816 }
1817 ch = *p & ((1 << (7 - utf8_len)) - 1);
1818 for (i = 1; i < utf8_len; i++)
1819 {
1820 unsigned int u = p[i];
1821 if ((u & 0xC0) != 0x80)
1822 {
1823 *value = (unsigned int) -1;
1824 return 0;
1825 }
1826 ch = (ch << 6) | (u & 0x3F);
1827 }
1828 if ( (ch <= 0x7F && utf8_len > 1)
1829 || (ch <= 0x7FF && utf8_len > 2)
1830 || (ch <= 0xFFFF && utf8_len > 3)
1831 || (ch <= 0x1FFFFF && utf8_len > 4)
1832 || (ch <= 0x3FFFFFF && utf8_len > 5)
1833 || (ch >= 0xD800 && ch <= 0xDFFF))
1834 {
1835 *value = (unsigned int) -1;
1836 return 0;
1837 }
1838 *value = ch;
1839 return utf8_len;
1840 }
1841 else
1842 {
1843 *value = t;
1844 return 1;
1845 }
1846}
1847
ab9b814d
JM
1848/* Allocator for identifier_to_locale and corresponding function to
1849 free memory. */
1850
1851void *(*identifier_to_locale_alloc) (size_t) = xmalloc;
1852void (*identifier_to_locale_free) (void *) = free;
1853
a3af5087
JM
1854/* Given IDENT, an identifier in the internal encoding, return a
1855 version of IDENT suitable for diagnostics in the locale character
ab9b814d
JM
1856 set: either IDENT itself, or a string, allocated using
1857 identifier_to_locale_alloc, converted to the locale character set
1858 and using escape sequences if not representable in the locale
1859 character set or containing control characters or invalid byte
1860 sequences. Existing backslashes in IDENT are not doubled, so the
1861 result may not uniquely specify the contents of an arbitrary byte
1862 sequence identifier. */
a3af5087
JM
1863
1864const char *
1865identifier_to_locale (const char *ident)
1866{
1867 const unsigned char *uid = (const unsigned char *) ident;
1868 size_t idlen = strlen (ident);
1869 bool valid_printable_utf8 = true;
1870 bool all_ascii = true;
1871 size_t i;
1872
1873 for (i = 0; i < idlen;)
1874 {
1875 unsigned int c;
1876 size_t utf8_len = decode_utf8_char (&uid[i], idlen - i, &c);
1877 if (utf8_len == 0 || c <= 0x1F || (c >= 0x7F && c <= 0x9F))
1878 {
1879 valid_printable_utf8 = false;
1880 break;
1881 }
1882 if (utf8_len > 1)
1883 all_ascii = false;
1884 i += utf8_len;
1885 }
1886
1887 /* If IDENT contains invalid UTF-8 sequences (which may occur with
1888 attributes putting arbitrary byte sequences in identifiers), or
1889 control characters, we use octal escape sequences for all bytes
1890 outside printable ASCII. */
1891 if (!valid_printable_utf8)
1892 {
ab9b814d 1893 char *ret = (char *) identifier_to_locale_alloc (4 * idlen + 1);
a3af5087
JM
1894 char *p = ret;
1895 for (i = 0; i < idlen; i++)
1896 {
1897 if (uid[i] > 0x1F && uid[i] < 0x7F)
1898 *p++ = uid[i];
1899 else
1900 {
1901 sprintf (p, "\\%03o", uid[i]);
1902 p += 4;
1903 }
1904 }
1905 *p = 0;
1906 return ret;
1907 }
1908
1909 /* Otherwise, if it is valid printable ASCII, or printable UTF-8
1910 with the locale character set being UTF-8, IDENT is used. */
1911 if (all_ascii || locale_utf8)
1912 return ident;
1913
1914 /* Otherwise IDENT is converted to the locale character set if
1915 possible. */
1916#if defined ENABLE_NLS && defined HAVE_LANGINFO_CODESET && HAVE_ICONV
1917 if (locale_encoding != NULL)
1918 {
1919 iconv_t cd = iconv_open (locale_encoding, "UTF-8");
1920 bool conversion_ok = true;
1921 char *ret = NULL;
1922 if (cd != (iconv_t) -1)
1923 {
1924 size_t ret_alloc = 4 * idlen + 1;
1925 for (;;)
1926 {
1927 /* Repeat the whole conversion process as needed with
1928 larger buffers so non-reversible transformations can
1929 always be detected. */
1930 ICONV_CONST char *inbuf = CONST_CAST (char *, ident);
1931 char *outbuf;
1932 size_t inbytesleft = idlen;
1933 size_t outbytesleft = ret_alloc - 1;
1934 size_t iconv_ret;
1935
ab9b814d 1936 ret = (char *) identifier_to_locale_alloc (ret_alloc);
a3af5087
JM
1937 outbuf = ret;
1938
1939 if (iconv (cd, 0, 0, 0, 0) == (size_t) -1)
1940 {
1941 conversion_ok = false;
1942 break;
1943 }
1944
1945 iconv_ret = iconv (cd, &inbuf, &inbytesleft,
1946 &outbuf, &outbytesleft);
1947 if (iconv_ret == (size_t) -1 || inbytesleft != 0)
1948 {
1949 if (errno == E2BIG)
1950 {
1951 ret_alloc *= 2;
ab9b814d 1952 identifier_to_locale_free (ret);
a3af5087
JM
1953 ret = NULL;
1954 continue;
1955 }
1956 else
1957 {
1958 conversion_ok = false;
1959 break;
1960 }
1961 }
1962 else if (iconv_ret != 0)
1963 {
1964 conversion_ok = false;
1965 break;
1966 }
1967 /* Return to initial shift state. */
1968 if (iconv (cd, 0, 0, &outbuf, &outbytesleft) == (size_t) -1)
1969 {
1970 if (errno == E2BIG)
1971 {
1972 ret_alloc *= 2;
ab9b814d 1973 identifier_to_locale_free (ret);
a3af5087
JM
1974 ret = NULL;
1975 continue;
1976 }
1977 else
1978 {
1979 conversion_ok = false;
1980 break;
1981 }
1982 }
1983 *outbuf = 0;
1984 break;
1985 }
1986 iconv_close (cd);
1987 if (conversion_ok)
1988 return ret;
1989 }
1990 }
1991#endif
1992
1993 /* Otherwise, convert non-ASCII characters in IDENT to UCNs. */
1994 {
ab9b814d 1995 char *ret = (char *) identifier_to_locale_alloc (10 * idlen + 1);
a3af5087
JM
1996 char *p = ret;
1997 for (i = 0; i < idlen;)
1998 {
1999 unsigned int c;
2000 size_t utf8_len = decode_utf8_char (&uid[i], idlen - i, &c);
2001 if (utf8_len == 1)
2002 *p++ = uid[i];
2003 else
2004 {
2005 sprintf (p, "\\U%08x", c);
2006 p += 10;
2007 }
2008 i += utf8_len;
2009 }
2010 *p = 0;
2011 return ret;
2012 }
2013}
4ccab56d
DM
2014
2015#if CHECKING_P
2016
2017namespace selftest {
2018
2019/* Smoketest for pretty_printer. */
2020
2021static void
2022test_basic_printing ()
2023{
2024 pretty_printer pp;
2025 pp_string (&pp, "hello");
2026 pp_space (&pp);
2027 pp_string (&pp, "world");
2028
2029 ASSERT_STREQ ("hello world", pp_formatted_text (&pp));
2030}
2031
2032/* Helper function for testing pp_format.
2033 Verify that pp_format (FMT, ...) followed by pp_output_formatted_text
2034 prints EXPECTED, assuming that pp_show_color is SHOW_COLOR. */
2035
2036static void
09765e3a
DM
2037assert_pp_format_va (const location &loc, const char *expected,
2038 bool show_color, const char *fmt, va_list *ap)
4ccab56d
DM
2039{
2040 pretty_printer pp;
2041 text_info ti;
2042 rich_location rich_loc (line_table, UNKNOWN_LOCATION);
2043
2044 ti.format_spec = fmt;
2045 ti.args_ptr = ap;
2046 ti.err_no = 0;
2047 ti.x_data = NULL;
2048 ti.m_richloc = &rich_loc;
2049
2050 pp_show_color (&pp) = show_color;
2051 pp_format (&pp, &ti);
2052 pp_output_formatted_text (&pp);
09765e3a 2053 ASSERT_STREQ_AT (loc, expected, pp_formatted_text (&pp));
4ccab56d
DM
2054}
2055
2056/* Verify that pp_format (FMT, ...) followed by pp_output_formatted_text
2057 prints EXPECTED, with show_color disabled. */
2058
2059static void
09765e3a
DM
2060assert_pp_format (const location &loc, const char *expected,
2061 const char *fmt, ...)
4ccab56d
DM
2062{
2063 va_list ap;
2064
2065 va_start (ap, fmt);
09765e3a 2066 assert_pp_format_va (loc, expected, false, fmt, &ap);
4ccab56d
DM
2067 va_end (ap);
2068}
2069
2070/* As above, but with colorization enabled. */
2071
2072static void
09765e3a
DM
2073assert_pp_format_colored (const location &loc, const char *expected,
2074 const char *fmt, ...)
4ccab56d 2075{
2fe00b1f
DM
2076 /* The tests of colorization assume the default color scheme.
2077 If GCC_COLORS is set, then the colors have potentially been
2078 overridden; skip the test. */
2079 if (getenv ("GCC_COLORS"))
2080 return;
2081
4ccab56d
DM
2082 va_list ap;
2083
2084 va_start (ap, fmt);
09765e3a 2085 assert_pp_format_va (loc, expected, true, fmt, &ap);
4ccab56d
DM
2086 va_end (ap);
2087}
2088
09765e3a
DM
2089/* Helper function for calling testing pp_format,
2090 by calling assert_pp_format with various numbers of arguments.
2091 These exist mostly to avoid having to write SELFTEST_LOCATION
2092 throughout test_pp_format. */
2093
2094#define ASSERT_PP_FORMAT_1(EXPECTED, FMT, ARG1) \
2095 SELFTEST_BEGIN_STMT \
2096 assert_pp_format ((SELFTEST_LOCATION), (EXPECTED), (FMT), \
2097 (ARG1)); \
2098 SELFTEST_END_STMT
2099
2100#define ASSERT_PP_FORMAT_2(EXPECTED, FMT, ARG1, ARG2) \
2101 SELFTEST_BEGIN_STMT \
2102 assert_pp_format ((SELFTEST_LOCATION), (EXPECTED), (FMT), \
2103 (ARG1), (ARG2)); \
2104 SELFTEST_END_STMT
2105
2106#define ASSERT_PP_FORMAT_3(EXPECTED, FMT, ARG1, ARG2, ARG3) \
2107 SELFTEST_BEGIN_STMT \
2108 assert_pp_format ((SELFTEST_LOCATION), (EXPECTED), (FMT), \
2109 (ARG1), (ARG2), (ARG3)); \
2110 SELFTEST_END_STMT
2111
4ccab56d
DM
2112/* Verify that pp_format works, for various format codes. */
2113
2114static void
2115test_pp_format ()
2116{
2117 /* Avoid introducing locale-specific differences in the results
2118 by hardcoding open_quote and close_quote. */
dbf96d49 2119 auto_fix_quotes fix_quotes;
4ccab56d
DM
2120
2121 /* Verify that plain text is passed through unchanged. */
09765e3a 2122 assert_pp_format (SELFTEST_LOCATION, "unformatted", "unformatted");
4ccab56d
DM
2123
2124 /* Verify various individual format codes, in the order listed in the
2125 comment for pp_format above. For each code, we append a second
2126 argument with a known bit pattern (0x12345678), to ensure that we
2127 are consuming arguments correctly. */
09765e3a
DM
2128 ASSERT_PP_FORMAT_2 ("-27 12345678", "%d %x", -27, 0x12345678);
2129 ASSERT_PP_FORMAT_2 ("-5 12345678", "%i %x", -5, 0x12345678);
2130 ASSERT_PP_FORMAT_2 ("10 12345678", "%u %x", 10, 0x12345678);
2131 ASSERT_PP_FORMAT_2 ("17 12345678", "%o %x", 15, 0x12345678);
2132 ASSERT_PP_FORMAT_2 ("cafebabe 12345678", "%x %x", 0xcafebabe, 0x12345678);
2133 ASSERT_PP_FORMAT_2 ("-27 12345678", "%ld %x", (long)-27, 0x12345678);
2134 ASSERT_PP_FORMAT_2 ("-5 12345678", "%li %x", (long)-5, 0x12345678);
2135 ASSERT_PP_FORMAT_2 ("10 12345678", "%lu %x", (long)10, 0x12345678);
2136 ASSERT_PP_FORMAT_2 ("17 12345678", "%lo %x", (long)15, 0x12345678);
2137 ASSERT_PP_FORMAT_2 ("cafebabe 12345678", "%lx %x", (long)0xcafebabe,
2138 0x12345678);
2139 ASSERT_PP_FORMAT_2 ("-27 12345678", "%lld %x", (long long)-27, 0x12345678);
2140 ASSERT_PP_FORMAT_2 ("-5 12345678", "%lli %x", (long long)-5, 0x12345678);
2141 ASSERT_PP_FORMAT_2 ("10 12345678", "%llu %x", (long long)10, 0x12345678);
2142 ASSERT_PP_FORMAT_2 ("17 12345678", "%llo %x", (long long)15, 0x12345678);
2143 ASSERT_PP_FORMAT_2 ("cafebabe 12345678", "%llx %x", (long long)0xcafebabe,
2144 0x12345678);
2145 ASSERT_PP_FORMAT_2 ("-27 12345678", "%wd %x", (HOST_WIDE_INT)-27, 0x12345678);
2146 ASSERT_PP_FORMAT_2 ("-5 12345678", "%wi %x", (HOST_WIDE_INT)-5, 0x12345678);
2147 ASSERT_PP_FORMAT_2 ("10 12345678", "%wu %x", (unsigned HOST_WIDE_INT)10,
2148 0x12345678);
2149 ASSERT_PP_FORMAT_2 ("17 12345678", "%wo %x", (HOST_WIDE_INT)15, 0x12345678);
2150 ASSERT_PP_FORMAT_2 ("0xcafebabe 12345678", "%wx %x", (HOST_WIDE_INT)0xcafebabe,
2151 0x12345678);
2152 ASSERT_PP_FORMAT_2 ("A 12345678", "%c %x", 'A', 0x12345678);
2153 ASSERT_PP_FORMAT_2 ("hello world 12345678", "%s %x", "hello world",
2154 0x12345678);
86ef85d3
MS
2155
2156 /* Not nul-terminated. */
2157 char arr[5] = { '1', '2', '3', '4', '5' };
2158 ASSERT_PP_FORMAT_3 ("123 12345678", "%.*s %x", 3, arr, 0x12345678);
2159 ASSERT_PP_FORMAT_3 ("1234 12345678", "%.*s %x", -1, "1234", 0x12345678);
2160 ASSERT_PP_FORMAT_3 ("12345 12345678", "%.*s %x", 7, "12345", 0x12345678);
2161
914bc2b9
DM
2162 /* We can't test for %p; the pointer is printed in an implementation-defined
2163 manner. */
09765e3a
DM
2164 ASSERT_PP_FORMAT_2 ("normal colored normal 12345678",
2165 "normal %rcolored%R normal %x",
2166 "error", 0x12345678);
4ccab56d 2167 assert_pp_format_colored
09765e3a
DM
2168 (SELFTEST_LOCATION,
2169 "normal \33[01;31m\33[Kcolored\33[m\33[K normal 12345678",
4ccab56d
DM
2170 "normal %rcolored%R normal %x", "error", 0x12345678);
2171 /* TODO:
2172 %m: strerror(text->err_no) - does not consume a value from args_ptr. */
09765e3a
DM
2173 ASSERT_PP_FORMAT_1 ("% 12345678", "%% %x", 0x12345678);
2174 ASSERT_PP_FORMAT_1 ("` 12345678", "%< %x", 0x12345678);
2175 ASSERT_PP_FORMAT_1 ("' 12345678", "%> %x", 0x12345678);
2176 ASSERT_PP_FORMAT_1 ("' 12345678", "%' %x", 0x12345678);
2177 ASSERT_PP_FORMAT_3 ("abc 12345678", "%.*s %x", 3, "abcdef", 0x12345678);
2178 ASSERT_PP_FORMAT_2 ("abc 12345678", "%.3s %x", "abcdef", 0x12345678);
4ccab56d
DM
2179
2180 /* Verify flag 'q'. */
09765e3a
DM
2181 ASSERT_PP_FORMAT_2 ("`foo' 12345678", "%qs %x", "foo", 0x12345678);
2182 assert_pp_format_colored (SELFTEST_LOCATION,
2183 "`\33[01m\33[Kfoo\33[m\33[K' 12345678", "%qs %x",
4ccab56d
DM
2184 "foo", 0x12345678);
2185
975672f3
PK
2186 /* Verify %Z. */
2187 int v[] = { 1, 2, 3 };
2188 ASSERT_PP_FORMAT_3 ("1, 2, 3 12345678", "%Z %x", v, 3, 0x12345678);
2189
2190 int v2[] = { 0 };
2191 ASSERT_PP_FORMAT_3 ("0 12345678", "%Z %x", v2, 1, 0x12345678);
2192
4ccab56d 2193 /* Verify that combinations work, along with unformatted text. */
09765e3a
DM
2194 assert_pp_format (SELFTEST_LOCATION,
2195 "the quick brown fox jumps over the lazy dog",
4ccab56d
DM
2196 "the %s %s %s jumps over the %s %s",
2197 "quick", "brown", "fox", "lazy", "dog");
09765e3a
DM
2198 assert_pp_format (SELFTEST_LOCATION, "item 3 of 7", "item %i of %i", 3, 7);
2199 assert_pp_format (SELFTEST_LOCATION, "problem with `bar' at line 10",
4ccab56d 2200 "problem with %qs at line %i", "bar", 10);
4ccab56d
DM
2201}
2202
2203/* Run all of the selftests within this file. */
2204
2205void
2206pretty_print_c_tests ()
2207{
2208 test_basic_printing ();
2209 test_pp_format ();
2210}
2211
2212} // namespace selftest
2213
2214#endif /* CHECKING_P */