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