1 /* Output generating routines for GDB. 2 3 Copyright (C) 1999, 2000, 2001, 2002, 2004, 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 "gdb_string.h" 26 #include "expression.h" /* For language.h */ 27 #include "language.h" 28 #include "ui-out.h" 29 #include "gdb_assert.h" 30 31 /* table header structures */ 32 33 struct ui_out_hdr 34 { 35 int colno; 36 int width; 37 int alignment; 38 char *col_name; 39 char *colhdr; 40 struct ui_out_hdr *next; 41 }; 42 43 /* Maintain a stack so that the info applicable to the inner most list 44 is always available. Stack/nested level 0 is reserved for the 45 top-level result. */ 46 47 enum { MAX_UI_OUT_LEVELS = 6 }; 48 49 struct ui_out_level 50 { 51 /* Count each field; the first element is for non-list fields */ 52 int field_count; 53 /* The type of this level. */ 54 enum ui_out_type type; 55 }; 56 57 /* Tables are special. Maintain a separate structure that tracks 58 their state. At present an output can only contain a single table 59 but that restriction might eventually be lifted. */ 60 61 struct ui_out_table 62 { 63 /* If on, a table is being generated. */ 64 int flag; 65 66 /* If on, the body of a table is being generated. If off, the table 67 header is being generated. */ 68 int body_flag; 69 70 /* The level at which each entry of the table is to be found. A row 71 (a tuple) is made up of entries. Consequently ENTRY_LEVEL is one 72 above that of the table. */ 73 int entry_level; 74 75 /* Number of table columns (as specified in the table_begin call). */ 76 int columns; 77 78 /* String identifying the table (as specified in the table_begin 79 call). */ 80 char *id; 81 82 /* Points to the first table header (if any). */ 83 struct ui_out_hdr *header_first; 84 85 /* Points to the last table header (if any). */ 86 struct ui_out_hdr *header_last; 87 88 /* Points to header of NEXT column to format. */ 89 struct ui_out_hdr *header_next; 90 91 }; 92 93 94 /* The ui_out structure */ 95 /* Any change here requires a corresponding one in the initialization 96 of the default uiout, which is statically initialized */ 97 98 struct ui_out 99 { 100 int flags; 101 /* specific implementation of ui-out */ 102 struct ui_out_impl *impl; 103 struct ui_out_data *data; 104 105 /* Sub structure tracking the ui-out depth. */ 106 int level; 107 struct ui_out_level levels[MAX_UI_OUT_LEVELS]; 108 109 /* A table, if any. At present only a single table is supported. */ 110 struct ui_out_table table; 111 }; 112 113 /* The current (inner most) level. */ 114 static struct ui_out_level * 115 current_level (struct ui_out *uiout) 116 { 117 return &uiout->levels[uiout->level]; 118 } 119 120 /* Create a new level, of TYPE. Return the new level's index. */ 121 static int 122 push_level (struct ui_out *uiout, 123 enum ui_out_type type, 124 const char *id) 125 { 126 struct ui_out_level *current; 127 /* We had better not overflow the buffer. */ 128 uiout->level++; 129 gdb_assert (uiout->level >= 0 && uiout->level < MAX_UI_OUT_LEVELS); 130 current = current_level (uiout); 131 current->field_count = 0; 132 current->type = type; 133 return uiout->level; 134 } 135 136 /* Discard the current level, return the discarded level's index. 137 TYPE is the type of the level being discarded. */ 138 static int 139 pop_level (struct ui_out *uiout, 140 enum ui_out_type type) 141 { 142 /* We had better not underflow the buffer. */ 143 gdb_assert (uiout->level > 0 && uiout->level < MAX_UI_OUT_LEVELS); 144 gdb_assert (current_level (uiout)->type == type); 145 uiout->level--; 146 return uiout->level + 1; 147 } 148 149 150 /* These are the default implementation functions */ 151 152 static void default_table_begin (struct ui_out *uiout, int nbrofcols, 153 int nr_rows, const char *tblid); 154 static void default_table_body (struct ui_out *uiout); 155 static void default_table_end (struct ui_out *uiout); 156 static void default_table_header (struct ui_out *uiout, int width, 157 enum ui_align alig, const char *col_name, 158 const char *colhdr); 159 static void default_begin (struct ui_out *uiout, 160 enum ui_out_type type, 161 int level, const char *id); 162 static void default_end (struct ui_out *uiout, 163 enum ui_out_type type, 164 int level); 165 static void default_field_int (struct ui_out *uiout, int fldno, int width, 166 enum ui_align alig, 167 const char *fldname, 168 int value); 169 static void default_field_skip (struct ui_out *uiout, int fldno, int width, 170 enum ui_align alig, 171 const char *fldname); 172 static void default_field_string (struct ui_out *uiout, int fldno, int width, 173 enum ui_align align, 174 const char *fldname, 175 const char *string); 176 static void default_field_fmt (struct ui_out *uiout, int fldno, 177 int width, enum ui_align align, 178 const char *fldname, 179 const char *format, 180 va_list args) ATTR_FORMAT (printf, 6, 0); 181 static void default_spaces (struct ui_out *uiout, int numspaces); 182 static void default_text (struct ui_out *uiout, const char *string); 183 static void default_message (struct ui_out *uiout, int verbosity, 184 const char *format, 185 va_list args) ATTR_FORMAT (printf, 3, 0); 186 static void default_wrap_hint (struct ui_out *uiout, char *identstring); 187 static void default_flush (struct ui_out *uiout); 188 189 /* This is the default ui-out implementation functions vector */ 190 191 struct ui_out_impl default_ui_out_impl = 192 { 193 default_table_begin, 194 default_table_body, 195 default_table_end, 196 default_table_header, 197 default_begin, 198 default_end, 199 default_field_int, 200 default_field_skip, 201 default_field_string, 202 default_field_fmt, 203 default_spaces, 204 default_text, 205 default_message, 206 default_wrap_hint, 207 default_flush, 208 NULL, 209 0, /* Does not need MI hacks. */ 210 }; 211 212 /* The default ui_out */ 213 214 struct ui_out def_uiout = 215 { 216 0, /* flags */ 217 &default_ui_out_impl, /* impl */ 218 }; 219 220 /* Pointer to current ui_out */ 221 /* FIXME: This should not be a global, but something passed down from main.c 222 or top.c */ 223 224 struct ui_out *uiout = &def_uiout; 225 226 /* These are the interfaces to implementation functions */ 227 228 static void uo_table_begin (struct ui_out *uiout, int nbrofcols, 229 int nr_rows, const char *tblid); 230 static void uo_table_body (struct ui_out *uiout); 231 static void uo_table_end (struct ui_out *uiout); 232 static void uo_table_header (struct ui_out *uiout, int width, 233 enum ui_align align, const char *col_name, 234 const char *colhdr); 235 static void uo_begin (struct ui_out *uiout, 236 enum ui_out_type type, 237 int level, const char *id); 238 static void uo_end (struct ui_out *uiout, 239 enum ui_out_type type, 240 int level); 241 static void uo_field_int (struct ui_out *uiout, int fldno, int width, 242 enum ui_align align, const char *fldname, int value); 243 static void uo_field_skip (struct ui_out *uiout, int fldno, int width, 244 enum ui_align align, const char *fldname); 245 static void uo_field_string (struct ui_out *uiout, int fldno, int width, 246 enum ui_align align, const char *fldname, 247 const char *string); 248 static void uo_field_fmt (struct ui_out *uiout, int fldno, int width, 249 enum ui_align align, const char *fldname, 250 const char *format, va_list args) 251 ATTR_FORMAT (printf, 6, 0); 252 static void uo_spaces (struct ui_out *uiout, int numspaces); 253 static void uo_text (struct ui_out *uiout, const char *string); 254 static void uo_message (struct ui_out *uiout, int verbosity, 255 const char *format, va_list args) 256 ATTR_FORMAT (printf, 3, 0); 257 static void uo_wrap_hint (struct ui_out *uiout, char *identstring); 258 static void uo_flush (struct ui_out *uiout); 259 static int uo_redirect (struct ui_out *uiout, struct ui_file *outstream); 260 261 /* Prototypes for local functions */ 262 263 extern void _initialize_ui_out (void); 264 static void append_header_to_list (struct ui_out *uiout, int width, 265 int alignment, const char *col_name, 266 const char *colhdr); 267 static int get_next_header (struct ui_out *uiout, int *colno, int *width, 268 int *alignment, char **colhdr); 269 static void clear_header_list (struct ui_out *uiout); 270 static void verify_field (struct ui_out *uiout, int *fldno, int *width, 271 int *align); 272 273 /* exported functions (ui_out API) */ 274 275 /* Mark beginning of a table */ 276 277 static void 278 ui_out_table_begin (struct ui_out *uiout, int nbrofcols, 279 int nr_rows, 280 const char *tblid) 281 { 282 if (uiout->table.flag) 283 internal_error (__FILE__, __LINE__, 284 _("tables cannot be nested; table_begin found before \ 285 previous table_end.")); 286 287 uiout->table.flag = 1; 288 uiout->table.body_flag = 0; 289 uiout->table.entry_level = uiout->level + 1; 290 uiout->table.columns = nbrofcols; 291 if (tblid != NULL) 292 uiout->table.id = xstrdup (tblid); 293 else 294 uiout->table.id = NULL; 295 clear_header_list (uiout); 296 297 uo_table_begin (uiout, nbrofcols, nr_rows, uiout->table.id); 298 } 299 300 void 301 ui_out_table_body (struct ui_out *uiout) 302 { 303 if (!uiout->table.flag) 304 internal_error (__FILE__, __LINE__, 305 _("table_body outside a table is not valid; it must be \ 306 after a table_begin and before a table_end.")); 307 if (uiout->table.body_flag) 308 internal_error (__FILE__, __LINE__, 309 _("extra table_body call not allowed; there must be \ 310 only one table_body after a table_begin and before a table_end.")); 311 if (uiout->table.header_next->colno != uiout->table.columns) 312 internal_error (__FILE__, __LINE__, 313 _("number of headers differ from number of table \ 314 columns.")); 315 316 uiout->table.body_flag = 1; 317 uiout->table.header_next = uiout->table.header_first; 318 319 uo_table_body (uiout); 320 } 321 322 static void 323 ui_out_table_end (struct ui_out *uiout) 324 { 325 if (!uiout->table.flag) 326 internal_error (__FILE__, __LINE__, 327 _("misplaced table_end or missing table_begin.")); 328 329 uiout->table.entry_level = 0; 330 uiout->table.body_flag = 0; 331 uiout->table.flag = 0; 332 333 uo_table_end (uiout); 334 335 if (uiout->table.id) 336 xfree (uiout->table.id); 337 clear_header_list (uiout); 338 } 339 340 void 341 ui_out_table_header (struct ui_out *uiout, int width, enum ui_align alignment, 342 const char *col_name, 343 const char *colhdr) 344 { 345 if (!uiout->table.flag || uiout->table.body_flag) 346 internal_error (__FILE__, __LINE__, 347 _("table header must be specified after table_begin \ 348 and before table_body.")); 349 350 append_header_to_list (uiout, width, alignment, col_name, colhdr); 351 352 uo_table_header (uiout, width, alignment, col_name, colhdr); 353 } 354 355 static void 356 do_cleanup_table_end (void *data) 357 { 358 struct ui_out *ui_out = data; 359 360 ui_out_table_end (ui_out); 361 } 362 363 struct cleanup * 364 make_cleanup_ui_out_table_begin_end (struct ui_out *ui_out, int nr_cols, 365 int nr_rows, const char *tblid) 366 { 367 ui_out_table_begin (ui_out, nr_cols, nr_rows, tblid); 368 return make_cleanup (do_cleanup_table_end, ui_out); 369 } 370 371 void 372 ui_out_begin (struct ui_out *uiout, 373 enum ui_out_type type, 374 const char *id) 375 { 376 int new_level; 377 if (uiout->table.flag && !uiout->table.body_flag) 378 internal_error (__FILE__, __LINE__, 379 _("table header or table_body expected; lists must be \ 380 specified after table_body.")); 381 382 /* Be careful to verify the ``field'' before the new tuple/list is 383 pushed onto the stack. That way the containing list/table/row is 384 verified and not the newly created tuple/list. This verification 385 is needed (at least) for the case where a table row entry 386 contains either a tuple/list. For that case bookkeeping such as 387 updating the column count or advancing to the next heading still 388 needs to be performed. */ 389 { 390 int fldno; 391 int width; 392 int align; 393 verify_field (uiout, &fldno, &width, &align); 394 } 395 396 new_level = push_level (uiout, type, id); 397 398 /* If the push puts us at the same level as a table row entry, we've 399 got a new table row. Put the header pointer back to the start. */ 400 if (uiout->table.body_flag 401 && uiout->table.entry_level == new_level) 402 uiout->table.header_next = uiout->table.header_first; 403 404 uo_begin (uiout, type, new_level, id); 405 } 406 407 void 408 ui_out_end (struct ui_out *uiout, 409 enum ui_out_type type) 410 { 411 int old_level = pop_level (uiout, type); 412 uo_end (uiout, type, old_level); 413 } 414 415 struct ui_out_end_cleanup_data 416 { 417 struct ui_out *uiout; 418 enum ui_out_type type; 419 }; 420 421 static void 422 do_cleanup_end (void *data) 423 { 424 struct ui_out_end_cleanup_data *end_cleanup_data = data; 425 ui_out_end (end_cleanup_data->uiout, end_cleanup_data->type); 426 xfree (end_cleanup_data); 427 } 428 429 static struct cleanup * 430 make_cleanup_ui_out_end (struct ui_out *uiout, 431 enum ui_out_type type) 432 { 433 struct ui_out_end_cleanup_data *end_cleanup_data; 434 end_cleanup_data = XMALLOC (struct ui_out_end_cleanup_data); 435 end_cleanup_data->uiout = uiout; 436 end_cleanup_data->type = type; 437 return make_cleanup (do_cleanup_end, end_cleanup_data); 438 } 439 440 struct cleanup * 441 make_cleanup_ui_out_tuple_begin_end (struct ui_out *uiout, 442 const char *id) 443 { 444 ui_out_begin (uiout, ui_out_type_tuple, id); 445 return make_cleanup_ui_out_end (uiout, ui_out_type_tuple); 446 } 447 448 struct cleanup * 449 make_cleanup_ui_out_list_begin_end (struct ui_out *uiout, 450 const char *id) 451 { 452 ui_out_begin (uiout, ui_out_type_list, id); 453 return make_cleanup_ui_out_end (uiout, ui_out_type_list); 454 } 455 456 void 457 ui_out_field_int (struct ui_out *uiout, 458 const char *fldname, 459 int value) 460 { 461 int fldno; 462 int width; 463 int align; 464 struct ui_out_level *current = current_level (uiout); 465 466 verify_field (uiout, &fldno, &width, &align); 467 468 uo_field_int (uiout, fldno, width, align, fldname, value); 469 } 470 471 void 472 ui_out_field_fmt_int (struct ui_out *uiout, 473 int input_width, 474 enum ui_align input_align, 475 const char *fldname, 476 int value) 477 { 478 int fldno; 479 int width; 480 int align; 481 struct ui_out_level *current = current_level (uiout); 482 483 verify_field (uiout, &fldno, &width, &align); 484 485 uo_field_int (uiout, fldno, input_width, input_align, fldname, value); 486 } 487 488 void 489 ui_out_field_core_addr (struct ui_out *uiout, 490 const char *fldname, 491 struct gdbarch *gdbarch, 492 CORE_ADDR address) 493 { 494 char addstr[20]; 495 int addr_bit = gdbarch_addr_bit (gdbarch); 496 497 if (addr_bit < (sizeof (CORE_ADDR) * HOST_CHAR_BIT)) 498 address &= ((CORE_ADDR) 1 << addr_bit) - 1; 499 500 /* FIXME: cagney/2002-05-03: Need local_address_string() function 501 that returns the language localized string formatted to a width 502 based on gdbarch_addr_bit. */ 503 if (addr_bit <= 32) 504 strcpy (addstr, hex_string_custom (address, 8)); 505 else 506 strcpy (addstr, hex_string_custom (address, 16)); 507 508 ui_out_field_string (uiout, fldname, addstr); 509 } 510 511 void 512 ui_out_field_stream (struct ui_out *uiout, 513 const char *fldname, 514 struct ui_stream *buf) 515 { 516 long length; 517 char *buffer = ui_file_xstrdup (buf->stream, &length); 518 struct cleanup *old_cleanup = make_cleanup (xfree, buffer); 519 if (length > 0) 520 ui_out_field_string (uiout, fldname, buffer); 521 else 522 ui_out_field_skip (uiout, fldname); 523 ui_file_rewind (buf->stream); 524 do_cleanups (old_cleanup); 525 } 526 527 /* used to ommit a field */ 528 529 void 530 ui_out_field_skip (struct ui_out *uiout, 531 const char *fldname) 532 { 533 int fldno; 534 int width; 535 int align; 536 537 verify_field (uiout, &fldno, &width, &align); 538 539 uo_field_skip (uiout, fldno, width, align, fldname); 540 } 541 542 void 543 ui_out_field_string (struct ui_out *uiout, 544 const char *fldname, 545 const char *string) 546 { 547 int fldno; 548 int width; 549 int align; 550 551 verify_field (uiout, &fldno, &width, &align); 552 553 uo_field_string (uiout, fldno, width, align, fldname, string); 554 } 555 556 /* VARARGS */ 557 void 558 ui_out_field_fmt (struct ui_out *uiout, 559 const char *fldname, 560 const char *format, ...) 561 { 562 va_list args; 563 int fldno; 564 int width; 565 int align; 566 567 /* will not align, but has to call anyway */ 568 verify_field (uiout, &fldno, &width, &align); 569 570 va_start (args, format); 571 572 uo_field_fmt (uiout, fldno, width, align, fldname, format, args); 573 574 va_end (args); 575 } 576 577 void 578 ui_out_spaces (struct ui_out *uiout, int numspaces) 579 { 580 uo_spaces (uiout, numspaces); 581 } 582 583 void 584 ui_out_text (struct ui_out *uiout, 585 const char *string) 586 { 587 uo_text (uiout, string); 588 } 589 590 void 591 ui_out_message (struct ui_out *uiout, int verbosity, 592 const char *format,...) 593 { 594 va_list args; 595 596 va_start (args, format); 597 598 uo_message (uiout, verbosity, format, args); 599 600 va_end (args); 601 } 602 603 struct ui_stream * 604 ui_out_stream_new (struct ui_out *uiout) 605 { 606 struct ui_stream *tempbuf; 607 608 tempbuf = XMALLOC (struct ui_stream); 609 tempbuf->uiout = uiout; 610 tempbuf->stream = mem_fileopen (); 611 return tempbuf; 612 } 613 614 void 615 ui_out_stream_delete (struct ui_stream *buf) 616 { 617 ui_file_delete (buf->stream); 618 xfree (buf); 619 } 620 621 static void 622 do_stream_delete (void *buf) 623 { 624 ui_out_stream_delete (buf); 625 } 626 627 struct cleanup * 628 make_cleanup_ui_out_stream_delete (struct ui_stream *buf) 629 { 630 return make_cleanup (do_stream_delete, buf); 631 } 632 633 634 void 635 ui_out_wrap_hint (struct ui_out *uiout, char *identstring) 636 { 637 uo_wrap_hint (uiout, identstring); 638 } 639 640 void 641 ui_out_flush (struct ui_out *uiout) 642 { 643 uo_flush (uiout); 644 } 645 646 int 647 ui_out_redirect (struct ui_out *uiout, struct ui_file *outstream) 648 { 649 return uo_redirect (uiout, outstream); 650 } 651 652 /* set the flags specified by the mask given */ 653 int 654 ui_out_set_flags (struct ui_out *uiout, int mask) 655 { 656 int oldflags = uiout->flags; 657 658 uiout->flags |= mask; 659 660 return oldflags; 661 } 662 663 /* clear the flags specified by the mask given */ 664 int 665 ui_out_clear_flags (struct ui_out *uiout, int mask) 666 { 667 int oldflags = uiout->flags; 668 669 uiout->flags &= ~mask; 670 671 return oldflags; 672 } 673 674 /* test the flags against the mask given */ 675 int 676 ui_out_test_flags (struct ui_out *uiout, int mask) 677 { 678 return (uiout->flags & mask); 679 } 680 681 /* obtain the current verbosity level (as stablished by the 682 'set verbositylevel' command */ 683 684 int 685 ui_out_get_verblvl (struct ui_out *uiout) 686 { 687 /* FIXME: not implemented yet */ 688 return 0; 689 } 690 691 #if 0 692 void 693 ui_out_result_begin (struct ui_out *uiout, char *class) 694 { 695 } 696 697 void 698 ui_out_result_end (struct ui_out *uiout) 699 { 700 } 701 702 void 703 ui_out_info_begin (struct ui_out *uiout, char *class) 704 { 705 } 706 707 void 708 ui_out_info_end (struct ui_out *uiout) 709 { 710 } 711 712 void 713 ui_out_notify_begin (struct ui_out *uiout, char *class) 714 { 715 } 716 717 void 718 ui_out_notify_end (struct ui_out *uiout) 719 { 720 } 721 722 void 723 ui_out_error_begin (struct ui_out *uiout, char *class) 724 { 725 } 726 727 void 728 ui_out_error_end (struct ui_out *uiout) 729 { 730 } 731 #endif 732 733 #if 0 734 void 735 gdb_error (ui_out * uiout, int severity, char *format,...) 736 { 737 va_list args; 738 } 739 740 void 741 gdb_query (struct ui_out *uiout, int qflags, char *qprompt) 742 { 743 } 744 #endif 745 746 int 747 ui_out_is_mi_like_p (struct ui_out *uiout) 748 { 749 return uiout->impl->is_mi_like_p; 750 } 751 752 /* default gdb-out hook functions */ 753 754 static void 755 default_table_begin (struct ui_out *uiout, int nbrofcols, 756 int nr_rows, 757 const char *tblid) 758 { 759 } 760 761 static void 762 default_table_body (struct ui_out *uiout) 763 { 764 } 765 766 static void 767 default_table_end (struct ui_out *uiout) 768 { 769 } 770 771 static void 772 default_table_header (struct ui_out *uiout, int width, enum ui_align alignment, 773 const char *col_name, 774 const char *colhdr) 775 { 776 } 777 778 static void 779 default_begin (struct ui_out *uiout, 780 enum ui_out_type type, 781 int level, 782 const char *id) 783 { 784 } 785 786 static void 787 default_end (struct ui_out *uiout, 788 enum ui_out_type type, 789 int level) 790 { 791 } 792 793 static void 794 default_field_int (struct ui_out *uiout, int fldno, int width, 795 enum ui_align align, 796 const char *fldname, int value) 797 { 798 } 799 800 static void 801 default_field_skip (struct ui_out *uiout, int fldno, int width, 802 enum ui_align align, const char *fldname) 803 { 804 } 805 806 static void 807 default_field_string (struct ui_out *uiout, 808 int fldno, 809 int width, 810 enum ui_align align, 811 const char *fldname, 812 const char *string) 813 { 814 } 815 816 static void 817 default_field_fmt (struct ui_out *uiout, int fldno, int width, 818 enum ui_align align, 819 const char *fldname, 820 const char *format, 821 va_list args) 822 { 823 } 824 825 static void 826 default_spaces (struct ui_out *uiout, int numspaces) 827 { 828 } 829 830 static void 831 default_text (struct ui_out *uiout, const char *string) 832 { 833 } 834 835 static void 836 default_message (struct ui_out *uiout, int verbosity, 837 const char *format, 838 va_list args) 839 { 840 } 841 842 static void 843 default_wrap_hint (struct ui_out *uiout, char *identstring) 844 { 845 } 846 847 static void 848 default_flush (struct ui_out *uiout) 849 { 850 } 851 852 /* Interface to the implementation functions */ 853 854 void 855 uo_table_begin (struct ui_out *uiout, int nbrofcols, 856 int nr_rows, 857 const char *tblid) 858 { 859 if (!uiout->impl->table_begin) 860 return; 861 uiout->impl->table_begin (uiout, nbrofcols, nr_rows, tblid); 862 } 863 864 void 865 uo_table_body (struct ui_out *uiout) 866 { 867 if (!uiout->impl->table_body) 868 return; 869 uiout->impl->table_body (uiout); 870 } 871 872 void 873 uo_table_end (struct ui_out *uiout) 874 { 875 if (!uiout->impl->table_end) 876 return; 877 uiout->impl->table_end (uiout); 878 } 879 880 void 881 uo_table_header (struct ui_out *uiout, int width, enum ui_align align, 882 const char *col_name, 883 const char *colhdr) 884 { 885 if (!uiout->impl->table_header) 886 return; 887 uiout->impl->table_header (uiout, width, align, col_name, colhdr); 888 } 889 890 void 891 uo_begin (struct ui_out *uiout, 892 enum ui_out_type type, 893 int level, 894 const char *id) 895 { 896 if (uiout->impl->begin == NULL) 897 return; 898 uiout->impl->begin (uiout, type, level, id); 899 } 900 901 void 902 uo_end (struct ui_out *uiout, 903 enum ui_out_type type, 904 int level) 905 { 906 if (uiout->impl->end == NULL) 907 return; 908 uiout->impl->end (uiout, type, level); 909 } 910 911 void 912 uo_field_int (struct ui_out *uiout, int fldno, int width, enum ui_align align, 913 const char *fldname, 914 int value) 915 { 916 if (!uiout->impl->field_int) 917 return; 918 uiout->impl->field_int (uiout, fldno, width, align, fldname, value); 919 } 920 921 void 922 uo_field_skip (struct ui_out *uiout, int fldno, int width, enum ui_align align, 923 const char *fldname) 924 { 925 if (!uiout->impl->field_skip) 926 return; 927 uiout->impl->field_skip (uiout, fldno, width, align, fldname); 928 } 929 930 void 931 uo_field_string (struct ui_out *uiout, int fldno, int width, 932 enum ui_align align, 933 const char *fldname, 934 const char *string) 935 { 936 if (!uiout->impl->field_string) 937 return; 938 uiout->impl->field_string (uiout, fldno, width, align, fldname, string); 939 } 940 941 void 942 uo_field_fmt (struct ui_out *uiout, int fldno, int width, enum ui_align align, 943 const char *fldname, 944 const char *format, 945 va_list args) 946 { 947 if (!uiout->impl->field_fmt) 948 return; 949 uiout->impl->field_fmt (uiout, fldno, width, align, fldname, format, args); 950 } 951 952 void 953 uo_spaces (struct ui_out *uiout, int numspaces) 954 { 955 if (!uiout->impl->spaces) 956 return; 957 uiout->impl->spaces (uiout, numspaces); 958 } 959 960 void 961 uo_text (struct ui_out *uiout, 962 const char *string) 963 { 964 if (!uiout->impl->text) 965 return; 966 uiout->impl->text (uiout, string); 967 } 968 969 void 970 uo_message (struct ui_out *uiout, int verbosity, 971 const char *format, 972 va_list args) 973 { 974 if (!uiout->impl->message) 975 return; 976 uiout->impl->message (uiout, verbosity, format, args); 977 } 978 979 void 980 uo_wrap_hint (struct ui_out *uiout, char *identstring) 981 { 982 if (!uiout->impl->wrap_hint) 983 return; 984 uiout->impl->wrap_hint (uiout, identstring); 985 } 986 987 void 988 uo_flush (struct ui_out *uiout) 989 { 990 if (!uiout->impl->flush) 991 return; 992 uiout->impl->flush (uiout); 993 } 994 995 int 996 uo_redirect (struct ui_out *uiout, struct ui_file *outstream) 997 { 998 if (!uiout->impl->redirect) 999 return -1; 1000 uiout->impl->redirect (uiout, outstream); 1001 return 0; 1002 } 1003 1004 /* local functions */ 1005 1006 /* list of column headers manipulation routines */ 1007 1008 static void 1009 clear_header_list (struct ui_out *uiout) 1010 { 1011 while (uiout->table.header_first != NULL) 1012 { 1013 uiout->table.header_next = uiout->table.header_first; 1014 uiout->table.header_first = uiout->table.header_first->next; 1015 if (uiout->table.header_next->colhdr != NULL) 1016 xfree (uiout->table.header_next->colhdr); 1017 xfree (uiout->table.header_next); 1018 } 1019 gdb_assert (uiout->table.header_first == NULL); 1020 uiout->table.header_last = NULL; 1021 uiout->table.header_next = NULL; 1022 } 1023 1024 static void 1025 append_header_to_list (struct ui_out *uiout, 1026 int width, 1027 int alignment, 1028 const char *col_name, 1029 const char *colhdr) 1030 { 1031 struct ui_out_hdr *temphdr; 1032 1033 temphdr = XMALLOC (struct ui_out_hdr); 1034 temphdr->width = width; 1035 temphdr->alignment = alignment; 1036 /* We have to copy the column title as the original may be an 1037 automatic. */ 1038 if (colhdr != NULL) 1039 temphdr->colhdr = xstrdup (colhdr); 1040 else 1041 temphdr->colhdr = NULL; 1042 1043 if (col_name != NULL) 1044 temphdr->col_name = xstrdup (col_name); 1045 else if (colhdr != NULL) 1046 temphdr->col_name = xstrdup (colhdr); 1047 else 1048 temphdr->col_name = NULL; 1049 1050 temphdr->next = NULL; 1051 if (uiout->table.header_first == NULL) 1052 { 1053 temphdr->colno = 1; 1054 uiout->table.header_first = temphdr; 1055 uiout->table.header_last = temphdr; 1056 } 1057 else 1058 { 1059 temphdr->colno = uiout->table.header_last->colno + 1; 1060 uiout->table.header_last->next = temphdr; 1061 uiout->table.header_last = temphdr; 1062 } 1063 uiout->table.header_next = uiout->table.header_last; 1064 } 1065 1066 /* Extract the format information for the NEXT header and and advance 1067 the header pointer. Return 0 if there was no next header. */ 1068 1069 static int 1070 get_next_header (struct ui_out *uiout, 1071 int *colno, 1072 int *width, 1073 int *alignment, 1074 char **colhdr) 1075 { 1076 /* There may be no headers at all or we may have used all columns. */ 1077 if (uiout->table.header_next == NULL) 1078 return 0; 1079 *colno = uiout->table.header_next->colno; 1080 *width = uiout->table.header_next->width; 1081 *alignment = uiout->table.header_next->alignment; 1082 *colhdr = uiout->table.header_next->colhdr; 1083 /* Advance the header pointer to the next entry. */ 1084 uiout->table.header_next = uiout->table.header_next->next; 1085 return 1; 1086 } 1087 1088 1089 /* Verify that the field/tuple/list is correctly positioned. Return 1090 the field number and corresponding alignment (if 1091 available/applicable). */ 1092 1093 static void 1094 verify_field (struct ui_out *uiout, int *fldno, int *width, int *align) 1095 { 1096 struct ui_out_level *current = current_level (uiout); 1097 char *text; 1098 1099 if (uiout->table.flag) 1100 { 1101 if (!uiout->table.body_flag) 1102 internal_error (__FILE__, __LINE__, 1103 _("table_body missing; table fields must be \ 1104 specified after table_body and inside a list.")); 1105 /* NOTE: cagney/2001-12-08: There was a check here to ensure 1106 that this code was only executed when uiout->level was 1107 greater than zero. That no longer applies - this code is run 1108 before each table row tuple is started and at that point the 1109 level is zero. */ 1110 } 1111 1112 current->field_count += 1; 1113 1114 if (uiout->table.body_flag 1115 && uiout->table.entry_level == uiout->level 1116 && get_next_header (uiout, fldno, width, align, &text)) 1117 { 1118 if (*fldno != current->field_count) 1119 internal_error (__FILE__, __LINE__, 1120 _("ui-out internal error in handling headers.")); 1121 } 1122 else 1123 { 1124 *width = 0; 1125 *align = ui_noalign; 1126 *fldno = current->field_count; 1127 } 1128 } 1129 1130 1131 /* access to ui_out format private members */ 1132 1133 void 1134 ui_out_get_field_separator (struct ui_out *uiout) 1135 { 1136 } 1137 1138 /* Access to ui-out members data */ 1139 1140 struct ui_out_data * 1141 ui_out_data (struct ui_out *uiout) 1142 { 1143 return uiout->data; 1144 } 1145 1146 /* initalize private members at startup */ 1147 1148 struct ui_out * 1149 ui_out_new (struct ui_out_impl *impl, 1150 struct ui_out_data *data, 1151 int flags) 1152 { 1153 struct ui_out *uiout = XMALLOC (struct ui_out); 1154 uiout->data = data; 1155 uiout->impl = impl; 1156 uiout->flags = flags; 1157 uiout->table.flag = 0; 1158 uiout->table.body_flag = 0; 1159 uiout->level = 0; 1160 memset (uiout->levels, 0, sizeof (uiout->levels)); 1161 uiout->table.header_first = NULL; 1162 uiout->table.header_last = NULL; 1163 uiout->table.header_next = NULL; 1164 return uiout; 1165 } 1166 1167 /* standard gdb initialization hook */ 1168 1169 void 1170 _initialize_ui_out (void) 1171 { 1172 /* nothing needs to be done */ 1173 } 1174