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