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 28struct ui_out_data 29 { 30 int suppress_field_separator; 31 int suppress_output; 32 int mi_version; 33 struct ui_file *buffer; 34 }; 35typedef struct ui_out_data mi_out_data; 36 37/* These are the MI output functions */ 38 39static void mi_table_begin (struct ui_out *uiout, int nbrofcols, 40 int nr_rows, const char *tblid); 41static void mi_table_body (struct ui_out *uiout); 42static void mi_table_end (struct ui_out *uiout); 43static void mi_table_header (struct ui_out *uiout, int width, 44 enum ui_align alig, const char *col_name, 45 const char *colhdr); 46static void mi_begin (struct ui_out *uiout, enum ui_out_type type, 47 int level, const char *id); 48static void mi_end (struct ui_out *uiout, enum ui_out_type type, int level); 49static void mi_field_int (struct ui_out *uiout, int fldno, int width, 50 enum ui_align alig, const char *fldname, int value); 51static void mi_field_skip (struct ui_out *uiout, int fldno, int width, 52 enum ui_align alig, const char *fldname); 53static void mi_field_string (struct ui_out *uiout, int fldno, int width, 54 enum ui_align alig, const char *fldname, 55 const char *string); 56static 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); 60static void mi_spaces (struct ui_out *uiout, int numspaces); 61static void mi_text (struct ui_out *uiout, const char *string); 62static void mi_message (struct ui_out *uiout, int verbosity, 63 const char *format, va_list args); 64static void mi_wrap_hint (struct ui_out *uiout, char *identstring); 65static 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 72struct 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 95extern void _initialize_mi_out (void); 96static void field_separator (struct ui_out *uiout); 97static void mi_open (struct ui_out *uiout, const char *name, 98 enum ui_out_type type); 99static void mi_close (struct ui_out *uiout, enum ui_out_type type); 100 101/* Mark beginning of a table */ 102 103void 104mi_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 120void 121mi_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 133void 134mi_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 144void 145mi_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 162void 163mi_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 176void 177mi_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 189void 190mi_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 204void 205mi_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 217void 218mi_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 239void 240mi_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 258void 259mi_spaces (struct ui_out *uiout, int numspaces) 260{ 261} 262 263void 264mi_text (struct ui_out *uiout, const char *string) 265{ 266} 267 268void 269mi_message (struct ui_out *uiout, int verbosity, 270 const char *format, 271 va_list args) 272{ 273} 274 275void 276mi_wrap_hint (struct ui_out *uiout, char *identstring) 277{ 278 wrap_here (identstring); 279} 280 281void 282mi_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 292static void 293field_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 302static void 303mi_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 325static void 326mi_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 346void 347mi_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 355void 356mi_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 364static void 365do_write (void *data, const char *buffer, long length_buffer) 366{ 367 ui_file_write (data, buffer, length_buffer); 368} 369 370void 371mi_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 381int 382mi_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 390struct ui_out * 391mi_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 */ 405void 406_initialize_mi_out (void) 407{ 408 /* nothing happens here */ 409} 410