ui-out.h 13 KB

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