1 /* MI Command Set - output generating routines. 2 3 Copyright 2000, 2002, 2003, 2004 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 2 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, write to the Free Software 21 Foundation, Inc., 59 Temple Place - Suite 330, 22 Boston, MA 02111-1307, USA. */ 23 24 #include "defs.h" 25 #include "ui-out.h" 26 #include "mi-out.h" 27 28 struct ui_out_data 29 { 30 int suppress_field_separator; 31 int suppress_output; 32 int mi_version; 33 struct ui_file *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); 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 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_out_data *data = ui_out_data (uiout); 110 mi_open (uiout, tblid, ui_out_type_tuple); 111 mi_field_int (uiout, -1/*fldno*/, -1/*width*/, -1/*alin*/, 112 "nr_rows", nr_rows); 113 mi_field_int (uiout, -1/*fldno*/, -1/*width*/, -1/*alin*/, 114 "nr_cols", nr_cols); 115 mi_open (uiout, "hdr", ui_out_type_list); 116 } 117 118 /* Mark beginning of a table body */ 119 120 void 121 mi_table_body (struct ui_out *uiout) 122 { 123 mi_out_data *data = ui_out_data (uiout); 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 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, 147 const char *colhdr) 148 { 149 mi_out_data *data = ui_out_data (uiout); 150 if (data->suppress_output) 151 return; 152 mi_open (uiout, NULL, ui_out_type_tuple); 153 mi_field_int (uiout, 0, 0, 0, "width", width); 154 mi_field_int (uiout, 0, 0, 0, "alignment", alignment); 155 mi_field_string (uiout, 0, 0, 0, "col_name", col_name); 156 mi_field_string (uiout, 0, width, alignment, "colhdr", colhdr); 157 mi_close (uiout, ui_out_type_tuple); 158 } 159 160 /* Mark beginning of a list */ 161 162 void 163 mi_begin (struct ui_out *uiout, 164 enum ui_out_type type, 165 int level, 166 const char *id) 167 { 168 mi_out_data *data = ui_out_data (uiout); 169 if (data->suppress_output) 170 return; 171 mi_open (uiout, id, type); 172 } 173 174 /* Mark end of a list */ 175 176 void 177 mi_end (struct ui_out *uiout, 178 enum ui_out_type type, 179 int level) 180 { 181 mi_out_data *data = ui_out_data (uiout); 182 if (data->suppress_output) 183 return; 184 mi_close (uiout, type); 185 } 186 187 /* output an int field */ 188 189 void 190 mi_field_int (struct ui_out *uiout, int fldno, int width, 191 enum ui_align alignment, const char *fldname, int value) 192 { 193 char buffer[20]; /* FIXME: how many chars long a %d can become? */ 194 mi_out_data *data = ui_out_data (uiout); 195 if (data->suppress_output) 196 return; 197 198 sprintf (buffer, "%d", value); 199 mi_field_string (uiout, fldno, width, alignment, fldname, buffer); 200 } 201 202 /* used to ommit a field */ 203 204 void 205 mi_field_skip (struct ui_out *uiout, int fldno, int width, 206 enum ui_align alignment, const char *fldname) 207 { 208 mi_out_data *data = ui_out_data (uiout); 209 if (data->suppress_output) 210 return; 211 mi_field_string (uiout, fldno, width, alignment, fldname, ""); 212 } 213 214 /* other specific mi_field_* end up here so alignment and field 215 separators are both handled by mi_field_string */ 216 217 void 218 mi_field_string (struct ui_out *uiout, 219 int fldno, 220 int width, 221 enum ui_align align, 222 const char *fldname, 223 const char *string) 224 { 225 mi_out_data *data = ui_out_data (uiout); 226 if (data->suppress_output) 227 return; 228 field_separator (uiout); 229 if (fldname) 230 fprintf_unfiltered (data->buffer, "%s=", fldname); 231 fprintf_unfiltered (data->buffer, "\""); 232 if (string) 233 fputstr_unfiltered (string, '"', data->buffer); 234 fprintf_unfiltered (data->buffer, "\""); 235 } 236 237 /* This is the only field function that does not align */ 238 239 void 240 mi_field_fmt (struct ui_out *uiout, int fldno, 241 int width, enum ui_align align, 242 const char *fldname, 243 const char *format, 244 va_list args) 245 { 246 mi_out_data *data = ui_out_data (uiout); 247 if (data->suppress_output) 248 return; 249 field_separator (uiout); 250 if (fldname) 251 fprintf_unfiltered (data->buffer, "%s=\"", fldname); 252 else 253 fputs_unfiltered ("\"", data->buffer); 254 vfprintf_unfiltered (data->buffer, format, args); 255 fputs_unfiltered ("\"", data->buffer); 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, int verbosity, 270 const char *format, 271 va_list args) 272 { 273 } 274 275 void 276 mi_wrap_hint (struct ui_out *uiout, char *identstring) 277 { 278 wrap_here (identstring); 279 } 280 281 void 282 mi_flush (struct ui_out *uiout) 283 { 284 mi_out_data *data = ui_out_data (uiout); 285 gdb_flush (data->buffer); 286 } 287 288 /* local functions */ 289 290 /* access to ui_out format private members */ 291 292 static void 293 field_separator (struct ui_out *uiout) 294 { 295 mi_out_data *data = ui_out_data (uiout); 296 if (data->suppress_field_separator) 297 data->suppress_field_separator = 0; 298 else 299 fputc_unfiltered (',', data->buffer); 300 } 301 302 static void 303 mi_open (struct ui_out *uiout, 304 const char *name, 305 enum ui_out_type type) 306 { 307 mi_out_data *data = ui_out_data (uiout); 308 field_separator (uiout); 309 data->suppress_field_separator = 1; 310 if (name) 311 fprintf_unfiltered (data->buffer, "%s=", name); 312 switch (type) 313 { 314 case ui_out_type_tuple: 315 fputc_unfiltered ('{', data->buffer); 316 break; 317 case ui_out_type_list: 318 fputc_unfiltered ('[', data->buffer); 319 break; 320 default: 321 internal_error (__FILE__, __LINE__, "bad switch"); 322 } 323 } 324 325 static void 326 mi_close (struct ui_out *uiout, 327 enum ui_out_type type) 328 { 329 mi_out_data *data = ui_out_data (uiout); 330 switch (type) 331 { 332 case ui_out_type_tuple: 333 fputc_unfiltered ('}', data->buffer); 334 break; 335 case ui_out_type_list: 336 fputc_unfiltered (']', data->buffer); 337 break; 338 default: 339 internal_error (__FILE__, __LINE__, "bad switch"); 340 } 341 data->suppress_field_separator = 0; 342 } 343 344 /* add a string to the buffer */ 345 346 void 347 mi_out_buffered (struct ui_out *uiout, char *string) 348 { 349 mi_out_data *data = ui_out_data (uiout); 350 fprintf_unfiltered (data->buffer, "%s", string); 351 } 352 353 /* clear the buffer */ 354 355 void 356 mi_out_rewind (struct ui_out *uiout) 357 { 358 mi_out_data *data = ui_out_data (uiout); 359 ui_file_rewind (data->buffer); 360 } 361 362 /* dump the buffer onto the specified stream */ 363 364 static void 365 do_write (void *data, const char *buffer, long length_buffer) 366 { 367 ui_file_write (data, buffer, length_buffer); 368 } 369 370 void 371 mi_out_put (struct ui_out *uiout, 372 struct ui_file *stream) 373 { 374 mi_out_data *data = ui_out_data (uiout); 375 ui_file_put (data->buffer, do_write, stream); 376 ui_file_rewind (data->buffer); 377 } 378 379 /* Current MI version. */ 380 381 int 382 mi_version (struct ui_out *uiout) 383 { 384 mi_out_data *data = ui_out_data (uiout); 385 return data->mi_version; 386 } 387 388 /* initalize private members at startup */ 389 390 struct ui_out * 391 mi_out_new (int mi_version) 392 { 393 int flags = 0; 394 mi_out_data *data = XMALLOC (mi_out_data); 395 data->suppress_field_separator = 0; 396 data->suppress_output = 0; 397 data->mi_version = mi_version; 398 /* FIXME: This code should be using a ``string_file'' and not the 399 TUI buffer hack. */ 400 data->buffer = mem_fileopen (); 401 return ui_out_new (&mi_ui_out_impl, data, flags); 402 } 403 404 /* standard gdb initialization hook */ 405 void 406 _initialize_mi_out (void) 407 { 408 /* nothing happens here */ 409 } 410