From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 28374 invoked by alias); 30 Nov 2016 21:48:28 -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 28347 invoked by uid 89); 30 Nov 2016 21:48:27 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.8 required=5.0 tests=AWL,BAYES_00 autolearn=ham version=3.3.2 spammy=UD:table.columns, UD:id, UD:columns, table.columns X-HELO: sesbmg23.ericsson.net Received: from sesbmg23.ericsson.net (HELO sesbmg23.ericsson.net) (193.180.251.37) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 30 Nov 2016 21:48:17 +0000 Received: from ESESSHC015.ericsson.se (Unknown_Domain [153.88.183.63]) by (Symantec Mail Security) with SMTP id 18.58.32482.9194F385; Wed, 30 Nov 2016 22:48:11 +0100 (CET) Received: from EUR01-DB5-obe.outbound.protection.outlook.com (153.88.183.145) by oa.msg.ericsson.com (153.88.183.63) with Microsoft SMTP Server (TLS) id 14.3.319.2; Wed, 30 Nov 2016 22:48:09 +0100 Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=simon.marchi@ericsson.com; Received: from elxcz23q12-y4.ca.am.ericsson.se (192.75.88.130) by AM3PR07MB388.eurprd07.prod.outlook.com (2a01:111:e400:8820::22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P384) id 15.1.761.5; Wed, 30 Nov 2016 21:48:07 +0000 From: Simon Marchi To: CC: Simon Marchi Subject: [PATCH v2] Class-ify ui_out_table Date: Wed, 30 Nov 2016 21:48:00 -0000 Message-ID: <20161130214750.20592-1-simon.marchi@ericsson.com> In-Reply-To: References: MIME-Version: 1.0 Content-Type: text/plain X-ClientProxiedBy: MWHPR09CA0010.namprd09.prod.outlook.com (2603:10b6:300:80::20) To AM3PR07MB388.eurprd07.prod.outlook.com (2a01:111:e400:8820::22) X-MS-Office365-Filtering-Correlation-Id: 9ab0f66d-d04d-4b84-74f4-08d4196a928f X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:(22001);SRVR:AM3PR07MB388; X-Microsoft-Exchange-Diagnostics: 1;AM3PR07MB388;3:fzJX5tSAoTfkc0+6x4l0/wZmf3sgKsXWFEHJOXoCEnBt35t58UfUw213/BmUyDME3UHIpc9/jado5Hjbc4klWfw16C/roAt/6JYyu+JKxkw8zRF3uPsHanDWUFc9brRIiNZXQ0QuOXkVG7Vxt1HiSjFoO+dcF17pShge5Zo7B6jWbcgyTTxcr00jmaaygQWw/nfXJLaBVAImtPGJbJmTJil78GlcQQ0Jmn90FSGIsJn5IXIWRqdvu2fj3GzXGdVM21v+jgCUge/XvSphySTUBQ== X-Microsoft-Exchange-Diagnostics: 1;AM3PR07MB388;25:LvEczMTd8PT9XqharHKsppk96QPFKV5GIK1kTELo93lncECppoGAxGe/4b1X2IYtNItMGtPso19YirKFsjyLtTyzOLYj7ozsEbRytTlnmRGJ+aaeawD+4a+Rb/pVMcrkjAao1tzMKF57Kmwjs+oG9k8nrb9ZULniR4emaR5Ns2y8y/G4oCs3a4lxJ8wADsLPEVK0FUG5AZNG3WqoUg9jTDjQRzKZqlbHphbafUvkEhMiLDCB5rM7Uxq0xD+FrdLgeKOrP7syhZZ7C1B6UYatEyvwVLt7KsJkbZ2Ujc/X6wKe1dhhQM5SblBHSaFKTxWrMJl4ZA9VjCM1BaZwjEx5qYxrM1Gw0hea6Rmo9pRkloOItLIwT1147EAucsl8r/ChGB/wOAvxn1xWXrCo5ThnUuBhiz34Ldhz527jd4z03T9VPjtqO2/xDunY0vg2Mgp2/XgYfY2qgsPg+Bkzs5a+HYJYjNp67sxFZ8AE7+RvI+O9WY8m1DINHYeW7xhHNf5dzGWEv1rU6hmoXUiOsBgdJPs5Ku9m1kXiBMNDDwssGu6ux7JJ+pJmcKeCYCkZFxBCno+IXJSj0acg3KUfI904VABAcz7OE/RI4iMb/Umf2nJTJKi5+1kyRjuukScdLVsFAolRNWxPR6spVrx3WbUitXSfi9WvRuk0VVDWrBnCSs5IwifzS0izz7RLf1jHMjsGXIj/TgQmCtT12x4B4ISupD/7aa4rH819KNbOb/MIOwgDv4Xc7U5YMt195SnaxGvQDxVikTF/XL/tJ7t1JtPdcA== X-Microsoft-Exchange-Diagnostics: 1;AM3PR07MB388;31:BOyEpNo+9eMPvRKjWj2jQ4cDWMjagZ68dhog2p7HUlcSG1BeZam/mdqN5VqhxcKkJEIx5n73n3N1lXlRKZ4/H7DF1t+wvybeviju1NnyXkYCGnzDKG/VtXhDrOdOVM/t0efQzGE998XcY0kbbH7Qprp2hfh+qM4lyYtoK9WOkVUwHAlCbtGduXQMXhAAmHHocUPjpBjc/tBRyQLC4K8fxe80cwaQvD35HVdPfiTjKA2/ixANvWBCIOo7eesI5nk6nDBK1g3jxEGwb7V4kI19TQ==;20:iRhUMTlDWs8lyX5Sa61+9ALz3gdjOxmJX1jjPSSnLAF1CeQsfiWb3/Do5i5TsRH2Y00CKrjrGgrEbXglTo1e7xz3Y4F26M6qYxhfSyDQ5IFH6uvSZ2sYaTJMNrVbaGs+LmY1YxOBT3P3YV9bu08vYfuBXhINBeSbx+TiIPevE1tim4OIhoN0cWRIvhA9TbM0lzRLeADTVB3JHQbA5+MCaIp/L50tor8QmnmZgTLA77KB1Hi4qT09RwKnktzb5uTzpS5kIwEx8BpDMzsFzJdFk9Uj56LxxD6gy68coKIc5XtqUU7tarnjE1majTyrY1LNS3q1Z5PIj0FeIdg5qyi/X5GmuTJfVPSN4gCwXIYwVFSXQoflIeW6vh+bj+Z7ee5k6q0wHu0cWAHYPacReGmU64TctdbioEVnss4+oTjdt75KETzArcC5yZ6Xfcw9UMSyL0Q2S8qSw67PPeXFDgZ4eWvcqZP3pJoI6ju+4tvGAXjVtQQ2j5/CtP+WPBEl+5Q5 X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(788757137089)(17755550239193); X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(6040375)(601004)(2401047)(5005006)(8121501046)(10201501046)(3002001)(6041248)(20161123560025)(20161123564025)(20161123562025)(20161123555025)(6072148);SRVR:AM3PR07MB388;BCL:0;PCL:0;RULEID:;SRVR:AM3PR07MB388; X-Microsoft-Exchange-Diagnostics: 1;AM3PR07MB388;4:ymXf/ktHeDQm06DNmY0cewjaRDJYht5G8w8sSxrGXaQMv/bGfRwOnV6bG1rTO7MQQyBVdX4sMW61xiIzRRRb4AFdvg8doly1v2okR5ypJAb5N6LulvNY4TUlLAj+w16IrIykFZzm1/mg9ZfgRct9WZsDy/3uvbFU32Vyr8BQw/I+2+Xr4sCZ/LhNr0q4dCAaWP38Ryu+vXKc6+u9iW990M5zUZxDesAZW67Zwm9rLdf4RjuwW22RJlKqgbgjpWucO4LYc5eDzWaioBQ5KRioeTL719ovMnL2jObqC0q5L+TMLIRyZfrngP9c0C4UtQvesGDT6qJ9GYALqJcsrFWXF3UBKSkuI64j8PpS23qF4qBOrxyxV54NHd3UZ08ziH1b4b+geRHr7kI25anhhKdKxqAKSju7+EcuwGNObOK27JcJUtrUN2OEBONrUV4Wo5ngTFA8evtWPl54ID7NjvecXs9ShqLJTf4Lk6Ky7OpnTuf7M8+8p/f2V6W3z65MbFHRfN1ru3doJC7z8Snoewm9jlnBzVAWFUDRxvYaeZi0vWAjuz9nh0K4uf0uEwCa9sBEMwbZEaFb+2SI9nT668RH6KjksNHPk/4bijibUTWKbCHBIasJzdBARNZM9/pQ81Y3m7EsxoKny09Ql8lufNmoRg== X-Forefront-PRVS: 0142F22657 X-Forefront-Antispam-Report: SFV:NSPM;SFS:(10009020)(4630300001)(6009001)(7916002)(54534003)(199003)(189002)(2906002)(92566002)(48376002)(105586002)(76176999)(2351001)(5660300001)(50986999)(106356001)(42186005)(101416001)(33646002)(50226002)(6666003)(68736007)(2950100002)(110136003)(6916009)(1076002)(3846002)(86362001)(8676002)(50466002)(5003940100001)(6116002)(38730400001)(81156014)(7736002)(4326007)(81166006)(97736004)(36756003)(66066001)(305945005)(39410400001)(7846002)(39450400002)(47776003)(6486002)(733004)(189998001);DIR:OUT;SFP:1101;SCL:1;SRVR:AM3PR07MB388;H:elxcz23q12-y4.ca.am.ericsson.se;FPR:;SPF:None;PTR:InfoNoRecords;A:1;MX:1;LANG:en; Received-SPF: None (protection.outlook.com: ericsson.com does not designate permitted sender hosts) X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1;AM3PR07MB388;23:aabW18Y06N+7aZaaTg7TuBaiSAIs+pR1jjUTG/HYGu?= =?us-ascii?Q?+kySGi+9TA/JI9Y7lWAORFMg8+ZcCbFug+V974l2iBDN2B4WQphuckUGgK4I?= =?us-ascii?Q?WEq875PUdjhSUVv8pz++N9lDUnShHpf+mA0pw2CenIQs7R6hfbIn3v8RrcUh?= =?us-ascii?Q?BnA0uOmw1cbFyyhcoWPcrDAYf4ZriLbas6sdi+RJzH7r+kF32RH34WK239RA?= =?us-ascii?Q?Wsf8AxVqxajL/uvAlmV6AFa0fdRn+9aY82jlgee6Po+fCreSCKzaukCyJlOa?= =?us-ascii?Q?CBKGI+ri5gGLdbYQTLgbkoYcAiyniNwgNFPCj6n6fYx4W32YKPcZaIGdCXuI?= =?us-ascii?Q?3pHIhCgPlVlrGg6esg2jHdxdNmFPME1rsrxIyuh3Gq9dZ1ch94/hlh/DLyK+?= =?us-ascii?Q?seXXS8sRn4SOhhBuA/y8KW7ZEex29tFeHSX+HLmDoCyfPm3xRccJy5H5u2w1?= =?us-ascii?Q?bCqxCUtFLfvdmq9E8jnB+9RgFPIw2TdwiLBsCifqBbmUDIIv+4sABru6H2A+?= =?us-ascii?Q?8XL5c6GTtX6zZjdnwuKnkJFZdk2PunY+pKDLzwRwDs0TRfSBJJSUbqyjpm1+?= =?us-ascii?Q?imua7gFh8me6Ucw4GboBxX228vBeTzQ2NxkOKwFVINKk/oYRjx2ODGR8foFa?= =?us-ascii?Q?jG5F3Bw9ry/CUwB5op+U+Uyh6r6LjTj/r1q3MHMkydF4X7b0cyezsQW/KT2a?= =?us-ascii?Q?Z+IQe45heXXIoGWjD1pVUFc7fsIsOj0yBog0lQPYkHpg+ZMVOSr735fbOpan?= =?us-ascii?Q?Zqa1D35S6zw690L1NEEa2Z7JbnJK5/Dtg+AJcowlqF+fLxHxEqCR3ySmnI3g?= =?us-ascii?Q?qR4y8QoTqS9WS3qIWd1+YhE3x5YUJQfXBC6xe9PmUAmOZN3Vsk1ExNfnLowO?= =?us-ascii?Q?73bv0j32FOA06dU5Fz/Go5F8dSU8ieHwDO67y4rd3LxIPCM4ryLhtjL6doq2?= =?us-ascii?Q?1KW4xG9kd8jw1WcVcC0E2vYol0rQu9JFMaqPGl1J530bJ6ug/4NV1+p8Mgtb?= =?us-ascii?Q?q41GByLtEo86FrtpxtpgZeqHdtS5ftoa8bJJRMbN0b1M2/NPZ3W0tFkQ+ZVU?= =?us-ascii?Q?QdoILoIdAhlC3cKWIdTSojsTOjh5L4uA94J647n0s4w7MuitGZx6fo2aOqhA?= =?us-ascii?Q?cH63tY7MF9lJgGT5WmREmGmrdIIJnc?= X-Microsoft-Exchange-Diagnostics: 1;AM3PR07MB388;6:X1esxkkvC1MmQtqPTCC63f7TaSoTws8iiDcO+YoRouF0tn4V/04dwJC63/iFW0ve8Fbu/lIGc4n5WWief2KDTqy0k/wKOwvxTiQ/G3z8LL9d/Ef4IJHnJkqf8W27/LoFKvoOYwXtXIZ6lapnBVUTkssQBARPaoZC0eEgsfvqY5AiqMe2MF4pscMX7Bdybn9w7leuxll3JUZp0SE6ZU9KqfRQs8+Rfz0KlmhBNDkoWuoiwuVo049E43sTzVXQj6Co2JcVRrOGdvg5eJ3YnlLuO+od0r2IxU3f8hlQ5F/gnjDT4AQYdn+EbiiduUZyZUTf83g8KNa7kajbtKcIzwSRCm9iKRqihybD6Jdozyxv0XbdvjRpiLeIYbkos/JnCqXN6T9ZdDyxzmovaPX1c8LWYnA2Nq0qh5xM2bUoV3GH+AL2IA5dtRr2e/L2dlEXpwCgZpGtAN2t59Z9Rsys+xYOfg==;5:wWb9hdzvHhrMDRFqfwhtDZyA9nD1XCCHznMjhVkgIuf94Xv0freQKEjlzd8jKItwz+RVppmfvdQQtaxpIdEf8aII0Ae1/jep9uDpn7N8k1P4CRsKuyh0NiiHmuvN136vR7eA7U0566mSZSCO28zP9Q==;24:EEbesj2KvIBE41yIhNKJ1B2L8hV25TSArI8x11pludA7vYj52X+2vMbtlJz/hncTmbuM7eQkq3y6DaX9uowlvxMsZt2dVp/JHOzXtkIGlY4= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1;AM3PR07MB388;7:3dEbVsVGYuOwkylO6QFqo7dmdQRBmoxSXx6nXmsqYd44l1ZdhuDT/5Pxawxl8h+LWW8D9Hc1q9e/dXWQk8pJyLhB7VHdlIsFSsLJUtsMxxEKpeZymPEFtFRdgJsctgdDMsBO89mNaOkysjPJZBtB6mvZdgeNlfeC8Hsh0LrkRgO1gjG64KRrxctkKgUeVkTayaY29tZr4GeUISSKt0SZ6DYUpXcZi9Enp+V5WoNA48M2yyY8Ze4IlcL3ndjwcKfmKJ8WfGf+/Qz5CFmYSjLsuX1vpUSKRGU/OGkv87BDni4aFY0lDGHyeY97iyTIW4EMBZGwu5zFrVx1FQEbh9fC+0WLRbHbRJ8bgxF64NLwaX6SFzPVr1t79GQUYfzSsaHi4PRimdnETpWWmaTiXo3Q7TqyactiGtTQFk/+RPPP2EuLI2UdQO943XmMJgCZEUJDVXSLpmstd190wZKqlvK1ig== X-MS-Exchange-CrossTenant-OriginalArrivalTime: 30 Nov 2016 21:48:07.2437 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM3PR07MB388 X-OriginatorOrg: ericsson.com X-IsSubscribed: yes X-SW-Source: 2016-11/txt/msg01029.txt.bz2 From: Simon Marchi 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. New in v2: use "enum class" for ui_out_table::state and update references. gdb/ChangeLog: * ui-out.c (enum ui_out_table_state): Move to class ui_out_table as ui_out_table::state. (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 6bd5126..32cea1f 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 class state + { + /* We are generating the table headers. */ + HEADERS, + + /* We are generating the table body. */ + BODY, + }; + + explicit ui_out_table (int entry_level, int nr_cols, const std::string &id) + : m_state (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 != 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 = 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 != 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 = 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::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::state::BODY) { internal_error (__FILE__, __LINE__, _("table_body missing; table fields must be \ @@ -808,9 +822,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::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__, @@ -829,26 +844,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. */ @@ -860,14 +859,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 the ui-out level #1, the default level. */ push_level (uiout, ui_out_type_tuple); - uiout->table.headers_iterator = uiout->table.headers.end (); - return uiout; } -- 2.10.2