gdb/tui: Link source and assembler scrolling .... again
[deliverable/binutils-gdb.git] / gdb / tui / tui-source.c
CommitLineData
f377b406 1/* TUI display source window.
f33c6cbf 2
b811d2c2 3 Copyright (C) 1998-2020 Free Software Foundation, Inc.
f33c6cbf 4
f377b406
SC
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
a9762ec7 11 the Free Software Foundation; either version 3 of the License, or
f377b406
SC
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
a9762ec7 20 along with this program. If not, see <http://www.gnu.org/licenses/>. */
c906108c
SS
21
22#include "defs.h"
d1da6b01 23#include <math.h>
c906108c
SS
24#include <ctype.h>
25#include "symtab.h"
26#include "frame.h"
27#include "breakpoint.h"
c2c6d25f 28#include "source.h"
13274fc3 29#include "objfiles.h"
a7417d46 30#include "filenames.h"
62f29fda 31#include "source-cache.h"
c906108c 32
d7b2e967
AC
33#include "tui/tui.h"
34#include "tui/tui-data.h"
62f29fda 35#include "tui/tui-io.h"
d7b2e967 36#include "tui/tui-stack.h"
d1da6b01 37#include "tui/tui-win.h"
d7b2e967
AC
38#include "tui/tui-winsource.h"
39#include "tui/tui-source.h"
6a83354a 40#include "gdb_curses.h"
c906108c 41
98427f35 42/* Function to display source in the source window. */
61c33f10 43bool
81c82c4b 44tui_source_window::set_contents (struct gdbarch *arch,
9f7540a5 45 const struct symtab_and_line &sal)
c906108c 46{
9f7540a5
TT
47 struct symtab *s = sal.symtab;
48 int line_no = sal.line;
81c82c4b 49
61c33f10
TT
50 if (s == NULL)
51 return false;
52
53 int line_width, nlines;
54
55 line_width = width - TUI_EXECINFO_SIZE - 1;
56 /* Take hilite (window border) into account, when
57 calculating the number of lines. */
58 nlines = (line_no + (height - 2)) - line_no;
59
60 std::string srclines;
61 const std::vector<off_t> *offsets;
62 if (!g_source_cache.get_source_lines (s, line_no, line_no + nlines,
63 &srclines)
64 || !g_source_cache.get_line_charpos (s, &offsets))
65 return false;
66
67 int cur_line_no, cur_line;
68 struct tui_locator_window *locator
69 = tui_locator_win_info_ptr ();
70 const char *s_filename = symtab_to_filename_for_display (s);
71
72 title = s_filename;
c906108c 73
61c33f10
TT
74 m_fullname = make_unique_xstrdup (symtab_to_fullname (s));
75
76 cur_line = 0;
77 gdbarch = get_objfile_arch (SYMTAB_OBJFILE (s));
78 start_line_or_addr.loa = LOA_LINE;
79 cur_line_no = start_line_or_addr.u.line_no = line_no;
80
81 int digits = 0;
82 if (compact_source)
83 {
84 /* Solaris 11+gcc 5.5 has ambiguous overloads of log10, so we
85 cast to double to get the right one. */
86 double l = log10 ((double) offsets->size ());
87 digits = 1 + (int) l;
88 }
89
90 const char *iter = srclines.c_str ();
91 content.resize (nlines);
92 while (cur_line < nlines)
c906108c 93 {
61c33f10
TT
94 struct tui_source_element *element
95 = &content[cur_line];
96
97 std::string text;
98 if (*iter != '\0')
99 text = tui_copy_source_line (&iter, cur_line_no,
100 horizontal_offset,
101 line_width, digits);
102
103 /* Set whether element is the execution point
104 and whether there is a break point on it. */
105 element->line_or_addr.loa = LOA_LINE;
106 element->line_or_addr.u.line_no = cur_line_no;
107 element->is_exec_point
108 = (filename_cmp (locator->full_name.c_str (),
109 symtab_to_fullname (s)) == 0
110 && cur_line_no == locator->line_no);
111
112 content[cur_line].line = std::move (text);
113
114 cur_line++;
115 cur_line_no++;
c906108c 116 }
61c33f10
TT
117
118 return true;
98427f35 119}
c906108c
SS
120
121
a358af15
AC
122/* Answer whether the source is currently displayed in the source
123 window. */
a38da35d
TT
124bool
125tui_source_window::showing_source_p (const char *fullname) const
c906108c 126{
f6cc34a9 127 return (!content.empty ()
9923f347 128 && (filename_cmp (tui_locator_win_info_ptr ()->full_name.c_str (),
56d397a3 129 fullname) == 0));
98427f35 130}
c906108c
SS
131
132
98427f35 133/* Scroll the source forward or backward vertically. */
c906108c 134void
c3bd716f 135tui_source_window::do_scroll_vertical (int num_to_scroll)
c906108c 136{
53e7cdba 137 if (!content.empty ())
c906108c 138 {
c906108c 139 struct symtab *s;
52575520 140 struct symtab_and_line cursal = get_current_source_symtab_and_line ();
9ae6bf64 141 struct gdbarch *arch = gdbarch;
c906108c 142
cafb3438 143 if (cursal.symtab == NULL)
9ae6bf64
TT
144 {
145 struct frame_info *fi = get_selected_frame (NULL);
146 s = find_pc_line_symtab (get_frame_pc (fi));
147 arch = get_frame_arch (fi);
148 }
c906108c 149 else
52575520 150 s = cursal.symtab;
c906108c 151
9ae6bf64 152 int line_no = start_line_or_addr.u.line_no + num_to_scroll;
cb44333d
TT
153 const std::vector<off_t> *offsets;
154 if (g_source_cache.get_line_charpos (s, &offsets)
9ae6bf64
TT
155 && line_no > offsets->size ())
156 line_no = start_line_or_addr.u.line_no;
157 if (line_no <= 0)
158 line_no = 1;
27229e99 159
9ae6bf64 160 cursal.line = line_no;
f5a7c406
AB
161 find_line_pc (cursal.symtab, cursal.line, &cursal.pc);
162 for (struct tui_source_window_base *win_info : tui_source_windows ())
163 win_info->update_source_window_as_is (arch, cursal);
c906108c 164 }
98427f35 165}
b73dd877 166
c2cd8994
TT
167bool
168tui_source_window::location_matches_p (struct bp_location *loc, int line_no)
169{
170 return (content[line_no].line_or_addr.loa == LOA_LINE
171 && content[line_no].line_or_addr.u.line_no == loc->line_number
172 && loc->symtab != NULL
7226433c 173 && filename_cmp (m_fullname.get (),
c2cd8994
TT
174 symtab_to_fullname (loc->symtab)) == 0);
175}
a54700c6 176
c9033fe8
TT
177/* See tui-source.h. */
178
179bool
180tui_source_window::line_is_displayed (int line) const
181{
cbfa8581
SV
182 if (content.size () < SCROLL_THRESHOLD)
183 return false;
184
185 for (size_t i = 0; i < content.size () - SCROLL_THRESHOLD; ++i)
c9033fe8 186 {
cbfa8581
SV
187 if (content[i].line_or_addr.loa == LOA_LINE
188 && content[i].line_or_addr.u.line_no == line)
189 return true;
c9033fe8
TT
190 }
191
cbfa8581 192 return false;
c9033fe8
TT
193}
194
a54700c6 195void
1ae58f0c 196tui_source_window::maybe_update (struct frame_info *fi, symtab_and_line sal)
a54700c6 197{
1630140d 198 int start_line = (sal.line - ((height - 2) / 2)) + 1;
a54700c6
TT
199 if (start_line <= 0)
200 start_line = 1;
201
202 bool source_already_displayed = (sal.symtab != 0
7226433c 203 && showing_source_p (m_fullname.get ()));
a54700c6 204
1ae58f0c 205 if (!(source_already_displayed && line_is_displayed (sal.line)))
9f7540a5
TT
206 {
207 sal.line = start_line;
208 update_source_window (get_frame_arch (fi), sal);
209 }
a54700c6
TT
210 else
211 {
9f7540a5
TT
212 struct tui_line_or_address l;
213
214 l.loa = LOA_LINE;
1ae58f0c 215 l.u.line_no = sal.line;
a54700c6
TT
216 set_is_exec_point_at (l);
217 }
218}
This page took 2.078937 seconds and 4 git commands to generate.