X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fmi%2Fmi-out.c;h=3761a5c0e54e1efaa739b1d873269a074275209e;hb=112e8700a6fd2fed65ca70132c9cbed4132e8bd4;hp=612cdf8c94d3406e0a037f930f4fe77b649d44f9;hpb=b6ba6518e9254bc25f88088228e93ac966ebccd1;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/mi/mi-out.c b/gdb/mi/mi-out.c index 612cdf8c94..3761a5c0e5 100644 --- a/gdb/mi/mi-out.c +++ b/gdb/mi/mi-out.c @@ -1,12 +1,14 @@ /* MI Command Set - output generating routines. - Copyright 2000 Free Software Foundation, Inc. + + Copyright (C) 2000-2016 Free Software Foundation, Inc. + Contributed by Cygnus Solutions (a Red Hat company). This file is part of GDB. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -15,353 +17,307 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ + along with this program. If not, see . */ #include "defs.h" #include "ui-out.h" #include "mi-out.h" +#include -/* Convenience macro for allocting typesafe memory. */ - -#ifndef XMALLOC -#define XMALLOC(TYPE) (TYPE*) xmalloc (sizeof (TYPE)) -#endif - -struct ui_out_data - { - int supress_field_separator; - int first_header; - struct ui_file *buffer; - }; - -/* These are the MI output functions */ - -static void mi_table_begin (struct ui_out *uiout, int nbrofcols, 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, char *colhdr); -static void mi_list_begin (struct ui_out *uiout, int list_flag, char *lstid); -static void mi_list_end (struct ui_out *uiout, int list_flag); -static void mi_field_int (struct ui_out *uiout, int fldno, int width, - enum ui_align alig, char *fldname, int value); -static void mi_field_skip (struct ui_out *uiout, int fldno, int width, - enum ui_align alig, char *fldname); -static void mi_field_string (struct ui_out *uiout, int fldno, int width, - enum ui_align alig, char *fldname, - const char *string); -static void mi_field_fmt (struct ui_out *uiout, int fldno, - int width, enum ui_align align, - char *fldname, char *format, va_list args); -static void mi_spaces (struct ui_out *uiout, int numspaces); -static void mi_text (struct ui_out *uiout, char *string); -static void mi_message (struct ui_out *uiout, int verbosity, char *format, - va_list args); -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_list_begin, - mi_list_end, - mi_field_int, - mi_field_skip, - mi_field_string, - mi_field_fmt, - mi_spaces, - mi_text, - mi_message, - mi_wrap_hint, - mi_flush -}; - -/* Prototypes for local functions */ - -extern void _initialize_mi_out (void); -static void field_separator (struct ui_out *uiout); -static void list_open (struct ui_out *uiout); -static void list_close (struct ui_out *uiout); - -static void out_field_fmt (struct ui_out *uiout, int fldno, char *fldname, - char *format,...); - -/* Mark beginning of a table */ +/* Mark beginning of a table. */ void -mi_table_begin (struct ui_out *uiout, int nbrofcols, char *tblid) +mi_ui_out::do_table_begin (int nr_cols, int nr_rows, + const char *tblid) { - struct ui_out_data *data = ui_out_data (uiout); - field_separator (uiout); - if (tblid) - fprintf_unfiltered (data->buffer, "%s=", tblid); - list_open (uiout); - data->first_header = 0; - data->supress_field_separator = 1; + open (tblid, ui_out_type_tuple); + do_field_int (-1, -1, ui_left, "nr_rows", nr_rows); + do_field_int (-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 () { - struct ui_out_data *data = ui_out_data (uiout); /* close the table header line if there were any headers */ - if (data->first_header) - list_close (uiout); + 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 () { - struct ui_out_data *data = ui_out_data (uiout); - list_close (uiout); - /* If table was empty this flag did not get reset yet */ - data->supress_field_separator = 0; + 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, int alignment, char *colhdr) +mi_ui_out::do_table_header (int width, ui_align alignment, + const std::string &col_name, + const std::string &col_hdr) { - struct ui_out_data *data = ui_out_data (uiout); - if (!data->first_header++) - { - fputs_unfiltered ("hdr=", data->buffer); - list_open (uiout); - } - mi_field_string (uiout, 0, width, alignment, 0, colhdr); + open (NULL, ui_out_type_tuple); + do_field_int (0, 0, ui_center, "width", width); + do_field_int (0, 0, ui_center, "alignment", alignment); + do_field_string (0, 0, ui_center, "col_name", col_name.c_str ()); + do_field_string (0, width, alignment, "colhdr", col_hdr.c_str ()); + close (ui_out_type_tuple); } -/* Mark beginning of a list */ +/* Mark beginning of a list. */ void -mi_list_begin (struct ui_out *uiout, int list_flag, char *lstid) +mi_ui_out::do_begin (ui_out_type type, const char *id) { - struct ui_out_data *data = ui_out_data (uiout); - field_separator (uiout); - data->supress_field_separator = 1; - if (lstid) - fprintf_unfiltered (data->buffer, "%s=", lstid); - list_open (uiout); + open (id, type); } -/* Mark end of a list */ +/* Mark end of a list. */ void -mi_list_end (struct ui_out *uiout, int list_flag) +mi_ui_out::do_end (ui_out_type type) { - struct ui_out_data *data = ui_out_data (uiout); - list_close (uiout); - /* If list was empty this flag did not get reset yet */ - data->supress_field_separator = 0; + close (type); } -/* output an int field */ +/* Output an int field. */ void -mi_field_int (struct ui_out *uiout, int fldno, int width, int alignment, - char *fldname, int value) +mi_ui_out::do_field_int (int fldno, int width, ui_align alignment, + const char *fldname, int value) { - char buffer[20]; /* FIXME: how many chars long a %d can become? */ + char buffer[20]; /* FIXME: how many chars long a %d can become? */ - sprintf (buffer, "%d", value); - mi_field_string (uiout, fldno, width, alignment, fldname, buffer); + xsnprintf (buffer, sizeof (buffer), "%d", value); + do_field_string (fldno, width, alignment, fldname, buffer); } -/* used to ommit a field */ +/* Used to omit a field. */ void -mi_field_skip (struct ui_out *uiout, int fldno, int width, int alignment, - char *fldname) +mi_ui_out::do_field_skip (int fldno, int width, ui_align alignment, + const char *fldname) { - 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, - int align, - char *fldname, - const char *string) +mi_ui_out::do_field_string (int fldno, int width, ui_align align, + const char *fldname, const char *string) { - struct ui_out_data *data = ui_out_data (uiout); - 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 */ +/* 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, - char *fldname, char *format, va_list args) +mi_ui_out::do_field_fmt (int fldno, int width, ui_align align, + const char *fldname, const char *format, + va_list args) { - struct ui_out_data *data = ui_out_data (uiout); - 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, char *string) +mi_ui_out::do_text (const char *string) { } void -mi_message (struct ui_out *uiout, int verbosity, char *format, va_list args) +mi_ui_out::do_message (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 () { - struct ui_out_data *data = ui_out_data (uiout); - gdb_flush (data->buffer); + + gdb_flush (m_streams.back ()); } -/* local functions */ +int +mi_ui_out::do_redirect (ui_file *outstream) +{ + if (outstream != NULL) + m_streams.push_back (outstream); + else + m_streams.pop_back (); -/* Like mi_field_fmt, but takes a variable number of args - and makes a va_list and does not insert a separator */ + return 0; +} -/* VARARGS */ -static void -out_field_fmt (struct ui_out *uiout, int fldno, char *fldname, - char *format,...) +void +mi_ui_out::field_separator () { - struct ui_out_data *data = ui_out_data (uiout); - va_list args; - - field_separator (uiout); - if (fldname) - fprintf_unfiltered (data->buffer, "%s=\"", fldname); + if (m_suppress_field_separator) + m_suppress_field_separator = false; else - fputs_unfiltered ("\"", data->buffer); + fputc_unfiltered (',', m_streams.back ()); +} + +void +mi_ui_out::open (const char *name, ui_out_type type) +{ + ui_file *stream = m_streams.back (); - va_start (args, format); - vfprintf_unfiltered (data->buffer, format, args); + field_separator (); + m_suppress_field_separator = true; - fputs_unfiltered ("\"", data->buffer); + if (name) + fprintf_unfiltered (stream, "%s=", name); - va_end (args); -} + switch (type) + { + case ui_out_type_tuple: + fputc_unfiltered ('{', stream); + break; -/* access to ui_out format private members */ + case ui_out_type_list: + fputc_unfiltered ('[', stream); + break; -static void -field_separator (struct ui_out *uiout) -{ - struct ui_out_data *data = ui_out_data (uiout); - if (data->supress_field_separator) - data->supress_field_separator = 0; - else - fputc_unfiltered (',', data->buffer); + default: + internal_error (__FILE__, __LINE__, _("bad switch")); + } } -static void -list_open (struct ui_out *uiout) +void +mi_ui_out::close (ui_out_type type) { - struct ui_out_data *data = ui_out_data (uiout); - fputc_unfiltered ('{', data->buffer); + ui_file *stream = m_streams.back (); + + switch (type) + { + case ui_out_type_tuple: + fputc_unfiltered ('}', stream); + break; + + case ui_out_type_list: + fputc_unfiltered (']', stream); + break; + + default: + internal_error (__FILE__, __LINE__, _("bad switch")); + } + + m_suppress_field_separator = false; } -static void -list_close (struct ui_out *uiout) +/* Clear the buffer. */ + +void +mi_ui_out::rewind () { - struct ui_out_data *data = ui_out_data (uiout); - fputc_unfiltered ('}', data->buffer); + ui_file_rewind (m_streams.back ()); } -/* add a string to the buffer */ +/* Dump the buffer onto the specified stream. */ void -mi_out_buffered (struct ui_out *uiout, char *string) +mi_ui_out::put (ui_file *stream) { - struct ui_out_data *data = ui_out_data (uiout); - fprintf_unfiltered (data->buffer, "%s", string); + ui_file *outstream = m_streams.back (); + + ui_file_put (outstream, ui_file_write_for_put, stream); + ui_file_rewind (outstream); } -/* clear the buffer */ +/* Return the current MI version. */ -void -mi_out_rewind (struct ui_out *uiout) +int +mi_ui_out::version () { - struct ui_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_file *stream) +: m_suppress_field_separator (false), + m_suppress_output (false), + m_mi_version (mi_version) { - ui_file_write (data, buffer, length_buffer); + gdb_assert (stream != NULL); + + m_streams.push_back (stream); } -void -mi_out_put (struct ui_out *uiout, - struct ui_file *stream) +mi_ui_out::~mi_ui_out () { - struct ui_out_data *data = ui_out_data (uiout); - ui_file_put (data->buffer, do_write, stream); - ui_file_rewind (data->buffer); } -/* initalize private members at startup */ +/* Initialize private members at startup. */ + +mi_ui_out * +mi_out_new (int mi_version) +{ + ui_file *stream = mem_fileopen (); -struct ui_out * -mi_out_new (void) + return new mi_ui_out (mi_version, stream); +} + +/* 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. */ + +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; - struct ui_out_data *data = XMALLOC (struct ui_out_data); - data->supress_field_separator = 0; - /* 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 (); }