1 /* Python implementation of ui_out 2 3 Copyright (C) 2023-2024 Free Software Foundation, Inc. 4 5 This file is part of GDB. 6 7 This program is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 3 of the License, or 10 (at your option) any later version. 11 12 This program is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 19 20 #ifndef GDB_PYTHON_PY_UIOUT_H 21 #define GDB_PYTHON_PY_UIOUT_H 22 23 #include "python-internal.h" 24 #include "ui-out.h" 25 26 /* A ui_out subclass that creates a Python object based on the data 27 that is passed in. */ 28 29 class py_ui_out : public ui_out 30 { 31 public: 32 33 py_ui_out () 34 : ui_out (fix_multi_location_breakpoint_output 35 | fix_breakpoint_script_output) 36 { 37 do_begin (ui_out_type_tuple, nullptr); 38 } 39 40 bool can_emit_style_escape () const override 41 { return false; } 42 43 bool do_is_mi_like_p () const override 44 { return true; } 45 46 /* Return the Python object that was created. If a Python error 47 occurred during the processing, set the Python error and return 48 nullptr. */ 49 gdbpy_ref<> result () 50 { 51 if (m_error.has_value ()) 52 { 53 m_error->restore (); 54 return nullptr; 55 } 56 return std::move (current ().obj); 57 } 58 59 ui_file *current_stream () const override 60 { return nullptr; } 61 62 protected: 63 64 void do_progress_end () override { } 65 void do_progress_start () override { } 66 void do_progress_notify (const std::string &, const char *, double, double) 67 override 68 { } 69 70 void do_table_begin (int nbrofcols, int nr_rows, const char *tblid) override 71 { 72 do_begin (ui_out_type_list, tblid); 73 } 74 void do_table_body () override 75 { } 76 void do_table_end () override 77 { 78 do_end (ui_out_type_list); 79 } 80 void do_table_header (int width, ui_align align, 81 const std::string &col_name, 82 const std::string &col_hdr) override 83 { } 84 85 void do_begin (ui_out_type type, const char *id) override; 86 void do_end (ui_out_type type) override; 87 88 void do_field_signed (int fldno, int width, ui_align align, 89 const char *fldname, LONGEST value) override; 90 void do_field_unsigned (int fldno, int width, ui_align align, 91 const char *fldname, ULONGEST value) override; 92 93 void do_field_skip (int fldno, int width, ui_align align, 94 const char *fldname) override 95 { } 96 97 void do_field_string (int fldno, int width, ui_align align, 98 const char *fldname, const char *string, 99 const ui_file_style &style) override; 100 void do_field_fmt (int fldno, int width, ui_align align, 101 const char *fldname, const ui_file_style &style, 102 const char *format, va_list args) override 103 ATTRIBUTE_PRINTF (7, 0); 104 105 void do_spaces (int numspaces) override 106 { } 107 108 void do_text (const char *string) override 109 { } 110 111 void do_message (const ui_file_style &style, 112 const char *format, va_list args) 113 override ATTRIBUTE_PRINTF (3,0) 114 { } 115 116 void do_wrap_hint (int indent) override 117 { } 118 119 void do_flush () override 120 { } 121 122 void do_redirect (struct ui_file *outstream) override 123 { } 124 125 private: 126 127 /* When constructing Python objects, this class keeps a stack of 128 objects being constructed. Each such object has this type. */ 129 struct object_desc 130 { 131 /* Name of the field (or empty for lists) that this object will 132 eventually become. */ 133 std::string field_name; 134 /* The object under construction. */ 135 gdbpy_ref<> obj; 136 /* The type of structure being created. Note that tables are 137 treated as lists here. */ 138 ui_out_type type; 139 }; 140 141 /* The stack of objects being created. */ 142 std::vector<object_desc> m_objects; 143 144 /* If an error occurred, this holds the exception information for 145 use by the 'release' method. */ 146 std::optional<gdbpy_err_fetch> m_error; 147 148 /* Return a reference to the object under construction. */ 149 object_desc ¤t () 150 { return m_objects.back (); } 151 152 /* Add a new field to the current object under construction. */ 153 void add_field (const char *name, const gdbpy_ref<> &obj); 154 }; 155 156 #endif /* GDB_PYTHON_PY_UIOUT_H */ 157