1 /* Output generating routines for GDB CLI. 2 3 Copyright (C) 1999, 2000, 2001, 2002, 2003, 2005, 2007, 2008, 2009 4 Free Software Foundation, Inc. 5 6 Contributed by Cygnus Solutions. 7 Written by Fernando Nasser for Cygnus. 8 9 This file is part of GDB. 10 11 This program is free software; you can redistribute it and/or modify 12 it under the terms of the GNU General Public License as published by 13 the Free Software Foundation; either version 3 of the License, or 14 (at your option) any later version. 15 16 This program is distributed in the hope that it will be useful, 17 but WITHOUT ANY WARRANTY; without even the implied warranty of 18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 GNU General Public License for more details. 20 21 You should have received a copy of the GNU General Public License 22 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 23 24 #include "defs.h" 25 #include "ui-out.h" 26 #include "tui.h" 27 #include "gdb_string.h" 28 #include "gdb_assert.h" 29 30 struct ui_out_data 31 { 32 struct ui_file *stream; 33 int suppress_output; 34 int line; 35 int start_of_line; 36 }; 37 typedef struct ui_out_data tui_out_data; 38 39 /* These are the CLI output functions. */ 40 41 static void tui_table_begin (struct ui_out *uiout, 42 int nbrofcols, int nr_rows, 43 const char *tblid); 44 static void tui_table_body (struct ui_out *uiout); 45 static void tui_table_end (struct ui_out *uiout); 46 static void tui_table_header (struct ui_out *uiout, 47 int width, enum ui_align alig, 48 const char *col_name, 49 const char *colhdr); 50 static void tui_begin (struct ui_out *uiout, 51 enum ui_out_type type, 52 int level, const char *lstid); 53 static void tui_end (struct ui_out *uiout, 54 enum ui_out_type type, int level); 55 static void tui_field_int (struct ui_out *uiout, 56 int fldno, int width, 57 enum ui_align alig, 58 const char *fldname, int value); 59 static void tui_field_skip (struct ui_out *uiout, 60 int fldno, int width, 61 enum ui_align alig, 62 const char *fldname); 63 static void tui_field_string (struct ui_out *uiout, 64 int fldno, int width, 65 enum ui_align alig, 66 const char *fldname, 67 const char *string); 68 static void tui_field_fmt (struct ui_out *uiout, int fldno, 69 int width, enum ui_align align, 70 const char *fldname, 71 const char *format, 72 va_list args) 73 ATTR_FORMAT (printf, 6, 0); 74 static void tui_spaces (struct ui_out *uiout, int numspaces); 75 static void tui_text (struct ui_out *uiout, const char *string); 76 static void tui_message (struct ui_out *uiout, int verbosity, 77 const char *format, va_list args) 78 ATTR_FORMAT (printf, 3, 0); 79 static void tui_wrap_hint (struct ui_out *uiout, 80 char *identstring); 81 static void tui_flush (struct ui_out *uiout); 82 83 /* This is the CLI ui-out implementation functions vector. */ 84 85 /* FIXME: This can be initialized dynamically after default is set to 86 handle initial output in main.c. */ 87 88 static struct ui_out_impl tui_ui_out_impl = { 89 tui_table_begin, 90 tui_table_body, 91 tui_table_end, 92 tui_table_header, 93 tui_begin, 94 tui_end, 95 tui_field_int, 96 tui_field_skip, 97 tui_field_string, 98 tui_field_fmt, 99 tui_spaces, 100 tui_text, 101 tui_message, 102 tui_wrap_hint, 103 tui_flush, 104 NULL, 105 0, /* Does not need MI hacks (i.e. needs CLI hacks). */ 106 }; 107 108 /* Prototypes for local functions. */ 109 110 extern void _initialize_tui_out (void); 111 112 static void field_separator (void); 113 114 static void out_field_fmt (struct ui_out *uiout, 115 int fldno, 116 const char *fldname, 117 const char *format,...) 118 ATTR_FORMAT (printf, 4, 5); 119 120 /* local variables */ 121 122 /* (none yet) */ 123 124 /* Mark beginning of a table. */ 125 126 void 127 tui_table_begin (struct ui_out *uiout, 128 int nbrofcols, 129 int nr_rows, 130 const char *tblid) 131 { 132 tui_out_data *data = ui_out_data (uiout); 133 if (nr_rows == 0) 134 data->suppress_output = 1; 135 else 136 /* Only the table suppresses the output and, fortunately, a table 137 is not a recursive data structure. */ 138 gdb_assert (data->suppress_output == 0); 139 } 140 141 /* Mark beginning of a table body. */ 142 143 void 144 tui_table_body (struct ui_out *uiout) 145 { 146 tui_out_data *data = ui_out_data (uiout); 147 if (data->suppress_output) 148 return; 149 /* First, close the table header line. */ 150 tui_text (uiout, "\n"); 151 } 152 153 /* Mark end of a table. */ 154 155 void 156 tui_table_end (struct ui_out *uiout) 157 { 158 tui_out_data *data = ui_out_data (uiout); 159 data->suppress_output = 0; 160 } 161 162 /* Specify table header. */ 163 164 void 165 tui_table_header (struct ui_out *uiout, 166 int width, 167 enum ui_align alignment, 168 const char *col_name, 169 const char *colhdr) 170 { 171 tui_out_data *data = ui_out_data (uiout); 172 if (data->suppress_output) 173 return; 174 tui_field_string (uiout, 0, width, alignment, 0, colhdr); 175 } 176 177 /* Mark beginning of a list. */ 178 179 void 180 tui_begin (struct ui_out *uiout, 181 enum ui_out_type type, 182 int level, 183 const char *id) 184 { 185 tui_out_data *data = ui_out_data (uiout); 186 if (data->suppress_output) 187 return; 188 } 189 190 /* Mark end of a list. */ 191 192 void 193 tui_end (struct ui_out *uiout, 194 enum ui_out_type type, 195 int level) 196 { 197 tui_out_data *data = ui_out_data (uiout); 198 if (data->suppress_output) 199 return; 200 } 201 202 /* Output an int field. */ 203 204 void 205 tui_field_int (struct ui_out *uiout, 206 int fldno, int width, 207 enum ui_align alignment, 208 const char *fldname, 209 int value) 210 { 211 char buffer[20]; /* FIXME: how many chars long a %d can become? */ 212 213 tui_out_data *data = ui_out_data (uiout); 214 if (data->suppress_output) 215 return; 216 217 /* Don't print line number, keep it for later. */ 218 if (data->start_of_line == 0 && strcmp (fldname, "line") == 0) 219 { 220 data->start_of_line ++; 221 data->line = value; 222 return; 223 } 224 data->start_of_line ++; 225 sprintf (buffer, "%d", value); 226 tui_field_string (uiout, fldno, width, alignment, fldname, buffer); 227 } 228 229 /* Used to ommit a field. */ 230 231 void 232 tui_field_skip (struct ui_out *uiout, 233 int fldno, int width, 234 enum ui_align alignment, 235 const char *fldname) 236 { 237 tui_out_data *data = ui_out_data (uiout); 238 if (data->suppress_output) 239 return; 240 tui_field_string (uiout, fldno, width, alignment, fldname, ""); 241 } 242 243 /* Other specific tui_field_* end up here so alignment and field 244 separators are both handled by tui_field_string. */ 245 246 void 247 tui_field_string (struct ui_out *uiout, 248 int fldno, int width, 249 enum ui_align align, 250 const char *fldname, 251 const char *string) 252 { 253 int before = 0; 254 int after = 0; 255 256 tui_out_data *data = ui_out_data (uiout); 257 if (data->suppress_output) 258 return; 259 260 if (fldname && data->line > 0 && strcmp (fldname, "file") == 0) 261 { 262 data->start_of_line ++; 263 if (data->line > 0) 264 { 265 tui_show_source (string, data->line); 266 } 267 return; 268 } 269 270 data->start_of_line ++; 271 if ((align != ui_noalign) && string) 272 { 273 before = width - strlen (string); 274 if (before <= 0) 275 before = 0; 276 else 277 { 278 if (align == ui_right) 279 after = 0; 280 else if (align == ui_left) 281 { 282 after = before; 283 before = 0; 284 } 285 else 286 /* ui_center */ 287 { 288 after = before / 2; 289 before -= after; 290 } 291 } 292 } 293 294 if (before) 295 ui_out_spaces (uiout, before); 296 if (string) 297 out_field_fmt (uiout, fldno, fldname, "%s", string); 298 if (after) 299 ui_out_spaces (uiout, after); 300 301 if (align != ui_noalign) 302 field_separator (); 303 } 304 305 /* This is the only field function that does not align. */ 306 307 void 308 tui_field_fmt (struct ui_out *uiout, int fldno, 309 int width, enum ui_align align, 310 const char *fldname, 311 const char *format, 312 va_list args) 313 { 314 tui_out_data *data = ui_out_data (uiout); 315 if (data->suppress_output) 316 return; 317 318 data->start_of_line ++; 319 vfprintf_filtered (data->stream, format, args); 320 321 if (align != ui_noalign) 322 field_separator (); 323 } 324 325 void 326 tui_spaces (struct ui_out *uiout, int numspaces) 327 { 328 tui_out_data *data = ui_out_data (uiout); 329 if (data->suppress_output) 330 return; 331 print_spaces_filtered (numspaces, data->stream); 332 } 333 334 void 335 tui_text (struct ui_out *uiout, const char *string) 336 { 337 tui_out_data *data = ui_out_data (uiout); 338 if (data->suppress_output) 339 return; 340 data->start_of_line ++; 341 if (data->line > 0) 342 { 343 if (strchr (string, '\n') != 0) 344 { 345 data->line = -1; 346 data->start_of_line = 0; 347 } 348 return; 349 } 350 if (strchr (string, '\n')) 351 data->start_of_line = 0; 352 fputs_filtered (string, data->stream); 353 } 354 355 void 356 tui_message (struct ui_out *uiout, 357 int verbosity, 358 const char *format, 359 va_list args) 360 { 361 tui_out_data *data = ui_out_data (uiout); 362 if (data->suppress_output) 363 return; 364 if (ui_out_get_verblvl (uiout) >= verbosity) 365 vfprintf_unfiltered (data->stream, format, args); 366 } 367 368 void 369 tui_wrap_hint (struct ui_out *uiout, char *identstring) 370 { 371 tui_out_data *data = ui_out_data (uiout); 372 if (data->suppress_output) 373 return; 374 wrap_here (identstring); 375 } 376 377 void 378 tui_flush (struct ui_out *uiout) 379 { 380 tui_out_data *data = ui_out_data (uiout); 381 gdb_flush (data->stream); 382 } 383 384 /* Local functions. */ 385 386 /* Like tui_field_fmt, but takes a variable number of args and makes a 387 va_list and does not insert a separator. */ 388 389 /* VARARGS */ 390 static void 391 out_field_fmt (struct ui_out *uiout, 392 int fldno, 393 const char *fldname, 394 const char *format,...) 395 { 396 tui_out_data *data = ui_out_data (uiout); 397 va_list args; 398 399 va_start (args, format); 400 vfprintf_filtered (data->stream, format, args); 401 402 va_end (args); 403 } 404 405 /* Access to ui_out format private members. */ 406 407 static void 408 field_separator (void) 409 { 410 tui_out_data *data = ui_out_data (uiout); 411 fputc_filtered (' ', data->stream); 412 } 413 414 /* Initalize private members at startup. */ 415 416 struct ui_out * 417 tui_out_new (struct ui_file *stream) 418 { 419 int flags = 0; 420 421 tui_out_data *data = XMALLOC (tui_out_data); 422 data->stream = stream; 423 data->suppress_output = 0; 424 data->line = -1; 425 data->start_of_line = 0; 426 return ui_out_new (&tui_ui_out_impl, data, flags); 427 } 428 429 /* Standard gdb initialization hook. */ 430 void 431 _initialize_tui_out (void) 432 { 433 /* Nothing needs to be done. */ 434 } 435