pretty-print.c revision 169689
1309577Sglebius/* Various declarations for language-independent pretty-print subroutines. 2309577Sglebius Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc. 3309577Sglebius Contributed by Gabriel Dos Reis <gdr@integrable-solutions.net> 4309577Sglebius 5309577SglebiusThis file is part of GCC. 6309577Sglebius 7309577SglebiusGCC is free software; you can redistribute it and/or modify it under 8309577Sglebiusthe terms of the GNU General Public License as published by the Free 9309577SglebiusSoftware Foundation; either version 2, or (at your option) any later 10309577Sglebiusversion. 11309577Sglebius 12309577SglebiusGCC is distributed in the hope that it will be useful, but WITHOUT ANY 13309577SglebiusWARRANTY; without even the implied warranty of MERCHANTABILITY or 14309577SglebiusFITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15309577Sglebiusfor more details. 16309577Sglebius 17309577SglebiusYou should have received a copy of the GNU General Public License 18309577Sglebiusalong with GCC; see the file COPYING. If not, write to the Free 19309577SglebiusSoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 20309577Sglebius02110-1301, USA. */ 21309577Sglebius 22309577Sglebius#include "config.h" 23309577Sglebius#undef FLOAT /* This is for hpux. They should change hpux. */ 24309577Sglebius#undef FFS /* Some systems define this in param.h. */ 25309577Sglebius#include "system.h" 26309577Sglebius#include "coretypes.h" 27309577Sglebius#include "intl.h" 28309577Sglebius#include "pretty-print.h" 29309577Sglebius#include "tree.h" 30309577Sglebius 31309577Sglebius#define obstack_chunk_alloc xmalloc 32309577Sglebius#define obstack_chunk_free free 33309577Sglebius 34309577Sglebius/* A pointer to the formatted diagnostic message. */ 35309577Sglebius#define pp_formatted_text_data(PP) \ 36309577Sglebius ((const char *) obstack_base (pp_base (PP)->buffer->obstack)) 37309577Sglebius 38309577Sglebius/* Format an integer given by va_arg (ARG, type-specifier T) where 39309577Sglebius type-specifier is a precision modifier as indicated by PREC. F is 40309577Sglebius a string used to construct the appropriate format-specifier. */ 41309577Sglebius#define pp_integer_with_precision(PP, ARG, PREC, T, F) \ 42309577Sglebius do \ 43309577Sglebius switch (PREC) \ 44309577Sglebius { \ 45309577Sglebius case 0: \ 46309577Sglebius pp_scalar (PP, "%" F, va_arg (ARG, T)); \ 47309577Sglebius break; \ 48309577Sglebius \ 49309577Sglebius case 1: \ 50309577Sglebius pp_scalar (PP, "%l" F, va_arg (ARG, long T)); \ 51309577Sglebius break; \ 52309577Sglebius \ 53309577Sglebius case 2: \ 54309577Sglebius pp_scalar (PP, "%ll" F, va_arg (ARG, long long T)); \ 55309577Sglebius break; \ 56309577Sglebius \ 57309577Sglebius default: \ 58309577Sglebius break; \ 59309577Sglebius } \ 60309577Sglebius while (0) 61309577Sglebius 62309577Sglebius 63309577Sglebius/* Subroutine of pp_set_maximum_length. Set up PRETTY-PRINTER's 64309577Sglebius internal maximum characters per line. */ 65309577Sglebiusstatic void 66309577Sglebiuspp_set_real_maximum_length (pretty_printer *pp) 67309577Sglebius{ 68325322Sgordon /* If we're told not to wrap lines then do the obvious thing. In case 69309577Sglebius we'll emit prefix only once per message, it is appropriate 70309577Sglebius not to increase unnecessarily the line-length cut-off. */ 71309577Sglebius if (!pp_is_wrapping_line (pp) 72309577Sglebius || pp_prefixing_rule (pp) == DIAGNOSTICS_SHOW_PREFIX_ONCE 73309577Sglebius || pp_prefixing_rule (pp) == DIAGNOSTICS_SHOW_PREFIX_NEVER) 74309577Sglebius pp->maximum_length = pp_line_cutoff (pp); 75309577Sglebius else 76309577Sglebius { 77309577Sglebius int prefix_length = pp->prefix ? strlen (pp->prefix) : 0; 78325322Sgordon /* If the prefix is ridiculously too long, output at least 79309577Sglebius 32 characters. */ 80309577Sglebius if (pp_line_cutoff (pp) - prefix_length < 32) 81309577Sglebius pp->maximum_length = pp_line_cutoff (pp) + 32; 82309577Sglebius else 83309577Sglebius pp->maximum_length = pp_line_cutoff (pp); 84309577Sglebius } 85309577Sglebius} 86309577Sglebius 87309577Sglebius/* Clear PRETTY-PRINTER's output state. */ 88309577Sglebiusstatic inline void 89309577Sglebiuspp_clear_state (pretty_printer *pp) 90309577Sglebius{ 91309577Sglebius pp->emitted_prefix = false; 92309577Sglebius pp_indentation (pp) = 0; 93309577Sglebius} 94309577Sglebius 95309577Sglebius/* Flush the formatted text of PRETTY-PRINTER onto the attached stream. */ 96325322Sgordonvoid 97309577Sglebiuspp_write_text_to_stream (pretty_printer *pp) 98309577Sglebius{ 99309577Sglebius const char *text = pp_formatted_text (pp); 100309577Sglebius fputs (text, pp->buffer->stream); 101325322Sgordon pp_clear_output_area (pp); 102309577Sglebius} 103309577Sglebius 104309577Sglebius/* Wrap a text delimited by START and END into PRETTY-PRINTER. */ 105309577Sglebiusstatic void 106309577Sglebiuspp_wrap_text (pretty_printer *pp, const char *start, const char *end) 107325322Sgordon{ 108309577Sglebius bool wrapping_line = pp_is_wrapping_line (pp); 109309577Sglebius 110309577Sglebius while (start != end) 111309577Sglebius { 112309577Sglebius /* Dump anything bordered by whitespaces. */ 113309577Sglebius { 114309577Sglebius const char *p = start; 115309577Sglebius while (p != end && !ISBLANK (*p) && *p != '\n') 116309577Sglebius ++p; 117309577Sglebius if (wrapping_line 118309577Sglebius && p - start >= pp_remaining_character_count_for_line (pp)) 119309577Sglebius pp_newline (pp); 120309577Sglebius pp_append_text (pp, start, p); 121309577Sglebius start = p; 122309577Sglebius } 123309577Sglebius 124309577Sglebius if (start != end && ISBLANK (*start)) 125325322Sgordon { 126325322Sgordon pp_space (pp); 127325322Sgordon ++start; 128309577Sglebius } 129309577Sglebius if (start != end && *start == '\n') 130309577Sglebius { 131309577Sglebius pp_newline (pp); 132325322Sgordon ++start; 133309577Sglebius } 134309577Sglebius } 135309577Sglebius} 136309577Sglebius 137309577Sglebius/* Same as pp_wrap_text but wrap text only when in line-wrapping mode. */ 138309577Sglebiusstatic inline void 139309577Sglebiuspp_maybe_wrap_text (pretty_printer *pp, const char *start, const char *end) 140309577Sglebius{ 141309577Sglebius if (pp_is_wrapping_line (pp)) 142309577Sglebius pp_wrap_text (pp, start, end); 143309577Sglebius else 144309577Sglebius pp_append_text (pp, start, end); 145309577Sglebius} 146309577Sglebius 147309577Sglebius/* Append to the output area of PRETTY-PRINTER a string specified by its 148309577Sglebius STARTing character and LENGTH. */ 149309577Sglebiusstatic inline void 150309577Sglebiuspp_append_r (pretty_printer *pp, const char *start, int length) 151325322Sgordon{ 152325322Sgordon obstack_grow (pp->buffer->obstack, start, length); 153309577Sglebius pp->buffer->line_length += length; 154309577Sglebius} 155309577Sglebius 156309577Sglebius/* Insert enough spaces into the output area of PRETTY-PRINTER to bring 157309577Sglebius the column position to the current indentation level, assuming that a 158309577Sglebius newline has just been written to the buffer. */ 159309577Sglebiusvoid 160309577Sglebiuspp_base_indent (pretty_printer *pp) 161309577Sglebius{ 162309577Sglebius int n = pp_indentation (pp); 163309577Sglebius int i; 164309577Sglebius 165309577Sglebius for (i = 0; i < n; ++i) 166309577Sglebius pp_space (pp); 167309577Sglebius} 168309577Sglebius 169309577Sglebius/* The following format specifiers are recognized as being client independent: 170309577Sglebius %d, %i: (signed) integer in base ten. 171309577Sglebius %u: unsigned integer in base ten. 172309577Sglebius %o: unsigned integer in base eight. 173331986Sgordon %x: unsigned integer in base sixteen. 174309577Sglebius %ld, %li, %lo, %lu, %lx: long versions of the above. 175309577Sglebius %lld, %lli, %llo, %llu, %llx: long long versions. 176331986Sgordon %wd, %wi, %wo, %wu, %wx: HOST_WIDE_INT versions. 177309577Sglebius %c: character. 178309577Sglebius %s: string. 179331986Sgordon %p: pointer. 180309577Sglebius %m: strerror(text->err_no) - does not consume a value from args_ptr. 181309577Sglebius %%: '%'. 182309577Sglebius %<: opening quote. 183309577Sglebius %>: closing quote. 184309577Sglebius %': apostrophe (should only be used in untranslated messages; 185309577Sglebius translations should use appropriate punctuation directly). 186309577Sglebius %.*s: a substring the length of which is specified by an argument 187309577Sglebius integer. 188309577Sglebius %Ns: likewise, but length specified as constant in the format string. 189309577Sglebius %H: location_t. 190309577Sglebius %J: a decl tree, from which DECL_SOURCE_LOCATION will be recorded. 191309577Sglebius Flag 'q': quote formatted text (must come immediately after '%'). 192309577Sglebius 193309577Sglebius Arguments can be used sequentially, or through %N$ resp. *N$ 194309577Sglebius notation Nth argument after the format string. If %N$ / *N$ 195309577Sglebius notation is used, it must be used for all arguments, except %m, %%, 196309577Sglebius %<, %> and %', which may not have a number, as they do not consume 197309577Sglebius an argument. When %M$.*N$s is used, M must be N + 1. (This may 198309577Sglebius also be written %M$.*s, provided N is not otherwise used.) The 199309577Sglebius format string must have conversion specifiers with argument numbers 200309577Sglebius 1 up to highest argument; each argument may only be used once. 201309577Sglebius A format string can have at most 30 arguments. */ 202309577Sglebius 203309577Sglebius/* Formatting phases 1 and 2: render TEXT->format_spec plus 204309577Sglebius TEXT->args_ptr into a series of chunks in PP->buffer->args[]. 205309577Sglebius Phase 3 is in pp_base_format_text. */ 206309577Sglebius 207309577Sglebiusvoid 208309577Sglebiuspp_base_format (pretty_printer *pp, text_info *text) 209309577Sglebius{ 210309577Sglebius output_buffer *buffer = pp->buffer; 211309577Sglebius const char *p; 212309577Sglebius const char **args; 213309577Sglebius struct chunk_info *new_chunk_array; 214325322Sgordon 215309577Sglebius unsigned int curarg = 0, chunk = 0, argno; 216309577Sglebius pp_wrapping_mode_t old_wrapping_mode; 217309577Sglebius bool any_unnumbered = false, any_numbered = false; 218309577Sglebius const char **formatters[PP_NL_ARGMAX]; 219325322Sgordon 220309577Sglebius /* Allocate a new chunk structure. */ 221309577Sglebius new_chunk_array = XOBNEW (&buffer->chunk_obstack, struct chunk_info); 222309577Sglebius new_chunk_array->prev = buffer->cur_chunk_array; 223309577Sglebius buffer->cur_chunk_array = new_chunk_array; 224309577Sglebius args = new_chunk_array->args; 225309577Sglebius 226325322Sgordon /* Formatting phase 1: split up TEXT->format_spec into chunks in 227309577Sglebius PP->buffer->args[]. Even-numbered chunks are to be output 228309577Sglebius verbatim, odd-numbered chunks are format specifiers. 229309577Sglebius %m, %%, %<, %>, and %' are replaced with the appropriate text at 230309577Sglebius this point. */ 231309577Sglebius 232309577Sglebius memset (formatters, 0, sizeof formatters); 233309577Sglebius 234309577Sglebius for (p = text->format_spec; *p; ) 235309577Sglebius { 236309577Sglebius while (*p != '\0' && *p != '%') 237309577Sglebius { 238309577Sglebius obstack_1grow (&buffer->chunk_obstack, *p); 239309577Sglebius p++; 240309577Sglebius } 241309577Sglebius 242309577Sglebius if (*p == '\0') 243309577Sglebius break; 244309577Sglebius 245309577Sglebius switch (*++p) 246309577Sglebius { 247309577Sglebius case '\0': 248309577Sglebius gcc_unreachable (); 249309577Sglebius 250309577Sglebius case '%': 251309577Sglebius obstack_1grow (&buffer->chunk_obstack, '%'); 252309577Sglebius p++; 253309577Sglebius continue; 254309577Sglebius 255309577Sglebius case '<': 256309577Sglebius obstack_grow (&buffer->chunk_obstack, 257325322Sgordon open_quote, strlen (open_quote)); 258325322Sgordon p++; 259325322Sgordon continue; 260325322Sgordon 261325322Sgordon case '>': 262325322Sgordon case '\'': 263325322Sgordon obstack_grow (&buffer->chunk_obstack, 264325322Sgordon close_quote, strlen (close_quote)); 265325322Sgordon p++; 266309577Sglebius continue; 267309577Sglebius 268309577Sglebius case 'm': 269325322Sgordon { 270309577Sglebius const char *errstr = xstrerror (text->err_no); 271309577Sglebius obstack_grow (&buffer->chunk_obstack, errstr, strlen (errstr)); 272309577Sglebius } 273309577Sglebius p++; 274331986Sgordon continue; 275309577Sglebius 276309577Sglebius default: 277331986Sgordon /* Handled in phase 2. Terminate the plain chunk here. */ 278331986Sgordon obstack_1grow (&buffer->chunk_obstack, '\0'); 279331986Sgordon gcc_assert (chunk < PP_NL_ARGMAX * 2); 280331986Sgordon args[chunk++] = XOBFINISH (&buffer->chunk_obstack, const char *); 281331986Sgordon break; 282331986Sgordon } 283331986Sgordon 284331986Sgordon if (ISDIGIT (*p)) 285331986Sgordon { 286331986Sgordon char *end; 287309577Sglebius argno = strtoul (p, &end, 10) - 1; 288309577Sglebius p = end; 289309577Sglebius gcc_assert (*p == '$'); 290309577Sglebius p++; 291309577Sglebius 292309577Sglebius any_numbered = true; 293309577Sglebius gcc_assert (!any_unnumbered); 294309577Sglebius } 295309577Sglebius else 296309577Sglebius { 297309577Sglebius argno = curarg++; 298309577Sglebius any_unnumbered = true; 299309577Sglebius gcc_assert (!any_numbered); 300309577Sglebius } 301309577Sglebius gcc_assert (argno < PP_NL_ARGMAX); 302309577Sglebius gcc_assert (!formatters[argno]); 303309577Sglebius formatters[argno] = &args[chunk]; 304309577Sglebius do 305309577Sglebius { 306309577Sglebius obstack_1grow (&buffer->chunk_obstack, *p); 307309577Sglebius p++; 308309577Sglebius } 309309577Sglebius while (strchr ("qwl+#", p[-1])); 310309577Sglebius 311309577Sglebius if (p[-1] == '.') 312309577Sglebius { 313309577Sglebius /* We handle '%.Ns' and '%.*s' or '%M$.*N$s' 314309577Sglebius (where M == N + 1). */ 315309577Sglebius if (ISDIGIT (*p)) 316309577Sglebius { 317309577Sglebius do 318309577Sglebius { 319309577Sglebius obstack_1grow (&buffer->chunk_obstack, *p); 320309577Sglebius p++; 321309577Sglebius } 322309577Sglebius while (ISDIGIT (p[-1])); 323309577Sglebius gcc_assert (p[-1] == 's'); 324309577Sglebius } 325309577Sglebius else 326309577Sglebius { 327309577Sglebius gcc_assert (*p == '*'); 328309577Sglebius obstack_1grow (&buffer->chunk_obstack, '*'); 329309577Sglebius p++; 330309577Sglebius 331309577Sglebius if (ISDIGIT (*p)) 332309577Sglebius { 333309577Sglebius char *end; 334309577Sglebius unsigned int argno2 = strtoul (p, &end, 10) - 1; 335309577Sglebius p = end; 336309577Sglebius gcc_assert (argno2 == argno - 1); 337309577Sglebius gcc_assert (!any_unnumbered); 338309577Sglebius gcc_assert (*p == '$'); 339309577Sglebius 340309577Sglebius p++; 341309577Sglebius formatters[argno2] = formatters[argno]; 342309577Sglebius } 343309577Sglebius else 344309577Sglebius { 345309577Sglebius gcc_assert (!any_numbered); 346309577Sglebius formatters[argno+1] = formatters[argno]; 347309577Sglebius curarg++; 348309577Sglebius } 349309577Sglebius gcc_assert (*p == 's'); 350309577Sglebius obstack_1grow (&buffer->chunk_obstack, 's'); 351309577Sglebius p++; 352309577Sglebius } 353309577Sglebius } 354309577Sglebius if (*p == '\0') 355309577Sglebius break; 356309577Sglebius 357309577Sglebius obstack_1grow (&buffer->chunk_obstack, '\0'); 358309577Sglebius gcc_assert (chunk < PP_NL_ARGMAX * 2); 359309577Sglebius args[chunk++] = XOBFINISH (&buffer->chunk_obstack, const char *); 360309577Sglebius } 361331986Sgordon 362331986Sgordon obstack_1grow (&buffer->chunk_obstack, '\0'); 363331986Sgordon gcc_assert (chunk < PP_NL_ARGMAX * 2); 364331986Sgordon args[chunk++] = XOBFINISH (&buffer->chunk_obstack, const char *); 365331986Sgordon args[chunk] = 0; 366331986Sgordon 367331986Sgordon /* Set output to the argument obstack, and switch line-wrapping and 368331986Sgordon prefixing off. */ 369331986Sgordon buffer->obstack = &buffer->chunk_obstack; 370331986Sgordon old_wrapping_mode = pp_set_verbatim_wrapping (pp); 371331986Sgordon 372331986Sgordon /* Second phase. Replace each formatter with the formatted text it 373331986Sgordon corresponds to. */ 374331986Sgordon 375331986Sgordon for (argno = 0; formatters[argno]; argno++) 376331986Sgordon { 377331986Sgordon int precision = 0; 378331986Sgordon bool wide = false; 379331986Sgordon bool plus = false; 380331986Sgordon bool hash = false; 381331986Sgordon bool quote = false; 382331986Sgordon 383331986Sgordon /* We do not attempt to enforce any ordering on the modifier 384331986Sgordon characters. */ 385309577Sglebius 386309577Sglebius for (p = *formatters[argno];; p++) 387309577Sglebius { 388309577Sglebius switch (*p) 389309577Sglebius { 390309577Sglebius case 'q': 391309577Sglebius gcc_assert (!quote); 392325322Sgordon quote = true; 393325322Sgordon continue; 394325322Sgordon 395325322Sgordon case '+': 396325322Sgordon gcc_assert (!plus); 397325322Sgordon plus = true; 398309577Sglebius continue; 399309577Sglebius 400309577Sglebius case '#': 401309577Sglebius gcc_assert (!hash); 402309577Sglebius hash = true; 403309577Sglebius continue; 404309577Sglebius 405309577Sglebius case 'w': 406309577Sglebius gcc_assert (!wide); 407309577Sglebius wide = true; 408309577Sglebius continue; 409309577Sglebius 410309577Sglebius case 'l': 411309577Sglebius /* We don't support precision beyond that of "long long". */ 412309577Sglebius gcc_assert (precision < 2); 413309577Sglebius precision++; 414309577Sglebius continue; 415309577Sglebius } 416309577Sglebius break; 417309577Sglebius } 418309577Sglebius 419309577Sglebius gcc_assert (!wide || precision == 0); 420309577Sglebius 421309577Sglebius if (quote) 422309577Sglebius pp_string (pp, open_quote); 423309577Sglebius 424309577Sglebius switch (*p) 425309577Sglebius { 426309577Sglebius case 'c': 427309577Sglebius pp_character (pp, va_arg (*text->args_ptr, int)); 428309577Sglebius break; 429309577Sglebius 430325322Sgordon case 'd': 431309577Sglebius case 'i': 432309577Sglebius if (wide) 433309577Sglebius pp_wide_integer (pp, va_arg (*text->args_ptr, HOST_WIDE_INT)); 434325322Sgordon else 435325322Sgordon pp_integer_with_precision 436309577Sglebius (pp, *text->args_ptr, precision, int, "d"); 437309577Sglebius break; 438309577Sglebius 439309577Sglebius case 'o': 440309577Sglebius if (wide) 441309577Sglebius pp_scalar (pp, "%" HOST_WIDE_INT_PRINT "o", 442309577Sglebius va_arg (*text->args_ptr, unsigned HOST_WIDE_INT)); 443309577Sglebius else 444309577Sglebius pp_integer_with_precision 445309577Sglebius (pp, *text->args_ptr, precision, unsigned, "o"); 446331986Sgordon break; 447309577Sglebius 448309577Sglebius case 's': 449309577Sglebius pp_string (pp, va_arg (*text->args_ptr, const char *)); 450309577Sglebius break; 451309577Sglebius 452309577Sglebius case 'p': 453309577Sglebius pp_pointer (pp, va_arg (*text->args_ptr, void *)); 454309577Sglebius break; 455309577Sglebius 456309577Sglebius case 'u': 457309577Sglebius if (wide) 458325322Sgordon pp_scalar (pp, HOST_WIDE_INT_PRINT_UNSIGNED, 459309577Sglebius va_arg (*text->args_ptr, unsigned HOST_WIDE_INT)); 460309577Sglebius else 461309577Sglebius pp_integer_with_precision 462309577Sglebius (pp, *text->args_ptr, precision, unsigned, "u"); 463309577Sglebius break; 464309577Sglebius 465309577Sglebius case 'x': 466309577Sglebius if (wide) 467309577Sglebius pp_scalar (pp, HOST_WIDE_INT_PRINT_HEX, 468309577Sglebius va_arg (*text->args_ptr, unsigned HOST_WIDE_INT)); 469325322Sgordon else 470325322Sgordon pp_integer_with_precision 471325322Sgordon (pp, *text->args_ptr, precision, unsigned, "x"); 472325322Sgordon break; 473325322Sgordon 474325322Sgordon case 'H': 475309577Sglebius { 476309577Sglebius location_t *locus = va_arg (*text->args_ptr, location_t *); 477309577Sglebius gcc_assert (text->locus != NULL); 478309577Sglebius *text->locus = *locus; 479309577Sglebius } 480325322Sgordon break; 481309577Sglebius 482325322Sgordon case 'J': 483325322Sgordon { 484309577Sglebius tree t = va_arg (*text->args_ptr, tree); 485309577Sglebius gcc_assert (text->locus != NULL); 486309577Sglebius *text->locus = DECL_SOURCE_LOCATION (t); 487309577Sglebius } 488325322Sgordon break; 489325322Sgordon 490309577Sglebius case '.': 491309577Sglebius { 492309577Sglebius int n; 493309577Sglebius const char *s; 494325322Sgordon 495309577Sglebius /* We handle '%.Ns' and '%.*s' or '%M$.*N$s' 496309577Sglebius (where M == N + 1). The format string should be verified 497309577Sglebius already from the first phase. */ 498309577Sglebius p++; 499309577Sglebius if (ISDIGIT (*p)) 500325322Sgordon { 501309577Sglebius char *end; 502309577Sglebius n = strtoul (p, &end, 10); 503309577Sglebius p = end; 504309577Sglebius gcc_assert (*p == 's'); 505325322Sgordon } 506309577Sglebius else 507309577Sglebius { 508309577Sglebius gcc_assert (*p == '*'); 509309577Sglebius p++; 510309577Sglebius gcc_assert (*p == 's'); 511309577Sglebius n = va_arg (*text->args_ptr, int); 512309577Sglebius 513309577Sglebius /* This consumes a second entry in the formatters array. */ 514309577Sglebius gcc_assert (formatters[argno] == formatters[argno+1]); 515309577Sglebius argno++; 516309577Sglebius } 517309577Sglebius 518325322Sgordon s = va_arg (*text->args_ptr, const char *); 519325322Sgordon pp_append_text (pp, s, s + n); 520325322Sgordon } 521325322Sgordon break; 522325322Sgordon 523325322Sgordon default: 524309577Sglebius { 525309577Sglebius bool ok; 526309577Sglebius 527309577Sglebius gcc_assert (pp_format_decoder (pp)); 528309577Sglebius ok = pp_format_decoder (pp) (pp, text, p, 529309577Sglebius precision, wide, plus, hash); 530309577Sglebius gcc_assert (ok); 531309577Sglebius } 532309577Sglebius } 533309577Sglebius 534309577Sglebius if (quote) 535309577Sglebius pp_string (pp, close_quote); 536309577Sglebius 537309577Sglebius obstack_1grow (&buffer->chunk_obstack, '\0'); 538325322Sgordon *formatters[argno] = XOBFINISH (&buffer->chunk_obstack, const char *); 539325322Sgordon } 540325322Sgordon 541325322Sgordon#ifdef ENABLE_CHECKING 542325322Sgordon for (; argno < PP_NL_ARGMAX; argno++) 543325322Sgordon gcc_assert (!formatters[argno]); 544309577Sglebius#endif 545309577Sglebius 546309577Sglebius /* Revert to normal obstack and wrapping mode. */ 547325322Sgordon buffer->obstack = &buffer->formatted_obstack; 548309577Sglebius buffer->line_length = 0; 549309577Sglebius pp_wrapping_mode (pp) = old_wrapping_mode; 550309577Sglebius pp_clear_state (pp); 551309577Sglebius} 552309577Sglebius 553309577Sglebius/* Format of a message pointed to by TEXT. */ 554309577Sglebiusvoid 555309577Sglebiuspp_base_output_formatted_text (pretty_printer *pp) 556309577Sglebius{ 557309577Sglebius unsigned int chunk; 558309577Sglebius output_buffer *buffer = pp_buffer (pp); 559309577Sglebius struct chunk_info *chunk_array = buffer->cur_chunk_array; 560309577Sglebius const char **args = chunk_array->args; 561309577Sglebius 562309577Sglebius gcc_assert (buffer->obstack == &buffer->formatted_obstack); 563309577Sglebius gcc_assert (buffer->line_length == 0); 564309577Sglebius 565309577Sglebius /* This is a third phase, first 2 phases done in pp_base_format_args. 566309577Sglebius Now we actually print it. */ 567325322Sgordon for (chunk = 0; args[chunk]; chunk++) 568309577Sglebius pp_string (pp, args[chunk]); 569331986Sgordon 570325322Sgordon /* Deallocate the chunk structure and everything after it (i.e. the 571309577Sglebius associated series of formatted strings). */ 572309577Sglebius buffer->cur_chunk_array = chunk_array->prev; 573309577Sglebius obstack_free (&buffer->chunk_obstack, chunk_array); 574309577Sglebius} 575309577Sglebius 576309577Sglebius/* Helper subroutine of output_verbatim and verbatim. Do the appropriate 577309577Sglebius settings needed by BUFFER for a verbatim formatting. */ 578309577Sglebiusvoid 579309577Sglebiuspp_base_format_verbatim (pretty_printer *pp, text_info *text) 580309577Sglebius{ 581309577Sglebius /* Set verbatim mode. */ 582325322Sgordon pp_wrapping_mode_t oldmode = pp_set_verbatim_wrapping (pp); 583309577Sglebius 584309577Sglebius /* Do the actual formatting. */ 585309577Sglebius pp_format (pp, text); 586325322Sgordon pp_output_formatted_text (pp); 587309577Sglebius 588309577Sglebius /* Restore previous settings. */ 589309577Sglebius pp_wrapping_mode (pp) = oldmode; 590309577Sglebius} 591309577Sglebius 592309577Sglebius/* Flush the content of BUFFER onto the attached stream. */ 593309577Sglebiusvoid 594309577Sglebiuspp_base_flush (pretty_printer *pp) 595309577Sglebius{ 596309577Sglebius pp_write_text_to_stream (pp); 597309577Sglebius pp_clear_state (pp); 598309577Sglebius fputc ('\n', pp->buffer->stream); 599309577Sglebius fflush (pp->buffer->stream); 600309577Sglebius pp_needs_newline (pp) = false; 601325322Sgordon} 602309577Sglebius 603331986Sgordon/* Sets the number of maximum characters per line PRETTY-PRINTER can 604325322Sgordon output in line-wrapping mode. A LENGTH value 0 suppresses 605309577Sglebius line-wrapping. */ 606309577Sglebiusvoid 607309577Sglebiuspp_base_set_line_maximum_length (pretty_printer *pp, int length) 608309577Sglebius{ 609309577Sglebius pp_line_cutoff (pp) = length; 610309577Sglebius pp_set_real_maximum_length (pp); 611309577Sglebius} 612309577Sglebius 613309577Sglebius/* Clear PRETTY-PRINTER output area text info. */ 614309577Sglebiusvoid 615309577Sglebiuspp_base_clear_output_area (pretty_printer *pp) 616309577Sglebius{ 617309577Sglebius obstack_free (pp->buffer->obstack, obstack_base (pp->buffer->obstack)); 618309577Sglebius pp->buffer->line_length = 0; 619309577Sglebius} 620309577Sglebius 621309577Sglebius/* Set PREFIX for PRETTY-PRINTER. */ 622309577Sglebiusvoid 623309577Sglebiuspp_base_set_prefix (pretty_printer *pp, const char *prefix) 624309577Sglebius{ 625309577Sglebius pp->prefix = prefix; 626309577Sglebius pp_set_real_maximum_length (pp); 627309577Sglebius pp->emitted_prefix = false; 628309577Sglebius pp_indentation (pp) = 0; 629309577Sglebius} 630309577Sglebius 631309577Sglebius/* Free PRETTY-PRINTER's prefix, a previously malloc()'d string. */ 632309577Sglebiusvoid 633309577Sglebiuspp_base_destroy_prefix (pretty_printer *pp) 634309577Sglebius{ 635309577Sglebius if (pp->prefix != NULL) 636309577Sglebius { 637309577Sglebius free ((char *) pp->prefix); 638309577Sglebius pp->prefix = NULL; 639309577Sglebius } 640309577Sglebius} 641309577Sglebius 642309577Sglebius/* Write out PRETTY-PRINTER's prefix. */ 643309577Sglebiusvoid 644309577Sglebiuspp_base_emit_prefix (pretty_printer *pp) 645309577Sglebius{ 646309577Sglebius if (pp->prefix != NULL) 647309577Sglebius { 648309577Sglebius switch (pp_prefixing_rule (pp)) 649309577Sglebius { 650309577Sglebius default: 651309577Sglebius case DIAGNOSTICS_SHOW_PREFIX_NEVER: 652309577Sglebius break; 653309577Sglebius 654309577Sglebius case DIAGNOSTICS_SHOW_PREFIX_ONCE: 655309577Sglebius if (pp->emitted_prefix) 656309577Sglebius { 657309577Sglebius pp_base_indent (pp); 658309577Sglebius break; 659309577Sglebius } 660309577Sglebius pp_indentation (pp) += 3; 661309577Sglebius /* Fall through. */ 662309577Sglebius 663309577Sglebius case DIAGNOSTICS_SHOW_PREFIX_EVERY_LINE: 664309577Sglebius { 665309577Sglebius int prefix_length = strlen (pp->prefix); 666309577Sglebius pp_append_r (pp, pp->prefix, prefix_length); 667309577Sglebius pp->emitted_prefix = true; 668309577Sglebius } 669309577Sglebius break; 670309577Sglebius } 671309577Sglebius } 672309577Sglebius} 673309577Sglebius 674309577Sglebius/* Construct a PRETTY-PRINTER with PREFIX and of MAXIMUM_LENGTH 675309577Sglebius characters per line. */ 676309577Sglebiusvoid 677309577Sglebiuspp_construct (pretty_printer *pp, const char *prefix, int maximum_length) 678309577Sglebius{ 679309577Sglebius memset (pp, 0, sizeof (pretty_printer)); 680309577Sglebius pp->buffer = XCNEW (output_buffer); 681309577Sglebius obstack_init (&pp->buffer->chunk_obstack); 682309577Sglebius obstack_init (&pp->buffer->formatted_obstack); 683309577Sglebius pp->buffer->obstack = &pp->buffer->formatted_obstack; 684309577Sglebius pp->buffer->stream = stderr; 685309577Sglebius pp_line_cutoff (pp) = maximum_length; 686309577Sglebius pp_prefixing_rule (pp) = DIAGNOSTICS_SHOW_PREFIX_ONCE; 687309577Sglebius pp_set_prefix (pp, prefix); 688309577Sglebius} 689309577Sglebius 690325322Sgordon/* Append a string delimited by START and END to the output area of 691325322Sgordon PRETTY-PRINTER. No line wrapping is done. However, if beginning a 692325322Sgordon new line then emit PRETTY-PRINTER's prefix and skip any leading 693309577Sglebius whitespace if appropriate. The caller must ensure that it is 694309577Sglebius safe to do so. */ 695309577Sglebiusvoid 696309577Sglebiuspp_base_append_text (pretty_printer *pp, const char *start, const char *end) 697325322Sgordon{ 698325322Sgordon /* Emit prefix and skip whitespace if we're starting a new line. */ 699309577Sglebius if (pp->buffer->line_length == 0) 700 { 701 pp_emit_prefix (pp); 702 if (pp_is_wrapping_line (pp)) 703 while (start != end && *start == ' ') 704 ++start; 705 } 706 pp_append_r (pp, start, end - start); 707} 708 709/* Finishes constructing a NULL-terminated character string representing 710 the PRETTY-PRINTED text. */ 711const char * 712pp_base_formatted_text (pretty_printer *pp) 713{ 714 obstack_1grow (pp->buffer->obstack, '\0'); 715 return pp_formatted_text_data (pp); 716} 717 718/* Return a pointer to the last character emitted in PRETTY-PRINTER's 719 output area. A NULL pointer means no character available. */ 720const char * 721pp_base_last_position_in_text (const pretty_printer *pp) 722{ 723 const char *p = NULL; 724 struct obstack *text = pp->buffer->obstack; 725 726 if (obstack_base (text) != obstack_next_free (text)) 727 p = ((const char *) obstack_next_free (text)) - 1; 728 return p; 729} 730 731/* Return the amount of characters PRETTY-PRINTER can accept to 732 make a full line. Meaningful only in line-wrapping mode. */ 733int 734pp_base_remaining_character_count_for_line (pretty_printer *pp) 735{ 736 return pp->maximum_length - pp->buffer->line_length; 737} 738 739 740/* Format a message into BUFFER a la printf. */ 741void 742pp_printf (pretty_printer *pp, const char *msg, ...) 743{ 744 text_info text; 745 va_list ap; 746 747 va_start (ap, msg); 748 text.err_no = errno; 749 text.args_ptr = ≈ 750 text.format_spec = msg; 751 text.locus = NULL; 752 pp_format (pp, &text); 753 pp_output_formatted_text (pp); 754 va_end (ap); 755} 756 757 758/* Output MESSAGE verbatim into BUFFER. */ 759void 760pp_verbatim (pretty_printer *pp, const char *msg, ...) 761{ 762 text_info text; 763 va_list ap; 764 765 va_start (ap, msg); 766 text.err_no = errno; 767 text.args_ptr = ≈ 768 text.format_spec = msg; 769 text.locus = NULL; 770 pp_format_verbatim (pp, &text); 771 va_end (ap); 772} 773 774 775 776/* Have PRETTY-PRINTER start a new line. */ 777void 778pp_base_newline (pretty_printer *pp) 779{ 780 obstack_1grow (pp->buffer->obstack, '\n'); 781 pp->buffer->line_length = 0; 782} 783 784/* Have PRETTY-PRINTER add a CHARACTER. */ 785void 786pp_base_character (pretty_printer *pp, int c) 787{ 788 if (pp_is_wrapping_line (pp) 789 && pp_remaining_character_count_for_line (pp) <= 0) 790 { 791 pp_newline (pp); 792 if (ISSPACE (c)) 793 return; 794 } 795 obstack_1grow (pp->buffer->obstack, c); 796 ++pp->buffer->line_length; 797} 798 799/* Append a STRING to the output area of PRETTY-PRINTER; the STRING may 800 be line-wrapped if in appropriate mode. */ 801void 802pp_base_string (pretty_printer *pp, const char *str) 803{ 804 pp_maybe_wrap_text (pp, str, str + (str ? strlen (str) : 0)); 805} 806 807/* Maybe print out a whitespace if needed. */ 808 809void 810pp_base_maybe_space (pretty_printer *pp) 811{ 812 if (pp_base (pp)->padding != pp_none) 813 { 814 pp_space (pp); 815 pp_base (pp)->padding = pp_none; 816 } 817} 818