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