X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fmi%2Fmi-out.c;h=050c05c7e0653a0684e8be8d853236b4451ad4d9;hb=cd9629e1df1a280c19e1daaf6c1195afbab0aca9;hp=94d00ef3f1a20ba24d4ec1f52639b9111e85d669;hpb=0fb0cc7590113e9b459dfcc48dc71c9d419d9580;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/mi/mi-out.c b/gdb/mi/mi-out.c index 94d00ef3f1..050c05c7e0 100644 --- a/gdb/mi/mi-out.c +++ b/gdb/mi/mi-out.c @@ -1,7 +1,6 @@ /* MI Command Set - output generating routines. - Copyright (C) 2000, 2002, 2003, 2004, 2005, 2007, 2008, 2009 - Free Software Foundation, Inc. + Copyright (C) 2000-2020 Free Software Foundation, Inc. Contributed by Cygnus Solutions (a Red Hat company). @@ -21,389 +20,332 @@ along with this program. If not, see . */ #include "defs.h" -#include "ui-out.h" #include "mi-out.h" -struct ui_out_data - { - int suppress_field_separator; - int suppress_output; - int mi_version; - struct ui_file *buffer; - }; -typedef struct ui_out_data mi_out_data; - -/* These are the MI output functions */ - -static void mi_table_begin (struct ui_out *uiout, int nbrofcols, - int nr_rows, const char *tblid); -static void mi_table_body (struct ui_out *uiout); -static void mi_table_end (struct ui_out *uiout); -static void mi_table_header (struct ui_out *uiout, int width, - enum ui_align alig, const char *col_name, - const char *colhdr); -static void mi_begin (struct ui_out *uiout, enum ui_out_type type, - int level, const char *id); -static void mi_end (struct ui_out *uiout, enum ui_out_type type, int level); -static void mi_field_int (struct ui_out *uiout, int fldno, int width, - enum ui_align alig, const char *fldname, int value); -static void mi_field_skip (struct ui_out *uiout, int fldno, int width, - enum ui_align alig, const char *fldname); -static void mi_field_string (struct ui_out *uiout, int fldno, int width, - enum ui_align alig, const char *fldname, - const char *string); -static void mi_field_fmt (struct ui_out *uiout, int fldno, - int width, enum ui_align align, - const char *fldname, const char *format, - va_list args) ATTR_FORMAT (printf, 6, 0); -static void mi_spaces (struct ui_out *uiout, int numspaces); -static void mi_text (struct ui_out *uiout, const char *string); -static void mi_message (struct ui_out *uiout, int verbosity, - const char *format, va_list args) - ATTR_FORMAT (printf, 3, 0); -static void mi_wrap_hint (struct ui_out *uiout, char *identstring); -static void mi_flush (struct ui_out *uiout); - -/* This is the MI ui-out implementation functions vector */ - -/* FIXME: This can be initialized dynamically after default is set to - handle initial output in main.c */ - -struct ui_out_impl mi_ui_out_impl = -{ - mi_table_begin, - mi_table_body, - mi_table_end, - mi_table_header, - mi_begin, - mi_end, - mi_field_int, - mi_field_skip, - mi_field_string, - mi_field_fmt, - mi_spaces, - mi_text, - mi_message, - mi_wrap_hint, - mi_flush, - NULL, - 1, /* Needs MI hacks. */ -}; - -/* Prototypes for local functions */ - -extern void _initialize_mi_out (void); -static void field_separator (struct ui_out *uiout); -static void mi_open (struct ui_out *uiout, const char *name, - enum ui_out_type type); -static void mi_close (struct ui_out *uiout, enum ui_out_type type); - -/* Mark beginning of a table */ +#include + +#include "interps.h" +#include "ui-out.h" +#include "utils.h" + +/* Mark beginning of a table. */ void -mi_table_begin (struct ui_out *uiout, - int nr_cols, - int nr_rows, - const char *tblid) +mi_ui_out::do_table_begin (int nr_cols, int nr_rows, + const char *tblid) { - mi_out_data *data = ui_out_data (uiout); - mi_open (uiout, tblid, ui_out_type_tuple); - mi_field_int (uiout, -1/*fldno*/, -1/*width*/, -1/*alin*/, - "nr_rows", nr_rows); - mi_field_int (uiout, -1/*fldno*/, -1/*width*/, -1/*alin*/, - "nr_cols", nr_cols); - mi_open (uiout, "hdr", ui_out_type_list); + open (tblid, ui_out_type_tuple); + do_field_signed (-1, -1, ui_left, "nr_rows", nr_rows); + do_field_signed (-1, -1, ui_left, "nr_cols", nr_cols); + open ("hdr", ui_out_type_list); } -/* Mark beginning of a table body */ +/* Mark beginning of a table body. */ void -mi_table_body (struct ui_out *uiout) +mi_ui_out::do_table_body () { - mi_out_data *data = ui_out_data (uiout); - if (data->suppress_output) - return; /* close the table header line if there were any headers */ - mi_close (uiout, ui_out_type_list); - mi_open (uiout, "body", ui_out_type_list); + close (ui_out_type_list); + open ("body", ui_out_type_list); } -/* Mark end of a table */ +/* Mark end of a table. */ void -mi_table_end (struct ui_out *uiout) +mi_ui_out::do_table_end () { - mi_out_data *data = ui_out_data (uiout); - data->suppress_output = 0; - mi_close (uiout, ui_out_type_list); /* body */ - mi_close (uiout, ui_out_type_tuple); + close (ui_out_type_list); /* body */ + close (ui_out_type_tuple); } -/* Specify table header */ +/* Specify table header. */ void -mi_table_header (struct ui_out *uiout, int width, enum ui_align alignment, - const char *col_name, - const char *colhdr) +mi_ui_out::do_table_header (int width, ui_align alignment, + const std::string &col_name, + const std::string &col_hdr) { - mi_out_data *data = ui_out_data (uiout); - if (data->suppress_output) - return; - mi_open (uiout, NULL, ui_out_type_tuple); - mi_field_int (uiout, 0, 0, 0, "width", width); - mi_field_int (uiout, 0, 0, 0, "alignment", alignment); - mi_field_string (uiout, 0, 0, 0, "col_name", col_name); - mi_field_string (uiout, 0, width, alignment, "colhdr", colhdr); - mi_close (uiout, ui_out_type_tuple); + open (NULL, ui_out_type_tuple); + do_field_signed (0, 0, ui_center, "width", width); + do_field_signed (0, 0, ui_center, "alignment", alignment); + do_field_string (0, 0, ui_center, "col_name", col_name.c_str (), + ui_file_style ()); + do_field_string (0, width, alignment, "colhdr", col_hdr.c_str (), + ui_file_style ()); + close (ui_out_type_tuple); } -/* Mark beginning of a list */ +/* Mark beginning of a list. */ void -mi_begin (struct ui_out *uiout, - enum ui_out_type type, - int level, - const char *id) +mi_ui_out::do_begin (ui_out_type type, const char *id) { - mi_out_data *data = ui_out_data (uiout); - if (data->suppress_output) - return; - mi_open (uiout, id, type); + open (id, type); } -/* Mark end of a list */ +/* Mark end of a list. */ void -mi_end (struct ui_out *uiout, - enum ui_out_type type, - int level) +mi_ui_out::do_end (ui_out_type type) { - mi_out_data *data = ui_out_data (uiout); - if (data->suppress_output) - return; - mi_close (uiout, type); + close (type); } -/* output an int field */ +/* Output an int field. */ void -mi_field_int (struct ui_out *uiout, int fldno, int width, - enum ui_align alignment, const char *fldname, int value) +mi_ui_out::do_field_signed (int fldno, int width, ui_align alignment, + const char *fldname, LONGEST value) { - char buffer[20]; /* FIXME: how many chars long a %d can become? */ - mi_out_data *data = ui_out_data (uiout); - if (data->suppress_output) - return; + do_field_string (fldno, width, alignment, fldname, plongest (value), + ui_file_style ()); +} + +/* Output an unsigned field. */ - sprintf (buffer, "%d", value); - mi_field_string (uiout, fldno, width, alignment, fldname, buffer); +void +mi_ui_out::do_field_unsigned (int fldno, int width, ui_align alignment, + const char *fldname, ULONGEST value) +{ + do_field_string (fldno, width, alignment, fldname, pulongest (value), + ui_file_style ()); } -/* used to ommit a field */ +/* Used to omit a field. */ void -mi_field_skip (struct ui_out *uiout, int fldno, int width, - enum ui_align alignment, const char *fldname) +mi_ui_out::do_field_skip (int fldno, int width, ui_align alignment, + const char *fldname) { - mi_out_data *data = ui_out_data (uiout); - if (data->suppress_output) - return; - mi_field_string (uiout, fldno, width, alignment, fldname, ""); } -/* other specific mi_field_* end up here so alignment and field - separators are both handled by mi_field_string */ +/* Other specific mi_field_* end up here so alignment and field + separators are both handled by mi_field_string. */ void -mi_field_string (struct ui_out *uiout, - int fldno, - int width, - enum ui_align align, - const char *fldname, - const char *string) +mi_ui_out::do_field_string (int fldno, int width, ui_align align, + const char *fldname, const char *string, + const ui_file_style &style) { - mi_out_data *data = ui_out_data (uiout); - if (data->suppress_output) - return; - field_separator (uiout); + ui_file *stream = m_streams.back (); + field_separator (); + if (fldname) - fprintf_unfiltered (data->buffer, "%s=", fldname); - fprintf_unfiltered (data->buffer, "\""); + fprintf_unfiltered (stream, "%s=", fldname); + fprintf_unfiltered (stream, "\""); if (string) - fputstr_unfiltered (string, '"', data->buffer); - fprintf_unfiltered (data->buffer, "\""); + fputstr_unfiltered (string, '"', stream); + fprintf_unfiltered (stream, "\""); } -/* This is the only field function that does not align */ - void -mi_field_fmt (struct ui_out *uiout, int fldno, - int width, enum ui_align align, - const char *fldname, - const char *format, - va_list args) +mi_ui_out::do_field_fmt (int fldno, int width, ui_align align, + const char *fldname, const ui_file_style &style, + const char *format, va_list args) { - mi_out_data *data = ui_out_data (uiout); - if (data->suppress_output) - return; - field_separator (uiout); + ui_file *stream = m_streams.back (); + field_separator (); + if (fldname) - fprintf_unfiltered (data->buffer, "%s=\"", fldname); + fprintf_unfiltered (stream, "%s=\"", fldname); else - fputs_unfiltered ("\"", data->buffer); - vfprintf_unfiltered (data->buffer, format, args); - fputs_unfiltered ("\"", data->buffer); + fputs_unfiltered ("\"", stream); + vfprintf_unfiltered (stream, format, args); + fputs_unfiltered ("\"", stream); } void -mi_spaces (struct ui_out *uiout, int numspaces) +mi_ui_out::do_spaces (int numspaces) { } void -mi_text (struct ui_out *uiout, const char *string) +mi_ui_out::do_text (const char *string) { } void -mi_message (struct ui_out *uiout, int verbosity, - const char *format, - va_list args) +mi_ui_out::do_message (const ui_file_style &style, + const char *format, va_list args) { } void -mi_wrap_hint (struct ui_out *uiout, char *identstring) +mi_ui_out::do_wrap_hint (const char *identstring) { wrap_here (identstring); } void -mi_flush (struct ui_out *uiout) +mi_ui_out::do_flush () { - mi_out_data *data = ui_out_data (uiout); - gdb_flush (data->buffer); -} -/* local functions */ + gdb_flush (m_streams.back ()); +} -/* access to ui_out format private members */ +void +mi_ui_out::do_redirect (ui_file *outstream) +{ + if (outstream != NULL) + m_streams.push_back (outstream); + else + m_streams.pop_back (); +} -static void -field_separator (struct ui_out *uiout) +void +mi_ui_out::field_separator () { - mi_out_data *data = ui_out_data (uiout); - if (data->suppress_field_separator) - data->suppress_field_separator = 0; + if (m_suppress_field_separator) + m_suppress_field_separator = false; else - fputc_unfiltered (',', data->buffer); + fputc_unfiltered (',', m_streams.back ()); } -static void -mi_open (struct ui_out *uiout, - const char *name, - enum ui_out_type type) +void +mi_ui_out::open (const char *name, ui_out_type type) { - mi_out_data *data = ui_out_data (uiout); - field_separator (uiout); - data->suppress_field_separator = 1; + ui_file *stream = m_streams.back (); + + field_separator (); + m_suppress_field_separator = true; + if (name) - fprintf_unfiltered (data->buffer, "%s=", name); + fprintf_unfiltered (stream, "%s=", name); + switch (type) { case ui_out_type_tuple: - fputc_unfiltered ('{', data->buffer); + fputc_unfiltered ('{', stream); break; + case ui_out_type_list: - fputc_unfiltered ('[', data->buffer); + fputc_unfiltered ('[', stream); break; + default: internal_error (__FILE__, __LINE__, _("bad switch")); } } -static void -mi_close (struct ui_out *uiout, - enum ui_out_type type) +void +mi_ui_out::close (ui_out_type type) { - mi_out_data *data = ui_out_data (uiout); + ui_file *stream = m_streams.back (); + switch (type) { case ui_out_type_tuple: - fputc_unfiltered ('}', data->buffer); + fputc_unfiltered ('}', stream); break; + case ui_out_type_list: - fputc_unfiltered (']', data->buffer); + fputc_unfiltered (']', stream); break; + default: internal_error (__FILE__, __LINE__, _("bad switch")); } - data->suppress_field_separator = 0; + + m_suppress_field_separator = false; } -/* add a string to the buffer */ +string_file * +mi_ui_out::main_stream () +{ + gdb_assert (m_streams.size () == 1); + + return (string_file *) m_streams.back (); +} + +/* Clear the buffer. */ void -mi_out_buffered (struct ui_out *uiout, char *string) +mi_ui_out::rewind () { - mi_out_data *data = ui_out_data (uiout); - fprintf_unfiltered (data->buffer, "%s", string); + main_stream ()->clear (); } -/* clear the buffer */ +/* Dump the buffer onto the specified stream. */ void -mi_out_rewind (struct ui_out *uiout) +mi_ui_out::put (ui_file *where) +{ + string_file *mi_stream = main_stream (); + + where->write (mi_stream->data (), mi_stream->size ()); + mi_stream->clear (); +} + +/* Return the current MI version. */ + +int +mi_ui_out::version () { - mi_out_data *data = ui_out_data (uiout); - ui_file_rewind (data->buffer); + return m_mi_version; } -/* dump the buffer onto the specified stream */ +/* Constructor for an `mi_out_data' object. */ -static void -do_write (void *data, const char *buffer, long length_buffer) +mi_ui_out::mi_ui_out (int mi_version) +: ui_out (mi_version >= 3 + ? fix_multi_location_breakpoint_output : (ui_out_flag) 0), + m_suppress_field_separator (false), + m_suppress_output (false), + m_mi_version (mi_version) { - ui_file_write (data, buffer, length_buffer); + string_file *stream = new string_file (); + m_streams.push_back (stream); } -void -mi_out_put (struct ui_out *uiout, - struct ui_file *stream) +mi_ui_out::~mi_ui_out () { - mi_out_data *data = ui_out_data (uiout); - ui_file_put (data->buffer, do_write, stream); - ui_file_rewind (data->buffer); } -/* Current MI version. */ +/* See mi/mi-out.h. */ -int -mi_version (struct ui_out *uiout) +mi_ui_out * +mi_out_new (const char *mi_version) { - mi_out_data *data = ui_out_data (uiout); - return data->mi_version; + if (streq (mi_version, INTERP_MI3) || streq (mi_version, INTERP_MI)) + return new mi_ui_out (3); + + if (streq (mi_version, INTERP_MI2)) + return new mi_ui_out (2); + + if (streq (mi_version, INTERP_MI1)) + return new mi_ui_out (1); + + return nullptr; } -/* initalize private members at startup */ +/* Helper function to return the given UIOUT as an mi_ui_out. It is an error + to call this function with an ui_out that is not an MI. */ -struct ui_out * -mi_out_new (int mi_version) +static mi_ui_out * +as_mi_ui_out (ui_out *uiout) +{ + mi_ui_out *mi_uiout = dynamic_cast (uiout); + + gdb_assert (mi_uiout != NULL); + + return mi_uiout; +} + +int +mi_version (ui_out *uiout) +{ + return as_mi_ui_out (uiout)->version (); +} + +void +mi_out_put (ui_out *uiout, struct ui_file *stream) { - int flags = 0; - mi_out_data *data = XMALLOC (mi_out_data); - data->suppress_field_separator = 0; - data->suppress_output = 0; - data->mi_version = mi_version; - /* FIXME: This code should be using a ``string_file'' and not the - TUI buffer hack. */ - data->buffer = mem_fileopen (); - return ui_out_new (&mi_ui_out_impl, data, flags); + return as_mi_ui_out (uiout)->put (stream); } -/* standard gdb initialization hook */ void -_initialize_mi_out (void) +mi_out_rewind (ui_out *uiout) { - /* nothing happens here */ + return as_mi_ui_out (uiout)->rewind (); }