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
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207 void
00208 pp_base_format (pretty_printer *pp, text_info *text)
00209 {
00210 output_buffer *buffer = pp->buffer;
00211 const char *p;
00212 const char **args;
00213 struct chunk_info *new_chunk_array;
00214
00215 unsigned int curarg = 0, chunk = 0, argno;
00216 pp_wrapping_mode_t old_wrapping_mode;
00217 bool any_unnumbered = false, any_numbered = false;
00218 const char **formatters[PP_NL_ARGMAX];
00219
00220
00221 new_chunk_array = XOBNEW (&buffer->chunk_obstack, struct chunk_info);
00222 new_chunk_array->prev = buffer->cur_chunk_array;
00223 buffer->cur_chunk_array = new_chunk_array;
00224 args = new_chunk_array->args;
00225
00226
00227
00228
00229
00230
00231
00232 memset (formatters, 0, sizeof formatters);
00233
00234 for (p = text->format_spec; *p; )
00235 {
00236 while (*p != '\0' && *p != '%')
00237 {
00238 obstack_1grow (&buffer->chunk_obstack, *p);
00239 p++;
00240 }
00241
00242 if (*p == '\0')
00243 break;
00244
00245 switch (*++p)
00246 {
00247 case '\0':
00248 gcc_unreachable ();
00249
00250 case '%':
00251 obstack_1grow (&buffer->chunk_obstack, '%');
00252 p++;
00253 continue;
00254
00255 case '<':
00256 obstack_grow (&buffer->chunk_obstack,
00257 open_quote, strlen (open_quote));
00258 p++;
00259 continue;
00260
00261 case '>':
00262 case '\'':
00263 obstack_grow (&buffer->chunk_obstack,
00264 close_quote, strlen (close_quote));
00265 p++;
00266 continue;
00267
00268 case 'm':
00269 {
00270 const char *errstr = xstrerror (text->err_no);
00271 obstack_grow (&buffer->chunk_obstack, errstr, strlen (errstr));
00272 }
00273 p++;
00274 continue;
00275
00276 default:
00277
00278 obstack_1grow (&buffer->chunk_obstack, '\0');
00279 gcc_assert (chunk < PP_NL_ARGMAX * 2);
00280 args[chunk++] = XOBFINISH (&buffer->chunk_obstack, const char *);
00281 break;
00282 }
00283
00284 if (ISDIGIT (*p))
00285 {
00286 char *end;
00287 argno = strtoul (p, &end, 10) - 1;
00288 p = end;
00289 gcc_assert (*p == '$');
00290 p++;
00291
00292 any_numbered = true;
00293 gcc_assert (!any_unnumbered);
00294 }
00295 else
00296 {
00297 argno = curarg++;
00298 any_unnumbered = true;
00299 gcc_assert (!any_numbered);
00300 }
00301 gcc_assert (argno < PP_NL_ARGMAX);
00302 gcc_assert (!formatters[argno]);
00303 formatters[argno] = &args[chunk];
00304 do
00305 {
00306 obstack_1grow (&buffer->chunk_obstack, *p);
00307 p++;
00308 }
00309 while (strchr ("qwl+#", p[-1]));
00310
00311 if (p[-1] == '.')
00312 {
00313
00314
00315 if (ISDIGIT (*p))
00316 {
00317 do
00318 {
00319 obstack_1grow (&buffer->chunk_obstack, *p);
00320 p++;
00321 }
00322 while (ISDIGIT (p[-1]));
00323 gcc_assert (p[-1] == 's');
00324 }
00325 else
00326 {
00327 gcc_assert (*p == '*');
00328 obstack_1grow (&buffer->chunk_obstack, '*');
00329 p++;
00330
00331 if (ISDIGIT (*p))
00332 {
00333 char *end;
00334 unsigned int argno2 = strtoul (p, &end, 10) - 1;
00335 p = end;
00336 gcc_assert (argno2 == argno - 1);
00337 gcc_assert (!any_unnumbered);
00338 gcc_assert (*p == '$');
00339
00340 p++;
00341 formatters[argno2] = formatters[argno];
00342 }
00343 else
00344 {
00345 gcc_assert (!any_numbered);
00346 formatters[argno+1] = formatters[argno];
00347 curarg++;
00348 }
00349 gcc_assert (*p == 's');
00350 obstack_1grow (&buffer->chunk_obstack, 's');
00351 p++;
00352 }
00353 }
00354 if (*p == '\0')
00355 break;
00356
00357 obstack_1grow (&buffer->chunk_obstack, '\0');
00358 gcc_assert (chunk < PP_NL_ARGMAX * 2);
00359 args[chunk++] = XOBFINISH (&buffer->chunk_obstack, const char *);
00360 }
00361
00362 obstack_1grow (&buffer->chunk_obstack, '\0');
00363 gcc_assert (chunk < PP_NL_ARGMAX * 2);
00364 args[chunk++] = XOBFINISH (&buffer->chunk_obstack, const char *);
00365 args[chunk] = 0;
00366
00367
00368
00369 buffer->obstack = &buffer->chunk_obstack;
00370 old_wrapping_mode = pp_set_verbatim_wrapping (pp);
00371
00372
00373
00374
00375 for (argno = 0; formatters[argno]; argno++)
00376 {
00377 int precision = 0;
00378 bool wide = false;
00379 bool plus = false;
00380 bool hash = false;
00381 bool quote = false;
00382
00383
00384
00385
00386 for (p = *formatters[argno];; p++)
00387 {
00388 switch (*p)
00389 {
00390 case 'q':
00391 gcc_assert (!quote);
00392 quote = true;
00393 continue;
00394
00395 case '+':
00396 gcc_assert (!plus);
00397 plus = true;
00398 continue;
00399
00400 case '#':
00401 gcc_assert (!hash);
00402 hash = true;
00403 continue;
00404
00405 case 'w':
00406 gcc_assert (!wide);
00407 wide = true;
00408 continue;
00409
00410 case 'l':
00411
00412 gcc_assert (precision < 2);
00413 precision++;
00414 continue;
00415 }
00416 break;
00417 }
00418
00419 gcc_assert (!wide || precision == 0);
00420
00421 if (quote)
00422 pp_string (pp, open_quote);
00423
00424 switch (*p)
00425 {
00426 case 'c':
00427 pp_character (pp, va_arg (*text->args_ptr, int));
00428 break;
00429
00430 case 'd':
00431 case 'i':
00432 if (wide)
00433 pp_wide_integer (pp, va_arg (*text->args_ptr, HOST_WIDE_INT));
00434 else
00435 pp_integer_with_precision
00436 (pp, *text->args_ptr, precision, int, "d");
00437 break;
00438
00439 case 'o':
00440 if (wide)
00441 pp_scalar (pp, "%" HOST_WIDE_INT_PRINT "o",
00442 va_arg (*text->args_ptr, unsigned HOST_WIDE_INT));
00443 else
00444 pp_integer_with_precision
00445 (pp, *text->args_ptr, precision, unsigned, "o");
00446 break;
00447
00448 case 's':
00449 pp_string (pp, va_arg (*text->args_ptr, const char *));
00450 break;
00451
00452 case 'p':
00453 pp_pointer (pp, va_arg (*text->args_ptr, void *));
00454 break;
00455
00456 case 'u':
00457 if (wide)
00458 pp_scalar (pp, HOST_WIDE_INT_PRINT_UNSIGNED,
00459 va_arg (*text->args_ptr, unsigned HOST_WIDE_INT));
00460 else
00461 pp_integer_with_precision
00462 (pp, *text->args_ptr, precision, unsigned, "u");
00463 break;
00464
00465 case 'x':
00466 if (wide)
00467 pp_scalar (pp, HOST_WIDE_INT_PRINT_HEX,
00468 va_arg (*text->args_ptr, unsigned HOST_WIDE_INT));
00469 else
00470 pp_integer_with_precision
00471 (pp, *text->args_ptr, precision, unsigned, "x");
00472 break;
00473
00474 case 'H':
00475 {
00476 location_t *locus = va_arg (*text->args_ptr, location_t *);
00477 gcc_assert (text->locus != NULL);
00478 *text->locus = *locus;
00479 }
00480 break;
00481
00482 case 'J':
00483 {
00484 tree t = va_arg (*text->args_ptr, tree);
00485 gcc_assert (text->locus != NULL);
00486 *text->locus = DECL_SOURCE_LOCATION (t);
00487 }
00488 break;
00489
00490 case '.':
00491 {
00492 int n;
00493 const char *s;
00494
00495
00496
00497
00498 p++;
00499 if (ISDIGIT (*p))
00500 {
00501 char *end;
00502 n = strtoul (p, &end, 10);
00503 p = end;
00504 gcc_assert (*p == 's');
00505 }
00506 else
00507 {
00508 gcc_assert (*p == '*');
00509 p++;
00510 gcc_assert (*p == 's');
00511 n = va_arg (*text->args_ptr, int);
00512
00513
00514 gcc_assert (formatters[argno] == formatters[argno+1]);
00515 argno++;
00516 }
00517
00518 s = va_arg (*text->args_ptr, const char *);
00519 pp_append_text (pp, s, s + n);
00520 }
00521 break;
00522
00523 default:
00524 {
00525 bool ok;
00526
00527 gcc_assert (pp_format_decoder (pp));
00528 ok = pp_format_decoder (pp) (pp, text, p,
00529 precision, wide, plus, hash);
00530 gcc_assert (ok);
00531 }
00532 }
00533
00534 if (quote)
00535 pp_string (pp, close_quote);
00536
00537 obstack_1grow (&buffer->chunk_obstack, '\0');
00538 *formatters[argno] = XOBFINISH (&buffer->chunk_obstack, const char *);
00539 }
00540
00541 #ifdef ENABLE_CHECKING
00542 for (; argno < PP_NL_ARGMAX; argno++)
00543 gcc_assert (!formatters[argno]);
00544 #endif
00545
00546
00547 buffer->obstack = &buffer->formatted_obstack;
00548 buffer->line_length = 0;
00549 pp_wrapping_mode (pp) = old_wrapping_mode;
00550 pp_clear_state (pp);
00551 }
00552
00553
00554 void
00555 pp_base_output_formatted_text (pretty_printer *pp)
00556 {
00557 unsigned int chunk;
00558 output_buffer *buffer = pp_buffer (pp);
00559 struct chunk_info *chunk_array = buffer->cur_chunk_array;
00560 const char **args = chunk_array->args;
00561
00562 gcc_assert (buffer->obstack == &buffer->formatted_obstack);
00563 gcc_assert (buffer->line_length == 0);
00564
00565
00566
00567 for (chunk = 0; args[chunk]; chunk++)
00568 pp_string (pp, args[chunk]);
00569
00570
00571
00572 buffer->cur_chunk_array = chunk_array->prev;
00573 obstack_free (&buffer->chunk_obstack, chunk_array);
00574 }
00575
00576
00577
00578 void
00579 pp_base_format_verbatim (pretty_printer *pp, text_info *text)
00580 {
00581
00582 pp_wrapping_mode_t oldmode = pp_set_verbatim_wrapping (pp);
00583
00584
00585 pp_format (pp, text);
00586 pp_output_formatted_text (pp);
00587
00588
00589 pp_wrapping_mode (pp) = oldmode;
00590 }
00591
00592
00593 void
00594 pp_base_flush (pretty_printer *pp)
00595 {
00596 pp_write_text_to_stream (pp);
00597 pp_clear_state (pp);
00598 fputc ('\n', pp->buffer->stream);
00599 fflush (pp->buffer->stream);
00600 pp_needs_newline (pp) = false;
00601 }
00602
00603
00604
00605
00606 void
00607 pp_base_set_line_maximum_length (pretty_printer *pp, int length)
00608 {
00609 pp_line_cutoff (pp) = length;
00610 pp_set_real_maximum_length (pp);
00611 }
00612
00613
00614 void
00615 pp_base_clear_output_area (pretty_printer *pp)
00616 {
00617 obstack_free (pp->buffer->obstack, obstack_base (pp->buffer->obstack));
00618 pp->buffer->line_length = 0;
00619 }
00620
00621
00622 void
00623 pp_base_set_prefix (pretty_printer *pp, const char *prefix)
00624 {
00625 pp->prefix = prefix;
00626 pp_set_real_maximum_length (pp);
00627 pp->emitted_prefix = false;
00628 pp_indentation (pp) = 0;
00629 }
00630
00631
00632 void
00633 pp_base_destroy_prefix (pretty_printer *pp)
00634 {
00635 if (pp->prefix != NULL)
00636 {
00637 free ((char *) pp->prefix);
00638 pp->prefix = NULL;
00639 }
00640 }
00641
00642
00643 void
00644 pp_base_emit_prefix (pretty_printer *pp)
00645 {
00646 if (pp->prefix != NULL)
00647 {
00648 switch (pp_prefixing_rule (pp))
00649 {
00650 default:
00651 case DIAGNOSTICS_SHOW_PREFIX_NEVER:
00652 break;
00653
00654 case DIAGNOSTICS_SHOW_PREFIX_ONCE:
00655 if (pp->emitted_prefix)
00656 {
00657 pp_base_indent (pp);
00658 break;
00659 }
00660 pp_indentation (pp) += 3;
00661
00662
00663 case DIAGNOSTICS_SHOW_PREFIX_EVERY_LINE:
00664 {
00665 int prefix_length = strlen (pp->prefix);
00666 pp_append_r (pp, pp->prefix, prefix_length);
00667 pp->emitted_prefix = true;
00668 }
00669 break;
00670 }
00671 }
00672 }
00673
00674
00675
00676 void
00677 pp_construct (pretty_printer *pp, const char *prefix, int maximum_length)
00678 {
00679 memset (pp, 0, sizeof (pretty_printer));
00680 pp->buffer = XCNEW (output_buffer);
00681 obstack_init (&pp->buffer->chunk_obstack);
00682 obstack_init (&pp->buffer->formatted_obstack);
00683 pp->buffer->obstack = &pp->buffer->formatted_obstack;
00684 pp->buffer->stream = stderr;
00685 pp_line_cutoff (pp) = maximum_length;
00686 pp_prefixing_rule (pp) = DIAGNOSTICS_SHOW_PREFIX_ONCE;
00687 pp_set_prefix (pp, prefix);
00688 }
00689
00690
00691
00692
00693
00694
00695 void
00696 pp_base_append_text (pretty_printer *pp, const char *start, const char *end)
00697 {
00698
00699 if (pp->buffer->line_length == 0)
00700 {
00701 pp_emit_prefix (pp);
00702 if (pp_is_wrapping_line (pp))
00703 while (start != end && *start == ' ')
00704 ++start;
00705 }
00706 pp_append_r (pp, start, end - start);
00707 }
00708
00709
00710
00711 const char *
00712 pp_base_formatted_text (pretty_printer *pp)
00713 {
00714 obstack_1grow (pp->buffer->obstack, '\0');
00715 return pp_formatted_text_data (pp);
00716 }
00717
00718
00719
00720 const char *
00721 pp_base_last_position_in_text (const pretty_printer *pp)
00722 {
00723 const char *p = NULL;
00724 struct obstack *text = pp->buffer->obstack;
00725
00726 if (obstack_base (text) != obstack_next_free (text))
00727 p = ((const char *) obstack_next_free (text)) - 1;
00728 return p;
00729 }
00730
00731
00732
00733 int
00734 pp_base_remaining_character_count_for_line (pretty_printer *pp)
00735 {
00736 return pp->maximum_length - pp->buffer->line_length;
00737 }
00738
00739
00740
00741 void
00742 pp_printf (pretty_printer *pp, const char *msg, ...)
00743 {
00744 text_info text;
00745 va_list ap;
00746
00747 va_start (ap, msg);
00748 text.err_no = errno;
00749 text.args_ptr = ≈
00750 text.format_spec = msg;
00751 text.locus = NULL;
00752 pp_format (pp, &text);
00753 pp_output_formatted_text (pp);
00754 va_end (ap);
00755 }
00756
00757
00758
00759 void
00760 pp_verbatim (pretty_printer *pp, const char *msg, ...)
00761 {
00762 text_info text;
00763 va_list ap;
00764
00765 va_start (ap, msg);
00766 text.err_no = errno;
00767 text.args_ptr = ≈
00768 text.format_spec = msg;
00769 text.locus = NULL;
00770 pp_format_verbatim (pp, &text);
00771 va_end (ap);
00772 }
00773
00774
00775
00776
00777 void
00778 pp_base_newline (pretty_printer *pp)
00779 {
00780 obstack_1grow (pp->buffer->obstack, '\n');
00781 pp->buffer->line_length = 0;
00782 }
00783
00784
00785 void
00786 pp_base_character (pretty_printer *pp, int c)
00787 {
00788 if (pp_is_wrapping_line (pp)
00789 && pp_remaining_character_count_for_line (pp) <= 0)
00790 {
00791 pp_newline (pp);
00792 if (ISSPACE (c))
00793 return;
00794 }
00795 obstack_1grow (pp->buffer->obstack, c);
00796 ++pp->buffer->line_length;
00797 }
00798
00799
00800
00801 void
00802 pp_base_string (pretty_printer *pp, const char *str)
00803 {
00804 pp_maybe_wrap_text (pp, str, str + (str ? strlen (str) : 0));
00805 }
00806
00807
00808
00809 void
00810 pp_base_maybe_space (pretty_printer *pp)
00811 {
00812 if (pp_base (pp)->padding != pp_none)
00813 {
00814 pp_space (pp);
00815 pp_base (pp)->padding = pp_none;
00816 }
00817 }