From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 119399 invoked by alias); 26 Nov 2016 15:20:10 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Received: (qmail 119376 invoked by uid 89); 26 Nov 2016 15:20:09 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-4.9 required=5.0 tests=BAYES_00,RP_MATCHES_RCVD,SPF_HELO_PASS,SPF_PASS autolearn=ham version=3.3.2 spammy=gdb_assert, 2322, strchr, *stream X-HELO: smtp.polymtl.ca Received: from smtp.polymtl.ca (HELO smtp.polymtl.ca) (132.207.4.11) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Sat, 26 Nov 2016 15:19:59 +0000 Received: from nova.polymtl.ca (nova.polymtl.ca [132.207.4.47]) by smtp.polymtl.ca (8.14.3/8.14.3) with ESMTP id uAQFJu6C000622; Sat, 26 Nov 2016 10:19:56 -0500 From: simon.marchi@polymtl.ca To: gdb-patches@sourceware.org Cc: Simon Marchi Subject: [PATCH 19/22] Class-ify ui_out_impl Date: Sat, 26 Nov 2016 15:20:00 -0000 Message-Id: <1480173587-7053-19-git-send-email-simon.marchi@polymtl.ca> In-Reply-To: <20161124152428.24725-1-simon.marchi@polymtl.ca> References: <20161124152428.24725-1-simon.marchi@polymtl.ca> X-Poly-FromMTA: (nova.polymtl.ca [132.207.4.47]) at Sat, 26 Nov 2016 15:19:56 +0000 X-IsSubscribed: yes X-SW-Source: 2016-11/txt/msg00889.txt.bz2 From: Simon Marchi This patch makes the ui_out_impl implementations an actual class hierarchy, instead of an array of function pointers. gdb/ChangeLog: * ui-out.h (class ui_out_impl_base): New class, based on now removed struct ui_out_impl. (table_begin_ftype): Remove, replace with pure virtual method in class ui_out_impl_base. (table_body_ftype): Likewise. (table_end_ftype): Likewise. (table_header_ftype): Likewise. (ui_out_begin_ftype): Likewise. (ui_out_end_ftype): Likewise. (field_int_ftype): Likewise. (field_skip_ftype): Likewise. (field_string_ftype): Likewise. (field_fmt_ftype): Likewise. (spaces_ftype): Likewise. (text_ftype): Likewise. (message_ftype): Likewise. (wrap_hint_ftype): Likewise. (flush_ftype): Likewise. (redirect_ftype): Likewise. (data_destroy_ftype): Likewise. (struct ui_out_impl): Remove. (ui_out_data): Remove. (ui_out_new): Change type of parameter impl, remove parameter data, add default value to parameter flags. (ui_out_impl): New function. (uo_field_string): Move declaration to ui-out.c. * ui-out.c (struct ui_out) : Change type to unique_ptr to ui_out_impl_base. : Remove. (uo_field_string): Move declaration from ui-out.h. (ui_out_is_mi_like_p): Update to call virtual method. (uo_table_begin): Remove null check, update call to virtual method. (uo_table_body): Likewise. (uo_table_end): Likewise. (uo_table_header): Likewise. (uo_begin): Likewise. (uo_end): Likewise. (uo_field_int): Likewise. (uo_field_skip): Likewise. (uo_field_string): Likewise. (uo_field_fmt): Likewise. (uo_spaces): Likewise. (uo_text): Likewise. (uo_message): Likewise. (uo_wrap_hint): Likewise. (uo_flush): Likewise. (uo_redirect): Likewise. (ui_out_data): Remove. (ui_out_new): Change type of parameter impl, remove parameter data, add default value to parameter flags. Update assignment to unique_ptr (ui_out_impl): New function. * cli-out.h (cli_ui_out_data): Remove, replace with class cli_ui_out_impl. (class cli_ui_out_impl): New class. (cli_ui_out_impl): Remove global variable. (cli_out_data_ctor): Remove. * cli-out.c (cli_out_data): Remove. (cli_uiout_dtor): Remove. (cli_table_begin): Replace with ... (cli_ui_out_impl::table_begin): ... this new method. (cli_table_body): Replace with ... (cli_ui_out_impl::table_body): ... this new method. (cli_table_end): Replace with ... (cli_ui_out_impl::table_end): ... this new method. (cli_table_header): Replace with ... (cli_ui_out_impl::table_header): ... this new method. (cli_begin): Replace with ... (cli_ui_out_impl::begin): ... this new method. (cli_end): Replace with ... (cli_ui_out_impl::table_end): ... this new method. (cli_field_int): Replace with ... (cli_ui_out_impl::field_int): ... this new method. (cli_field_skip): Replace with ... (cli_ui_out_impl::field_skip): ... this new method. (cli_field_string): Replace with ... (cli_ui_out_impl::field_string): ... this new method. (cli_field_fmt): Replace with ... (cli_ui_out_impl::field_fmt): ... this new method. (cli_spaces): Replace with ... (cli_ui_out_impl::spaces): ... this new method. (cli_text): Replace with ... (cli_ui_out_impl::text): ... this new method. (cli_message): Replace with ... (cli_ui_out_impl::message): ... this new method. (cli_wrap_hint): Replace with ... (cli_ui_out_impl::wrap_hint): ... this new method. (cli_flush): Replace with ... (cli_ui_out_impl::flush): ... this new method. (cli_redirect): Replace with ... (cli_ui_out_impl::redirect): ... this new method. (out_field_fmt): Replace with ... (cli_ui_out_impl::out_field_fmt): ... this new method. (field_separator): Replace with ... (cli_ui_out_impl::field_separator): ... this new method. (cli_ui_out_impl): Remove. (cli_out_data_ctor): Remove. (cli_ui_out_impl::cli_ui_out_impl): New constructor. (cli_ui_out_impl::~cli_ui_out_impl): New destructor. (cli_out_new): Instantiate (cli_field_string): Likewise. (cli_redirect): Likewise. (cli_out_data_ctor): Likewise. * mi/mi-out.c (UNKNOWN): Likewise. (mi_field_skip): Likewise. (mi_field_string): Likewise. (mi_field_fmt): Likewise. (mi_out_put): Likewise. (mi_out_data_dtor): Likewise. (mi_ui_out_impl_from): New function. * mi/mi-out.h (UNKNOWN): Likewise. * tui/tui-out.c (UNKNOWN): Likewise. --- gdb/cli-out.c | 306 +++++++++++++++++-------------------------------- gdb/cli-out.h | 58 ++++++++-- gdb/mi/mi-out.c | 333 +++++++++++++++++++++--------------------------------- gdb/mi/mi-out.h | 69 ++++++++++- gdb/tui/tui-out.c | 158 +++++++++++--------------- gdb/ui-out.c | 95 +++++----------- gdb/ui-out.h | 125 +++++++------------- 7 files changed, 479 insertions(+), 665 deletions(-) diff --git a/gdb/cli-out.c b/gdb/cli-out.c index e042926..93ca5ed 100644 --- a/gdb/cli-out.c +++ b/gdb/cli-out.c @@ -27,163 +27,107 @@ #include "vec.h" #include "readline/readline.h" -typedef struct cli_ui_out_data cli_out_data; - -/* Prototypes for local functions */ - -static void cli_text (struct ui_out *uiout, const char *string); - -static void field_separator (void); - -static void out_field_fmt (struct ui_out *uiout, int fldno, - const char *fldname, - const char *format,...) ATTRIBUTE_PRINTF (4, 5); - -/* The destructor. */ - -static void -cli_uiout_dtor (struct ui_out *ui_out) -{ - cli_out_data *data = (cli_out_data *) ui_out_data (ui_out); - - delete data; -} - /* These are the CLI output functions */ /* Mark beginning of a table */ -static void -cli_table_begin (struct ui_out *uiout, int nbrofcols, - int nr_rows, - const char *tblid) +void +cli_ui_out_impl::table_begin (int nbrofcols, int nr_rows, const char *tblid) { - cli_out_data *data = (cli_out_data *) ui_out_data (uiout); - if (nr_rows == 0) - data->suppress_output = 1; + m_suppress_output = 1; else /* Only the table suppresses the output and, fortunately, a table is not a recursive data structure. */ - gdb_assert (data->suppress_output == 0); + gdb_assert (m_suppress_output == 0); } /* Mark beginning of a table body */ -static void -cli_table_body (struct ui_out *uiout) +void +cli_ui_out_impl::table_body () { - cli_out_data *data = (cli_out_data *) ui_out_data (uiout); - - if (data->suppress_output) + if (m_suppress_output) return; + /* first, close the table header line */ - cli_text (uiout, "\n"); + text ("\n"); } /* Mark end of a table */ -static void -cli_table_end (struct ui_out *uiout) +void +cli_ui_out_impl::table_end () { - cli_out_data *data = (cli_out_data *) ui_out_data (uiout); - - data->suppress_output = 0; + m_suppress_output = 0; } /* Specify table header */ -static void -cli_table_header (struct ui_out *uiout, int width, enum ui_align alignment, - const std::string &col_name, const std::string &col_hdr) +void +cli_ui_out_impl::table_header (int width, ui_align alignment, + const std::string &col_name, + const std::string &col_hdr) { - cli_out_data *data = (cli_out_data *) ui_out_data (uiout); - - if (data->suppress_output) + if (m_suppress_output) return; - /* Always go through the function pointer (virtual function call). - We may have been extended. */ - uo_field_string (uiout, 0, width, alignment, 0, col_hdr.c_str ()); + field_string (0, width, alignment, 0, col_hdr.c_str ()); } /* Mark beginning of a list */ -static void -cli_begin (struct ui_out *uiout, - enum ui_out_type type, - const char *id) +void +cli_ui_out_impl::begin (ui_out_type type, const char *id) { - cli_out_data *data = (cli_out_data *) ui_out_data (uiout); - - if (data->suppress_output) - return; } /* Mark end of a list */ -static void -cli_end (struct ui_out *uiout, - enum ui_out_type type) +void +cli_ui_out_impl::end (ui_out_type type) { - cli_out_data *data = (cli_out_data *) ui_out_data (uiout); - - if (data->suppress_output) - return; } /* output an int field */ -static void -cli_field_int (struct ui_out *uiout, int fldno, int width, - enum ui_align alignment, - const char *fldname, int value) +void +cli_ui_out_impl::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? */ - cli_out_data *data = (cli_out_data *) ui_out_data (uiout); - if (data->suppress_output) + if (m_suppress_output) return; + xsnprintf (buffer, sizeof (buffer), "%d", value); - /* Always go through the function pointer (virtual function call). - We may have been extended. */ - uo_field_string (uiout, fldno, width, alignment, fldname, buffer); + field_string (fldno, width, alignment, fldname, buffer); } -/* used to ommit a field */ +/* used to omit a field */ -static void -cli_field_skip (struct ui_out *uiout, int fldno, int width, - enum ui_align alignment, - const char *fldname) +void +cli_ui_out_impl::field_skip (int fldno, int width, ui_align alignment, + const char *fldname) { - cli_out_data *data = (cli_out_data *) ui_out_data (uiout); - - if (data->suppress_output) + if (m_suppress_output) return; - /* Always go through the function pointer (virtual function call). - We may have been extended. */ - uo_field_string (uiout, fldno, width, alignment, fldname, ""); + field_string (fldno, width, alignment, fldname, ""); } /* other specific cli_field_* end up here so alignment and field separators are both handled by cli_field_string */ -static void -cli_field_string (struct ui_out *uiout, - int fldno, - int width, - enum ui_align align, - const char *fldname, - const char *string) +void +cli_ui_out_impl::field_string (int fldno, int width, ui_align align, + const char *fldname, const char *string) { int before = 0; int after = 0; - cli_out_data *data = (cli_out_data *) ui_out_data (uiout); - if (data->suppress_output) + if (m_suppress_output) return; if ((align != ui_noalign) && string) @@ -210,11 +154,13 @@ cli_field_string (struct ui_out *uiout, } if (before) - ui_out_spaces (uiout, before); + spaces (before); + if (string) - out_field_fmt (uiout, fldno, fldname, "%s", string); + out_field_fmt (fldno, fldname, "%s", string); + if (after) - ui_out_spaces (uiout, after); + spaces (after); if (align != ui_noalign) field_separator (); @@ -222,96 +168,73 @@ cli_field_string (struct ui_out *uiout, /* This is the only field function that does not align. */ -static void ATTRIBUTE_PRINTF (6, 0) -cli_field_fmt (struct ui_out *uiout, int fldno, - int width, enum ui_align align, - const char *fldname, - const char *format, - va_list args) +void +cli_ui_out_impl::field_fmt (int fldno, int width, ui_align align, + const char *fldname, const char *format, + va_list args) { - cli_out_data *data = (cli_out_data *) ui_out_data (uiout); - struct ui_file *stream; - - if (data->suppress_output) + if (m_suppress_output) return; - stream = data->streams.back (); - vfprintf_filtered (stream, format, args); + vfprintf_filtered (m_streams.back (), format, args); if (align != ui_noalign) field_separator (); } -static void -cli_spaces (struct ui_out *uiout, int numspaces) +void +cli_ui_out_impl::spaces (int numspaces) { - cli_out_data *data = (cli_out_data *) ui_out_data (uiout); - struct ui_file *stream; - - if (data->suppress_output) + if (m_suppress_output) return; - stream = data->streams.back (); - print_spaces_filtered (numspaces, stream); + print_spaces_filtered (numspaces, m_streams.back ()); } -static void -cli_text (struct ui_out *uiout, const char *string) +void +cli_ui_out_impl::text (const char *string) { - cli_out_data *data = (cli_out_data *) ui_out_data (uiout); - struct ui_file *stream; - - if (data->suppress_output) + if (m_suppress_output) return; - stream = data->streams.back (); - fputs_filtered (string, stream); + fputs_filtered (string, m_streams.back ()); } -static void ATTRIBUTE_PRINTF (2, 0) -cli_message (struct ui_out *uiout, const char *format, va_list args) +void +cli_ui_out_impl::message (const char *format, va_list args) { - cli_out_data *data = (cli_out_data *) ui_out_data (uiout); - - if (data->suppress_output) + if (m_suppress_output) return; - struct ui_file *stream = data->streams.back (); - vfprintf_unfiltered (stream, format, args); + vfprintf_unfiltered (m_streams.back (), format, args); } -static void -cli_wrap_hint (struct ui_out *uiout, const char *identstring) +void +cli_ui_out_impl::wrap_hint (const char *identstring) { - cli_out_data *data = (cli_out_data *) ui_out_data (uiout); - - if (data->suppress_output) + if (m_suppress_output) return; + wrap_here (identstring); } -static void -cli_flush (struct ui_out *uiout) +void +cli_ui_out_impl::flush () { - cli_out_data *data = (cli_out_data *) ui_out_data (uiout); - struct ui_file *stream = data->streams.back (); - - gdb_flush (stream); + gdb_flush (m_streams.back ()); } /* OUTSTREAM as non-NULL will push OUTSTREAM on the stack of output streams and make it therefore active. OUTSTREAM as NULL will pop the last pushed output stream; it is an internal error if it does not exist. */ -static int -cli_redirect (struct ui_out *uiout, struct ui_file *outstream) +int +cli_ui_out_impl::redirect (ui_file *outstream) { - cli_out_data *data = (cli_out_data *) ui_out_data (uiout); - if (outstream != NULL) - data->streams.push_back (outstream); + m_streams.push_back (outstream); else - data->streams.pop_back (); + m_streams.pop_back (); return 0; } @@ -322,66 +245,38 @@ cli_redirect (struct ui_out *uiout, struct ui_file *outstream) and makes a va_list and does not insert a separator. */ /* VARARGS */ -static void -out_field_fmt (struct ui_out *uiout, int fldno, - const char *fldname, - const char *format,...) +void +cli_ui_out_impl::out_field_fmt (int fldno, const char *fldname, + const char *format, ...) { - cli_out_data *data = (cli_out_data *) ui_out_data (uiout); - struct ui_file *stream = data->streams.back (); va_list args; va_start (args, format); - vfprintf_filtered (stream, format, args); + vfprintf_filtered (m_streams.back (), format, args); va_end (args); } /* Access to ui_out format private members. */ -static void -field_separator (void) +void +cli_ui_out_impl::field_separator (void) { - cli_out_data *data = (cli_out_data *) ui_out_data (current_uiout); - struct ui_file *stream = data->streams.back (); - - fputc_filtered (' ', stream); + fputc_filtered (' ', m_streams.back ()); } -/* This is the CLI ui-out implementation functions vector */ +/* Constructor for cli_ui_out_impl. */ -const struct ui_out_impl cli_ui_out_impl = -{ - cli_table_begin, - cli_table_body, - cli_table_end, - cli_table_header, - cli_begin, - cli_end, - cli_field_int, - cli_field_skip, - cli_field_string, - cli_field_fmt, - cli_spaces, - cli_text, - cli_message, - cli_wrap_hint, - cli_flush, - cli_redirect, - cli_uiout_dtor, - 0, /* Does not need MI hacks (i.e. needs CLI hacks). */ -}; - -/* Constructor for a `cli_out_data' object. */ - -void -cli_out_data_ctor (cli_out_data *self, struct ui_file *stream) +cli_ui_out_impl::cli_ui_out_impl (ui_file *stream) +: m_suppress_output (0) { gdb_assert (stream != NULL); - self->streams.push_back (stream); + m_streams.push_back (stream); +} - self->suppress_output = 0; +cli_ui_out_impl::~cli_ui_out_impl () +{ } /* Initialize private members at startup. */ @@ -389,26 +284,33 @@ cli_out_data_ctor (cli_out_data *self, struct ui_file *stream) struct ui_out * cli_out_new (struct ui_file *stream) { - int flags = ui_source_list; - cli_out_data *data = new cli_out_data (); + cli_ui_out_impl *impl = new cli_ui_out_impl (stream); - cli_out_data_ctor (data, stream); - return ui_out_new (&cli_ui_out_impl, data, flags); + return ui_out_new (impl, ui_source_list); } -struct ui_file * -cli_out_set_stream (struct ui_out *uiout, struct ui_file *stream) +ui_file * +cli_ui_out_impl::set_stream (struct ui_file *stream) { - cli_out_data *data = (cli_out_data *) ui_out_data (uiout); - struct ui_file *old; + ui_file *old; - old = data->streams.back (); - data->streams.pop_back (); - data->streams.push_back (stream); + old = m_streams.back (); + m_streams.pop_back (); + m_streams.push_back (stream); return old; } +ui_file * +cli_out_set_stream (struct ui_out *uiout, ui_file *stream) +{ + cli_ui_out_impl *impl = dynamic_cast (ui_out_impl (uiout)); + + gdb_assert (impl != NULL); + + return impl->set_stream (stream); +} + /* CLI interface to display tab-completion matches. */ /* CLI version of displayer.crlf. */ diff --git a/gdb/cli-out.h b/gdb/cli-out.h index 296b8c0..aacb8c5 100644 --- a/gdb/cli-out.h +++ b/gdb/cli-out.h @@ -23,22 +23,58 @@ #include "ui-out.h" #include -/* These are exported so that they can be extended by other `ui_out' - implementations, like TUI's. */ +class cli_ui_out_impl : public ui_out_impl_base +{ +public: -struct cli_ui_out_data - { - std::vector streams; - int suppress_output; - }; + cli_ui_out_impl (ui_file *stream); + virtual ~cli_ui_out_impl (); -extern const struct ui_out_impl cli_ui_out_impl; + virtual void table_begin (int nbrofcols, int nr_rows, + const char *tblid) override; + virtual void table_body () override; + virtual void table_end () override; + virtual void table_header (int width, ui_align align, + const std::string &col_name, + const std::string &col_hdr) override; + /* Note: level 0 is the top-level so LEVEL is always greater than + zero. */ + virtual void begin (ui_out_type type, const char *id) override; + virtual void end (ui_out_type type) override; + virtual void field_int (int fldno, int width, ui_align align, + const char *fldname, int value) override; + virtual void field_skip (int fldno, int width, ui_align align, + const char *fldname) override; + virtual void field_string (int fldno, int width, ui_align align, + const char *fldname, const char *string) override; + virtual void ATTRIBUTE_PRINTF(6,0) field_fmt (int fldno, int width, + ui_align align, + const char *fldname, + const char *format, + va_list args) override; + virtual void spaces (int numspaces) override; + virtual void text (const char *string) override; + virtual void ATTRIBUTE_PRINTF(2,0) + message (const char *format, va_list args) override; + virtual void wrap_hint (const char *identstring) override; + virtual void flush () override; + virtual int redirect (struct ui_file * outstream) override; + ui_file *set_stream (ui_file *stream); -extern struct ui_out *cli_out_new (struct ui_file *stream); +protected: + + std::vector m_streams; + int m_suppress_output; + +private: + void field_separator (void); -extern void cli_out_data_ctor (struct cli_ui_out_data *data, - struct ui_file *stream); + void ATTRIBUTE_PRINTF(4, 5) + out_field_fmt (int fldno, const char *fldname, const char *format, ...); +}; + +extern struct ui_out *cli_out_new (struct ui_file *stream); extern struct ui_file *cli_out_set_stream (struct ui_out *uiout, struct ui_file *stream); diff --git a/gdb/mi/mi-out.c b/gdb/mi/mi-out.c index b7cd433..744b113 100644 --- a/gdb/mi/mi-out.c +++ b/gdb/mi/mi-out.c @@ -25,185 +25,100 @@ #include "vec.h" #include -struct mi_ui_out_data - { - int suppress_field_separator; - int suppress_output; - int mi_version; - std::vector streams; - }; -typedef struct mi_ui_out_data mi_out_data; - -/* These are the MI output functions */ - -static void mi_out_data_dtor (struct ui_out *ui_out); -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 alignment, - const std::string &col_name, - const std::string &col_hdr); -static void mi_begin (struct ui_out *uiout, enum ui_out_type type, - const char *id); -static void mi_end (struct ui_out *uiout, enum ui_out_type type); -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) ATTRIBUTE_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, const char *format, va_list args) - ATTRIBUTE_PRINTF (2, 0); -static void mi_wrap_hint (struct ui_out *uiout, const char *identstring); -static void mi_flush (struct ui_out *uiout); -static int mi_redirect (struct ui_out *uiout, struct ui_file *outstream); - -/* This is the MI ui-out implementation functions vector */ - -static const 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, - mi_redirect, - mi_out_data_dtor, - 1, /* Needs MI hacks. */ -}; - -/* Prototypes for local functions */ - -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. */ void -mi_table_begin (struct ui_out *uiout, - int nr_cols, - int nr_rows, - const char *tblid) +mi_ui_out_impl::table_begin (int nr_cols, int nr_rows, + const char *tblid) { - mi_open (uiout, tblid, ui_out_type_tuple); - mi_field_int (uiout, -1, -1, ui_left, "nr_rows", nr_rows); - mi_field_int (uiout, -1, -1, ui_left, "nr_cols", nr_cols); - mi_open (uiout, "hdr", ui_out_type_list); + open (tblid, ui_out_type_tuple); + field_int (-1, -1, ui_left, "nr_rows", nr_rows); + field_int (-1, -1, ui_left, "nr_cols", nr_cols); + open ("hdr", ui_out_type_list); } /* Mark beginning of a table body. */ void -mi_table_body (struct ui_out *uiout) +mi_ui_out_impl::table_body () { - mi_out_data *data = (mi_out_data *) ui_out_data (uiout); - - if (data->suppress_output) + if (m_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. */ void -mi_table_end (struct ui_out *uiout) +mi_ui_out_impl::table_end () { - mi_out_data *data = (mi_out_data *) ui_out_data (uiout); - - data->suppress_output = 0; - mi_close (uiout, ui_out_type_list); /* body */ - mi_close (uiout, ui_out_type_tuple); + m_suppress_output = 0; + close (ui_out_type_list); /* body */ + close (ui_out_type_tuple); } /* Specify table header. */ void -mi_table_header (struct ui_out *uiout, int width, enum ui_align alignment, - const std::string &col_name, const std::string &col_hdr) +mi_ui_out_impl::table_header (int width, ui_align alignment, + const std::string &col_name, + const std::string &col_hdr) { - mi_out_data *data = (mi_out_data *) ui_out_data (uiout); - - if (data->suppress_output) + if (m_suppress_output) return; - mi_open (uiout, NULL, ui_out_type_tuple); - mi_field_int (uiout, 0, 0, ui_center, "width", width); - mi_field_int (uiout, 0, 0, ui_center, "alignment", alignment); - mi_field_string (uiout, 0, 0, ui_center, "col_name", col_name.c_str ()); - mi_field_string (uiout, 0, width, alignment, "colhdr", col_hdr.c_str ()); - mi_close (uiout, ui_out_type_tuple); + open (NULL, ui_out_type_tuple); + field_int (0, 0, ui_center, "width", width); + field_int (0, 0, ui_center, "alignment", alignment); + field_string (0, 0, ui_center, "col_name", col_name.c_str ()); + field_string (0, width, alignment, "colhdr", col_hdr.c_str ()); + close (ui_out_type_tuple); } /* Mark beginning of a list. */ void -mi_begin (struct ui_out *uiout, enum ui_out_type type, const char *id) +mi_ui_out_impl::begin (ui_out_type type, const char *id) { - mi_out_data *data = (mi_out_data *) ui_out_data (uiout); - - if (data->suppress_output) + if (m_suppress_output) return; - mi_open (uiout, id, type); + open (id, type); } /* Mark end of a list. */ void -mi_end (struct ui_out *uiout, enum ui_out_type type) +mi_ui_out_impl::end (ui_out_type type) { - mi_out_data *data = (mi_out_data *) ui_out_data (uiout); - - if (data->suppress_output) + if (m_suppress_output) return; - mi_close (uiout, type); + close (type); } /* Output an int field. */ -static void -mi_field_int (struct ui_out *uiout, int fldno, int width, - enum ui_align alignment, const char *fldname, int value) +void +mi_ui_out_impl::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? */ - mi_out_data *data = (mi_out_data *) ui_out_data (uiout); - if (data->suppress_output) + if (m_suppress_output) return; xsnprintf (buffer, sizeof (buffer), "%d", value); - mi_field_string (uiout, fldno, width, alignment, fldname, buffer); + field_string (fldno, width, alignment, fldname, buffer); } /* 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_impl::field_skip (int fldno, int width, ui_align alignment, + const char *fldname) { } @@ -211,17 +126,15 @@ mi_field_skip (struct ui_out *uiout, int fldno, int width, 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_impl::field_string (int fldno, int width, ui_align align, + const char *fldname, const char *string) { - mi_out_data *data = (mi_out_data *) ui_out_data (uiout); - struct ui_file *stream; - - if (data->suppress_output) + if (m_suppress_output) return; - stream = data->streams.back (); - field_separator (uiout); + ui_file *stream = m_streams.back (); + field_separator (); + if (fldname) fprintf_unfiltered (stream, "%s=", fldname); fprintf_unfiltered (stream, "\""); @@ -233,18 +146,16 @@ mi_field_string (struct ui_out *uiout, int fldno, int width, /* 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_impl::field_fmt (int fldno, int width, ui_align align, + const char *fldname, const char *format, + va_list args) { - mi_out_data *data = (mi_out_data *) ui_out_data (uiout); - struct ui_file *stream; - - if (data->suppress_output) + if (m_suppress_output) return; - stream = data->streams.back (); - field_separator (uiout); + ui_file *stream = m_streams.back (); + field_separator (); + if (fldname) fprintf_unfiltered (stream, "%s=\"", fldname); else @@ -254,125 +165,115 @@ mi_field_fmt (struct ui_out *uiout, int fldno, int width, } void -mi_spaces (struct ui_out *uiout, int numspaces) +mi_ui_out_impl::spaces (int numspaces) { } void -mi_text (struct ui_out *uiout, const char *string) +mi_ui_out_impl::text (const char *string) { } void -mi_message (struct ui_out *uiout, const char *format, va_list args) +mi_ui_out_impl::message (const char *format, va_list args) { } void -mi_wrap_hint (struct ui_out *uiout, const char *identstring) +mi_ui_out_impl::wrap_hint (const char *identstring) { wrap_here (identstring); } void -mi_flush (struct ui_out *uiout) +mi_ui_out_impl::flush () { - mi_out_data *data = (mi_out_data *) ui_out_data (uiout); - struct ui_file *stream = data->streams.back (); - gdb_flush (stream); + gdb_flush (m_streams.back ()); } int -mi_redirect (struct ui_out *uiout, struct ui_file *outstream) +mi_ui_out_impl::redirect (ui_file *outstream) { - mi_out_data *data = (mi_out_data *) ui_out_data (uiout); - if (outstream != NULL) - data->streams.push_back (outstream); + m_streams.push_back (outstream); else - data->streams.pop_back (); + m_streams.pop_back (); return 0; } -/* local functions */ - -/* access to ui_out format private members */ - -static void -field_separator (struct ui_out *uiout) +void +mi_ui_out_impl::field_separator () { - mi_out_data *data = (mi_out_data *) ui_out_data (uiout); - ui_file *stream = data->streams.back (); - - if (data->suppress_field_separator) - data->suppress_field_separator = 0; + if (m_suppress_field_separator) + m_suppress_field_separator = 0; else - fputc_unfiltered (',', stream); + 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_impl::open (const char *name, ui_out_type type) { - mi_out_data *data = (mi_out_data *) ui_out_data (uiout); - ui_file *stream = data->streams.back (); + ui_file *stream = m_streams.back (); + + field_separator (); + m_suppress_field_separator = 1; - field_separator (uiout); - data->suppress_field_separator = 1; if (name) fprintf_unfiltered (stream, "%s=", name); + 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")); } } -static void -mi_close (struct ui_out *uiout, enum ui_out_type type) +void +mi_ui_out_impl::close (ui_out_type type) { - mi_out_data *data = (mi_out_data *) ui_out_data (uiout); - ui_file *stream = data->streams.back (); + 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")); } - data->suppress_field_separator = 0; + + m_suppress_field_separator = 0; } /* Clear the buffer. */ void -mi_out_rewind (struct ui_out *uiout) +mi_ui_out_impl::rewind () { - mi_out_data *data = (mi_out_data *) ui_out_data (uiout); - ui_file *stream = data->streams.back (); - - ui_file_rewind (stream); + ui_file_rewind (m_streams.back ()); } /* Dump the buffer onto the specified stream. */ void -mi_out_put (struct ui_out *uiout, struct ui_file *stream) +mi_ui_out_impl::put (ui_file *stream) { - mi_out_data *data = (mi_out_data *) ui_out_data (uiout); - ui_file *outstream = data->streams.back (); + ui_file *outstream = m_streams.back (); ui_file_put (outstream, ui_file_write_for_put, stream); ui_file_rewind (outstream); @@ -381,35 +282,25 @@ mi_out_put (struct ui_out *uiout, struct ui_file *stream) /* Return the current MI version. */ int -mi_version (struct ui_out *uiout) +mi_ui_out_impl::version () { - mi_out_data *data = (mi_out_data *) ui_out_data (uiout); - - return data->mi_version; + return m_mi_version; } /* Constructor for an `mi_out_data' object. */ -static void -mi_out_data_ctor (mi_out_data *self, int mi_version, struct ui_file *stream) +mi_ui_out_impl::mi_ui_out_impl (int mi_version, ui_file *stream) +: m_suppress_field_separator (0), + m_suppress_output (0), + m_mi_version (mi_version) { gdb_assert (stream != NULL); - self->streams.push_back (stream); - - self->suppress_field_separator = 0; - self->suppress_output = 0; - self->mi_version = mi_version; + m_streams.push_back (stream); } -/* The destructor. */ - -static void -mi_out_data_dtor (struct ui_out *ui_out) +mi_ui_out_impl::~mi_ui_out_impl () { - mi_out_data *data = (mi_out_data *) ui_out_data (ui_out); - - delete data; } /* Initialize private members at startup. */ @@ -417,10 +308,40 @@ mi_out_data_dtor (struct ui_out *ui_out) struct ui_out * mi_out_new (int mi_version) { - int flags = 0; - mi_out_data *data = new mi_out_data (); - struct ui_file *stream = mem_fileopen (); + ui_file *stream = mem_fileopen (); + mi_ui_out_impl *impl = new mi_ui_out_impl (mi_version, stream); + + return ui_out_new (impl); +} + +/* Helper to return the implementation behind UIOUT, casted to a + mi_ui_out_impl *. It is an error to call this function with an ui_out that + is not an MI. */ + +static mi_ui_out_impl * +mi_ui_out_impl_from (ui_out *uiout) +{ + mi_ui_out_impl *impl = dynamic_cast (ui_out_impl (uiout)); + + gdb_assert (impl != NULL); + + return impl; +} + +int +mi_version (ui_out *uiout) +{ + return mi_ui_out_impl_from (uiout)->version (); +} + +void +mi_out_put (ui_out *uiout, struct ui_file *stream) +{ + return mi_ui_out_impl_from (uiout)->put (stream); +} - mi_out_data_ctor (data, mi_version, stream); - return ui_out_new (&mi_ui_out_impl, data, flags); +void +mi_out_rewind (ui_out *uiout) +{ + return mi_ui_out_impl_from (uiout)->rewind (); } diff --git a/gdb/mi/mi-out.h b/gdb/mi/mi-out.h index ba18950..a45d2e3 100644 --- a/gdb/mi/mi-out.h +++ b/gdb/mi/mi-out.h @@ -20,14 +20,73 @@ #ifndef MI_OUT_H #define MI_OUT_H 1 +#include + struct ui_out; struct ui_file; -extern struct ui_out *mi_out_new (int mi_version); -extern void mi_out_put (struct ui_out *uiout, struct ui_file *stream); -extern void mi_out_rewind (struct ui_out *uiout); -/* Return the version number of the current MI. */ -extern int mi_version (struct ui_out *uiout); +class mi_ui_out_impl : public ui_out_impl_base +{ +public: + + mi_ui_out_impl (int mi_version, ui_file *stream); + virtual ~mi_ui_out_impl (); + + virtual void table_begin (int nbrofcols, int nr_rows, const char *tblid) + override; + virtual void table_body () override; + virtual void table_header (int width, ui_align align, + const std::string &col_name, + const std::string &col_hdr) override; + virtual void table_end () override; + + /* Note: level 0 is the top-level so LEVEL is always greater than + zero. */ + virtual void begin (ui_out_type type, const char *id) override; + virtual void end (ui_out_type type) override; + virtual void field_int (int fldno, int width, ui_align align, + const char *fldname, int value) override; + virtual void field_skip (int fldno, int width, ui_align align, + const char *fldname) override; + virtual void field_string (int fldno, int width, ui_align align, + const char *fldname, const char *string) override; + virtual void ATTRIBUTE_PRINTF(6,0) + field_fmt (int fldno, int width, ui_align align, const char *fldname, + const char *format, va_list args) override; + virtual void spaces (int numspaces) override; + virtual void text (const char *string) override; + virtual void ATTRIBUTE_PRINTF(2,0) message (const char *format, va_list args) + override; + virtual void wrap_hint (const char *identstring) override; + virtual void flush () override; + virtual int redirect (struct ui_file * outstream) override; + + virtual int is_mi_like_p () override + { return 1; } + + /* MI-specific */ + void rewind (); + void put (struct ui_file *stream); + /* Return the version number of the current MI. */ + int version (); + +private: + + void field_separator (); + void open (const char *name, ui_out_type type); + void close (ui_out_type type); + + int m_suppress_field_separator; + int m_suppress_output; + int m_mi_version; + std::vector m_streams; +}; + +ui_out *mi_out_new (int mi_version); +int mi_version (ui_out *uiout); +void mi_out_put (ui_out *uiout, struct ui_file *stream); +void mi_out_rewind (ui_out *uiout); + #endif /* MI_OUT_H */ diff --git a/gdb/tui/tui-out.c b/gdb/tui/tui-out.c index 4856562..70633f3 100644 --- a/gdb/tui/tui-out.c +++ b/gdb/tui/tui-out.c @@ -24,154 +24,122 @@ #include "ui-out.h" #include "cli-out.h" #include "tui.h" -struct tui_ui_out_data - { - struct cli_ui_out_data base; - int line; - int start_of_line; - }; -typedef struct tui_ui_out_data tui_out_data; +class tui_ui_out_impl : public cli_ui_out_impl +{ +public: + + tui_ui_out_impl (ui_file *stream); + + void field_int (int fldno, int width, ui_align align, const char *fldname, + int value) override; + void field_string (int fldno, int width, ui_align align, const char *fldname, + const char *string) override; + void ATTRIBUTE_PRINTF(6,0) + field_fmt (int fldno, int width, ui_align align, const char *fldname, + const char *format, va_list args) override; + void text (const char *string) override; -/* This is the TUI ui-out implementation functions vector. It is - initialized below in _initialize_tui_out, inheriting the CLI - version, and overriding a few methods. */ +private: -static struct ui_out_impl tui_ui_out_impl; + int m_line; + int m_start_of_line; +}; /* Output an int field. */ -static void -tui_field_int (struct ui_out *uiout, - int fldno, int width, - enum ui_align alignment, - const char *fldname, - int value) +void +tui_ui_out_impl::field_int (int fldno, int width, ui_align alignment, + const char *fldname, int value) { - tui_out_data *data = (tui_out_data *) ui_out_data (uiout); - - if (data->base.suppress_output) + if (m_suppress_output) return; /* Don't print line number, keep it for later. */ - if (data->start_of_line == 0 && strcmp (fldname, "line") == 0) + if (m_start_of_line == 0 && strcmp (fldname, "line") == 0) { - data->start_of_line ++; - data->line = value; + m_start_of_line++; + m_line = value; return; } - data->start_of_line ++; + m_start_of_line++; - (*cli_ui_out_impl.field_int) (uiout, fldno, - width, alignment, fldname, value); + cli_ui_out_impl::field_int (fldno, width, alignment, fldname, value); } /* Other cli_field_* end up here so alignment and field separators are both handled by tui_field_string. */ -static void -tui_field_string (struct ui_out *uiout, - int fldno, int width, - enum ui_align align, - const char *fldname, - const char *string) +void +tui_ui_out_impl::field_string (int fldno, int width, ui_align align, + const char *fldname, const char *string) { - tui_out_data *data = (tui_out_data *) ui_out_data (uiout); - - if (data->base.suppress_output) + if (m_suppress_output) return; - if (fldname && data->line > 0 && strcmp (fldname, "fullname") == 0) + if (fldname && m_line > 0 && strcmp (fldname, "fullname") == 0) { - data->start_of_line ++; - if (data->line > 0) + m_start_of_line++; + if (m_line > 0) { - tui_show_source (string, data->line); + tui_show_source (string, m_line); } return; } - data->start_of_line++; + m_start_of_line++; - (*cli_ui_out_impl.field_string) (uiout, fldno, - width, align, - fldname, string); + cli_ui_out_impl::field_string (fldno, width, align, fldname, string); } /* This is the only field function that does not align. */ -static void -tui_field_fmt (struct ui_out *uiout, int fldno, - int width, enum ui_align align, - const char *fldname, - const char *format, - va_list args) +void +tui_ui_out_impl::field_fmt (int fldno, int width, ui_align align, + const char *fldname, const char *format, + va_list args) { - tui_out_data *data = (tui_out_data *) ui_out_data (uiout); - - if (data->base.suppress_output) + if (m_suppress_output) return; - data->start_of_line++; + m_start_of_line++; - (*cli_ui_out_impl.field_fmt) (uiout, fldno, - width, align, - fldname, format, args); + cli_ui_out_impl::field_fmt (fldno, width, align, fldname, format, args); } -static void -tui_text (struct ui_out *uiout, const char *string) +void +tui_ui_out_impl::text (const char *string) { - tui_out_data *data = (tui_out_data *) ui_out_data (uiout); - - if (data->base.suppress_output) + if (m_suppress_output) return; - data->start_of_line ++; - if (data->line > 0) + + m_start_of_line++; + if (m_line > 0) { if (strchr (string, '\n') != 0) { - data->line = -1; - data->start_of_line = 0; + m_line = -1; + m_start_of_line = 0; } return; } if (strchr (string, '\n')) - data->start_of_line = 0; + m_start_of_line = 0; - (*cli_ui_out_impl.text) (uiout, string); + cli_ui_out_impl::text (string); } -struct ui_out * -tui_out_new (struct ui_file *stream) +tui_ui_out_impl::tui_ui_out_impl (ui_file *stream) +: cli_ui_out_impl (stream), + m_line (0), + m_start_of_line (-1) { - int flags = 0; - - tui_out_data *data = new tui_out_data (); - - /* Initialize base "class". */ - cli_out_data_ctor (&data->base, stream); - - /* Initialize our fields. */ - data->line = -1; - data->start_of_line = 0; - - return ui_out_new (&tui_ui_out_impl, data, flags); } -/* Standard gdb initialization hook. */ - -extern void _initialize_tui_out (void); - -void -_initialize_tui_out (void) +struct ui_out * +tui_out_new (struct ui_file *stream) { - /* Inherit the CLI version. */ - tui_ui_out_impl = cli_ui_out_impl; - - /* Override a few methods. */ - tui_ui_out_impl.field_int = tui_field_int; - tui_ui_out_impl.field_string = tui_field_string; - tui_ui_out_impl.field_fmt = tui_field_fmt; - tui_ui_out_impl.text = tui_text; + tui_ui_out_impl *impl = new tui_ui_out_impl (stream); + + return ui_out_new (impl, 0); } diff --git a/gdb/ui-out.c b/gdb/ui-out.c index 1717491..78db2be 100644 --- a/gdb/ui-out.c +++ b/gdb/ui-out.c @@ -28,6 +28,7 @@ #include #include #include +#include /* A header of a ui_out_table. */ @@ -175,8 +176,7 @@ struct ui_out { int flags; /* Specific implementation of ui-out. */ - const struct ui_out_impl *impl; - void *data; + std::unique_ptr impl; /* Vector to store and track the ui-out levels. */ std::vector> levels; @@ -251,6 +251,10 @@ static void uo_message (struct ui_out *uiout, static void uo_wrap_hint (struct ui_out *uiout, const char *identstring); static void uo_flush (struct ui_out *uiout); static int uo_redirect (struct ui_out *uiout, struct ui_file *outstream); +static void uo_field_string (struct ui_out *uiout, int fldno, int width, + enum ui_align align, const char *fldname, + const char *string); + /* Prototypes for local functions */ @@ -603,7 +607,7 @@ ui_out_test_flags (struct ui_out *uiout, int mask) int ui_out_is_mi_like_p (struct ui_out *uiout) { - return uiout->impl->is_mi_like_p; + return uiout->impl->is_mi_like_p (); } /* Interface to the implementation functions. */ @@ -613,34 +617,26 @@ uo_table_begin (struct ui_out *uiout, int nbrofcols, int nr_rows, const char *tblid) { - if (!uiout->impl->table_begin) - return; - uiout->impl->table_begin (uiout, nbrofcols, nr_rows, tblid); + uiout->impl->table_begin (nbrofcols, nr_rows, tblid); } void uo_table_body (struct ui_out *uiout) { - if (!uiout->impl->table_body) - return; - uiout->impl->table_body (uiout); + uiout->impl->table_body (); } void uo_table_end (struct ui_out *uiout) { - if (!uiout->impl->table_end) - return; - uiout->impl->table_end (uiout); + uiout->impl->table_end (); } void uo_table_header (struct ui_out *uiout, int width, enum ui_align align, const std::string &col_name, const std::string &col_hdr) { - if (!uiout->impl->table_header) - return; - uiout->impl->table_header (uiout, width, align, col_name, col_hdr); + uiout->impl->table_header (width, align, col_name, col_hdr); } /* Clear the table associated with UIOUT. */ @@ -657,18 +653,14 @@ uo_begin (struct ui_out *uiout, enum ui_out_type type, const char *id) { - if (uiout->impl->begin == NULL) - return; - uiout->impl->begin (uiout, type, id); + uiout->impl->begin (type, id); } void uo_end (struct ui_out *uiout, enum ui_out_type type) { - if (uiout->impl->end == NULL) - return; - uiout->impl->end (uiout, type); + uiout->impl->end (type); } void @@ -676,18 +668,14 @@ uo_field_int (struct ui_out *uiout, int fldno, int width, enum ui_align align, const char *fldname, int value) { - if (!uiout->impl->field_int) - return; - uiout->impl->field_int (uiout, fldno, width, align, fldname, value); + uiout->impl->field_int (fldno, width, align, fldname, value); } void uo_field_skip (struct ui_out *uiout, int fldno, int width, enum ui_align align, const char *fldname) { - if (!uiout->impl->field_skip) - return; - uiout->impl->field_skip (uiout, fldno, width, align, fldname); + uiout->impl->field_skip (fldno, width, align, fldname); } void @@ -696,9 +684,7 @@ uo_field_string (struct ui_out *uiout, int fldno, int width, const char *fldname, const char *string) { - if (!uiout->impl->field_string) - return; - uiout->impl->field_string (uiout, fldno, width, align, fldname, string); + uiout->impl->field_string (fldno, width, align, fldname, string); } void @@ -707,26 +693,20 @@ uo_field_fmt (struct ui_out *uiout, int fldno, int width, enum ui_align align, const char *format, va_list args) { - if (!uiout->impl->field_fmt) - return; - uiout->impl->field_fmt (uiout, fldno, width, align, fldname, format, args); + uiout->impl->field_fmt (fldno, width, align, fldname, format, args); } void uo_spaces (struct ui_out *uiout, int numspaces) { - if (!uiout->impl->spaces) - return; - uiout->impl->spaces (uiout, numspaces); + uiout->impl->spaces (numspaces); } void uo_text (struct ui_out *uiout, const char *string) { - if (!uiout->impl->text) - return; - uiout->impl->text (uiout, string); + uiout->impl->text (string); } void @@ -734,33 +714,25 @@ uo_message (struct ui_out *uiout, const char *format, va_list args) { - if (!uiout->impl->message) - return; - uiout->impl->message (uiout, format, args); + uiout->impl->message (format, args); } void uo_wrap_hint (struct ui_out *uiout, const char *identstring) { - if (!uiout->impl->wrap_hint) - return; - uiout->impl->wrap_hint (uiout, identstring); + uiout->impl->wrap_hint (identstring); } void uo_flush (struct ui_out *uiout) { - if (!uiout->impl->flush) - return; - uiout->impl->flush (uiout); + uiout->impl->flush (); } int uo_redirect (struct ui_out *uiout, struct ui_file *outstream) { - if (!uiout->impl->redirect) - return -1; - return uiout->impl->redirect (uiout, outstream); + return uiout->impl->redirect (outstream); } /* local functions */ @@ -857,15 +829,6 @@ specified after table_body and inside a list.")); } } - -/* Access to ui-out members data. */ - -void * -ui_out_data (struct ui_out *uiout) -{ - return uiout->data; -} - /* Access table field parameters. */ int ui_out_query_field (struct ui_out *uiout, int colno, @@ -896,13 +859,11 @@ ui_out_query_field (struct ui_out *uiout, int colno, /* Initialize private members at startup. */ struct ui_out * -ui_out_new (const struct ui_out_impl *impl, void *data, - int flags) +ui_out_new (ui_out_impl_base *impl, int flags) { struct ui_out *uiout = new ui_out (); - uiout->data = data; - uiout->impl = impl; + uiout->impl.reset (impl); uiout->flags = flags; uiout->table.flag = 0; uiout->table.state = TABLE_STATE_HEADERS; @@ -914,3 +875,9 @@ ui_out_new (const struct ui_out_impl *impl, void *data, return uiout; } + +ui_out_impl_base * +ui_out_impl (ui_out *uiout) +{ + return uiout->impl.get (); +} diff --git a/gdb/ui-out.h b/gdb/ui-out.h index 06c05e2..17c502e 100644 --- a/gdb/ui-out.h +++ b/gdb/ui-out.h @@ -140,91 +140,52 @@ extern int ui_out_query_field (struct ui_out *uiout, int colno, extern int ui_out_is_mi_like_p (struct ui_out *uiout); -/* From here on we have things that are only needed by implementation - routines and main.c. We should pehaps have a separate file for that, - like a ui-out-impl.h file. */ - -/* User Interface Output Implementation Function Table */ - -/* Type definition of all implementation functions. */ - -typedef void (table_begin_ftype) (struct ui_out * uiout, - int nbrofcols, int nr_rows, - const char *tblid); -typedef void (table_body_ftype) (struct ui_out * uiout); -typedef void (table_end_ftype) (struct ui_out * uiout); -typedef void (table_header_ftype) (struct ui_out * uiout, int width, - enum ui_align align, - const std::string &col_name, - const std::string &col_hdr); - -typedef void (ui_out_begin_ftype) (struct ui_out *uiout, - enum ui_out_type type, - const char *id); -typedef void (ui_out_end_ftype) (struct ui_out *uiout, - enum ui_out_type type); -typedef void (field_int_ftype) (struct ui_out * uiout, int fldno, int width, - enum ui_align align, - const char *fldname, int value); -typedef void (field_skip_ftype) (struct ui_out * uiout, int fldno, int width, - enum ui_align align, - const char *fldname); -typedef void (field_string_ftype) (struct ui_out * uiout, int fldno, int width, - enum ui_align align, - const char *fldname, - const char *string); -typedef void (field_fmt_ftype) (struct ui_out * uiout, int fldno, int width, - enum ui_align align, - const char *fldname, - const char *format, - va_list args) ATTRIBUTE_FPTR_PRINTF(6,0); -typedef void (spaces_ftype) (struct ui_out * uiout, int numspaces); -typedef void (text_ftype) (struct ui_out * uiout, - const char *string); -typedef void (message_ftype) (struct ui_out * uiout, - const char *format, va_list args) - ATTRIBUTE_FPTR_PRINTF(2,0); -typedef void (wrap_hint_ftype) (struct ui_out * uiout, const char *identstring); -typedef void (flush_ftype) (struct ui_out * uiout); -typedef int (redirect_ftype) (struct ui_out * uiout, - struct ui_file * outstream); -typedef void (data_destroy_ftype) (struct ui_out *uiout); - -/* ui-out-impl */ - -struct ui_out_impl - { - table_begin_ftype *table_begin; - table_body_ftype *table_body; - table_end_ftype *table_end; - table_header_ftype *table_header; - ui_out_begin_ftype *begin; - ui_out_end_ftype *end; - field_int_ftype *field_int; - field_skip_ftype *field_skip; - field_string_ftype *field_string; - field_fmt_ftype *field_fmt; - spaces_ftype *spaces; - text_ftype *text; - message_ftype *message; - wrap_hint_ftype *wrap_hint; - flush_ftype *flush; - redirect_ftype *redirect; - data_destroy_ftype *data_destroy; - int is_mi_like_p; - }; - -extern void *ui_out_data (struct ui_out *uiout); - -extern void uo_field_string (struct ui_out *uiout, int fldno, int width, - enum ui_align align, const char *fldname, - const char *string); +/* Base of all ui-out implementations. */ + +class ui_out_impl_base +{ + public: + + virtual ~ui_out_impl_base () {} + + virtual void table_begin (int nbrofcols, int nr_rows, const char *tblid) = 0; + virtual void table_body () = 0; + virtual void table_end () = 0; + virtual void table_header (int width, ui_align align, + const std::string &col_name, + const std::string &col_hdr) = 0; + + virtual void begin (ui_out_type type, const char *id) = 0; + virtual void end (ui_out_type type) = 0; + virtual void field_int (int fldno, int width, ui_align align, + const char *fldname, int value) = 0; + virtual void field_skip (int fldno, int width, ui_align align, + const char *fldname) = 0; + virtual void field_string (int fldno, int width, ui_align align, + const char *fldname, const char *string) = 0; + virtual void ATTRIBUTE_PRINTF(6,0) + field_fmt (int fldno, int width, ui_align align, const char *fldname, + const char *format, va_list args) = 0; + virtual void spaces (int numspaces) = 0; + virtual void text (const char *string) = 0; + virtual void ATTRIBUTE_PRINTF(2,0) + message (const char *format, va_list args) = 0; + virtual void wrap_hint (const char *identstring) = 0; + virtual void flush () = 0; + virtual int redirect (struct ui_file * outstream) = 0; + + /* Set as not MI-like by default. It is overridden in subclasses if + necessary. */ + + virtual int is_mi_like_p () + { return 0; } +}; + +ui_out_impl_base *ui_out_impl (ui_out *uiout); /* Create a ui_out object */ -extern struct ui_out *ui_out_new (const struct ui_out_impl *impl, - void *data, - int flags); +extern ui_out *ui_out_new (ui_out_impl_base *impl, int flags = 0); /* Redirect the ouptut of a ui_out object temporarily. */ -- 2.8.1