Simplify ui-out level code
[deliverable/binutils-gdb.git] / gdb / mi / mi-out.c
CommitLineData
fb40c209 1/* MI Command Set - output generating routines.
349c5d5f 2
618f726f 3 Copyright (C) 2000-2016 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"
23#include "ui-out.h"
24#include "mi-out.h"
4a9d4ea5 25#include <vector>
fb40c209 26
0abe66b5 27struct mi_ui_out_data
fb40c209 28 {
59807497 29 int suppress_field_separator;
76fe6b98 30 int suppress_output;
b30bf9ee 31 int mi_version;
4a9d4ea5 32 std::vector<ui_file *> streams;
fb40c209 33 };
0abe66b5 34typedef struct mi_ui_out_data mi_out_data;
fb40c209
AC
35
36/* These are the MI output functions */
37
4d6cceb4 38static void mi_out_data_dtor (struct ui_out *ui_out);
e2e11a41 39static void mi_table_begin (struct ui_out *uiout, int nbrofcols,
d63f1d40 40 int nr_rows, const char *tblid);
fb40c209
AC
41static void mi_table_body (struct ui_out *uiout);
42static void mi_table_end (struct ui_out *uiout);
43static void mi_table_header (struct ui_out *uiout, int width,
c5209615
SM
44 enum ui_align alignment,
45 const std::string &col_name,
46 const std::string &col_hdr);
631ec795 47static void mi_begin (struct ui_out *uiout, enum ui_out_type type,
33b2fac6
SM
48 const char *id);
49static void mi_end (struct ui_out *uiout, enum ui_out_type type);
fb40c209 50static void mi_field_int (struct ui_out *uiout, int fldno, int width,
e2e11a41 51 enum ui_align alig, const char *fldname, int value);
fb40c209 52static void mi_field_skip (struct ui_out *uiout, int fldno, int width,
e2e11a41 53 enum ui_align alig, const char *fldname);
fb40c209 54static void mi_field_string (struct ui_out *uiout, int fldno, int width,
e2e11a41 55 enum ui_align alig, const char *fldname,
fb40c209
AC
56 const char *string);
57static void mi_field_fmt (struct ui_out *uiout, int fldno,
58 int width, enum ui_align align,
e2e11a41 59 const char *fldname, const char *format,
a0b31db1 60 va_list args) ATTRIBUTE_PRINTF (6, 0);
fb40c209 61static void mi_spaces (struct ui_out *uiout, int numspaces);
e2e11a41 62static void mi_text (struct ui_out *uiout, const char *string);
7fb048a2
SM
63static void mi_message (struct ui_out *uiout, const char *format, va_list args)
64 ATTRIBUTE_PRINTF (2, 0);
d2c0eef4 65static void mi_wrap_hint (struct ui_out *uiout, const char *identstring);
fb40c209 66static void mi_flush (struct ui_out *uiout);
8d3788bd 67static int mi_redirect (struct ui_out *uiout, struct ui_file *outstream);
fb40c209
AC
68
69/* This is the MI ui-out implementation functions vector */
70
89de4da4 71static const struct ui_out_impl mi_ui_out_impl =
fb40c209
AC
72{
73 mi_table_begin,
74 mi_table_body,
75 mi_table_end,
76 mi_table_header,
631ec795
AC
77 mi_begin,
78 mi_end,
fb40c209
AC
79 mi_field_int,
80 mi_field_skip,
81 mi_field_string,
82 mi_field_fmt,
83 mi_spaces,
84 mi_text,
85 mi_message,
86 mi_wrap_hint,
9dc5e2a9 87 mi_flush,
8d3788bd 88 mi_redirect,
4d6cceb4 89 mi_out_data_dtor,
9dc5e2a9 90 1, /* Needs MI hacks. */
fb40c209
AC
91};
92
93/* Prototypes for local functions */
94
fb40c209 95static void field_separator (struct ui_out *uiout);
d5e8ba62
AC
96static void mi_open (struct ui_out *uiout, const char *name,
97 enum ui_out_type type);
9a0f0643 98static void mi_close (struct ui_out *uiout, enum ui_out_type type);
fb40c209 99
2b03b41d 100/* Mark beginning of a table. */
fb40c209
AC
101
102void
cff22675
AC
103mi_table_begin (struct ui_out *uiout,
104 int nr_cols,
d63f1d40 105 int nr_rows,
e2e11a41 106 const char *tblid)
fb40c209 107{
d5e8ba62 108 mi_open (uiout, tblid, ui_out_type_tuple);
f486487f
SM
109 mi_field_int (uiout, -1, -1, ui_left, "nr_rows", nr_rows);
110 mi_field_int (uiout, -1, -1, ui_left, "nr_cols", nr_cols);
cff22675 111 mi_open (uiout, "hdr", ui_out_type_list);
fb40c209
AC
112}
113
2b03b41d 114/* Mark beginning of a table body. */
fb40c209
AC
115
116void
fba45db2 117mi_table_body (struct ui_out *uiout)
fb40c209 118{
19ba03f4 119 mi_out_data *data = (mi_out_data *) ui_out_data (uiout);
102040f0 120
76fe6b98
AC
121 if (data->suppress_output)
122 return;
cff22675
AC
123 /* close the table header line if there were any headers */
124 mi_close (uiout, ui_out_type_list);
cff22675 125 mi_open (uiout, "body", ui_out_type_list);
fb40c209
AC
126}
127
2b03b41d 128/* Mark end of a table. */
fb40c209
AC
129
130void
fba45db2 131mi_table_end (struct ui_out *uiout)
fb40c209 132{
19ba03f4 133 mi_out_data *data = (mi_out_data *) ui_out_data (uiout);
102040f0 134
76fe6b98 135 data->suppress_output = 0;
cff22675 136 mi_close (uiout, ui_out_type_list); /* body */
666547aa 137 mi_close (uiout, ui_out_type_tuple);
fb40c209
AC
138}
139
2b03b41d 140/* Specify table header. */
fb40c209
AC
141
142void
46712191 143mi_table_header (struct ui_out *uiout, int width, enum ui_align alignment,
c5209615 144 const std::string &col_name, const std::string &col_hdr)
fb40c209 145{
19ba03f4 146 mi_out_data *data = (mi_out_data *) ui_out_data (uiout);
102040f0 147
76fe6b98
AC
148 if (data->suppress_output)
149 return;
2b03b41d 150
cff22675 151 mi_open (uiout, NULL, ui_out_type_tuple);
f486487f
SM
152 mi_field_int (uiout, 0, 0, ui_center, "width", width);
153 mi_field_int (uiout, 0, 0, ui_center, "alignment", alignment);
c5209615
SM
154 mi_field_string (uiout, 0, 0, ui_center, "col_name", col_name.c_str ());
155 mi_field_string (uiout, 0, width, alignment, "colhdr", col_hdr.c_str ());
cff22675 156 mi_close (uiout, ui_out_type_tuple);
fb40c209
AC
157}
158
2b03b41d 159/* Mark beginning of a list. */
fb40c209
AC
160
161void
33b2fac6 162mi_begin (struct ui_out *uiout, enum ui_out_type type, const char *id)
fb40c209 163{
19ba03f4 164 mi_out_data *data = (mi_out_data *) ui_out_data (uiout);
102040f0 165
76fe6b98
AC
166 if (data->suppress_output)
167 return;
2b03b41d 168
d5e8ba62 169 mi_open (uiout, id, type);
fb40c209
AC
170}
171
2b03b41d 172/* Mark end of a list. */
fb40c209
AC
173
174void
33b2fac6 175mi_end (struct ui_out *uiout, enum ui_out_type type)
fb40c209 176{
19ba03f4 177 mi_out_data *data = (mi_out_data *) ui_out_data (uiout);
102040f0 178
76fe6b98
AC
179 if (data->suppress_output)
180 return;
2b03b41d 181
9a0f0643 182 mi_close (uiout, type);
fb40c209
AC
183}
184
2b03b41d 185/* Output an int field. */
fb40c209 186
2b03b41d 187static void
46712191
KB
188mi_field_int (struct ui_out *uiout, int fldno, int width,
189 enum ui_align alignment, const char *fldname, int value)
fb40c209 190{
102040f0 191 char buffer[20]; /* FIXME: how many chars long a %d can become? */
19ba03f4 192 mi_out_data *data = (mi_out_data *) ui_out_data (uiout);
102040f0 193
76fe6b98
AC
194 if (data->suppress_output)
195 return;
fb40c209 196
08850b56 197 xsnprintf (buffer, sizeof (buffer), "%d", value);
fb40c209
AC
198 mi_field_string (uiout, fldno, width, alignment, fldname, buffer);
199}
200
2b03b41d 201/* Used to omit a field. */
fb40c209
AC
202
203void
46712191
KB
204mi_field_skip (struct ui_out *uiout, int fldno, int width,
205 enum ui_align alignment, const char *fldname)
fb40c209 206{
fb40c209
AC
207}
208
2b03b41d
SS
209/* Other specific mi_field_* end up here so alignment and field
210 separators are both handled by mi_field_string. */
fb40c209
AC
211
212void
2b03b41d
SS
213mi_field_string (struct ui_out *uiout, int fldno, int width,
214 enum ui_align align, const char *fldname, const char *string)
fb40c209 215{
19ba03f4 216 mi_out_data *data = (mi_out_data *) ui_out_data (uiout);
4d6cceb4 217 struct ui_file *stream;
102040f0 218
76fe6b98
AC
219 if (data->suppress_output)
220 return;
2b03b41d 221
4a9d4ea5 222 stream = data->streams.back ();
fb40c209
AC
223 field_separator (uiout);
224 if (fldname)
4d6cceb4
DE
225 fprintf_unfiltered (stream, "%s=", fldname);
226 fprintf_unfiltered (stream, "\"");
fb40c209 227 if (string)
4d6cceb4
DE
228 fputstr_unfiltered (string, '"', stream);
229 fprintf_unfiltered (stream, "\"");
fb40c209
AC
230}
231
2b03b41d 232/* This is the only field function that does not align. */
fb40c209
AC
233
234void
2b03b41d
SS
235mi_field_fmt (struct ui_out *uiout, int fldno, int width,
236 enum ui_align align, const char *fldname,
237 const char *format, va_list args)
fb40c209 238{
19ba03f4 239 mi_out_data *data = (mi_out_data *) ui_out_data (uiout);
4d6cceb4 240 struct ui_file *stream;
102040f0 241
76fe6b98
AC
242 if (data->suppress_output)
243 return;
2b03b41d 244
4a9d4ea5 245 stream = data->streams.back ();
fb40c209
AC
246 field_separator (uiout);
247 if (fldname)
4d6cceb4 248 fprintf_unfiltered (stream, "%s=\"", fldname);
fb40c209 249 else
4d6cceb4
DE
250 fputs_unfiltered ("\"", stream);
251 vfprintf_unfiltered (stream, format, args);
252 fputs_unfiltered ("\"", stream);
fb40c209
AC
253}
254
255void
fba45db2 256mi_spaces (struct ui_out *uiout, int numspaces)
fb40c209
AC
257{
258}
259
260void
e2e11a41 261mi_text (struct ui_out *uiout, const char *string)
fb40c209
AC
262{
263}
264
265void
7fb048a2 266mi_message (struct ui_out *uiout, const char *format, va_list args)
fb40c209
AC
267{
268}
269
270void
d2c0eef4 271mi_wrap_hint (struct ui_out *uiout, const char *identstring)
fb40c209
AC
272{
273 wrap_here (identstring);
274}
275
276void
fba45db2 277mi_flush (struct ui_out *uiout)
fb40c209 278{
19ba03f4 279 mi_out_data *data = (mi_out_data *) ui_out_data (uiout);
4a9d4ea5 280 struct ui_file *stream = data->streams.back ();
102040f0 281
4d6cceb4 282 gdb_flush (stream);
fb40c209
AC
283}
284
8d3788bd
VP
285int
286mi_redirect (struct ui_out *uiout, struct ui_file *outstream)
287{
19ba03f4 288 mi_out_data *data = (mi_out_data *) ui_out_data (uiout);
8d3788bd
VP
289
290 if (outstream != NULL)
4a9d4ea5 291 data->streams.push_back (outstream);
4d6cceb4 292 else
4a9d4ea5 293 data->streams.pop_back ();
8d3788bd
VP
294
295 return 0;
296}
297
fb40c209
AC
298/* local functions */
299
fb40c209
AC
300/* access to ui_out format private members */
301
302static void
303field_separator (struct ui_out *uiout)
304{
19ba03f4 305 mi_out_data *data = (mi_out_data *) ui_out_data (uiout);
4a9d4ea5 306 ui_file *stream = data->streams.back ();
102040f0 307
59807497
AC
308 if (data->suppress_field_separator)
309 data->suppress_field_separator = 0;
fb40c209 310 else
4d6cceb4 311 fputc_unfiltered (',', stream);
fb40c209
AC
312}
313
314static void
2b03b41d 315mi_open (struct ui_out *uiout, const char *name, enum ui_out_type type)
fb40c209 316{
19ba03f4 317 mi_out_data *data = (mi_out_data *) ui_out_data (uiout);
4a9d4ea5 318 ui_file *stream = data->streams.back ();
102040f0 319
d5e8ba62 320 field_separator (uiout);
59807497 321 data->suppress_field_separator = 1;
d5e8ba62 322 if (name)
4d6cceb4 323 fprintf_unfiltered (stream, "%s=", name);
5a9aa5dc
AC
324 switch (type)
325 {
326 case ui_out_type_tuple:
4d6cceb4 327 fputc_unfiltered ('{', stream);
5a9aa5dc
AC
328 break;
329 case ui_out_type_list:
4d6cceb4 330 fputc_unfiltered ('[', stream);
5a9aa5dc
AC
331 break;
332 default:
e2e0b3e5 333 internal_error (__FILE__, __LINE__, _("bad switch"));
5a9aa5dc 334 }
fb40c209
AC
335}
336
337static void
2b03b41d 338mi_close (struct ui_out *uiout, enum ui_out_type type)
fb40c209 339{
19ba03f4 340 mi_out_data *data = (mi_out_data *) ui_out_data (uiout);
4a9d4ea5 341 ui_file *stream = data->streams.back ();
102040f0 342
5a9aa5dc
AC
343 switch (type)
344 {
345 case ui_out_type_tuple:
4d6cceb4 346 fputc_unfiltered ('}', stream);
5a9aa5dc
AC
347 break;
348 case ui_out_type_list:
4d6cceb4 349 fputc_unfiltered (']', stream);
5a9aa5dc
AC
350 break;
351 default:
e2e0b3e5 352 internal_error (__FILE__, __LINE__, _("bad switch"));
5a9aa5dc 353 }
59807497 354 data->suppress_field_separator = 0;
fb40c209
AC
355}
356
2b03b41d 357/* Clear the buffer. */
fb40c209
AC
358
359void
360mi_out_rewind (struct ui_out *uiout)
361{
19ba03f4 362 mi_out_data *data = (mi_out_data *) ui_out_data (uiout);
4a9d4ea5 363 ui_file *stream = data->streams.back ();
102040f0 364
4d6cceb4 365 ui_file_rewind (stream);
fb40c209
AC
366}
367
2b03b41d 368/* Dump the buffer onto the specified stream. */
fb40c209 369
fb40c209 370void
2b03b41d 371mi_out_put (struct ui_out *uiout, struct ui_file *stream)
fb40c209 372{
19ba03f4 373 mi_out_data *data = (mi_out_data *) ui_out_data (uiout);
4a9d4ea5 374 ui_file *outstream = data->streams.back ();
102040f0 375
4d6cceb4
DE
376 ui_file_put (outstream, ui_file_write_for_put, stream);
377 ui_file_rewind (outstream);
fb40c209
AC
378}
379
2b03b41d 380/* Return the current MI version. */
c7ec4050
AC
381
382int
383mi_version (struct ui_out *uiout)
384{
19ba03f4 385 mi_out_data *data = (mi_out_data *) ui_out_data (uiout);
102040f0 386
c7ec4050
AC
387 return data->mi_version;
388}
389
4d6cceb4
DE
390/* Constructor for an `mi_out_data' object. */
391
392static void
393mi_out_data_ctor (mi_out_data *self, int mi_version, struct ui_file *stream)
394{
395 gdb_assert (stream != NULL);
396
4a9d4ea5 397 self->streams.push_back (stream);
4d6cceb4
DE
398
399 self->suppress_field_separator = 0;
400 self->suppress_output = 0;
401 self->mi_version = mi_version;
402}
403
404/* The destructor. */
405
406static void
407mi_out_data_dtor (struct ui_out *ui_out)
408{
19ba03f4 409 mi_out_data *data = (mi_out_data *) ui_out_data (ui_out);
4d6cceb4 410
5486f164 411 delete data;
4d6cceb4
DE
412}
413
2b03b41d 414/* Initialize private members at startup. */
fb40c209
AC
415
416struct ui_out *
b30bf9ee 417mi_out_new (int mi_version)
fb40c209
AC
418{
419 int flags = 0;
5486f164 420 mi_out_data *data = new mi_out_data ();
4d6cceb4
DE
421 struct ui_file *stream = mem_fileopen ();
422
423 mi_out_data_ctor (data, mi_version, stream);
fb40c209
AC
424 return ui_out_new (&mi_ui_out_impl, data, flags);
425}
This page took 1.572512 seconds and 4 git commands to generate.