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