6e69d7cb348bf8758685f89b912e0af415e9dd47
[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 mi_version;
31 std::vector<ui_file *> streams;
32 };
33 typedef struct mi_ui_out_data mi_out_data;
34
35 /* These are the MI output functions */
36
37 static void mi_out_data_dtor (struct ui_out *ui_out);
38 static void mi_table_begin (struct ui_out *uiout, int nbrofcols,
39 int nr_rows, const char *tblid);
40 static void mi_table_body (struct ui_out *uiout);
41 static void mi_table_end (struct ui_out *uiout);
42 static void mi_table_header (struct ui_out *uiout, int width,
43 enum ui_align alignment,
44 const std::string &col_name,
45 const std::string &col_hdr);
46 static void mi_begin (struct ui_out *uiout, enum ui_out_type type,
47 const char *id);
48 static void mi_end (struct ui_out *uiout, enum ui_out_type type);
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 /* close the table header line if there were any headers */
121 mi_close (uiout, ui_out_type_list);
122 mi_open (uiout, "body", ui_out_type_list);
123 }
124
125 /* Mark end of a table. */
126
127 void
128 mi_table_end (struct ui_out *uiout)
129 {
130 mi_out_data *data = (mi_out_data *) ui_out_data (uiout);
131
132 mi_close (uiout, ui_out_type_list); /* body */
133 mi_close (uiout, ui_out_type_tuple);
134 }
135
136 /* Specify table header. */
137
138 void
139 mi_table_header (struct ui_out *uiout, int width, enum ui_align alignment,
140 const std::string &col_name, const std::string &col_hdr)
141 {
142 mi_out_data *data = (mi_out_data *) ui_out_data (uiout);
143
144 mi_open (uiout, NULL, ui_out_type_tuple);
145 mi_field_int (uiout, 0, 0, ui_center, "width", width);
146 mi_field_int (uiout, 0, 0, ui_center, "alignment", alignment);
147 mi_field_string (uiout, 0, 0, ui_center, "col_name", col_name.c_str ());
148 mi_field_string (uiout, 0, width, alignment, "colhdr", col_hdr.c_str ());
149 mi_close (uiout, ui_out_type_tuple);
150 }
151
152 /* Mark beginning of a list. */
153
154 void
155 mi_begin (struct ui_out *uiout, enum ui_out_type type, const char *id)
156 {
157 mi_out_data *data = (mi_out_data *) ui_out_data (uiout);
158
159 mi_open (uiout, id, type);
160 }
161
162 /* Mark end of a list. */
163
164 void
165 mi_end (struct ui_out *uiout, enum ui_out_type type)
166 {
167 mi_out_data *data = (mi_out_data *) ui_out_data (uiout);
168
169 mi_close (uiout, type);
170 }
171
172 /* Output an int field. */
173
174 static void
175 mi_field_int (struct ui_out *uiout, int fldno, int width,
176 enum ui_align alignment, const char *fldname, int value)
177 {
178 char buffer[20]; /* FIXME: how many chars long a %d can become? */
179 mi_out_data *data = (mi_out_data *) ui_out_data (uiout);
180
181 xsnprintf (buffer, sizeof (buffer), "%d", value);
182 mi_field_string (uiout, fldno, width, alignment, fldname, buffer);
183 }
184
185 /* Used to omit a field. */
186
187 void
188 mi_field_skip (struct ui_out *uiout, int fldno, int width,
189 enum ui_align alignment, const char *fldname)
190 {
191 }
192
193 /* Other specific mi_field_* end up here so alignment and field
194 separators are both handled by mi_field_string. */
195
196 void
197 mi_field_string (struct ui_out *uiout, int fldno, int width,
198 enum ui_align align, const char *fldname, const char *string)
199 {
200 mi_out_data *data = (mi_out_data *) ui_out_data (uiout);
201 struct ui_file *stream;
202
203 stream = data->streams.back ();
204 field_separator (uiout);
205 if (fldname)
206 fprintf_unfiltered (stream, "%s=", fldname);
207 fprintf_unfiltered (stream, "\"");
208 if (string)
209 fputstr_unfiltered (string, '"', stream);
210 fprintf_unfiltered (stream, "\"");
211 }
212
213 /* This is the only field function that does not align. */
214
215 void
216 mi_field_fmt (struct ui_out *uiout, int fldno, int width,
217 enum ui_align align, const char *fldname,
218 const char *format, va_list args)
219 {
220 mi_out_data *data = (mi_out_data *) ui_out_data (uiout);
221 struct ui_file *stream;
222
223 stream = data->streams.back ();
224 field_separator (uiout);
225 if (fldname)
226 fprintf_unfiltered (stream, "%s=\"", fldname);
227 else
228 fputs_unfiltered ("\"", stream);
229 vfprintf_unfiltered (stream, format, args);
230 fputs_unfiltered ("\"", stream);
231 }
232
233 void
234 mi_spaces (struct ui_out *uiout, int numspaces)
235 {
236 }
237
238 void
239 mi_text (struct ui_out *uiout, const char *string)
240 {
241 }
242
243 void
244 mi_message (struct ui_out *uiout, const char *format, va_list args)
245 {
246 }
247
248 void
249 mi_wrap_hint (struct ui_out *uiout, const char *identstring)
250 {
251 wrap_here (identstring);
252 }
253
254 void
255 mi_flush (struct ui_out *uiout)
256 {
257 mi_out_data *data = (mi_out_data *) ui_out_data (uiout);
258 struct ui_file *stream = data->streams.back ();
259
260 gdb_flush (stream);
261 }
262
263 int
264 mi_redirect (struct ui_out *uiout, struct ui_file *outstream)
265 {
266 mi_out_data *data = (mi_out_data *) ui_out_data (uiout);
267
268 if (outstream != NULL)
269 data->streams.push_back (outstream);
270 else
271 data->streams.pop_back ();
272
273 return 0;
274 }
275
276 /* local functions */
277
278 /* access to ui_out format private members */
279
280 static void
281 field_separator (struct ui_out *uiout)
282 {
283 mi_out_data *data = (mi_out_data *) ui_out_data (uiout);
284 ui_file *stream = data->streams.back ();
285
286 if (data->suppress_field_separator)
287 data->suppress_field_separator = 0;
288 else
289 fputc_unfiltered (',', stream);
290 }
291
292 static void
293 mi_open (struct ui_out *uiout, const char *name, enum ui_out_type type)
294 {
295 mi_out_data *data = (mi_out_data *) ui_out_data (uiout);
296 ui_file *stream = data->streams.back ();
297
298 field_separator (uiout);
299 data->suppress_field_separator = 1;
300 if (name)
301 fprintf_unfiltered (stream, "%s=", name);
302 switch (type)
303 {
304 case ui_out_type_tuple:
305 fputc_unfiltered ('{', stream);
306 break;
307 case ui_out_type_list:
308 fputc_unfiltered ('[', stream);
309 break;
310 default:
311 internal_error (__FILE__, __LINE__, _("bad switch"));
312 }
313 }
314
315 static void
316 mi_close (struct ui_out *uiout, enum ui_out_type type)
317 {
318 mi_out_data *data = (mi_out_data *) ui_out_data (uiout);
319 ui_file *stream = data->streams.back ();
320
321 switch (type)
322 {
323 case ui_out_type_tuple:
324 fputc_unfiltered ('}', stream);
325 break;
326 case ui_out_type_list:
327 fputc_unfiltered (']', stream);
328 break;
329 default:
330 internal_error (__FILE__, __LINE__, _("bad switch"));
331 }
332 data->suppress_field_separator = 0;
333 }
334
335 /* Clear the buffer. */
336
337 void
338 mi_out_rewind (struct ui_out *uiout)
339 {
340 mi_out_data *data = (mi_out_data *) ui_out_data (uiout);
341 ui_file *stream = data->streams.back ();
342
343 ui_file_rewind (stream);
344 }
345
346 /* Dump the buffer onto the specified stream. */
347
348 void
349 mi_out_put (struct ui_out *uiout, struct ui_file *stream)
350 {
351 mi_out_data *data = (mi_out_data *) ui_out_data (uiout);
352 ui_file *outstream = data->streams.back ();
353
354 ui_file_put (outstream, ui_file_write_for_put, stream);
355 ui_file_rewind (outstream);
356 }
357
358 /* Return the current MI version. */
359
360 int
361 mi_version (struct ui_out *uiout)
362 {
363 mi_out_data *data = (mi_out_data *) ui_out_data (uiout);
364
365 return data->mi_version;
366 }
367
368 /* Constructor for an `mi_out_data' object. */
369
370 static void
371 mi_out_data_ctor (mi_out_data *self, int mi_version, struct ui_file *stream)
372 {
373 gdb_assert (stream != NULL);
374
375 self->streams.push_back (stream);
376
377 self->suppress_field_separator = 0;
378 self->mi_version = mi_version;
379 }
380
381 /* The destructor. */
382
383 static void
384 mi_out_data_dtor (struct ui_out *ui_out)
385 {
386 mi_out_data *data = (mi_out_data *) ui_out_data (ui_out);
387
388 delete data;
389 }
390
391 /* Initialize private members at startup. */
392
393 struct ui_out *
394 mi_out_new (int mi_version)
395 {
396 int flags = 0;
397 mi_out_data *data = new mi_out_data ();
398 struct ui_file *stream = mem_fileopen ();
399
400 mi_out_data_ctor (data, mi_version, stream);
401 return ui_out_new (&mi_ui_out_impl, data, flags);
402 }
This page took 0.044397 seconds and 3 git commands to generate.