/* Various declarations for language-independent pretty-print subroutines.
- Copyright (C) 2003-2013 Free Software Foundation, Inc.
+ Copyright (C) 2003-2016 Free Software Foundation, Inc.
Contributed by Gabriel Dos Reis <gdr@integrable-solutions.net>
This file is part of GCC.
#include "pretty-print.h"
#include "diagnostic-color.h"
-#include <new> // For placement-new.
-
#if HAVE_ICONV
#include <iconv.h>
#endif
+/* Overwrite the given location/range within this text_info's rich_location.
+ For use e.g. when implementing "+" in client format decoders. */
+
+void
+text_info::set_location (unsigned int idx, location_t loc, bool show_caret_p)
+{
+ gcc_checking_assert (m_richloc);
+ m_richloc->set_range (line_table, idx, loc, show_caret_p);
+}
+
+location_t
+text_info::get_location (unsigned int index_of_location) const
+{
+ gcc_checking_assert (m_richloc);
+
+ if (index_of_location == 0)
+ return m_richloc->get_loc ();
+ else
+ return UNKNOWN_LOCATION;
+}
+
// Default construct an output buffer.
output_buffer::output_buffer ()
cur_chunk_array (),
stream (stderr),
line_length (),
- digit_buffer ()
+ digit_buffer (),
+ flush_p (true)
{
obstack_init (&formatted_obstack);
obstack_init (&chunk_obstack);
}
-/* A pointer to the formatted diagnostic message. */
-#define pp_formatted_text_data(PP) \
- ((const char *) obstack_base ((PP)->buffer->obstack))
+// Release resources owned by an output buffer at the end of lifetime.
+
+output_buffer::~output_buffer ()
+{
+ obstack_free (&chunk_obstack, NULL);
+ obstack_free (&formatted_obstack, NULL);
+}
+
/* Format an integer given by va_arg (ARG, type-specifier T) where
type-specifier is a precision modifier as indicated by PREC. F is
pp_write_text_to_stream (pretty_printer *pp)
{
const char *text = pp_formatted_text (pp);
- fputs (text, pp->buffer->stream);
+ fputs (text, pp_buffer (pp)->stream);
pp_clear_output_area (pp);
}
{
const char *text = pp_formatted_text (pp);
const char *p = text;
- FILE *fp = pp->buffer->stream;
+ FILE *fp = pp_buffer (pp)->stream;
while (*p)
{
static inline void
pp_append_r (pretty_printer *pp, const char *start, int length)
{
- obstack_grow (pp->buffer->obstack, start, length);
- pp->buffer->line_length += length;
+ output_buffer_append_r (pp_buffer (pp), start, length);
}
/* Insert enough spaces into the output area of PRETTY-PRINTER to bring
A format string can have at most 30 arguments. */
/* Formatting phases 1 and 2: render TEXT->format_spec plus
- TEXT->args_ptr into a series of chunks in PP->buffer->args[].
+ TEXT->args_ptr into a series of chunks in pp_buffer (PP)->args[].
Phase 3 is in pp_format_text. */
void
pp_format (pretty_printer *pp, text_info *text)
{
- output_buffer *buffer = pp->buffer;
+ output_buffer *buffer = pp_buffer (pp);
const char *p;
const char **args;
struct chunk_info *new_chunk_array;
args = new_chunk_array->args;
/* Formatting phase 1: split up TEXT->format_spec into chunks in
- PP->buffer->args[]. Even-numbered chunks are to be output
+ pp_buffer (PP)->args[]. Even-numbered chunks are to be output
verbatim, odd-numbered chunks are format specifiers.
%m, %%, %<, %>, and %' are replaced with the appropriate text at
this point. */
*formatters[argno] = XOBFINISH (&buffer->chunk_obstack, const char *);
}
-#ifdef ENABLE_CHECKING
- for (; argno < PP_NL_ARGMAX; argno++)
- gcc_assert (!formatters[argno]);
-#endif
+ if (CHECKING_P)
+ for (; argno < PP_NL_ARGMAX; argno++)
+ gcc_assert (!formatters[argno]);
/* Revert to normal obstack and wrapping mode. */
buffer->obstack = &buffer->formatted_obstack;
pp_wrapping_mode (pp) = oldmode;
}
-/* Flush the content of BUFFER onto the attached stream. */
+/* Flush the content of BUFFER onto the attached stream. This
+ function does nothing unless pp->output_buffer->flush_p. */
void
pp_flush (pretty_printer *pp)
{
+ pp_clear_state (pp);
+ if (!pp->buffer->flush_p)
+ return;
pp_write_text_to_stream (pp);
+ fflush (pp_buffer (pp)->stream);
+}
+
+/* Flush the content of BUFFER onto the attached stream independently
+ of the value of pp->output_buffer->flush_p. */
+void
+pp_really_flush (pretty_printer *pp)
+{
pp_clear_state (pp);
- fflush (pp->buffer->stream);
+ pp_write_text_to_stream (pp);
+ fflush (pp_buffer (pp)->stream);
}
/* Sets the number of maximum characters per line PRETTY-PRINTER can
void
pp_clear_output_area (pretty_printer *pp)
{
- obstack_free (pp->buffer->obstack, obstack_base (pp->buffer->obstack));
- pp->buffer->line_length = 0;
+ obstack_free (pp_buffer (pp)->obstack,
+ obstack_base (pp_buffer (pp)->obstack));
+ pp_buffer (pp)->line_length = 0;
}
/* Set PREFIX for PRETTY-PRINTER. */
format_decoder (),
emitted_prefix (),
need_newline (),
- translate_identifiers(true),
+ translate_identifiers (true),
show_color ()
{
pp_line_cutoff (this) = l;
pp_set_prefix (this, p);
}
+pretty_printer::~pretty_printer ()
+{
+ buffer->~output_buffer ();
+ XDELETE (buffer);
+}
+
/* Append a string delimited by START and END to the output area of
PRETTY-PRINTER. No line wrapping is done. However, if beginning a
new line then emit PRETTY-PRINTER's prefix and skip any leading
pp_append_text (pretty_printer *pp, const char *start, const char *end)
{
/* Emit prefix and skip whitespace if we're starting a new line. */
- if (pp->buffer->line_length == 0)
+ if (pp_buffer (pp)->line_length == 0)
{
pp_emit_prefix (pp);
if (pp_is_wrapping_line (pp))
const char *
pp_formatted_text (pretty_printer *pp)
{
- obstack_1grow (pp->buffer->obstack, '\0');
- return pp_formatted_text_data (pp);
+ return output_buffer_formatted_text (pp_buffer (pp));
}
/* Return a pointer to the last character emitted in PRETTY-PRINTER's
const char *
pp_last_position_in_text (const pretty_printer *pp)
{
- const char *p = NULL;
- struct obstack *text = pp->buffer->obstack;
-
- if (obstack_base (text) != obstack_next_free (text))
- p = ((const char *) obstack_next_free (text)) - 1;
- return p;
+ return output_buffer_last_position_in_text (pp_buffer (pp));
}
/* Return the amount of characters PRETTY-PRINTER can accept to
int
pp_remaining_character_count_for_line (pretty_printer *pp)
{
- return pp->maximum_length - pp->buffer->line_length;
+ return pp->maximum_length - pp_buffer (pp)->line_length;
}
text.err_no = errno;
text.args_ptr = ≈
text.format_spec = msg;
- text.locus = NULL;
pp_format (pp, &text);
pp_output_formatted_text (pp);
va_end (ap);
text.err_no = errno;
text.args_ptr = ≈
text.format_spec = msg;
- text.locus = NULL;
pp_format_verbatim (pp, &text);
va_end (ap);
}
void
pp_newline (pretty_printer *pp)
{
- obstack_1grow (pp->buffer->obstack, '\n');
+ obstack_1grow (pp_buffer (pp)->obstack, '\n');
pp_needs_newline (pp) = false;
- pp->buffer->line_length = 0;
+ pp_buffer (pp)->line_length = 0;
}
/* Have PRETTY-PRINTER add a CHARACTER. */
if (ISSPACE (c))
return;
}
- obstack_1grow (pp->buffer->obstack, c);
- ++pp->buffer->line_length;
+ obstack_1grow (pp_buffer (pp)->obstack, c);
+ ++pp_buffer (pp)->line_length;
}
/* Append a STRING to the output area of PRETTY-PRINTER; the STRING may
void
pp_string (pretty_printer *pp, const char *str)
{
- pp_maybe_wrap_text (pp, str, str + (str ? strlen (str) : 0));
+ gcc_checking_assert (str);
+ pp_maybe_wrap_text (pp, str, str + strlen (str));
}
/* Maybe print out a whitespace if needed. */