GDB (API)
/home/stan/gdb/src/gdb/ui-out.c
Go to the documentation of this file.
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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines