1 /* TUI display source/assembly window. 2 3 Copyright (C) 1998-2023 Free Software Foundation, Inc. 4 5 Contributed by Hewlett-Packard Company. 6 7 This file is part of GDB. 8 9 This program is free software; you can redistribute it and/or modify 10 it under the terms of the GNU General Public License as published by 11 the Free Software Foundation; either version 3 of the License, or 12 (at your option) any later version. 13 14 This program is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 GNU General Public License for more details. 18 19 You should have received a copy of the GNU General Public License 20 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 21 22 #ifndef TUI_TUI_WINSOURCE_H 23 #define TUI_TUI_WINSOURCE_H 24 25 #include "tui/tui-data.h" 26 #include "symtab.h" 27 28 enum tui_line_or_address_kind 29 { 30 LOA_LINE, 31 LOA_ADDRESS 32 }; 33 34 /* Structure describing source line or line address. */ 35 struct tui_line_or_address 36 { 37 enum tui_line_or_address_kind loa; 38 union 39 { 40 int line_no; 41 CORE_ADDR addr; 42 } u; 43 }; 44 45 /* Flags to tell what kind of breakpoint is at current line. */ 46 enum tui_bp_flag 47 { 48 TUI_BP_ENABLED = 0x01, 49 TUI_BP_DISABLED = 0x02, 50 TUI_BP_HIT = 0x04, 51 TUI_BP_CONDITIONAL = 0x08, 52 TUI_BP_HARDWARE = 0x10 53 }; 54 55 DEF_ENUM_FLAGS_TYPE (enum tui_bp_flag, tui_bp_flags); 56 57 /* Position of breakpoint markers in the exec info string. */ 58 #define TUI_BP_HIT_POS 0 59 #define TUI_BP_BREAK_POS 1 60 #define TUI_EXEC_POS 2 61 #define TUI_EXECINFO_SIZE 4 62 63 /* Elements in the Source/Disassembly Window. */ 64 struct tui_source_element 65 { 66 tui_source_element () 67 { 68 line_or_addr.loa = LOA_LINE; 69 line_or_addr.u.line_no = 0; 70 } 71 72 DISABLE_COPY_AND_ASSIGN (tui_source_element); 73 74 tui_source_element (tui_source_element &&other) 75 : line (std::move (other.line)), 76 line_or_addr (other.line_or_addr), 77 is_exec_point (other.is_exec_point), 78 break_mode (other.break_mode) 79 { 80 } 81 82 std::string line; 83 struct tui_line_or_address line_or_addr; 84 bool is_exec_point = false; 85 tui_bp_flags break_mode = 0; 86 }; 87 88 89 /* The base class for all source-like windows, namely the source and 90 disassembly windows. */ 91 92 struct tui_source_window_base : public tui_win_info 93 { 94 protected: 95 tui_source_window_base (); 96 ~tui_source_window_base (); 97 98 DISABLE_COPY_AND_ASSIGN (tui_source_window_base); 99 100 void do_scroll_horizontal (int num_to_scroll) override; 101 102 /* Erase the content and display STRING. */ 103 void do_erase_source_content (const char *string); 104 105 void rerender () override; 106 107 virtual bool set_contents (struct gdbarch *gdbarch, 108 const struct symtab_and_line &sal) = 0; 109 110 /* Return the number of extra margin characters needed by this 111 instance. */ 112 virtual int extra_margin () const 113 { 114 return 0; 115 } 116 117 /* Display the line number in the window margin. OFFSET indicates 118 which line to display; it is 0-based, with 0 meaning the line at 119 the top of the window. */ 120 virtual void show_line_number (int offset) const 121 { 122 } 123 124 /* Redraw the complete line of a source or disassembly window. */ 125 void show_source_line (int lineno); 126 127 /* Used for horizontal scroll. */ 128 int m_horizontal_offset = 0; 129 struct tui_line_or_address m_start_line_or_addr; 130 131 /* Architecture associated with code at this location. */ 132 struct gdbarch *m_gdbarch = nullptr; 133 134 std::vector<tui_source_element> m_content; 135 136 /* Length of longest line to be displayed. */ 137 int m_max_length; 138 139 public: 140 141 /* Refill the source window's source cache and update it. If this 142 is a disassembly window, then just update it. */ 143 void refill (); 144 145 /* Set the location of the execution point. */ 146 void set_is_exec_point_at (struct tui_line_or_address l); 147 148 void update_tab_width () override; 149 150 virtual bool location_matches_p (struct bp_location *loc, int line_no) = 0; 151 152 void update_exec_info (); 153 154 /* Update the window to display the given location. Does nothing if 155 the location is already displayed. */ 156 virtual void maybe_update (frame_info_ptr fi, symtab_and_line sal) = 0; 157 158 void update_source_window_as_is (struct gdbarch *gdbarch, 159 const struct symtab_and_line &sal); 160 void update_source_window (struct gdbarch *gdbarch, 161 const struct symtab_and_line &sal); 162 163 /* Scan the source window and the breakpoints to update the 164 break_mode information for each line. Returns true if something 165 changed and the execution window must be refreshed. See 166 tui_update_all_breakpoint_info for a description of 167 BEING_DELETED. */ 168 bool update_breakpoint_info (struct breakpoint *being_deleted, 169 bool current_only); 170 171 /* Erase the source content. */ 172 virtual void erase_source_content () = 0; 173 174 void refresh_window () override; 175 176 /* Return the start address and gdbarch. */ 177 virtual void display_start_addr (struct gdbarch **gdbarch_p, 178 CORE_ADDR *addr_p) = 0; 179 180 private: 181 182 void show_source_content (); 183 184 /* Called when the user "set style enabled" setting is changed. */ 185 void style_changed (); 186 187 /* A token used to register and unregister an observer. */ 188 gdb::observers::token m_observable; 189 190 /* Pad used to display fixme mumble */ 191 std::unique_ptr<WINDOW, curses_deleter> m_pad; 192 }; 193 194 195 /* A wrapper for a TUI window iterator that only iterates over source 196 windows. */ 197 198 struct tui_source_window_iterator 199 { 200 public: 201 202 typedef std::vector<tui_win_info *>::iterator inner_iterator; 203 204 typedef tui_source_window_iterator self_type; 205 typedef struct tui_source_window_base *value_type; 206 typedef struct tui_source_window_base *&reference; 207 typedef struct tui_source_window_base **pointer; 208 typedef std::forward_iterator_tag iterator_category; 209 typedef int difference_type; 210 211 explicit tui_source_window_iterator (const inner_iterator &it, 212 const inner_iterator &end) 213 : m_iter (it), 214 m_end (end) 215 { 216 advance (); 217 } 218 219 explicit tui_source_window_iterator (const inner_iterator &it) 220 : m_iter (it) 221 { 222 } 223 224 bool operator!= (const self_type &other) const 225 { 226 return m_iter != other.m_iter; 227 } 228 229 value_type operator* () const 230 { 231 return dynamic_cast<tui_source_window_base *> (*m_iter); 232 } 233 234 self_type &operator++ () 235 { 236 ++m_iter; 237 advance (); 238 return *this; 239 } 240 241 private: 242 243 void advance () 244 { 245 while (m_iter != m_end 246 && dynamic_cast<tui_source_window_base *> (*m_iter) == nullptr) 247 ++m_iter; 248 } 249 250 inner_iterator m_iter; 251 inner_iterator m_end; 252 }; 253 254 /* A range adapter for source windows. */ 255 256 struct tui_source_windows 257 { 258 /* Work around Wmaybe-uninitalized warning with g++ 11.0.0, see also 259 PR gcc/96295. Note that "tui_source_windows () = default" doesn't work 260 around the warning. */ 261 tui_source_windows () {} 262 263 tui_source_window_iterator begin () const 264 { 265 return tui_source_window_iterator (tui_windows.begin (), 266 tui_windows.end ()); 267 } 268 269 tui_source_window_iterator end () const 270 { 271 return tui_source_window_iterator (tui_windows.end ()); 272 } 273 }; 274 275 /* Update the execution windows to show the active breakpoints. This 276 is called whenever a breakpoint is inserted, removed or has its 277 state changed. Normally BEING_DELETED is nullptr; if not nullptr, 278 it indicates a breakpoint that is in the process of being deleted, 279 and which should therefore be ignored by the update. This is done 280 because the relevant observer is notified before the breakpoint is 281 removed from the list of breakpoints. */ 282 extern void tui_update_all_breakpoint_info (struct breakpoint *being_deleted); 283 284 /* Function to display the "main" routine. */ 285 extern void tui_display_main (void); 286 extern void tui_update_source_windows_with_addr (struct gdbarch *, CORE_ADDR); 287 extern void tui_update_source_windows_with_line (struct symtab_and_line sal); 288 289 /* Extract some source text from PTR. Returns a string holding the 290 desired text. PTR is updated to point to the start of the next 291 line. If LENGTH is non-NULL, then the length of the line is stored 292 there. Escape sequences are not counted against the length. 293 Actually an approximation is used -- each byte of a multi-byte 294 sequence counts as a character here. */ 295 296 extern std::string tui_copy_source_line (const char **ptr, 297 int *length = nullptr); 298 299 /* Constant definitions. */ 300 #define SCROLL_THRESHOLD 2 /* Threshold for lazy scroll. */ 301 302 #endif /* TUI_TUI_WINSOURCE_H */ 303