00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "config.h"
00023 #undef FLOAT
00024 #undef FFS
00025 #include "system.h"
00026 #include "coretypes.h"
00027 #include "intl.h"
00028 #include "pretty-print.h"
00029 #include "tree.h"
00030
00031 #define obstack_chunk_alloc xmalloc
00032 #define obstack_chunk_free free
00033
00034
00035 #define pp_formatted_text_data(PP) \
00036 ((const char *) obstack_base (&pp_base (PP)->buffer->obstack))
00037
00038
00039
00040
00041 #define pp_integer_with_precision(PP, ARG, PREC, T, F) \
00042 do \
00043 switch (PREC) \
00044 { \
00045 case 0: \
00046 pp_scalar (PP, "%" F, va_arg (ARG, T)); \
00047 break; \
00048 \
00049 case 1: \
00050 pp_scalar (PP, "%l" F, va_arg (ARG, long T)); \
00051 break; \
00052 \
00053 case 2: \
00054 pp_scalar (PP, "%ll" F, va_arg (ARG, long long T)); \
00055 break; \
00056 \
00057 default: \
00058 break; \
00059 } \
00060 while (0)
00061
00062
00063
00064
00065 static void
00066 pp_set_real_maximum_length (pretty_printer *pp)
00067 {
00068
00069
00070
00071 if (!pp_is_wrapping_line (pp)
00072 || pp_prefixing_rule (pp) == DIAGNOSTICS_SHOW_PREFIX_ONCE
00073 || pp_prefixing_rule (pp) == DIAGNOSTICS_SHOW_PREFIX_NEVER)
00074 pp->maximum_length = pp_line_cutoff (pp);
00075 else
00076 {
00077 int prefix_length = pp->prefix ? strlen (pp->prefix) : 0;
00078
00079
00080 if (pp_line_cutoff (pp) - prefix_length < 32)
00081 pp->maximum_length = pp_line_cutoff (pp) + 32;
00082 else
00083 pp->maximum_length = pp_line_cutoff (pp);
00084 }
00085 }
00086
00087
00088 static inline void
00089 pp_clear_state (pretty_printer *pp)
00090 {
00091 pp->emitted_prefix = false;
00092 pp_indentation (pp) = 0;
00093 }
00094
00095
00096 void
00097 pp_write_text_to_stream (pretty_printer *pp)
00098 {
00099 const char *text = pp_formatted_text (pp);
00100 fputs (text, pp->buffer->stream);
00101 pp_clear_output_area (pp);
00102 }
00103
00104
00105 static void
00106 pp_wrap_text (pretty_printer *pp, const char *start, const char *end)
00107 {
00108 bool wrapping_line = pp_is_wrapping_line (pp);
00109
00110 while (start != end)
00111 {
00112
00113 {
00114 const char *p = start;
00115 while (p != end && !ISBLANK (*p) && *p != '\n')
00116 ++p;
00117 if (wrapping_line
00118 && p - start >= pp_remaining_character_count_for_line (pp))
00119 pp_newline (pp);
00120 pp_append_text (pp, start, p);
00121 start = p;
00122 }
00123
00124 if (start != end && ISBLANK (*start))
00125 {
00126 pp_space (pp);
00127 ++start;
00128 }
00129 if (start != end && *start == '\n')
00130 {
00131 pp_newline (pp);
00132 ++start;
00133 }
00134 }
00135 }
00136
00137
00138 static inline void
00139 pp_maybe_wrap_text (pretty_printer *pp, const char *start, const char *end)
00140 {
00141 if (pp_is_wrapping_line (pp))
00142 pp_wrap_text (pp, start, end);
00143 else
00144 pp_append_text (pp, start, end);
00145 }
00146
00147
00148
00149 static inline void
00150 pp_append_r (pretty_printer *pp, const char *start, int length)
00151 {
00152 obstack_grow (&pp->buffer->obstack, start, length);
00153 pp->buffer->line_length += length;
00154 }
00155
00156
00157
00158
00159 void
00160 pp_base_indent (pretty_printer *pp)
00161 {
00162 int n = pp_indentation (pp);
00163 int i;
00164
00165 for (i = 0; i < n; ++i)
00166 pp_space (pp);
00167 }
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177 void
00178 pp_base_prepare_to_format (pretty_printer *pp ATTRIBUTE_UNUSED,
00179 text_info *text,
00180 location_t *locus)
00181 {
00182 const char *p = text->format_spec;
00183 tree t;
00184
00185
00186 if (p[0] == '%')
00187 switch (p[1])
00188 {
00189 case 'H':
00190 *locus = *va_arg (*text->args_ptr, location_t *);
00191 text->format_spec = p + 2;
00192 break;
00193
00194 case 'J':
00195 t = va_arg (*text->args_ptr, tree);
00196 *locus = DECL_SOURCE_LOCATION (t);
00197 text->format_spec = p + 2;
00198 break;
00199 }
00200 }
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224 void
00225 pp_base_format_text (pretty_printer *pp, text_info *text)
00226 {
00227 for (; *text->format_spec; ++text->format_spec)
00228 {
00229 int precision = 0;
00230 bool wide = false;
00231 bool quoted = false;
00232
00233
00234 {
00235 const char *p = text->format_spec;
00236 while (*p && *p != '%')
00237 ++p;
00238 pp_wrap_text (pp, text->format_spec, p);
00239 text->format_spec = p;
00240 }
00241
00242 if (*text->format_spec == '\0')
00243 break;
00244
00245
00246
00247 if (*++text->format_spec == 'q')
00248 {
00249 quoted = true;
00250 ++text->format_spec;
00251 }
00252 switch (*text->format_spec)
00253 {
00254 case 'w':
00255 wide = true;
00256 ++text->format_spec;
00257 break;
00258
00259 case 'l':
00260 do
00261 ++precision;
00262 while (*++text->format_spec == 'l');
00263 break;
00264
00265 default:
00266 break;
00267 }
00268
00269 gcc_assert (precision <= 2);
00270
00271 if (quoted)
00272 pp_string (pp, open_quote);
00273 switch (*text->format_spec)
00274 {
00275 case 'c':
00276 pp_character (pp, va_arg (*text->args_ptr, int));
00277 break;
00278
00279 case 'd':
00280 case 'i':
00281 if (wide)
00282 pp_wide_integer (pp, va_arg (*text->args_ptr, HOST_WIDE_INT));
00283 else
00284 pp_integer_with_precision
00285 (pp, *text->args_ptr, precision, int, "d");
00286 break;
00287
00288 case 'o':
00289 if (wide)
00290 pp_scalar (pp, "%" HOST_WIDE_INT_PRINT "o",
00291 va_arg (*text->args_ptr, unsigned HOST_WIDE_INT));
00292 else
00293 pp_integer_with_precision
00294 (pp, *text->args_ptr, precision, unsigned, "u");
00295 break;
00296
00297 case 's':
00298 pp_string (pp, va_arg (*text->args_ptr, const char *));
00299 break;
00300
00301 case 'p':
00302 pp_pointer (pp, va_arg (*text->args_ptr, void *));
00303 break;
00304
00305 case 'u':
00306 if (wide)
00307 pp_scalar (pp, HOST_WIDE_INT_PRINT_UNSIGNED,
00308 va_arg (*text->args_ptr, unsigned HOST_WIDE_INT));
00309 else
00310 pp_integer_with_precision
00311 (pp, *text->args_ptr, precision, unsigned, "u");
00312 break;
00313
00314 case 'x':
00315 if (wide)
00316 pp_scalar (pp, HOST_WIDE_INT_PRINT_HEX,
00317 va_arg (*text->args_ptr, unsigned HOST_WIDE_INT));
00318 else
00319 pp_integer_with_precision
00320 (pp, *text->args_ptr, precision, unsigned, "x");
00321 break;
00322
00323 case 'm':
00324 pp_string (pp, xstrerror (text->err_no));
00325 break;
00326
00327 case '%':
00328 pp_character (pp, '%');
00329 break;
00330
00331 case '<':
00332 pp_string (pp, open_quote);
00333 break;
00334
00335 case '>':
00336 case '\'':
00337 pp_string (pp, close_quote);
00338 break;
00339
00340 case 'H':
00341 {
00342 location_t *locus = va_arg (*text->args_ptr, location_t *);
00343 expanded_location s = expand_location (*locus);
00344 pp_string (pp, "file '");
00345 pp_string (pp, s.file);
00346 pp_string (pp, "', line ");
00347 pp_decimal_int (pp, s.line);
00348 }
00349 break;
00350
00351 case '.':
00352 {
00353 int n;
00354 const char *s;
00355
00356 ++text->format_spec;
00357 gcc_assert (*text->format_spec == '*');
00358 ++text->format_spec;
00359 gcc_assert (*text->format_spec == 's');
00360
00361 n = va_arg (*text->args_ptr, int);
00362 s = va_arg (*text->args_ptr, const char *);
00363 pp_append_text (pp, s, s + n);
00364 }
00365 break;
00366
00367 default:
00368 if (!pp_format_decoder (pp) || !(*pp_format_decoder (pp)) (pp, text))
00369 {
00370
00371
00372
00373
00374 abort ();
00375 }
00376 }
00377 if (quoted)
00378 pp_string (pp, close_quote);
00379 }
00380 }
00381
00382
00383
00384 void
00385 pp_base_format_verbatim (pretty_printer *pp, text_info *text)
00386 {
00387 diagnostic_prefixing_rule_t rule = pp_prefixing_rule (pp);
00388 int line_cutoff = pp_line_cutoff (pp);
00389
00390
00391 pp->prefixing_rule = DIAGNOSTICS_SHOW_PREFIX_NEVER;
00392 pp_line_cutoff (pp) = 0;
00393
00394 pp_format_text (pp, text);
00395
00396 pp_prefixing_rule (pp) = rule;
00397 pp_line_cutoff (pp) = line_cutoff;
00398 }
00399
00400
00401 void
00402 pp_base_flush (pretty_printer *pp)
00403 {
00404 pp_write_text_to_stream (pp);
00405 pp_clear_state (pp);
00406 fputc ('\n', pp->buffer->stream);
00407 fflush (pp->buffer->stream);
00408 pp_needs_newline (pp) = false;
00409 }
00410
00411
00412
00413
00414 void
00415 pp_base_set_line_maximum_length (pretty_printer *pp, int length)
00416 {
00417 pp_line_cutoff (pp) = length;
00418 pp_set_real_maximum_length (pp);
00419 }
00420
00421
00422 void
00423 pp_base_clear_output_area (pretty_printer *pp)
00424 {
00425 obstack_free (&pp->buffer->obstack, obstack_base (&pp->buffer->obstack));
00426 pp->buffer->line_length = 0;
00427 }
00428
00429
00430 void
00431 pp_base_set_prefix (pretty_printer *pp, const char *prefix)
00432 {
00433 pp->prefix = prefix;
00434 pp_set_real_maximum_length (pp);
00435 pp->emitted_prefix = false;
00436 pp_indentation (pp) = 0;
00437 }
00438
00439
00440 void
00441 pp_base_destroy_prefix (pretty_printer *pp)
00442 {
00443 if (pp->prefix != NULL)
00444 {
00445 free ((char *) pp->prefix);
00446 pp->prefix = NULL;
00447 }
00448 }
00449
00450
00451 void
00452 pp_base_emit_prefix (pretty_printer *pp)
00453 {
00454 if (pp->prefix != NULL)
00455 {
00456 switch (pp_prefixing_rule (pp))
00457 {
00458 default:
00459 case DIAGNOSTICS_SHOW_PREFIX_NEVER:
00460 break;
00461
00462 case DIAGNOSTICS_SHOW_PREFIX_ONCE:
00463 if (pp->emitted_prefix)
00464 {
00465 pp_base_indent (pp);
00466 break;
00467 }
00468 pp_indentation (pp) += 3;
00469
00470
00471 case DIAGNOSTICS_SHOW_PREFIX_EVERY_LINE:
00472 {
00473 int prefix_length = strlen (pp->prefix);
00474 pp_append_r (pp, pp->prefix, prefix_length);
00475 pp->emitted_prefix = true;
00476 }
00477 break;
00478 }
00479 }
00480 }
00481
00482
00483
00484 void
00485 pp_construct (pretty_printer *pp, const char *prefix, int maximum_length)
00486 {
00487 memset (pp, 0, sizeof (pretty_printer));
00488 pp->buffer = xcalloc (1, sizeof (output_buffer));
00489 obstack_init (&pp->buffer->obstack);
00490 pp->buffer->stream = stderr;
00491 pp_line_cutoff (pp) = maximum_length;
00492 pp_prefixing_rule (pp) = DIAGNOSTICS_SHOW_PREFIX_ONCE;
00493 pp_set_prefix (pp, prefix);
00494 }
00495
00496
00497
00498
00499
00500
00501 void
00502 pp_base_append_text (pretty_printer *pp, const char *start, const char *end)
00503 {
00504
00505 if (pp->buffer->line_length == 0)
00506 {
00507 pp_emit_prefix (pp);
00508 if (pp_is_wrapping_line (pp))
00509 while (start != end && *start == ' ')
00510 ++start;
00511 }
00512 pp_append_r (pp, start, end - start);
00513 }
00514
00515
00516
00517 const char *
00518 pp_base_formatted_text (pretty_printer *pp)
00519 {
00520 obstack_1grow (&pp->buffer->obstack, '\0');
00521 return pp_formatted_text_data (pp);
00522 }
00523
00524
00525
00526 const char *
00527 pp_base_last_position_in_text (const pretty_printer *pp)
00528 {
00529 const char *p = NULL;
00530 struct obstack *text = &pp->buffer->obstack;
00531
00532 if (obstack_base (text) != obstack_next_free (text))
00533 p = ((const char *) obstack_next_free (text)) - 1;
00534 return p;
00535 }
00536
00537
00538
00539 int
00540 pp_base_remaining_character_count_for_line (pretty_printer *pp)
00541 {
00542 return pp->maximum_length - pp->buffer->line_length;
00543 }
00544
00545
00546
00547 void
00548 pp_printf (pretty_printer *pp, const char *msg, ...)
00549 {
00550 text_info text;
00551 va_list ap;
00552
00553 va_start (ap, msg);
00554 text.err_no = errno;
00555 text.args_ptr = ≈
00556 text.format_spec = msg;
00557 pp_format_text (pp, &text);
00558 va_end (ap);
00559 }
00560
00561
00562
00563 void
00564 pp_verbatim (pretty_printer *pp, const char *msg, ...)
00565 {
00566 text_info text;
00567 va_list ap;
00568
00569 va_start (ap, msg);
00570 text.err_no = errno;
00571 text.args_ptr = ≈
00572 text.format_spec = msg;
00573 pp_format_verbatim (pp, &text);
00574 va_end (ap);
00575 }
00576
00577
00578
00579
00580 void
00581 pp_base_newline (pretty_printer *pp)
00582 {
00583 obstack_1grow (&pp->buffer->obstack, '\n');
00584 pp->buffer->line_length = 0;
00585 }
00586
00587
00588 void
00589 pp_base_character (pretty_printer *pp, int c)
00590 {
00591 if (pp_is_wrapping_line (pp)
00592 && pp_remaining_character_count_for_line (pp) <= 0)
00593 {
00594 pp_newline (pp);
00595 if (ISSPACE (c))
00596 return;
00597 }
00598 obstack_1grow (&pp->buffer->obstack, c);
00599 ++pp->buffer->line_length;
00600 }
00601
00602
00603
00604 void
00605 pp_base_string (pretty_printer *pp, const char *str)
00606 {
00607 pp_maybe_wrap_text (pp, str, str + (str ? strlen (str) : 0));
00608 }
00609
00610
00611
00612 void
00613 pp_base_maybe_space (pretty_printer *pp)
00614 {
00615 if (pp_base (pp)->padding != pp_none)
00616 {
00617 pp_space (pp);
00618 pp_base (pp)->padding = pp_none;
00619 }
00620 }