GDB (API)
|
00001 /* Output generating routines for GDB. 00002 00003 Copyright (C) 1999-2013 Free Software Foundation, Inc. 00004 00005 Contributed by Cygnus Solutions. 00006 Written by Fernando Nasser for Cygnus. 00007 00008 This file is part of GDB. 00009 00010 This program is free software; you can redistribute it and/or modify 00011 it under the terms of the GNU General Public License as published by 00012 the Free Software Foundation; either version 3 of the License, or 00013 (at your option) any later version. 00014 00015 This program is distributed in the hope that it will be useful, 00016 but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00018 GNU General Public License for more details. 00019 00020 You should have received a copy of the GNU General Public License 00021 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 00022 00023 #include "defs.h" 00024 #include "gdb_string.h" 00025 #include "expression.h" /* For language.h */ 00026 #include "language.h" 00027 #include "ui-out.h" 00028 #include "gdb_assert.h" 00029 00030 /* table header structures */ 00031 00032 struct ui_out_hdr 00033 { 00034 int colno; 00035 int width; 00036 int alignment; 00037 char *col_name; 00038 char *colhdr; 00039 struct ui_out_hdr *next; 00040 }; 00041 00042 /* Maintain a stack so that the info applicable to the inner most list 00043 is always available. Stack/nested level 0 is reserved for the 00044 top-level result. */ 00045 00046 enum { MAX_UI_OUT_LEVELS = 8 }; 00047 00048 struct ui_out_level 00049 { 00050 /* Count each field; the first element is for non-list fields. */ 00051 int field_count; 00052 /* The type of this level. */ 00053 enum ui_out_type type; 00054 }; 00055 00056 /* Define uiout->level vector types and operations. */ 00057 typedef struct ui_out_level *ui_out_level_p; 00058 DEF_VEC_P (ui_out_level_p); 00059 00060 /* Tables are special. Maintain a separate structure that tracks 00061 their state. At present an output can only contain a single table 00062 but that restriction might eventually be lifted. */ 00063 00064 struct ui_out_table 00065 { 00066 /* If on, a table is being generated. */ 00067 int flag; 00068 00069 /* If on, the body of a table is being generated. If off, the table 00070 header is being generated. */ 00071 int body_flag; 00072 00073 /* The level at which each entry of the table is to be found. A row 00074 (a tuple) is made up of entries. Consequently ENTRY_LEVEL is one 00075 above that of the table. */ 00076 int entry_level; 00077 00078 /* Number of table columns (as specified in the table_begin call). */ 00079 int columns; 00080 00081 /* String identifying the table (as specified in the table_begin 00082 call). */ 00083 char *id; 00084 00085 /* Points to the first table header (if any). */ 00086 struct ui_out_hdr *header_first; 00087 00088 /* Points to the last table header (if any). */ 00089 struct ui_out_hdr *header_last; 00090 00091 /* Points to header of NEXT column to format. */ 00092 struct ui_out_hdr *header_next; 00093 00094 }; 00095 00096 00097 /* The ui_out structure */ 00098 /* Any change here requires a corresponding one in the initialization 00099 of the default uiout, which is statically initialized. */ 00100 00101 struct ui_out 00102 { 00103 int flags; 00104 /* Specific implementation of ui-out. */ 00105 struct ui_out_impl *impl; 00106 void *data; 00107 00108 /* Current level. */ 00109 int level; 00110 00111 /* Vector to store and track the ui-out levels. */ 00112 VEC (ui_out_level_p) *levels; 00113 00114 /* A table, if any. At present only a single table is supported. */ 00115 struct ui_out_table table; 00116 }; 00117 00118 /* The current (inner most) level. */ 00119 static struct ui_out_level * 00120 current_level (struct ui_out *uiout) 00121 { 00122 return VEC_index (ui_out_level_p, uiout->levels, uiout->level); 00123 } 00124 00125 /* Create a new level, of TYPE. Return the new level's index. */ 00126 static int 00127 push_level (struct ui_out *uiout, 00128 enum ui_out_type type, 00129 const char *id) 00130 { 00131 struct ui_out_level *current; 00132 00133 uiout->level++; 00134 current = XMALLOC (struct ui_out_level); 00135 current->field_count = 0; 00136 current->type = type; 00137 VEC_safe_push (ui_out_level_p, uiout->levels, current); 00138 return uiout->level; 00139 } 00140 00141 /* Discard the current level, return the discarded level's index. 00142 TYPE is the type of the level being discarded. */ 00143 static int 00144 pop_level (struct ui_out *uiout, 00145 enum ui_out_type type) 00146 { 00147 struct ui_out_level *current; 00148 00149 /* We had better not underflow the buffer. */ 00150 gdb_assert (uiout->level > 0); 00151 gdb_assert (current_level (uiout)->type == type); 00152 current = VEC_pop (ui_out_level_p, uiout->levels); 00153 xfree (current); 00154 uiout->level--; 00155 return uiout->level + 1; 00156 } 00157 00158 00159 /* These are the default implementation functions. */ 00160 00161 static void default_table_begin (struct ui_out *uiout, int nbrofcols, 00162 int nr_rows, const char *tblid); 00163 static void default_table_body (struct ui_out *uiout); 00164 static void default_table_end (struct ui_out *uiout); 00165 static void default_table_header (struct ui_out *uiout, int width, 00166 enum ui_align alig, const char *col_name, 00167 const char *colhdr); 00168 static void default_begin (struct ui_out *uiout, 00169 enum ui_out_type type, 00170 int level, const char *id); 00171 static void default_end (struct ui_out *uiout, 00172 enum ui_out_type type, 00173 int level); 00174 static void default_field_int (struct ui_out *uiout, int fldno, int width, 00175 enum ui_align alig, 00176 const char *fldname, 00177 int value); 00178 static void default_field_skip (struct ui_out *uiout, int fldno, int width, 00179 enum ui_align alig, 00180 const char *fldname); 00181 static void default_field_string (struct ui_out *uiout, int fldno, int width, 00182 enum ui_align align, 00183 const char *fldname, 00184 const char *string); 00185 static void default_field_fmt (struct ui_out *uiout, int fldno, 00186 int width, enum ui_align align, 00187 const char *fldname, 00188 const char *format, 00189 va_list args) ATTRIBUTE_PRINTF (6, 0); 00190 static void default_spaces (struct ui_out *uiout, int numspaces); 00191 static void default_text (struct ui_out *uiout, const char *string); 00192 static void default_message (struct ui_out *uiout, int verbosity, 00193 const char *format, 00194 va_list args) ATTRIBUTE_PRINTF (3, 0); 00195 static void default_wrap_hint (struct ui_out *uiout, char *identstring); 00196 static void default_flush (struct ui_out *uiout); 00197 static void default_data_destroy (struct ui_out *uiout); 00198 00199 /* This is the default ui-out implementation functions vector. */ 00200 00201 struct ui_out_impl default_ui_out_impl = 00202 { 00203 default_table_begin, 00204 default_table_body, 00205 default_table_end, 00206 default_table_header, 00207 default_begin, 00208 default_end, 00209 default_field_int, 00210 default_field_skip, 00211 default_field_string, 00212 default_field_fmt, 00213 default_spaces, 00214 default_text, 00215 default_message, 00216 default_wrap_hint, 00217 default_flush, 00218 NULL, 00219 default_data_destroy, 00220 0, /* Does not need MI hacks. */ 00221 }; 00222 00223 /* The default ui_out */ 00224 00225 struct ui_out def_uiout = 00226 { 00227 0, /* flags */ 00228 &default_ui_out_impl, /* impl */ 00229 }; 00230 00231 /* Pointer to current ui_out */ 00232 /* FIXME: This should not be a global, but something passed down from main.c 00233 or top.c. */ 00234 00235 struct ui_out *current_uiout = &def_uiout; 00236 00237 /* These are the interfaces to implementation functions. */ 00238 00239 static void uo_table_begin (struct ui_out *uiout, int nbrofcols, 00240 int nr_rows, const char *tblid); 00241 static void uo_table_body (struct ui_out *uiout); 00242 static void uo_table_end (struct ui_out *uiout); 00243 static void uo_table_header (struct ui_out *uiout, int width, 00244 enum ui_align align, const char *col_name, 00245 const char *colhdr); 00246 static void uo_begin (struct ui_out *uiout, 00247 enum ui_out_type type, 00248 int level, const char *id); 00249 static void uo_end (struct ui_out *uiout, 00250 enum ui_out_type type, 00251 int level); 00252 static void uo_field_int (struct ui_out *uiout, int fldno, int width, 00253 enum ui_align align, const char *fldname, int value); 00254 static void uo_field_skip (struct ui_out *uiout, int fldno, int width, 00255 enum ui_align align, const char *fldname); 00256 static void uo_field_fmt (struct ui_out *uiout, int fldno, int width, 00257 enum ui_align align, const char *fldname, 00258 const char *format, va_list args) 00259 ATTRIBUTE_PRINTF (6, 0); 00260 static void uo_spaces (struct ui_out *uiout, int numspaces); 00261 static void uo_text (struct ui_out *uiout, const char *string); 00262 static void uo_message (struct ui_out *uiout, int verbosity, 00263 const char *format, va_list args) 00264 ATTRIBUTE_PRINTF (3, 0); 00265 static void uo_wrap_hint (struct ui_out *uiout, char *identstring); 00266 static void uo_flush (struct ui_out *uiout); 00267 static int uo_redirect (struct ui_out *uiout, struct ui_file *outstream); 00268 static void uo_data_destroy (struct ui_out *uiout); 00269 00270 /* Prototypes for local functions */ 00271 00272 extern void _initialize_ui_out (void); 00273 static void append_header_to_list (struct ui_out *uiout, int width, 00274 int alignment, const char *col_name, 00275 const char *colhdr); 00276 static int get_next_header (struct ui_out *uiout, int *colno, int *width, 00277 int *alignment, char **colhdr); 00278 static void clear_header_list (struct ui_out *uiout); 00279 static void clear_table (struct ui_out *uiout); 00280 static void verify_field (struct ui_out *uiout, int *fldno, int *width, 00281 int *align); 00282 00283 /* exported functions (ui_out API) */ 00284 00285 /* Mark beginning of a table. */ 00286 00287 static void 00288 ui_out_table_begin (struct ui_out *uiout, int nbrofcols, 00289 int nr_rows, 00290 const char *tblid) 00291 { 00292 if (uiout->table.flag) 00293 internal_error (__FILE__, __LINE__, 00294 _("tables cannot be nested; table_begin found before \ 00295 previous table_end.")); 00296 00297 uiout->table.flag = 1; 00298 uiout->table.body_flag = 0; 00299 uiout->table.entry_level = uiout->level + 1; 00300 uiout->table.columns = nbrofcols; 00301 if (tblid != NULL) 00302 uiout->table.id = xstrdup (tblid); 00303 else 00304 uiout->table.id = NULL; 00305 clear_header_list (uiout); 00306 00307 uo_table_begin (uiout, nbrofcols, nr_rows, uiout->table.id); 00308 } 00309 00310 void 00311 ui_out_table_body (struct ui_out *uiout) 00312 { 00313 if (!uiout->table.flag) 00314 internal_error (__FILE__, __LINE__, 00315 _("table_body outside a table is not valid; it must be \ 00316 after a table_begin and before a table_end.")); 00317 if (uiout->table.body_flag) 00318 internal_error (__FILE__, __LINE__, 00319 _("extra table_body call not allowed; there must be \ 00320 only one table_body after a table_begin and before a table_end.")); 00321 if (uiout->table.header_next->colno != uiout->table.columns) 00322 internal_error (__FILE__, __LINE__, 00323 _("number of headers differ from number of table \ 00324 columns.")); 00325 00326 uiout->table.body_flag = 1; 00327 uiout->table.header_next = uiout->table.header_first; 00328 00329 uo_table_body (uiout); 00330 } 00331 00332 static void 00333 ui_out_table_end (struct ui_out *uiout) 00334 { 00335 if (!uiout->table.flag) 00336 internal_error (__FILE__, __LINE__, 00337 _("misplaced table_end or missing table_begin.")); 00338 00339 uiout->table.entry_level = 0; 00340 uiout->table.body_flag = 0; 00341 uiout->table.flag = 0; 00342 00343 uo_table_end (uiout); 00344 clear_table (uiout); 00345 } 00346 00347 void 00348 ui_out_table_header (struct ui_out *uiout, int width, enum ui_align alignment, 00349 const char *col_name, 00350 const char *colhdr) 00351 { 00352 if (!uiout->table.flag || uiout->table.body_flag) 00353 internal_error (__FILE__, __LINE__, 00354 _("table header must be specified after table_begin \ 00355 and before table_body.")); 00356 00357 append_header_to_list (uiout, width, alignment, col_name, colhdr); 00358 00359 uo_table_header (uiout, width, alignment, col_name, colhdr); 00360 } 00361 00362 static void 00363 do_cleanup_table_end (void *data) 00364 { 00365 struct ui_out *ui_out = data; 00366 00367 ui_out_table_end (ui_out); 00368 } 00369 00370 struct cleanup * 00371 make_cleanup_ui_out_table_begin_end (struct ui_out *ui_out, int nr_cols, 00372 int nr_rows, const char *tblid) 00373 { 00374 ui_out_table_begin (ui_out, nr_cols, nr_rows, tblid); 00375 return make_cleanup (do_cleanup_table_end, ui_out); 00376 } 00377 00378 void 00379 ui_out_begin (struct ui_out *uiout, 00380 enum ui_out_type type, 00381 const char *id) 00382 { 00383 int new_level; 00384 00385 if (uiout->table.flag && !uiout->table.body_flag) 00386 internal_error (__FILE__, __LINE__, 00387 _("table header or table_body expected; lists must be \ 00388 specified after table_body.")); 00389 00390 /* Be careful to verify the ``field'' before the new tuple/list is 00391 pushed onto the stack. That way the containing list/table/row is 00392 verified and not the newly created tuple/list. This verification 00393 is needed (at least) for the case where a table row entry 00394 contains either a tuple/list. For that case bookkeeping such as 00395 updating the column count or advancing to the next heading still 00396 needs to be performed. */ 00397 { 00398 int fldno; 00399 int width; 00400 int align; 00401 00402 verify_field (uiout, &fldno, &width, &align); 00403 } 00404 00405 new_level = push_level (uiout, type, id); 00406 00407 /* If the push puts us at the same level as a table row entry, we've 00408 got a new table row. Put the header pointer back to the start. */ 00409 if (uiout->table.body_flag 00410 && uiout->table.entry_level == new_level) 00411 uiout->table.header_next = uiout->table.header_first; 00412 00413 uo_begin (uiout, type, new_level, id); 00414 } 00415 00416 void 00417 ui_out_end (struct ui_out *uiout, 00418 enum ui_out_type type) 00419 { 00420 int old_level = pop_level (uiout, type); 00421 00422 uo_end (uiout, type, old_level); 00423 } 00424 00425 struct ui_out_end_cleanup_data 00426 { 00427 struct ui_out *uiout; 00428 enum ui_out_type type; 00429 }; 00430 00431 static void 00432 do_cleanup_end (void *data) 00433 { 00434 struct ui_out_end_cleanup_data *end_cleanup_data = data; 00435 00436 ui_out_end (end_cleanup_data->uiout, end_cleanup_data->type); 00437 xfree (end_cleanup_data); 00438 } 00439 00440 static struct cleanup * 00441 make_cleanup_ui_out_end (struct ui_out *uiout, 00442 enum ui_out_type type) 00443 { 00444 struct ui_out_end_cleanup_data *end_cleanup_data; 00445 00446 end_cleanup_data = XMALLOC (struct ui_out_end_cleanup_data); 00447 end_cleanup_data->uiout = uiout; 00448 end_cleanup_data->type = type; 00449 return make_cleanup (do_cleanup_end, end_cleanup_data); 00450 } 00451 00452 struct cleanup * 00453 make_cleanup_ui_out_tuple_begin_end (struct ui_out *uiout, 00454 const char *id) 00455 { 00456 ui_out_begin (uiout, ui_out_type_tuple, id); 00457 return make_cleanup_ui_out_end (uiout, ui_out_type_tuple); 00458 } 00459 00460 struct cleanup * 00461 make_cleanup_ui_out_list_begin_end (struct ui_out *uiout, 00462 const char *id) 00463 { 00464 ui_out_begin (uiout, ui_out_type_list, id); 00465 return make_cleanup_ui_out_end (uiout, ui_out_type_list); 00466 } 00467 00468 void 00469 ui_out_field_int (struct ui_out *uiout, 00470 const char *fldname, 00471 int value) 00472 { 00473 int fldno; 00474 int width; 00475 int align; 00476 00477 verify_field (uiout, &fldno, &width, &align); 00478 00479 uo_field_int (uiout, fldno, width, align, fldname, value); 00480 } 00481 00482 void 00483 ui_out_field_fmt_int (struct ui_out *uiout, 00484 int input_width, 00485 enum ui_align input_align, 00486 const char *fldname, 00487 int value) 00488 { 00489 int fldno; 00490 int width; 00491 int align; 00492 00493 verify_field (uiout, &fldno, &width, &align); 00494 00495 uo_field_int (uiout, fldno, input_width, input_align, fldname, value); 00496 } 00497 00498 /* Documented in ui-out.h. */ 00499 00500 void 00501 ui_out_field_core_addr (struct ui_out *uiout, 00502 const char *fldname, 00503 struct gdbarch *gdbarch, 00504 CORE_ADDR address) 00505 { 00506 ui_out_field_string (uiout, fldname, 00507 print_core_address (gdbarch, address)); 00508 } 00509 00510 void 00511 ui_out_field_stream (struct ui_out *uiout, 00512 const char *fldname, 00513 struct ui_file *stream) 00514 { 00515 long length; 00516 char *buffer = ui_file_xstrdup (stream, &length); 00517 struct cleanup *old_cleanup = make_cleanup (xfree, buffer); 00518 00519 if (length > 0) 00520 ui_out_field_string (uiout, fldname, buffer); 00521 else 00522 ui_out_field_skip (uiout, fldname); 00523 ui_file_rewind (stream); 00524 do_cleanups (old_cleanup); 00525 } 00526 00527 /* Used to omit a field. */ 00528 00529 void 00530 ui_out_field_skip (struct ui_out *uiout, 00531 const char *fldname) 00532 { 00533 int fldno; 00534 int width; 00535 int align; 00536 00537 verify_field (uiout, &fldno, &width, &align); 00538 00539 uo_field_skip (uiout, fldno, width, align, fldname); 00540 } 00541 00542 void 00543 ui_out_field_string (struct ui_out *uiout, 00544 const char *fldname, 00545 const char *string) 00546 { 00547 int fldno; 00548 int width; 00549 int align; 00550 00551 verify_field (uiout, &fldno, &width, &align); 00552 00553 uo_field_string (uiout, fldno, width, align, fldname, string); 00554 } 00555 00556 /* VARARGS */ 00557 void 00558 ui_out_field_fmt (struct ui_out *uiout, 00559 const char *fldname, 00560 const char *format, ...) 00561 { 00562 va_list args; 00563 int fldno; 00564 int width; 00565 int align; 00566 00567 /* Will not align, but has to call anyway. */ 00568 verify_field (uiout, &fldno, &width, &align); 00569 00570 va_start (args, format); 00571 00572 uo_field_fmt (uiout, fldno, width, align, fldname, format, args); 00573 00574 va_end (args); 00575 } 00576 00577 void 00578 ui_out_spaces (struct ui_out *uiout, int numspaces) 00579 { 00580 uo_spaces (uiout, numspaces); 00581 } 00582 00583 void 00584 ui_out_text (struct ui_out *uiout, 00585 const char *string) 00586 { 00587 uo_text (uiout, string); 00588 } 00589 00590 void 00591 ui_out_message (struct ui_out *uiout, int verbosity, 00592 const char *format,...) 00593 { 00594 va_list args; 00595 00596 va_start (args, format); 00597 uo_message (uiout, verbosity, format, args); 00598 va_end (args); 00599 } 00600 00601 void 00602 ui_out_wrap_hint (struct ui_out *uiout, char *identstring) 00603 { 00604 uo_wrap_hint (uiout, identstring); 00605 } 00606 00607 void 00608 ui_out_flush (struct ui_out *uiout) 00609 { 00610 uo_flush (uiout); 00611 } 00612 00613 int 00614 ui_out_redirect (struct ui_out *uiout, struct ui_file *outstream) 00615 { 00616 return uo_redirect (uiout, outstream); 00617 } 00618 00619 /* Set the flags specified by the mask given. */ 00620 int 00621 ui_out_set_flags (struct ui_out *uiout, int mask) 00622 { 00623 int oldflags = uiout->flags; 00624 00625 uiout->flags |= mask; 00626 return oldflags; 00627 } 00628 00629 /* Clear the flags specified by the mask given. */ 00630 int 00631 ui_out_clear_flags (struct ui_out *uiout, int mask) 00632 { 00633 int oldflags = uiout->flags; 00634 00635 uiout->flags &= ~mask; 00636 return oldflags; 00637 } 00638 00639 /* Test the flags against the mask given. */ 00640 int 00641 ui_out_test_flags (struct ui_out *uiout, int mask) 00642 { 00643 return (uiout->flags & mask); 00644 } 00645 00646 /* Obtain the current verbosity level (as stablished by the 00647 'set verbositylevel' command. */ 00648 00649 int 00650 ui_out_get_verblvl (struct ui_out *uiout) 00651 { 00652 /* FIXME: not implemented yet. */ 00653 return 0; 00654 } 00655 00656 int 00657 ui_out_is_mi_like_p (struct ui_out *uiout) 00658 { 00659 return uiout->impl->is_mi_like_p; 00660 } 00661 00662 /* Default gdb-out hook functions. */ 00663 00664 static void 00665 default_table_begin (struct ui_out *uiout, int nbrofcols, 00666 int nr_rows, 00667 const char *tblid) 00668 { 00669 } 00670 00671 static void 00672 default_table_body (struct ui_out *uiout) 00673 { 00674 } 00675 00676 static void 00677 default_table_end (struct ui_out *uiout) 00678 { 00679 } 00680 00681 static void 00682 default_table_header (struct ui_out *uiout, int width, enum ui_align alignment, 00683 const char *col_name, 00684 const char *colhdr) 00685 { 00686 } 00687 00688 static void 00689 default_begin (struct ui_out *uiout, 00690 enum ui_out_type type, 00691 int level, 00692 const char *id) 00693 { 00694 } 00695 00696 static void 00697 default_end (struct ui_out *uiout, 00698 enum ui_out_type type, 00699 int level) 00700 { 00701 } 00702 00703 static void 00704 default_field_int (struct ui_out *uiout, int fldno, int width, 00705 enum ui_align align, 00706 const char *fldname, int value) 00707 { 00708 } 00709 00710 static void 00711 default_field_skip (struct ui_out *uiout, int fldno, int width, 00712 enum ui_align align, const char *fldname) 00713 { 00714 } 00715 00716 static void 00717 default_field_string (struct ui_out *uiout, 00718 int fldno, 00719 int width, 00720 enum ui_align align, 00721 const char *fldname, 00722 const char *string) 00723 { 00724 } 00725 00726 static void 00727 default_field_fmt (struct ui_out *uiout, int fldno, int width, 00728 enum ui_align align, 00729 const char *fldname, 00730 const char *format, 00731 va_list args) 00732 { 00733 } 00734 00735 static void 00736 default_spaces (struct ui_out *uiout, int numspaces) 00737 { 00738 } 00739 00740 static void 00741 default_text (struct ui_out *uiout, const char *string) 00742 { 00743 } 00744 00745 static void 00746 default_message (struct ui_out *uiout, int verbosity, 00747 const char *format, 00748 va_list args) 00749 { 00750 } 00751 00752 static void 00753 default_wrap_hint (struct ui_out *uiout, char *identstring) 00754 { 00755 } 00756 00757 static void 00758 default_flush (struct ui_out *uiout) 00759 { 00760 } 00761 00762 static void 00763 default_data_destroy (struct ui_out *uiout) 00764 { 00765 } 00766 00767 /* Interface to the implementation functions. */ 00768 00769 void 00770 uo_table_begin (struct ui_out *uiout, int nbrofcols, 00771 int nr_rows, 00772 const char *tblid) 00773 { 00774 if (!uiout->impl->table_begin) 00775 return; 00776 uiout->impl->table_begin (uiout, nbrofcols, nr_rows, tblid); 00777 } 00778 00779 void 00780 uo_table_body (struct ui_out *uiout) 00781 { 00782 if (!uiout->impl->table_body) 00783 return; 00784 uiout->impl->table_body (uiout); 00785 } 00786 00787 void 00788 uo_table_end (struct ui_out *uiout) 00789 { 00790 if (!uiout->impl->table_end) 00791 return; 00792 uiout->impl->table_end (uiout); 00793 } 00794 00795 void 00796 uo_table_header (struct ui_out *uiout, int width, enum ui_align align, 00797 const char *col_name, 00798 const char *colhdr) 00799 { 00800 if (!uiout->impl->table_header) 00801 return; 00802 uiout->impl->table_header (uiout, width, align, col_name, colhdr); 00803 } 00804 00805 /* Clear the table associated with UIOUT. */ 00806 00807 static void 00808 clear_table (struct ui_out *uiout) 00809 { 00810 if (uiout->table.id) 00811 xfree (uiout->table.id); 00812 clear_header_list (uiout); 00813 } 00814 00815 void 00816 uo_begin (struct ui_out *uiout, 00817 enum ui_out_type type, 00818 int level, 00819 const char *id) 00820 { 00821 if (uiout->impl->begin == NULL) 00822 return; 00823 uiout->impl->begin (uiout, type, level, id); 00824 } 00825 00826 void 00827 uo_end (struct ui_out *uiout, 00828 enum ui_out_type type, 00829 int level) 00830 { 00831 if (uiout->impl->end == NULL) 00832 return; 00833 uiout->impl->end (uiout, type, level); 00834 } 00835 00836 void 00837 uo_field_int (struct ui_out *uiout, int fldno, int width, enum ui_align align, 00838 const char *fldname, 00839 int value) 00840 { 00841 if (!uiout->impl->field_int) 00842 return; 00843 uiout->impl->field_int (uiout, fldno, width, align, fldname, value); 00844 } 00845 00846 void 00847 uo_field_skip (struct ui_out *uiout, int fldno, int width, enum ui_align align, 00848 const char *fldname) 00849 { 00850 if (!uiout->impl->field_skip) 00851 return; 00852 uiout->impl->field_skip (uiout, fldno, width, align, fldname); 00853 } 00854 00855 void 00856 uo_field_string (struct ui_out *uiout, int fldno, int width, 00857 enum ui_align align, 00858 const char *fldname, 00859 const char *string) 00860 { 00861 if (!uiout->impl->field_string) 00862 return; 00863 uiout->impl->field_string (uiout, fldno, width, align, fldname, string); 00864 } 00865 00866 void 00867 uo_field_fmt (struct ui_out *uiout, int fldno, int width, enum ui_align align, 00868 const char *fldname, 00869 const char *format, 00870 va_list args) 00871 { 00872 if (!uiout->impl->field_fmt) 00873 return; 00874 uiout->impl->field_fmt (uiout, fldno, width, align, fldname, format, args); 00875 } 00876 00877 void 00878 uo_spaces (struct ui_out *uiout, int numspaces) 00879 { 00880 if (!uiout->impl->spaces) 00881 return; 00882 uiout->impl->spaces (uiout, numspaces); 00883 } 00884 00885 void 00886 uo_text (struct ui_out *uiout, 00887 const char *string) 00888 { 00889 if (!uiout->impl->text) 00890 return; 00891 uiout->impl->text (uiout, string); 00892 } 00893 00894 void 00895 uo_message (struct ui_out *uiout, int verbosity, 00896 const char *format, 00897 va_list args) 00898 { 00899 if (!uiout->impl->message) 00900 return; 00901 uiout->impl->message (uiout, verbosity, format, args); 00902 } 00903 00904 void 00905 uo_wrap_hint (struct ui_out *uiout, char *identstring) 00906 { 00907 if (!uiout->impl->wrap_hint) 00908 return; 00909 uiout->impl->wrap_hint (uiout, identstring); 00910 } 00911 00912 void 00913 uo_flush (struct ui_out *uiout) 00914 { 00915 if (!uiout->impl->flush) 00916 return; 00917 uiout->impl->flush (uiout); 00918 } 00919 00920 int 00921 uo_redirect (struct ui_out *uiout, struct ui_file *outstream) 00922 { 00923 if (!uiout->impl->redirect) 00924 return -1; 00925 uiout->impl->redirect (uiout, outstream); 00926 return 0; 00927 } 00928 00929 void 00930 uo_data_destroy (struct ui_out *uiout) 00931 { 00932 if (!uiout->impl->data_destroy) 00933 return; 00934 00935 uiout->impl->data_destroy (uiout); 00936 } 00937 00938 /* local functions */ 00939 00940 /* List of column headers manipulation routines. */ 00941 00942 static void 00943 clear_header_list (struct ui_out *uiout) 00944 { 00945 while (uiout->table.header_first != NULL) 00946 { 00947 uiout->table.header_next = uiout->table.header_first; 00948 uiout->table.header_first = uiout->table.header_first->next; 00949 xfree (uiout->table.header_next->colhdr); 00950 xfree (uiout->table.header_next->col_name); 00951 xfree (uiout->table.header_next); 00952 } 00953 gdb_assert (uiout->table.header_first == NULL); 00954 uiout->table.header_last = NULL; 00955 uiout->table.header_next = NULL; 00956 } 00957 00958 static void 00959 append_header_to_list (struct ui_out *uiout, 00960 int width, 00961 int alignment, 00962 const char *col_name, 00963 const char *colhdr) 00964 { 00965 struct ui_out_hdr *temphdr; 00966 00967 temphdr = XMALLOC (struct ui_out_hdr); 00968 temphdr->width = width; 00969 temphdr->alignment = alignment; 00970 /* We have to copy the column title as the original may be an 00971 automatic. */ 00972 if (colhdr != NULL) 00973 temphdr->colhdr = xstrdup (colhdr); 00974 else 00975 temphdr->colhdr = NULL; 00976 00977 if (col_name != NULL) 00978 temphdr->col_name = xstrdup (col_name); 00979 else if (colhdr != NULL) 00980 temphdr->col_name = xstrdup (colhdr); 00981 else 00982 temphdr->col_name = NULL; 00983 00984 temphdr->next = NULL; 00985 if (uiout->table.header_first == NULL) 00986 { 00987 temphdr->colno = 1; 00988 uiout->table.header_first = temphdr; 00989 uiout->table.header_last = temphdr; 00990 } 00991 else 00992 { 00993 temphdr->colno = uiout->table.header_last->colno + 1; 00994 uiout->table.header_last->next = temphdr; 00995 uiout->table.header_last = temphdr; 00996 } 00997 uiout->table.header_next = uiout->table.header_last; 00998 } 00999 01000 /* Extract the format information for the NEXT header and advance 01001 the header pointer. Return 0 if there was no next header. */ 01002 01003 static int 01004 get_next_header (struct ui_out *uiout, 01005 int *colno, 01006 int *width, 01007 int *alignment, 01008 char **colhdr) 01009 { 01010 /* There may be no headers at all or we may have used all columns. */ 01011 if (uiout->table.header_next == NULL) 01012 return 0; 01013 *colno = uiout->table.header_next->colno; 01014 *width = uiout->table.header_next->width; 01015 *alignment = uiout->table.header_next->alignment; 01016 *colhdr = uiout->table.header_next->colhdr; 01017 /* Advance the header pointer to the next entry. */ 01018 uiout->table.header_next = uiout->table.header_next->next; 01019 return 1; 01020 } 01021 01022 01023 /* Verify that the field/tuple/list is correctly positioned. Return 01024 the field number and corresponding alignment (if 01025 available/applicable). */ 01026 01027 static void 01028 verify_field (struct ui_out *uiout, int *fldno, int *width, int *align) 01029 { 01030 struct ui_out_level *current = current_level (uiout); 01031 char *text; 01032 01033 if (uiout->table.flag) 01034 { 01035 if (!uiout->table.body_flag) 01036 internal_error (__FILE__, __LINE__, 01037 _("table_body missing; table fields must be \ 01038 specified after table_body and inside a list.")); 01039 /* NOTE: cagney/2001-12-08: There was a check here to ensure 01040 that this code was only executed when uiout->level was 01041 greater than zero. That no longer applies - this code is run 01042 before each table row tuple is started and at that point the 01043 level is zero. */ 01044 } 01045 01046 current->field_count += 1; 01047 01048 if (uiout->table.body_flag 01049 && uiout->table.entry_level == uiout->level 01050 && get_next_header (uiout, fldno, width, align, &text)) 01051 { 01052 if (*fldno != current->field_count) 01053 internal_error (__FILE__, __LINE__, 01054 _("ui-out internal error in handling headers.")); 01055 } 01056 else 01057 { 01058 *width = 0; 01059 *align = ui_noalign; 01060 *fldno = current->field_count; 01061 } 01062 } 01063 01064 01065 /* Access to ui-out members data. */ 01066 01067 void * 01068 ui_out_data (struct ui_out *uiout) 01069 { 01070 return uiout->data; 01071 } 01072 01073 /* Access table field parameters. */ 01074 int 01075 ui_out_query_field (struct ui_out *uiout, int colno, 01076 int *width, int *alignment, char **col_name) 01077 { 01078 struct ui_out_hdr *hdr; 01079 01080 if (!uiout->table.flag) 01081 return 0; 01082 01083 for (hdr = uiout->table.header_first; hdr; hdr = hdr->next) 01084 if (hdr->colno == colno) 01085 { 01086 *width = hdr->width; 01087 *alignment = hdr->alignment; 01088 *col_name = hdr->col_name; 01089 return 1; 01090 } 01091 01092 return 0; 01093 } 01094 01095 /* Initalize private members at startup. */ 01096 01097 struct ui_out * 01098 ui_out_new (struct ui_out_impl *impl, void *data, 01099 int flags) 01100 { 01101 struct ui_out *uiout = XMALLOC (struct ui_out); 01102 struct ui_out_level *current = XMALLOC (struct ui_out_level); 01103 01104 uiout->data = data; 01105 uiout->impl = impl; 01106 uiout->flags = flags; 01107 uiout->table.flag = 0; 01108 uiout->table.body_flag = 0; 01109 uiout->level = 0; 01110 uiout->levels = NULL; 01111 01112 /* Create uiout->level 0, the default level. */ 01113 current->type = ui_out_type_tuple; 01114 current->field_count = 0; 01115 VEC_safe_push (ui_out_level_p, uiout->levels, current); 01116 01117 uiout->table.header_first = NULL; 01118 uiout->table.header_last = NULL; 01119 uiout->table.header_next = NULL; 01120 return uiout; 01121 } 01122 01123 /* Free UIOUT and the memory areas it references. */ 01124 01125 void 01126 ui_out_destroy (struct ui_out *uiout) 01127 { 01128 int i; 01129 struct ui_out_level *current; 01130 01131 /* Make sure that all levels are freed in the case where levels have 01132 been pushed, but not popped before the ui_out object is 01133 destroyed. */ 01134 for (i = 0; 01135 VEC_iterate (ui_out_level_p, uiout->levels, i, current); 01136 ++i) 01137 xfree (current); 01138 01139 VEC_free (ui_out_level_p, uiout->levels); 01140 uo_data_destroy (uiout); 01141 clear_table (uiout); 01142 xfree (uiout); 01143 } 01144 01145 /* Standard gdb initialization hook. */ 01146 01147 void 01148 _initialize_ui_out (void) 01149 { 01150 /* nothing needs to be done */ 01151 }