i386: Check vector length for scatter/gather prefetch instructions
[deliverable/binutils-gdb.git] / gdb / ui-out.c
CommitLineData
8b93c638 1/* Output generating routines for GDB.
349c5d5f 2
42a4f53d 3 Copyright (C) 1999-2019 Free Software Foundation, Inc.
349c5d5f 4
8b93c638
JM
5 Contributed by Cygnus Solutions.
6 Written by Fernando Nasser for Cygnus.
7
8 This file is part of GDB.
9
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
a9762ec7 12 the Free Software Foundation; either version 3 of the License, or
8b93c638
JM
13 (at your option) any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
a9762ec7 21 along with this program. If not, see <http://www.gnu.org/licenses/>. */
8b93c638
JM
22
23#include "defs.h"
8b93c638
JM
24#include "expression.h" /* For language.h */
25#include "language.h"
26#include "ui-out.h"
27
56df3084
SM
28#include <vector>
29#include <memory>
95a23284 30#include <string>
56df3084 31
ffdbe864
YQ
32namespace {
33
37e20dd6 34/* A header of a ui_out_table. */
8b93c638 35
37e20dd6
SM
36class ui_out_hdr
37{
38 public:
39
40 explicit ui_out_hdr (int number, int min_width, ui_align alignment,
41 const std::string &name, const std::string &header)
42 : m_number (number),
43 m_min_width (min_width),
44 m_alignment (alignment),
45 m_name (name),
46 m_header (header)
8b93c638 47 {
37e20dd6
SM
48 }
49
50 int number () const
51 {
52 return m_number;
53 }
54
55 int min_width () const
56 {
57 return m_min_width;
58 }
59
60 ui_align alignment () const
61 {
62 return m_alignment;
63 }
64
65 const std::string &header () const
66 {
67 return m_header;
68 }
69
70 const std::string &name () const
71 {
72 return m_name;
73 }
74
75 private:
76
77 /* The number of the table column this header represents, 1-based. */
78 int m_number;
79
80 /* Minimal column width in characters. May or may not be applicable,
81 depending on the actual implementation of ui_out. */
82 int m_min_width;
83
84 /* Alignment of the content in the column. May or may not be applicable,
85 depending on the actual implementation of ui_out. */
86 ui_align m_alignment;
87
88 /* Internal column name, used to internally refer to the column. */
89 std::string m_name;
90
91 /* Printed header text of the column. */
92 std::string m_header;
93};
8b93c638 94
ffdbe864
YQ
95} // namespace
96
909c0aa5
SM
97/* A level of nesting (either a list or a tuple) in a ui_out output. */
98
99class ui_out_level
100{
101 public:
102
103 explicit ui_out_level (ui_out_type type)
104 : m_type (type),
105 m_field_count (0)
80f49b30 106 {
909c0aa5
SM
107 }
108
109 ui_out_type type () const
110 {
111 return m_type;
112 }
113
114 int field_count () const
115 {
116 return m_field_count;
117 }
118
119 void inc_field_count ()
120 {
121 m_field_count++;
122 }
123
124 private:
125
126 /* The type of this level. */
127 ui_out_type m_type;
128
129 /* Count each field; the first element is for non-list fields. */
130 int m_field_count;
131};
80f49b30 132
bafdd3b3
AC
133/* Tables are special. Maintain a separate structure that tracks
134 their state. At present an output can only contain a single table
135 but that restriction might eventually be lifted. */
136
36d18bc5 137class ui_out_table
bafdd3b3 138{
36d18bc5
SM
139 public:
140
141 /* States (steps) of a table generation. */
142
143 enum class state
144 {
145 /* We are generating the table headers. */
146 HEADERS,
147
148 /* We are generating the table body. */
149 BODY,
150 };
151
152 explicit ui_out_table (int entry_level, int nr_cols, const std::string &id)
153 : m_state (state::HEADERS),
154 m_entry_level (entry_level),
155 m_nr_cols (nr_cols),
156 m_id (id)
157 {
158 }
159
160 /* Start building the body of the table. */
161
162 void start_body ();
163
164 /* Add a new header to the table. */
165
166 void append_header (int width, ui_align alignment,
167 const std::string &col_name, const std::string &col_hdr);
bafdd3b3 168
36d18bc5
SM
169 void start_row ();
170
171 /* Extract the format information for the next header and advance
172 the header iterator. Return false if there was no next header. */
173
174 bool get_next_header (int *colno, int *width, ui_align *alignment,
175 const char **col_hdr);
176
177 bool query_field (int colno, int *width, int *alignment,
178 const char **col_name) const;
179
180 state current_state () const;
181
182 int entry_level () const;
183
184 private:
185
186 state m_state;
bafdd3b3 187
a6c47c14
AC
188 /* The level at which each entry of the table is to be found. A row
189 (a tuple) is made up of entries. Consequently ENTRY_LEVEL is one
190 above that of the table. */
36d18bc5 191 int m_entry_level;
a6c47c14 192
bafdd3b3 193 /* Number of table columns (as specified in the table_begin call). */
36d18bc5 194 int m_nr_cols;
bafdd3b3
AC
195
196 /* String identifying the table (as specified in the table_begin
197 call). */
36d18bc5 198 std::string m_id;
bafdd3b3 199
78afa7f8 200 /* Pointers to the column headers. */
36d18bc5 201 std::vector<std::unique_ptr<ui_out_hdr>> m_headers;
bafdd3b3 202
78afa7f8 203 /* Iterator over the headers vector, used when printing successive fields. */
36d18bc5 204 std::vector<std::unique_ptr<ui_out_hdr>>::const_iterator m_headers_iterator;
bafdd3b3
AC
205};
206
36d18bc5
SM
207/* See ui-out.h. */
208
209void ui_out_table::start_body ()
210{
211 if (m_state != state::HEADERS)
212 internal_error (__FILE__, __LINE__,
213 _("extra table_body call not allowed; there must be only "
214 "one table_body after a table_begin and before a "
215 "table_end."));
216
217 /* Check if the number of defined headers matches the number of expected
218 columns. */
219 if (m_headers.size () != m_nr_cols)
220 internal_error (__FILE__, __LINE__,
221 _("number of headers differ from number of table "
222 "columns."));
223
224 m_state = state::BODY;
225 m_headers_iterator = m_headers.begin ();
226}
227
228/* See ui-out.h. */
229
230void ui_out_table::append_header (int width, ui_align alignment,
231 const std::string &col_name,
232 const std::string &col_hdr)
233{
234 if (m_state != state::HEADERS)
235 internal_error (__FILE__, __LINE__,
236 _("table header must be specified after table_begin and "
237 "before table_body."));
238
239 std::unique_ptr<ui_out_hdr> header (new ui_out_hdr (m_headers.size () + 1,
240 width, alignment,
241 col_name, col_hdr));
242
243 m_headers.push_back (std::move (header));
244}
245
246/* See ui-out.h. */
247
248void ui_out_table::start_row ()
249{
250 m_headers_iterator = m_headers.begin ();
251}
252
253/* See ui-out.h. */
254
255bool ui_out_table::get_next_header (int *colno, int *width, ui_align *alignment,
256 const char **col_hdr)
257{
258 /* There may be no headers at all or we may have used all columns. */
259 if (m_headers_iterator == m_headers.end ())
260 return false;
261
262 ui_out_hdr *hdr = m_headers_iterator->get ();
263
264 *colno = hdr->number ();
265 *width = hdr->min_width ();
266 *alignment = hdr->alignment ();
267 *col_hdr = hdr->header ().c_str ();
268
269 /* Advance the header pointer to the next entry. */
270 m_headers_iterator++;
271
272 return true;
273}
274
275/* See ui-out.h. */
276
277bool ui_out_table::query_field (int colno, int *width, int *alignment,
278 const char **col_name) const
279{
280 /* Column numbers are 1-based, so convert to 0-based index. */
281 int index = colno - 1;
282
283 if (index >= 0 && index < m_headers.size ())
284 {
285 ui_out_hdr *hdr = m_headers[index].get ();
286
287 gdb_assert (colno == hdr->number ());
288
289 *width = hdr->min_width ();
290 *alignment = hdr->alignment ();
291 *col_name = hdr->name ().c_str ();
292
293 return true;
294 }
295 else
296 return false;
297}
298
299/* See ui-out.h. */
300
301ui_out_table::state ui_out_table::current_state () const
302{
303 return m_state;
304}
305
306/* See ui-out.h. */
307
308int ui_out_table::entry_level () const
309{
310 return m_entry_level;
311}
bafdd3b3 312
112e8700
SM
313int
314ui_out::level () const
315{
316 return m_levels.size ();
317}
8b93c638 318
581e13c1 319/* The current (inner most) level. */
112e8700
SM
320
321ui_out_level *
322ui_out::current_level () const
80f49b30 323{
112e8700 324 return m_levels.back ().get ();
80f49b30
AC
325}
326
33b2fac6 327/* Create a new level, of TYPE. */
112e8700
SM
328void
329ui_out::push_level (ui_out_type type)
80f49b30 330{
909c0aa5 331 std::unique_ptr<ui_out_level> level (new ui_out_level (type));
56df3084 332
112e8700 333 m_levels.push_back (std::move (level));
80f49b30
AC
334}
335
33b2fac6
SM
336/* Discard the current level. TYPE is the type of the level being
337 discarded. */
112e8700
SM
338void
339ui_out::pop_level (ui_out_type type)
80f49b30 340{
581e13c1 341 /* We had better not underflow the buffer. */
112e8700
SM
342 gdb_assert (m_levels.size () > 0);
343 gdb_assert (current_level ()->type () == type);
344
345 m_levels.pop_back ();
346}
8b93c638 347
581e13c1 348/* Mark beginning of a table. */
8b93c638 349
112e8700
SM
350void
351ui_out::table_begin (int nr_cols, int nr_rows, const std::string &tblid)
8b93c638 352{
112e8700 353 if (m_table_up != nullptr)
8e65ff28 354 internal_error (__FILE__, __LINE__,
e2e0b3e5
AC
355 _("tables cannot be nested; table_begin found before \
356previous table_end."));
8b93c638 357
112e8700 358 m_table_up.reset (new ui_out_table (level () + 1, nr_cols, tblid));
95a23284 359
112e8700 360 do_table_begin (nr_cols, nr_rows, tblid.c_str ());
8b93c638
JM
361}
362
363void
112e8700
SM
364ui_out::table_header (int width, ui_align alignment,
365 const std::string &col_name, const std::string &col_hdr)
8b93c638 366{
112e8700 367 if (m_table_up == nullptr)
8e65ff28 368 internal_error (__FILE__, __LINE__,
112e8700
SM
369 _("table_header outside a table is not valid; it must be \
370after a table_begin and before a table_body."));
77a179e7 371
112e8700 372 m_table_up->append_header (width, alignment, col_name, col_hdr);
8b93c638 373
112e8700 374 do_table_header (width, alignment, col_name, col_hdr);
8b93c638
JM
375}
376
112e8700
SM
377void
378ui_out::table_body ()
8b93c638 379{
112e8700 380 if (m_table_up == nullptr)
8e65ff28 381 internal_error (__FILE__, __LINE__,
112e8700
SM
382 _("table_body outside a table is not valid; it must be "
383 "after a table_begin and before a table_end."));
8b93c638 384
112e8700 385 m_table_up->start_body ();
36d18bc5 386
112e8700 387 do_table_body ();
8b93c638
JM
388}
389
390void
112e8700 391ui_out::table_end ()
8b93c638 392{
112e8700 393 if (m_table_up == nullptr)
8e65ff28 394 internal_error (__FILE__, __LINE__,
112e8700 395 _("misplaced table_end or missing table_begin."));
8b93c638 396
112e8700 397 do_table_end ();
8b93c638 398
112e8700 399 m_table_up = nullptr;
8b93c638
JM
400}
401
402void
112e8700 403ui_out::begin (ui_out_type type, const char *id)
8b93c638 404{
a6c47c14
AC
405 /* Be careful to verify the ``field'' before the new tuple/list is
406 pushed onto the stack. That way the containing list/table/row is
407 verified and not the newly created tuple/list. This verification
408 is needed (at least) for the case where a table row entry
409 contains either a tuple/list. For that case bookkeeping such as
410 updating the column count or advancing to the next heading still
411 needs to be performed. */
412 {
413 int fldno;
414 int width;
112e8700 415 ui_align align;
5d502164 416
112e8700 417 verify_field (&fldno, &width, &align);
a6c47c14
AC
418 }
419
112e8700 420 push_level (type);
a6c47c14
AC
421
422 /* If the push puts us at the same level as a table row entry, we've
423 got a new table row. Put the header pointer back to the start. */
112e8700
SM
424 if (m_table_up != nullptr
425 && m_table_up->current_state () == ui_out_table::state::BODY
426 && m_table_up->entry_level () == level ())
427 m_table_up->start_row ();
a6c47c14 428
112e8700 429 do_begin (type, id);
631ec795
AC
430}
431
631ec795 432void
112e8700 433ui_out::end (ui_out_type type)
631ec795 434{
112e8700 435 pop_level (type);
5d502164 436
112e8700 437 do_end (type);
8b93c638
JM
438}
439
8b93c638 440void
112e8700 441ui_out::field_int (const char *fldname, int value)
8b93c638
JM
442{
443 int fldno;
444 int width;
112e8700 445 ui_align align;
8b93c638 446
112e8700 447 verify_field (&fldno, &width, &align);
8b93c638 448
112e8700 449 do_field_int (fldno, width, align, fldname, value);
8b93c638
JM
450}
451
52c6a6ac 452void
112e8700
SM
453ui_out::field_fmt_int (int input_width, ui_align input_align,
454 const char *fldname, int value)
52c6a6ac
JJ
455{
456 int fldno;
457 int width;
112e8700 458 ui_align align;
52c6a6ac 459
112e8700 460 verify_field (&fldno, &width, &align);
52c6a6ac 461
112e8700 462 do_field_int (fldno, input_width, input_align, fldname, value);
52c6a6ac
JJ
463}
464
15230f37
TJB
465/* Documented in ui-out.h. */
466
8b93c638 467void
112e8700
SM
468ui_out::field_core_addr (const char *fldname, struct gdbarch *gdbarch,
469 CORE_ADDR address)
8b93c638 470{
35fb8261
TT
471 field_string (fldname, print_core_address (gdbarch, address),
472 ui_out_style_kind::ADDRESS);
8b93c638
JM
473}
474
475void
cbe56571
TT
476ui_out::field_stream (const char *fldname, string_file &stream,
477 ui_out_style_kind style)
8b93c638 478{
d7e74731 479 if (!stream.empty ())
cbe56571 480 field_string (fldname, stream.c_str (), style);
8b93c638 481 else
112e8700 482 field_skip (fldname);
d7e74731 483 stream.clear ();
8b93c638
JM
484}
485
581e13c1 486/* Used to omit a field. */
8b93c638
JM
487
488void
112e8700 489ui_out::field_skip (const char *fldname)
8b93c638
JM
490{
491 int fldno;
492 int width;
112e8700 493 ui_align align;
8b93c638 494
112e8700 495 verify_field (&fldno, &width, &align);
8b93c638 496
112e8700 497 do_field_skip (fldno, width, align, fldname);
8b93c638
JM
498}
499
500void
cbe56571
TT
501ui_out::field_string (const char *fldname, const char *string,
502 ui_out_style_kind style)
8b93c638
JM
503{
504 int fldno;
505 int width;
112e8700 506 ui_align align;
8b93c638 507
112e8700 508 verify_field (&fldno, &width, &align);
8b93c638 509
cbe56571 510 do_field_string (fldno, width, align, fldname, string, style);
8b93c638
JM
511}
512
6fb16ce6
SM
513void
514ui_out::field_string (const char *fldname, const std::string &string)
515{
516 field_string (fldname, string.c_str ());
517}
518
8b93c638
JM
519/* VARARGS */
520void
112e8700 521ui_out::field_fmt (const char *fldname, const char *format, ...)
8b93c638
JM
522{
523 va_list args;
524 int fldno;
525 int width;
112e8700 526 ui_align align;
8b93c638 527
112e8700 528 verify_field (&fldno, &width, &align);
8b93c638
JM
529
530 va_start (args, format);
531
112e8700 532 do_field_fmt (fldno, width, align, fldname, format, args);
8b93c638
JM
533
534 va_end (args);
535}
536
537void
112e8700 538ui_out::spaces (int numspaces)
8b93c638 539{
112e8700 540 do_spaces (numspaces);
8b93c638
JM
541}
542
543void
112e8700 544ui_out::text (const char *string)
8b93c638 545{
112e8700 546 do_text (string);
8b93c638
JM
547}
548
549void
112e8700 550ui_out::message (const char *format, ...)
8b93c638
JM
551{
552 va_list args;
553
554 va_start (args, format);
112e8700 555 do_message (format, args);
8b93c638
JM
556 va_end (args);
557}
558
8b93c638 559void
112e8700 560ui_out::wrap_hint (const char *identstring)
8b93c638 561{
112e8700 562 do_wrap_hint (identstring);
8b93c638
JM
563}
564
565void
112e8700 566ui_out::flush ()
8b93c638 567{
112e8700 568 do_flush ();
8b93c638
JM
569}
570
7becfd03 571void
112e8700 572ui_out::redirect (ui_file *outstream)
0fac0b41 573{
7becfd03 574 do_redirect (outstream);
0fac0b41
DJ
575}
576
581e13c1 577/* Test the flags against the mask given. */
112e8700
SM
578ui_out_flags
579ui_out::test_flags (ui_out_flags mask)
8b93c638 580{
112e8700 581 return m_flags & mask;
8b93c638
JM
582}
583
112e8700 584bool
4904c3c6 585ui_out::is_mi_like_p () const
8b93c638 586{
112e8700 587 return do_is_mi_like_p ();
0fac0b41
DJ
588}
589
a6c47c14
AC
590/* Verify that the field/tuple/list is correctly positioned. Return
591 the field number and corresponding alignment (if
592 available/applicable). */
8b93c638 593
112e8700
SM
594void
595ui_out::verify_field (int *fldno, int *width, ui_align *align)
8b93c638 596{
112e8700 597 ui_out_level *current = current_level ();
c5209615 598 const char *text;
a6c47c14 599
112e8700
SM
600 if (m_table_up != nullptr
601 && m_table_up->current_state () != ui_out_table::state::BODY)
8b93c638 602 {
77a179e7
SM
603 internal_error (__FILE__, __LINE__,
604 _("table_body missing; table fields must be \
e2e0b3e5 605specified after table_body and inside a list."));
8b93c638 606 }
8b93c638 607
909c0aa5 608 current->inc_field_count ();
8b93c638 609
112e8700
SM
610 if (m_table_up != nullptr
611 && m_table_up->current_state () == ui_out_table::state::BODY
612 && m_table_up->entry_level () == level ()
613 && m_table_up->get_next_header (fldno, width, align, &text))
8b93c638 614 {
909c0aa5 615 if (*fldno != current->field_count ())
8e65ff28 616 internal_error (__FILE__, __LINE__,
e2e0b3e5 617 _("ui-out internal error in handling headers."));
8b93c638
JM
618 }
619 else
620 {
621 *width = 0;
622 *align = ui_noalign;
909c0aa5 623 *fldno = current->field_count ();
8b93c638
JM
624 }
625}
626
170b53b2 627/* Access table field parameters. */
112e8700
SM
628
629bool
630ui_out::query_table_field (int colno, int *width, int *alignment,
631 const char **col_name)
170b53b2 632{
112e8700
SM
633 if (m_table_up == nullptr)
634 return false;
170b53b2 635
112e8700 636 return m_table_up->query_field (colno, width, alignment, col_name);
170b53b2
UW
637}
638
112e8700 639/* The constructor. */
8b93c638 640
112e8700
SM
641ui_out::ui_out (ui_out_flags flags)
642: m_flags (flags)
8b93c638 643{
33b2fac6 644 /* Create the ui-out level #1, the default level. */
112e8700
SM
645 push_level (ui_out_type_tuple);
646}
54eb231c 647
112e8700
SM
648ui_out::~ui_out ()
649{
8b93c638 650}
This page took 1.948974 seconds and 4 git commands to generate.