1 /* Output generating routines for GDB. 2 3 Copyright (C) 1999-2020 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 "gdbsupport/enum-flags.h" 29 #include "ui-style.h" 30 31 class ui_out_level; 32 class ui_out_table; 33 struct ui_file; 34 35 /* the current ui_out */ 36 37 /* FIXME: This should not be a global but something passed down from main.c 38 or top.c. */ 39 extern struct ui_out **current_ui_current_uiout_ptr (void); 40 #define current_uiout (*current_ui_current_uiout_ptr ()) 41 42 /* alignment enum */ 43 enum ui_align 44 { 45 ui_left = -1, 46 ui_center, 47 ui_right, 48 ui_noalign 49 }; 50 51 /* flags enum */ 52 enum ui_out_flag 53 { 54 ui_source_list = (1 << 0), 55 fix_multi_location_breakpoint_output = (1 << 1), 56 /* For CLI output, this flag is set if unfiltered output is desired. 57 This should only be used by low-level formatting functions. */ 58 unfiltered_output = (1 << 2), 59 /* This indicates that %pF should be disallowed in a printf format 60 string. */ 61 disallow_ui_out_field = (1 << 3) 62 }; 63 64 DEF_ENUM_FLAGS_TYPE (ui_out_flag, ui_out_flags); 65 66 /* Prototypes for ui-out API. */ 67 68 /* A result is a recursive data structure consisting of lists and 69 tuples. */ 70 71 enum ui_out_type 72 { 73 ui_out_type_tuple, 74 ui_out_type_list 75 }; 76 77 /* The possible kinds of fields. */ 78 enum class field_kind 79 { 80 /* "FIELD_STRING" needs a funny name to avoid clashes with tokens 81 named "STRING". See PR build/25250. FIELD_SIGNED is given a 82 similar name for consistency. */ 83 FIELD_SIGNED, 84 FIELD_STRING, 85 }; 86 87 /* The base type of all fields that can be emitted using %pF. */ 88 89 struct base_field_s 90 { 91 const char *name; 92 field_kind kind; 93 }; 94 95 /* A signed integer field, to be passed to %pF in format strings. */ 96 97 struct signed_field_s : base_field_s 98 { 99 LONGEST val; 100 }; 101 102 /* Construct a temporary signed_field_s on the caller's stack and 103 return a pointer to the constructed object. We use this because 104 it's not possible to pass a reference via va_args. */ 105 106 static inline signed_field_s * 107 signed_field (const char *name, LONGEST val, 108 signed_field_s &&tmp = {}) 109 { 110 tmp.name = name; 111 tmp.kind = field_kind::FIELD_SIGNED; 112 tmp.val = val; 113 return &tmp; 114 } 115 116 /* A string field, to be passed to %pF in format strings. */ 117 118 struct string_field_s : base_field_s 119 { 120 const char *str; 121 }; 122 123 /* Construct a temporary string_field_s on the caller's stack and 124 return a pointer to the constructed object. We use this because 125 it's not possible to pass a reference via va_args. */ 126 127 static inline string_field_s * 128 string_field (const char *name, const char *str, 129 string_field_s &&tmp = {}) 130 { 131 tmp.name = name; 132 tmp.kind = field_kind::FIELD_STRING; 133 tmp.str = str; 134 return &tmp; 135 } 136 137 /* A styled string. */ 138 139 struct styled_string_s 140 { 141 /* The style. */ 142 ui_file_style style; 143 144 /* The string. */ 145 const char *str; 146 }; 147 148 /* Construct a temporary styled_string_s on the caller's stack and 149 return a pointer to the constructed object. We use this because 150 it's not possible to pass a reference via va_args. */ 151 152 static inline styled_string_s * 153 styled_string (const ui_file_style &style, const char *str, 154 styled_string_s &&tmp = {}) 155 { 156 tmp.style = style; 157 tmp.str = str; 158 return &tmp; 159 } 160 161 class ui_out 162 { 163 public: 164 165 explicit ui_out (ui_out_flags flags = 0); 166 virtual ~ui_out (); 167 168 void push_level (ui_out_type type); 169 void pop_level (ui_out_type type); 170 171 /* A table can be considered a special tuple/list combination with the 172 implied structure: ``table = { hdr = { header, ... } , body = [ { 173 field, ... }, ... ] }''. If NR_ROWS is negative then there is at 174 least one row. */ 175 176 void table_begin (int nr_cols, int nr_rows, const std::string &tblid); 177 void table_header (int width, ui_align align, const std::string &col_name, 178 const std::string &col_hdr); 179 void table_body (); 180 void table_end (); 181 182 void begin (ui_out_type type, const char *id); 183 void end (ui_out_type type); 184 185 void field_signed (const char *fldname, LONGEST value); 186 void field_fmt_signed (int width, ui_align align, const char *fldname, 187 LONGEST value); 188 /* Like field_signed, but print an unsigned value. */ 189 void field_unsigned (const char *fldname, ULONGEST value); 190 void field_core_addr (const char *fldname, struct gdbarch *gdbarch, 191 CORE_ADDR address); 192 void field_string (const char *fldname, const char *string, 193 const ui_file_style &style = ui_file_style ()); 194 void field_string (const char *fldname, const std::string &string); 195 void field_stream (const char *fldname, string_file &stream, 196 const ui_file_style &style = ui_file_style ()); 197 void field_skip (const char *fldname); 198 void field_fmt (const char *fldname, const char *format, ...) 199 ATTRIBUTE_PRINTF (3, 4); 200 void field_fmt (const char *fldname, const ui_file_style &style, 201 const char *format, ...) 202 ATTRIBUTE_PRINTF (4, 5); 203 204 void spaces (int numspaces); 205 void text (const char *string); 206 207 /* Output a printf-style formatted string. In addition to the usual 208 printf format specs, this supports a few GDB-specific 209 formatters: 210 211 - '%pF' - output a field. 212 213 The argument is a field, wrapped in any of the base_field_s 214 subclasses. signed_field for integer fields, string_field for 215 string fields. This is preferred over separate 216 uiout->field_signed(), uiout_>field_string() etc. calls when 217 the formatted message is translatable. E.g.: 218 219 uiout->message (_("\nWatchpoint %pF deleted because the program has " 220 "left the block in\n" 221 "which its expression is valid.\n"), 222 signed_field ("wpnum", b->number)); 223 224 - '%p[' - output the following text in a specified style. 225 '%p]' - output the following text in the default style. 226 227 The argument to '%p[' is a ui_file_style pointer. The argument 228 to '%p]' must be nullptr. 229 230 This is useful when you want to output some portion of a string 231 literal in some style. E.g.: 232 233 uiout->message (_(" %p[<repeats %u times>%p]"), 234 metadata_style.style ().ptr (), 235 reps, repeats, nullptr); 236 237 - '%ps' - output a styled string. 238 239 The argument is the result of a call to styled_string. This is 240 useful when you want to output some runtime-generated string in 241 some style. E.g.: 242 243 uiout->message (_("this is a target address %ps.\n"), 244 styled_string (address_style.style (), 245 paddress (gdbarch, pc))); 246 247 Note that these all "abuse" the %p printf format spec, in order 248 to be compatible with GCC's printf format checking. This is OK 249 because code in GDB that wants to print a host address should use 250 host_address_to_string instead of %p. */ 251 void message (const char *format, ...) ATTRIBUTE_PRINTF (2, 3); 252 void vmessage (const ui_file_style &in_style, 253 const char *format, va_list args) ATTRIBUTE_PRINTF (3, 0); 254 255 void wrap_hint (const char *identstring); 256 257 void flush (); 258 259 /* Redirect the output of a ui_out object temporarily. */ 260 void redirect (ui_file *outstream); 261 262 ui_out_flags test_flags (ui_out_flags mask); 263 264 /* HACK: Code in GDB is currently checking to see the type of ui_out 265 builder when determining which output to produce. This function is 266 a hack to encapsulate that test. Once GDB manages to separate the 267 CLI/MI from the core of GDB the problem should just go away .... */ 268 269 bool is_mi_like_p () const; 270 271 bool query_table_field (int colno, int *width, int *alignment, 272 const char **col_name); 273 274 /* Return true if this stream is prepared to handle style 275 escapes. */ 276 virtual bool can_emit_style_escape () const = 0; 277 278 protected: 279 280 virtual void do_table_begin (int nbrofcols, int nr_rows, const char *tblid) 281 = 0; 282 virtual void do_table_body () = 0; 283 virtual void do_table_end () = 0; 284 virtual void do_table_header (int width, ui_align align, 285 const std::string &col_name, 286 const std::string &col_hdr) = 0; 287 288 virtual void do_begin (ui_out_type type, const char *id) = 0; 289 virtual void do_end (ui_out_type type) = 0; 290 virtual void do_field_signed (int fldno, int width, ui_align align, 291 const char *fldname, LONGEST value) = 0; 292 virtual void do_field_unsigned (int fldno, int width, ui_align align, 293 const char *fldname, ULONGEST value) = 0; 294 virtual void do_field_skip (int fldno, int width, ui_align align, 295 const char *fldname) = 0; 296 virtual void do_field_string (int fldno, int width, ui_align align, 297 const char *fldname, const char *string, 298 const ui_file_style &style) = 0; 299 virtual void do_field_fmt (int fldno, int width, ui_align align, 300 const char *fldname, const ui_file_style &style, 301 const char *format, va_list args) 302 ATTRIBUTE_PRINTF (7, 0) = 0; 303 virtual void do_spaces (int numspaces) = 0; 304 virtual void do_text (const char *string) = 0; 305 virtual void do_message (const ui_file_style &style, 306 const char *format, va_list args) 307 ATTRIBUTE_PRINTF (3,0) = 0; 308 virtual void do_wrap_hint (const char *identstring) = 0; 309 virtual void do_flush () = 0; 310 virtual void do_redirect (struct ui_file *outstream) = 0; 311 312 /* Set as not MI-like by default. It is overridden in subclasses if 313 necessary. */ 314 315 virtual bool do_is_mi_like_p () const 316 { return false; } 317 318 private: 319 void call_do_message (const ui_file_style &style, const char *format, 320 ...); 321 322 ui_out_flags m_flags; 323 324 /* Vector to store and track the ui-out levels. */ 325 std::vector<std::unique_ptr<ui_out_level>> m_levels; 326 327 /* A table, if any. At present only a single table is supported. */ 328 std::unique_ptr<ui_out_table> m_table_up; 329 330 void verify_field (int *fldno, int *width, ui_align *align); 331 332 int level () const; 333 ui_out_level *current_level () const; 334 }; 335 336 /* Start a new tuple or list on construction, and end it on 337 destruction. Normally this is used via the typedefs 338 ui_out_emit_tuple and ui_out_emit_list. */ 339 template<ui_out_type Type> 340 class ui_out_emit_type 341 { 342 public: 343 344 ui_out_emit_type (struct ui_out *uiout, const char *id) 345 : m_uiout (uiout) 346 { 347 uiout->begin (Type, id); 348 } 349 350 ~ui_out_emit_type () 351 { 352 m_uiout->end (Type); 353 } 354 355 DISABLE_COPY_AND_ASSIGN (ui_out_emit_type<Type>); 356 357 private: 358 359 struct ui_out *m_uiout; 360 }; 361 362 typedef ui_out_emit_type<ui_out_type_tuple> ui_out_emit_tuple; 363 typedef ui_out_emit_type<ui_out_type_list> ui_out_emit_list; 364 365 /* Start a new table on construction, and end the table on 366 destruction. */ 367 class ui_out_emit_table 368 { 369 public: 370 371 ui_out_emit_table (struct ui_out *uiout, int nr_cols, int nr_rows, 372 const char *tblid) 373 : m_uiout (uiout) 374 { 375 m_uiout->table_begin (nr_cols, nr_rows, tblid); 376 } 377 378 ~ui_out_emit_table () 379 { 380 m_uiout->table_end (); 381 } 382 383 ui_out_emit_table (const ui_out_emit_table &) = delete; 384 ui_out_emit_table &operator= (const ui_out_emit_table &) = delete; 385 386 private: 387 388 struct ui_out *m_uiout; 389 }; 390 391 /* On destruction, pop the last redirection by calling the uiout's 392 redirect method with a NULL parameter. */ 393 class ui_out_redirect_pop 394 { 395 public: 396 397 ui_out_redirect_pop (ui_out *uiout) 398 : m_uiout (uiout) 399 { 400 } 401 402 ~ui_out_redirect_pop () 403 { 404 m_uiout->redirect (NULL); 405 } 406 407 ui_out_redirect_pop (const ui_out_redirect_pop &) = delete; 408 ui_out_redirect_pop &operator= (const ui_out_redirect_pop &) = delete; 409 410 private: 411 struct ui_out *m_uiout; 412 }; 413 414 #endif /* UI_OUT_H */ 415