]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/mi/mi-out.c
Update copyright year range in header of all files managed by GDB
[thirdparty/binutils-gdb.git] / gdb / mi / mi-out.c
CommitLineData
fb40c209 1/* MI Command Set - output generating routines.
349c5d5f 2
1d506c26 3 Copyright (C) 2000-2024 Free Software Foundation, Inc.
349c5d5f 4
ab91fdd5 5 Contributed by Cygnus Solutions (a Red Hat company).
fb40c209
AC
6
7 This file is part of GDB.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
a9762ec7 11 the Free Software Foundation; either version 3 of the License, or
fb40c209
AC
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
a9762ec7 20 along with this program. If not, see <http://www.gnu.org/licenses/>. */
fb40c209
AC
21
22#include "defs.h"
fb40c209 23#include "mi-out.h"
8e5e5494 24
4a9d4ea5 25#include <vector>
fb40c209 26
8e5e5494
SM
27#include "interps.h"
28#include "ui-out.h"
29#include "utils.h"
5f48d886 30#include "gdbsupport/gdb-checked-static-cast.h"
8e5e5494 31
2b03b41d 32/* Mark beginning of a table. */
fb40c209
AC
33
34void
112e8700
SM
35mi_ui_out::do_table_begin (int nr_cols, int nr_rows,
36 const char *tblid)
fb40c209 37{
112e8700 38 open (tblid, ui_out_type_tuple);
381befee
TT
39 do_field_signed (-1, -1, ui_left, "nr_rows", nr_rows);
40 do_field_signed (-1, -1, ui_left, "nr_cols", nr_cols);
112e8700 41 open ("hdr", ui_out_type_list);
fb40c209
AC
42}
43
2b03b41d 44/* Mark beginning of a table body. */
fb40c209
AC
45
46void
112e8700 47mi_ui_out::do_table_body ()
fb40c209 48{
cff22675 49 /* close the table header line if there were any headers */
112e8700
SM
50 close (ui_out_type_list);
51 open ("body", ui_out_type_list);
fb40c209
AC
52}
53
2b03b41d 54/* Mark end of a table. */
fb40c209
AC
55
56void
112e8700 57mi_ui_out::do_table_end ()
fb40c209 58{
112e8700
SM
59 close (ui_out_type_list); /* body */
60 close (ui_out_type_tuple);
fb40c209
AC
61}
62
2b03b41d 63/* Specify table header. */
fb40c209
AC
64
65void
112e8700
SM
66mi_ui_out::do_table_header (int width, ui_align alignment,
67 const std::string &col_name,
68 const std::string &col_hdr)
fb40c209 69{
112e8700 70 open (NULL, ui_out_type_tuple);
381befee
TT
71 do_field_signed (0, 0, ui_center, "width", width);
72 do_field_signed (0, 0, ui_center, "alignment", alignment);
cbe56571 73 do_field_string (0, 0, ui_center, "col_name", col_name.c_str (),
e43b10e1 74 ui_file_style ());
cbe56571 75 do_field_string (0, width, alignment, "colhdr", col_hdr.c_str (),
e43b10e1 76 ui_file_style ());
112e8700 77 close (ui_out_type_tuple);
fb40c209
AC
78}
79
2b03b41d 80/* Mark beginning of a list. */
fb40c209
AC
81
82void
112e8700 83mi_ui_out::do_begin (ui_out_type type, const char *id)
fb40c209 84{
112e8700 85 open (id, type);
fb40c209
AC
86}
87
2b03b41d 88/* Mark end of a list. */
fb40c209
AC
89
90void
112e8700 91mi_ui_out::do_end (ui_out_type type)
fb40c209 92{
112e8700 93 close (type);
fb40c209
AC
94}
95
2b03b41d 96/* Output an int field. */
fb40c209 97
112e8700 98void
381befee
TT
99mi_ui_out::do_field_signed (int fldno, int width, ui_align alignment,
100 const char *fldname, LONGEST value)
fb40c209 101{
07128006 102 do_field_string (fldno, width, alignment, fldname, plongest (value),
e43b10e1 103 ui_file_style ());
fb40c209
AC
104}
105
1f77b012
TT
106/* Output an unsigned field. */
107
108void
109mi_ui_out::do_field_unsigned (int fldno, int width, ui_align alignment,
110 const char *fldname, ULONGEST value)
111{
112 do_field_string (fldno, width, alignment, fldname, pulongest (value),
e43b10e1 113 ui_file_style ());
1f77b012
TT
114}
115
2b03b41d 116/* Used to omit a field. */
fb40c209
AC
117
118void
112e8700
SM
119mi_ui_out::do_field_skip (int fldno, int width, ui_align alignment,
120 const char *fldname)
fb40c209 121{
fb40c209
AC
122}
123
2b03b41d
SS
124/* Other specific mi_field_* end up here so alignment and field
125 separators are both handled by mi_field_string. */
fb40c209
AC
126
127void
112e8700 128mi_ui_out::do_field_string (int fldno, int width, ui_align align,
cbe56571 129 const char *fldname, const char *string,
e43b10e1 130 const ui_file_style &style)
fb40c209 131{
112e8700
SM
132 ui_file *stream = m_streams.back ();
133 field_separator ();
102040f0 134
fb40c209 135 if (fldname)
6cb06a8c
TT
136 gdb_printf (stream, "%s=", fldname);
137 gdb_printf (stream, "\"");
fb40c209 138 if (string)
d53fd721 139 stream->putstr (string, '"');
6cb06a8c 140 gdb_printf (stream, "\"");
fb40c209
AC
141}
142
fb40c209 143void
112e8700 144mi_ui_out::do_field_fmt (int fldno, int width, ui_align align,
7f6aba03
TT
145 const char *fldname, const ui_file_style &style,
146 const char *format, va_list args)
fb40c209 147{
112e8700
SM
148 ui_file *stream = m_streams.back ();
149 field_separator ();
102040f0 150
fb40c209 151 if (fldname)
6cb06a8c 152 gdb_printf (stream, "%s=\"", fldname);
fb40c209 153 else
0426ad51 154 gdb_puts ("\"", stream);
19a7b8ab 155 gdb_vprintf (stream, format, args);
0426ad51 156 gdb_puts ("\"", stream);
fb40c209
AC
157}
158
159void
112e8700 160mi_ui_out::do_spaces (int numspaces)
fb40c209
AC
161{
162}
163
164void
112e8700 165mi_ui_out::do_text (const char *string)
fb40c209
AC
166{
167}
168
169void
2a3c1174
PA
170mi_ui_out::do_message (const ui_file_style &style,
171 const char *format, va_list args)
fb40c209
AC
172{
173}
174
175void
6c92c339 176mi_ui_out::do_wrap_hint (int indent)
fb40c209 177{
7016a382 178 m_streams.back ()->wrap_here (indent);
fb40c209
AC
179}
180
181void
112e8700 182mi_ui_out::do_flush ()
fb40c209 183{
102040f0 184
112e8700 185 gdb_flush (m_streams.back ());
fb40c209
AC
186}
187
7becfd03 188void
112e8700 189mi_ui_out::do_redirect (ui_file *outstream)
8d3788bd 190{
8d3788bd 191 if (outstream != NULL)
112e8700 192 m_streams.push_back (outstream);
4d6cceb4 193 else
112e8700 194 m_streams.pop_back ();
8d3788bd
VP
195}
196
112e8700
SM
197void
198mi_ui_out::field_separator ()
fb40c209 199{
112e8700
SM
200 if (m_suppress_field_separator)
201 m_suppress_field_separator = false;
fb40c209 202 else
a11ac3b3 203 gdb_putc (',', m_streams.back ());
fb40c209
AC
204}
205
112e8700
SM
206void
207mi_ui_out::open (const char *name, ui_out_type type)
fb40c209 208{
112e8700
SM
209 ui_file *stream = m_streams.back ();
210
211 field_separator ();
212 m_suppress_field_separator = true;
102040f0 213
d5e8ba62 214 if (name)
6cb06a8c 215 gdb_printf (stream, "%s=", name);
112e8700 216
5a9aa5dc
AC
217 switch (type)
218 {
219 case ui_out_type_tuple:
a11ac3b3 220 gdb_putc ('{', stream);
5a9aa5dc 221 break;
112e8700 222
5a9aa5dc 223 case ui_out_type_list:
a11ac3b3 224 gdb_putc ('[', stream);
5a9aa5dc 225 break;
112e8700 226
5a9aa5dc 227 default:
f34652de 228 internal_error (_("bad switch"));
5a9aa5dc 229 }
fb40c209
AC
230}
231
112e8700
SM
232void
233mi_ui_out::close (ui_out_type type)
fb40c209 234{
112e8700 235 ui_file *stream = m_streams.back ();
102040f0 236
5a9aa5dc
AC
237 switch (type)
238 {
239 case ui_out_type_tuple:
a11ac3b3 240 gdb_putc ('}', stream);
5a9aa5dc 241 break;
112e8700 242
5a9aa5dc 243 case ui_out_type_list:
a11ac3b3 244 gdb_putc (']', stream);
5a9aa5dc 245 break;
112e8700 246
5a9aa5dc 247 default:
f34652de 248 internal_error (_("bad switch"));
5a9aa5dc 249 }
112e8700
SM
250
251 m_suppress_field_separator = false;
fb40c209
AC
252}
253
d7e74731
PA
254string_file *
255mi_ui_out::main_stream ()
256{
257 gdb_assert (m_streams.size () == 1);
258
259 return (string_file *) m_streams.back ();
260}
261
27859c6b
AM
262/* Initialize a progress update to be displayed with
263 mi_ui_out::do_progress_notify. */
264
265void
266mi_ui_out::do_progress_start ()
267{
268 m_progress_info.emplace_back ();
269}
270
271/* Indicate that a task described by MSG is in progress. */
272
273void
274mi_ui_out::do_progress_notify (const std::string &msg, const char *unit,
275 double cur, double total)
276{
277 mi_progress_info &info (m_progress_info.back ());
278
279 if (info.state == progress_update::START)
280 {
281 gdb_printf ("%s...\n", msg.c_str ());
282 info.state = progress_update::WORKING;
283 }
284}
285
286/* Remove the most recent progress update from the progress_info stack. */
287
288void
289mi_ui_out::do_progress_end ()
290{
291 m_progress_info.pop_back ();
292}
293
2b03b41d 294/* Clear the buffer. */
fb40c209
AC
295
296void
112e8700 297mi_ui_out::rewind ()
fb40c209 298{
d7e74731 299 main_stream ()->clear ();
fb40c209
AC
300}
301
2b03b41d 302/* Dump the buffer onto the specified stream. */
fb40c209 303
fb40c209 304void
d7e74731 305mi_ui_out::put (ui_file *where)
fb40c209 306{
d7e74731 307 string_file *mi_stream = main_stream ();
102040f0 308
d7e74731
PA
309 where->write (mi_stream->data (), mi_stream->size ());
310 mi_stream->clear ();
fb40c209
AC
311}
312
2b03b41d 313/* Return the current MI version. */
c7ec4050
AC
314
315int
112e8700 316mi_ui_out::version ()
c7ec4050 317{
112e8700 318 return m_mi_version;
c7ec4050
AC
319}
320
4d6cceb4
DE
321/* Constructor for an `mi_out_data' object. */
322
d7e74731 323mi_ui_out::mi_ui_out (int mi_version)
9db0d853 324: ui_out (make_flags (mi_version)),
13674803 325 m_suppress_field_separator (false),
112e8700
SM
326 m_suppress_output (false),
327 m_mi_version (mi_version)
4d6cceb4 328{
d7e74731 329 string_file *stream = new string_file ();
112e8700
SM
330 m_streams.push_back (stream);
331}
4d6cceb4 332
112e8700
SM
333mi_ui_out::~mi_ui_out ()
334{
4d6cceb4
DE
335}
336
8e5e5494 337/* See mi/mi-out.h. */
4d6cceb4 338
e200b179 339std::unique_ptr<mi_ui_out>
8e5e5494 340mi_out_new (const char *mi_version)
4d6cceb4 341{
9db0d853 342 if (streq (mi_version, INTERP_MI4) || streq (mi_version, INTERP_MI))
6b62451a 343 return std::make_unique<mi_ui_out> (4);
9db0d853
SM
344
345 if (streq (mi_version, INTERP_MI3))
6b62451a 346 return std::make_unique<mi_ui_out> (3);
8e5e5494 347
b4be1b06 348 if (streq (mi_version, INTERP_MI2))
6b62451a 349 return std::make_unique<mi_ui_out> (2);
8e5e5494 350
8e5e5494 351 return nullptr;
4d6cceb4
DE
352}
353
112e8700
SM
354/* Helper function to return the given UIOUT as an mi_ui_out. It is an error
355 to call this function with an ui_out that is not an MI. */
fb40c209 356
112e8700
SM
357static mi_ui_out *
358as_mi_ui_out (ui_out *uiout)
fb40c209 359{
5f48d886 360 return gdb::checked_static_cast<mi_ui_out *> (uiout);
112e8700 361}
4d6cceb4 362
112e8700
SM
363void
364mi_out_put (ui_out *uiout, struct ui_file *stream)
365{
366 return as_mi_ui_out (uiout)->put (stream);
367}
368
369void
370mi_out_rewind (ui_out *uiout)
371{
372 return as_mi_ui_out (uiout)->rewind ();
fb40c209 373}