From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 100346 invoked by alias); 24 Nov 2016 19:11:31 -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 99927 invoked by uid 89); 24 Nov 2016 19:11:30 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=1.5 required=5.0 tests=AWL,BAYES_50,SPF_SOFTFAIL autolearn=no version=3.3.2 spammy=Hx-spam-relays-external:sk:cable-1, H*RU:sk:cable-1, H*r:sk:cable-1, impl X-HELO: barracuda.ebox.ca Received: from barracuda.ebox.ca (HELO barracuda.ebox.ca) (96.127.255.19) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 24 Nov 2016 19:11:20 +0000 X-ASG-Debug-ID: 1480014677-0c856e65d4b8fd60001-fS2M51 Received: from smtp.electronicbox.net (smtp.electronicbox.net [96.127.255.82]) by barracuda.ebox.ca with ESMTP id Fi2Dr6ngY2bCjqf8 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Thu, 24 Nov 2016 14:11:17 -0500 (EST) X-Barracuda-Envelope-From: simon.marchi@polymtl.ca X-Barracuda-RBL-Trusted-Forwarder: 96.127.255.82 Received: from simark.lan (cable-11.246.173-162.electronicbox.net [173.246.11.162]) by smtp.electronicbox.net (Postfix) with ESMTP id 784A4440E7C; Thu, 24 Nov 2016 14:11:17 -0500 (EST) From: Simon Marchi X-Barracuda-Effective-Source-IP: cable-11.246.173-162.electronicbox.net[173.246.11.162] X-Barracuda-Apparent-Source-IP: 173.246.11.162 X-Barracuda-RBL-IP: 173.246.11.162 To: gdb-patches@sourceware.org Cc: Simon Marchi Subject: [PATCH 20/22] Class-ify ui_out_table Date: Thu, 24 Nov 2016 19:11:00 -0000 X-ASG-Orig-Subj: [PATCH 20/22] Class-ify ui_out_table Message-Id: <20161124191034.26931-20-simon.marchi@polymtl.ca> In-Reply-To: <20161124152428.24725-1-simon.marchi@polymtl.ca> References: <20161124152428.24725-1-simon.marchi@polymtl.ca> X-Barracuda-Connect: smtp.electronicbox.net[96.127.255.82] X-Barracuda-Start-Time: 1480014677 X-Barracuda-Encrypted: DHE-RSA-AES256-SHA X-Barracuda-URL: https://96.127.255.19:443/cgi-mod/mark.cgi X-Barracuda-Scan-Msg-Size: 16698 X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using global scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=8.0 tests=BSF_SC0_MISMATCH_TO X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.34711 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header X-IsSubscribed: yes X-SW-Source: 2016-11/txt/msg00783.txt.bz2 This patch makes a class out of the ui_out_table structure, the structure responsible for managing the generation of an UI table. To simplify the ui_out_table object, I changed it so that it can only be used for generating a single object. Instead of clearing the header list when starting a new table, we an ui_out_table when starting a table and delete it when we're done. Therefore, the checks: if (uiout->table->flag) if (!uiout->table->flag) are respectively replaced with if (uiout->table != nullptr) if (uiout->table == nullptr) Note: I removed the check at the beginning of ui_out_begin, because there is an equivalent check at the beginning of verify_field. gdb/ChangeLog: * ui-out.c (enum ui_out_table_state): Move to class ui_out_table. (struct ui_out_table): Change to ... (class ui_out_table): ... this. : Remove. : Rename to ... : ... this. : Rename to ... : ... this. : Rename to ... : ... this. : Rename to ... : ... this. : Rename to ... : ... this. : New methods. (struct ui_out) : Change type to unique_ptr to ui_out_table. (append_header_to_list, get_next_header, clear_header_list, clear_table): Remove. (ui_out_table_begin): Instantiate ui_out_table object. Update table check. (ui_out_table_body): Update table check, replace code with call to ui_out_table::start_body. (ui_out_table_end): Update table check, replace manual cleanup with assignment of uiout->table unique_ptr to nullptr. (ui_out_table_header): Update table check, replace call to append_header_to_list with call to append_header method. (ui_out_begin): Remove one table state check, update another. Replace code with call to start_row method. (verify_field): Update table checks. (ui_out_query_field): Update table check, replace code with call to query_field method. (ui_out_new): Remove table initialization code. --- gdb/ui-out.c | 313 +++++++++++++++++++++++++++++------------------------------ 1 file changed, 154 insertions(+), 159 deletions(-) diff --git a/gdb/ui-out.c b/gdb/ui-out.c index 78db2be..a943ec2 100644 --- a/gdb/ui-out.c +++ b/gdb/ui-out.c @@ -127,49 +127,154 @@ class ui_out_level int m_field_count; }; -/* States (steps) of a table generation. */ - -enum ui_out_table_state -{ - /* We are generating the table headers. */ - TABLE_STATE_HEADERS, - - /* We are generating the table body. */ - TABLE_STATE_BODY, -}; - /* Tables are special. Maintain a separate structure that tracks their state. At present an output can only contain a single table but that restriction might eventually be lifted. */ -struct ui_out_table +class ui_out_table { - /* If on, a table is being generated. */ - int flag; + public: + + /* States (steps) of a table generation. */ + + enum state + { + /* We are generating the table headers. */ + TABLE_STATE_HEADERS, + + /* We are generating the table body. */ + TABLE_STATE_BODY, + }; + + ui_out_table (int entry_level, int nr_cols, const std::string &id) + : m_state (TABLE_STATE_HEADERS), + m_entry_level (entry_level), + m_nr_cols (nr_cols), + m_id (id) + { + } + + /* Start building the body of the table. */ + + void start_body () + { + if (m_state != TABLE_STATE_HEADERS) + internal_error (__FILE__, __LINE__, + _("extra table_body call not allowed; there must be " + "only one table_body after a table_begin and before a " + "table_end.")); + + /* Check if the number of defined headers matches the number of expected + columns. */ + if (m_headers.size () != m_nr_cols) + internal_error (__FILE__, __LINE__, + _("number of headers differ from number of table " + "columns.")); + + m_state = TABLE_STATE_BODY; + m_headers_iterator = m_headers.begin (); + } + + /* Add a new header to the table. */ + + void append_header (int width, ui_align alignment, + const std::string &col_name, const std::string &col_hdr) + { + if (m_state != TABLE_STATE_HEADERS) + internal_error (__FILE__, __LINE__, + _("table header must be specified after table_begin and " + "before table_body.")); - ui_out_table_state state; + std::unique_ptr header (new ui_out_hdr (m_headers.size () + 1, + width, alignment, + col_name, col_hdr)); + + m_headers.push_back (std::move (header)); + } + + void start_row () + { + m_headers_iterator = m_headers.begin (); + } + + /* Extract the format information for the next header and advance + the header iterator. Return false if there was no next header. */ + + bool get_next_header (int *colno, int *width, ui_align *alignment, + const char **col_hdr) + { + /* There may be no headers at all or we may have used all columns. */ + if (m_headers_iterator == m_headers.end ()) + return false; + + ui_out_hdr *hdr = m_headers_iterator->get (); + + *colno = hdr->number (); + *width = hdr->min_width (); + *alignment = hdr->alignment (); + *col_hdr = hdr->header ().c_str (); + + /* Advance the header pointer to the next entry. */ + m_headers_iterator++; + + return true; + } + + bool query_field (int colno, int *width, int *alignment, + const char **col_name) + { + /* Column numbers are 1-based, so convert to 0-based index. */ + int index = colno - 1; + + if (index >= 0 && index < m_headers.size ()) + { + ui_out_hdr *hdr = m_headers[index].get (); + + gdb_assert (colno == hdr->number ()); + + *width = hdr->min_width (); + *alignment = hdr->alignment (); + *col_name = hdr->name ().c_str (); + + return true; + } + else + return false; + } + + state current_state () + { + return m_state; + } + + int entry_level () + { + return m_entry_level; + } + + private: + + state m_state; /* The level at which each entry of the table is to be found. A row (a tuple) is made up of entries. Consequently ENTRY_LEVEL is one above that of the table. */ - int entry_level; + int m_entry_level; /* Number of table columns (as specified in the table_begin call). */ - int columns; + int m_nr_cols; /* String identifying the table (as specified in the table_begin call). */ - std::string id; + std::string m_id; /* Pointers to the column headers. */ - std::vector> headers; + std::vector> m_headers; /* Iterator over the headers vector, used when printing successive fields. */ - std::vector>::const_iterator headers_iterator; - + std::vector>::const_iterator m_headers_iterator; }; - /* The ui_out structure */ struct ui_out @@ -187,7 +292,7 @@ struct ui_out } /* A table, if any. At present only a single table is supported. */ - struct ui_out_table table; + std::unique_ptr table; }; /* The current (inner most) level. */ @@ -258,14 +363,6 @@ static void uo_field_string (struct ui_out *uiout, int fldno, int width, /* Prototypes for local functions */ -static void append_header_to_list (struct ui_out *uiout, int width, - enum ui_align alignment, - const std::string &col_name, - const std::string &col_hdr); -static int get_next_header (struct ui_out *uiout, int *colno, int *width, - enum ui_align *alignment, const char **col_hdr); -static void clear_header_list (struct ui_out *uiout); -static void clear_table (struct ui_out *uiout); static void verify_field (struct ui_out *uiout, int *fldno, int *width, enum ui_align *align); @@ -274,44 +371,29 @@ static void verify_field (struct ui_out *uiout, int *fldno, int *width, /* Mark beginning of a table. */ static void -ui_out_table_begin (struct ui_out *uiout, int nbrofcols, +ui_out_table_begin (struct ui_out *uiout, int nr_cols, int nr_rows, const std::string &tblid) { - if (uiout->table.flag) + if (uiout->table != nullptr) internal_error (__FILE__, __LINE__, _("tables cannot be nested; table_begin found before \ previous table_end.")); - uiout->table.flag = 1; - uiout->table.state = ui_out_table_state::TABLE_STATE_HEADERS; - uiout->table.entry_level = uiout->level () + 1; - uiout->table.columns = nbrofcols; - uiout->table.id = tblid; - - clear_header_list (uiout); + uiout->table.reset ( + new ui_out_table (uiout->level () + 1, nr_cols, tblid)); - uo_table_begin (uiout, nbrofcols, nr_rows, uiout->table.id.c_str ()); + uo_table_begin (uiout, nr_cols, nr_rows, tblid.c_str ()); } void ui_out_table_body (struct ui_out *uiout) { - if (!uiout->table.flag) + if (uiout->table == nullptr) internal_error (__FILE__, __LINE__, _("table_body outside a table is not valid; it must be \ after a table_begin and before a table_end.")); - if (uiout->table.state == TABLE_STATE_BODY) - internal_error (__FILE__, __LINE__, - _("extra table_body call not allowed; there must be \ -only one table_body after a table_begin and before a table_end.")); - - if (uiout->table.headers.size () != uiout->table.columns) - internal_error (__FILE__, __LINE__, - _("number of headers differ from number of table \ -columns.")); - - uiout->table.state = TABLE_STATE_BODY; + uiout->table->start_body (); uo_table_body (uiout); } @@ -319,28 +401,25 @@ columns.")); static void ui_out_table_end (struct ui_out *uiout) { - if (!uiout->table.flag) + if (uiout->table == nullptr) internal_error (__FILE__, __LINE__, _("misplaced table_end or missing table_begin.")); - uiout->table.entry_level = 0; - uiout->table.state = TABLE_STATE_HEADERS; - uiout->table.flag = 0; - uo_table_end (uiout); - clear_table (uiout); + + uiout->table = nullptr; } void ui_out_table_header (struct ui_out *uiout, int width, enum ui_align alignment, const std::string &col_name, const std::string &col_hdr) { - if (!uiout->table.flag || uiout->table.state != TABLE_STATE_HEADERS) + if (uiout->table == nullptr) internal_error (__FILE__, __LINE__, - _("table header must be specified after table_begin \ -and before table_body.")); + _("table_header outside a table is not valid; it must be " + "after a table_begin and before a table_body.")); - append_header_to_list (uiout, width, alignment, col_name, col_hdr); + uiout->table->append_header (width, alignment, col_name, col_hdr); uo_table_header (uiout, width, alignment, col_name, col_hdr); } @@ -366,11 +445,6 @@ ui_out_begin (struct ui_out *uiout, enum ui_out_type type, const char *id) { - if (uiout->table.flag && uiout->table.state != TABLE_STATE_BODY) - internal_error (__FILE__, __LINE__, - _("table header or table_body expected; lists must be \ -specified after table_body.")); - /* Be careful to verify the ``field'' before the new tuple/list is pushed onto the stack. That way the containing list/table/row is verified and not the newly created tuple/list. This verification @@ -390,9 +464,10 @@ specified after table_body.")); /* If the push puts us at the same level as a table row entry, we've got a new table row. Put the header pointer back to the start. */ - if (uiout->table.state == TABLE_STATE_BODY - && uiout->table.entry_level == uiout->level ()) - uiout->table.headers_iterator = uiout->table.headers.begin (); + if (uiout->table != nullptr + && uiout->table->current_state () == ui_out_table::TABLE_STATE_BODY + && uiout->table->entry_level () == uiout->level ()) + uiout->table->start_row (); uo_begin (uiout, type, id); } @@ -639,15 +714,6 @@ uo_table_header (struct ui_out *uiout, int width, enum ui_align align, uiout->impl->table_header (width, align, col_name, col_hdr); } -/* Clear the table associated with UIOUT. */ - -static void -clear_table (struct ui_out *uiout) -{ - uiout->table.id.clear (); - clear_header_list (uiout); -} - void uo_begin (struct ui_out *uiout, enum ui_out_type type, @@ -735,59 +801,6 @@ uo_redirect (struct ui_out *uiout, struct ui_file *outstream) return uiout->impl->redirect (outstream); } -/* local functions */ - -/* List of column headers manipulation routines. */ - -static void -clear_header_list (struct ui_out *uiout) -{ - uiout->table.headers.clear (); - uiout->table.headers_iterator = uiout->table.headers.end (); -} - -static void -append_header_to_list (struct ui_out *uiout, - int width, - enum ui_align alignment, - const std::string &col_name, - const std::string &col_hdr) -{ - std::unique_ptr temphdr( - new ui_out_hdr (uiout->table.headers.size () + 1, width, - alignment, col_name, col_hdr)); - - uiout->table.headers.push_back (std::move (temphdr)); -} - -/* Extract the format information for the NEXT header and advance - the header pointer. Return 0 if there was no next header. */ - -static int -get_next_header (struct ui_out *uiout, - int *colno, - int *width, - enum ui_align *alignment, - const char **col_hdr) -{ - /* There may be no headers at all or we may have used all columns. */ - if (uiout->table.headers_iterator == uiout->table.headers.end ()) - return 0; - - ui_out_hdr *hdr = uiout->table.headers_iterator->get (); - - *colno = hdr->number (); - *width = hdr->min_width (); - *alignment = hdr->alignment (); - *col_hdr = hdr->header ().c_str (); - - /* Advance the header pointer to the next entry. */ - uiout->table.headers_iterator++; - - return 1; -} - - /* Verify that the field/tuple/list is correctly positioned. Return the field number and corresponding alignment (if available/applicable). */ @@ -799,7 +812,8 @@ verify_field (struct ui_out *uiout, int *fldno, int *width, ui_out_level *current = current_level (uiout); const char *text; - if (uiout->table.flag && uiout->table.state != TABLE_STATE_BODY) + if (uiout->table != nullptr + && uiout->table->current_state () != ui_out_table::TABLE_STATE_BODY) { internal_error (__FILE__, __LINE__, _("table_body missing; table fields must be \ @@ -813,9 +827,10 @@ specified after table_body and inside a list.")); current->inc_field_count (); - if (uiout->table.state == TABLE_STATE_BODY - && uiout->table.entry_level == uiout->level () - && get_next_header (uiout, fldno, width, align, &text)) + if (uiout->table != nullptr + && uiout->table->current_state () == ui_out_table::TABLE_STATE_BODY + && uiout->table->entry_level () == uiout->level () + && uiout->table->get_next_header (fldno, width, align, &text)) { if (*fldno != current->field_count ()) internal_error (__FILE__, __LINE__, @@ -834,26 +849,10 @@ int ui_out_query_field (struct ui_out *uiout, int colno, int *width, int *alignment, const char **col_name) { - if (!uiout->table.flag) + if (uiout->table == nullptr) return 0; - /* Column numbers are 1-based, so convert to 0-based index. */ - int index = colno - 1; - - if (index >= 0 && index < uiout->table.headers.size ()) - { - ui_out_hdr *hdr = uiout->table.headers[index].get (); - - gdb_assert (colno == hdr->number ()); - - *width = hdr->min_width (); - *alignment = hdr->alignment (); - *col_name = hdr->name ().c_str (); - - return 1; - } - else - return 0; + return uiout->table->query_field (colno, width, alignment, col_name); } /* Initialize private members at startup. */ @@ -865,14 +864,10 @@ ui_out_new (ui_out_impl_base *impl, int flags) uiout->impl.reset (impl); uiout->flags = flags; - uiout->table.flag = 0; - uiout->table.state = TABLE_STATE_HEADERS; /* Create uiout->level () 0, the default level. */ push_level (uiout, ui_out_type_tuple); - uiout->table.headers_iterator = uiout->table.headers.end (); - return uiout; } -- 2.10.0