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