1 /* Output generating routines for GDB. 2 3 Copyright (C) 1999-2019 Free Software Foundation, Inc. 4 5 Contributed by Cygnus Solutions. 6 Written by Fernando Nasser for Cygnus. 7 8 This file is part of GDB. 9 10 This program is free software; you can redistribute it and/or modify 11 it under the terms of the GNU General Public License as published by 12 the Free Software Foundation; either version 3 of the License, or 13 (at your option) any later version. 14 15 This program is distributed in the hope that it will be useful, 16 but WITHOUT ANY WARRANTY; without even the implied warranty of 17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 GNU General Public License for more details. 19 20 You should have received a copy of the GNU General Public License 21 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 22 23 #ifndef UI_OUT_H 24 #define UI_OUT_H 1 25 26 #include <vector> 27 28 #include "common/enum-flags.h" 29 30 class ui_out_level; 31 class ui_out_table; 32 struct ui_file; 33 34 /* the current ui_out */ 35 36 /* FIXME: This should not be a global but something passed down from main.c 37 or top.c. */ 38 extern struct ui_out **current_ui_current_uiout_ptr (void); 39 #define current_uiout (*current_ui_current_uiout_ptr ()) 40 41 /* alignment enum */ 42 enum ui_align 43 { 44 ui_left = -1, 45 ui_center, 46 ui_right, 47 ui_noalign 48 }; 49 50 /* flags enum */ 51 enum ui_out_flag 52 { 53 ui_source_list = (1 << 0), 54 }; 55 56 DEF_ENUM_FLAGS_TYPE (ui_out_flag, ui_out_flags); 57 58 /* Prototypes for ui-out API. */ 59 60 /* A result is a recursive data structure consisting of lists and 61 tuples. */ 62 63 enum ui_out_type 64 { 65 ui_out_type_tuple, 66 ui_out_type_list 67 }; 68 69 /* Possible kinds of styling. */ 70 71 enum class ui_out_style_kind 72 { 73 /* The default (plain) style. */ 74 DEFAULT, 75 /* File name. */ 76 FILE, 77 /* Function name. */ 78 FUNCTION, 79 /* Variable name. */ 80 VARIABLE, 81 /* Address. */ 82 ADDRESS 83 }; 84 85 class ui_out 86 { 87 public: 88 89 explicit ui_out (ui_out_flags flags = 0); 90 virtual ~ui_out (); 91 92 void push_level (ui_out_type type); 93 void pop_level (ui_out_type type); 94 95 /* A table can be considered a special tuple/list combination with the 96 implied structure: ``table = { hdr = { header, ... } , body = [ { 97 field, ... }, ... ] }''. If NR_ROWS is negative then there is at 98 least one row. */ 99 100 void table_begin (int nr_cols, int nr_rows, const std::string &tblid); 101 void table_header (int width, ui_align align, const std::string &col_name, 102 const std::string &col_hdr); 103 void table_body (); 104 void table_end (); 105 106 void begin (ui_out_type type, const char *id); 107 void end (ui_out_type type); 108 109 void field_int (const char *fldname, int value); 110 void field_fmt_int (int width, ui_align align, const char *fldname, 111 int value); 112 void field_core_addr (const char *fldname, struct gdbarch *gdbarch, 113 CORE_ADDR address); 114 void field_string (const char *fldname, const char *string, 115 ui_out_style_kind style = ui_out_style_kind::DEFAULT); 116 void field_string (const char *fldname, const std::string &string); 117 void field_stream (const char *fldname, string_file &stream, 118 ui_out_style_kind style = ui_out_style_kind::DEFAULT); 119 void field_skip (const char *fldname); 120 void field_fmt (const char *fldname, const char *format, ...) 121 ATTRIBUTE_PRINTF (3, 4); 122 123 void spaces (int numspaces); 124 void text (const char *string); 125 void message (const char *format, ...) ATTRIBUTE_PRINTF (2, 3); 126 void wrap_hint (const char *identstring); 127 128 void flush (); 129 130 /* Redirect the output of a ui_out object temporarily. */ 131 void redirect (ui_file *outstream); 132 133 ui_out_flags test_flags (ui_out_flags mask); 134 135 /* HACK: Code in GDB is currently checking to see the type of ui_out 136 builder when determining which output to produce. This function is 137 a hack to encapsulate that test. Once GDB manages to separate the 138 CLI/MI from the core of GDB the problem should just go away .... */ 139 140 bool is_mi_like_p () const; 141 142 bool query_table_field (int colno, int *width, int *alignment, 143 const char **col_name); 144 145 protected: 146 147 virtual void do_table_begin (int nbrofcols, int nr_rows, const char *tblid) 148 = 0; 149 virtual void do_table_body () = 0; 150 virtual void do_table_end () = 0; 151 virtual void do_table_header (int width, ui_align align, 152 const std::string &col_name, 153 const std::string &col_hdr) = 0; 154 155 virtual void do_begin (ui_out_type type, const char *id) = 0; 156 virtual void do_end (ui_out_type type) = 0; 157 virtual void do_field_int (int fldno, int width, ui_align align, 158 const char *fldname, int value) = 0; 159 virtual void do_field_skip (int fldno, int width, ui_align align, 160 const char *fldname) = 0; 161 virtual void do_field_string (int fldno, int width, ui_align align, 162 const char *fldname, const char *string, 163 ui_out_style_kind style) = 0; 164 virtual void do_field_fmt (int fldno, int width, ui_align align, 165 const char *fldname, const char *format, 166 va_list args) 167 ATTRIBUTE_PRINTF (6,0) = 0; 168 virtual void do_spaces (int numspaces) = 0; 169 virtual void do_text (const char *string) = 0; 170 virtual void do_message (const char *format, va_list args) 171 ATTRIBUTE_PRINTF (2,0) = 0; 172 virtual void do_wrap_hint (const char *identstring) = 0; 173 virtual void do_flush () = 0; 174 virtual void do_redirect (struct ui_file *outstream) = 0; 175 176 /* Set as not MI-like by default. It is overridden in subclasses if 177 necessary. */ 178 179 virtual bool do_is_mi_like_p () const 180 { return false; } 181 182 private: 183 184 ui_out_flags m_flags; 185 186 /* Vector to store and track the ui-out levels. */ 187 std::vector<std::unique_ptr<ui_out_level>> m_levels; 188 189 /* A table, if any. At present only a single table is supported. */ 190 std::unique_ptr<ui_out_table> m_table_up; 191 192 void verify_field (int *fldno, int *width, ui_align *align); 193 194 int level () const; 195 ui_out_level *current_level () const; 196 }; 197 198 /* Start a new tuple or list on construction, and end it on 199 destruction. Normally this is used via the typedefs 200 ui_out_emit_tuple and ui_out_emit_list. */ 201 template<ui_out_type Type> 202 class ui_out_emit_type 203 { 204 public: 205 206 ui_out_emit_type (struct ui_out *uiout, const char *id) 207 : m_uiout (uiout) 208 { 209 uiout->begin (Type, id); 210 } 211 212 ~ui_out_emit_type () 213 { 214 m_uiout->end (Type); 215 } 216 217 DISABLE_COPY_AND_ASSIGN (ui_out_emit_type<Type>); 218 219 private: 220 221 struct ui_out *m_uiout; 222 }; 223 224 typedef ui_out_emit_type<ui_out_type_tuple> ui_out_emit_tuple; 225 typedef ui_out_emit_type<ui_out_type_list> ui_out_emit_list; 226 227 /* Start a new table on construction, and end the table on 228 destruction. */ 229 class ui_out_emit_table 230 { 231 public: 232 233 ui_out_emit_table (struct ui_out *uiout, int nr_cols, int nr_rows, 234 const char *tblid) 235 : m_uiout (uiout) 236 { 237 m_uiout->table_begin (nr_cols, nr_rows, tblid); 238 } 239 240 ~ui_out_emit_table () 241 { 242 m_uiout->table_end (); 243 } 244 245 ui_out_emit_table (const ui_out_emit_table &) = delete; 246 ui_out_emit_table &operator= (const ui_out_emit_table &) = delete; 247 248 private: 249 250 struct ui_out *m_uiout; 251 }; 252 253 /* On destruction, pop the last redirection by calling the uiout's 254 redirect method with a NULL parameter. */ 255 class ui_out_redirect_pop 256 { 257 public: 258 259 ui_out_redirect_pop (ui_out *uiout) 260 : m_uiout (uiout) 261 { 262 } 263 264 ~ui_out_redirect_pop () 265 { 266 m_uiout->redirect (NULL); 267 } 268 269 ui_out_redirect_pop (const ui_out_redirect_pop &) = delete; 270 ui_out_redirect_pop &operator= (const ui_out_redirect_pop &) = delete; 271 272 private: 273 struct ui_out *m_uiout; 274 }; 275 276 #endif /* UI_OUT_H */ 277