xref: /openbsd-src/gnu/usr.bin/binutils/gdb/tui/tui-winsource.c (revision b725ae7711052a2233e31a66fefb8a752c388d7a)
1*b725ae77Skettenis /* TUI display source/assembly window.
2*b725ae77Skettenis 
3*b725ae77Skettenis    Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software
4*b725ae77Skettenis    Foundation, Inc.
5*b725ae77Skettenis 
6*b725ae77Skettenis    Contributed by Hewlett-Packard Company.
7*b725ae77Skettenis 
8*b725ae77Skettenis    This file is part of GDB.
9*b725ae77Skettenis 
10*b725ae77Skettenis    This program is free software; you can redistribute it and/or modify
11*b725ae77Skettenis    it under the terms of the GNU General Public License as published by
12*b725ae77Skettenis    the Free Software Foundation; either version 2 of the License, or
13*b725ae77Skettenis    (at your option) any later version.
14*b725ae77Skettenis 
15*b725ae77Skettenis    This program is distributed in the hope that it will be useful,
16*b725ae77Skettenis    but WITHOUT ANY WARRANTY; without even the implied warranty of
17*b725ae77Skettenis    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*b725ae77Skettenis    GNU General Public License for more details.
19*b725ae77Skettenis 
20*b725ae77Skettenis    You should have received a copy of the GNU General Public License
21*b725ae77Skettenis    along with this program; if not, write to the Free Software
22*b725ae77Skettenis    Foundation, Inc., 59 Temple Place - Suite 330,
23*b725ae77Skettenis    Boston, MA 02111-1307, USA.  */
24*b725ae77Skettenis 
25*b725ae77Skettenis #include "defs.h"
26*b725ae77Skettenis #include <ctype.h>
27*b725ae77Skettenis #include "symtab.h"
28*b725ae77Skettenis #include "frame.h"
29*b725ae77Skettenis #include "breakpoint.h"
30*b725ae77Skettenis #include "value.h"
31*b725ae77Skettenis #include "source.h"
32*b725ae77Skettenis 
33*b725ae77Skettenis #include "tui/tui.h"
34*b725ae77Skettenis #include "tui/tui-data.h"
35*b725ae77Skettenis #include "tui/tui-stack.h"
36*b725ae77Skettenis #include "tui/tui-win.h"
37*b725ae77Skettenis #include "tui/tui-wingeneral.h"
38*b725ae77Skettenis #include "tui/tui-winsource.h"
39*b725ae77Skettenis #include "tui/tui-source.h"
40*b725ae77Skettenis #include "tui/tui-disasm.h"
41*b725ae77Skettenis 
42*b725ae77Skettenis #include "gdb_string.h"
43*b725ae77Skettenis #include "gdb_curses.h"
44*b725ae77Skettenis 
45*b725ae77Skettenis /* Function to display the "main" routine.  */
46*b725ae77Skettenis void
tui_display_main(void)47*b725ae77Skettenis tui_display_main (void)
48*b725ae77Skettenis {
49*b725ae77Skettenis   if ((tui_source_windows ())->count > 0)
50*b725ae77Skettenis     {
51*b725ae77Skettenis       CORE_ADDR addr;
52*b725ae77Skettenis 
53*b725ae77Skettenis       addr = tui_get_begin_asm_address ();
54*b725ae77Skettenis       if (addr != (CORE_ADDR) 0)
55*b725ae77Skettenis 	{
56*b725ae77Skettenis 	  struct symtab_and_line sal;
57*b725ae77Skettenis 
58*b725ae77Skettenis 	  tui_update_source_windows_with_addr (addr);
59*b725ae77Skettenis 	  sal = find_pc_line (addr, 0);
60*b725ae77Skettenis           if (sal.symtab)
61*b725ae77Skettenis              tui_update_locator_filename (sal.symtab->filename);
62*b725ae77Skettenis           else
63*b725ae77Skettenis              tui_update_locator_filename ("??");
64*b725ae77Skettenis 	}
65*b725ae77Skettenis     }
66*b725ae77Skettenis }
67*b725ae77Skettenis 
68*b725ae77Skettenis 
69*b725ae77Skettenis 
70*b725ae77Skettenis /* Function to display source in the source window.  This function
71*b725ae77Skettenis    initializes the horizontal scroll to 0.  */
72*b725ae77Skettenis void
tui_update_source_window(struct tui_win_info * win_info,struct symtab * s,union tui_line_or_address line_or_addr,int noerror)73*b725ae77Skettenis tui_update_source_window (struct tui_win_info * win_info, struct symtab *s,
74*b725ae77Skettenis 			  union tui_line_or_address line_or_addr, int noerror)
75*b725ae77Skettenis {
76*b725ae77Skettenis   win_info->detail.source_info.horizontal_offset = 0;
77*b725ae77Skettenis   tui_update_source_window_as_is (win_info, s, line_or_addr, noerror);
78*b725ae77Skettenis 
79*b725ae77Skettenis   return;
80*b725ae77Skettenis }
81*b725ae77Skettenis 
82*b725ae77Skettenis 
83*b725ae77Skettenis /* Function to display source in the source/asm window.  This function
84*b725ae77Skettenis    shows the source as specified by the horizontal offset.  */
85*b725ae77Skettenis void
tui_update_source_window_as_is(struct tui_win_info * win_info,struct symtab * s,union tui_line_or_address line_or_addr,int noerror)86*b725ae77Skettenis tui_update_source_window_as_is (struct tui_win_info * win_info, struct symtab *s,
87*b725ae77Skettenis 				union tui_line_or_address line_or_addr, int noerror)
88*b725ae77Skettenis {
89*b725ae77Skettenis   enum tui_status ret;
90*b725ae77Skettenis 
91*b725ae77Skettenis   if (win_info->generic.type == SRC_WIN)
92*b725ae77Skettenis     ret = tui_set_source_content (s, line_or_addr.line_no, noerror);
93*b725ae77Skettenis   else
94*b725ae77Skettenis     ret = tui_set_disassem_content (line_or_addr.addr);
95*b725ae77Skettenis 
96*b725ae77Skettenis   if (ret == TUI_FAILURE)
97*b725ae77Skettenis     {
98*b725ae77Skettenis       tui_clear_source_content (win_info, EMPTY_SOURCE_PROMPT);
99*b725ae77Skettenis       tui_clear_exec_info_content (win_info);
100*b725ae77Skettenis     }
101*b725ae77Skettenis   else
102*b725ae77Skettenis     {
103*b725ae77Skettenis       tui_update_breakpoint_info (win_info, 0);
104*b725ae77Skettenis       tui_show_source_content (win_info);
105*b725ae77Skettenis       tui_update_exec_info (win_info);
106*b725ae77Skettenis       if (win_info->generic.type == SRC_WIN)
107*b725ae77Skettenis 	{
108*b725ae77Skettenis 	  struct symtab_and_line sal;
109*b725ae77Skettenis 
110*b725ae77Skettenis 	  sal.line = line_or_addr.line_no +
111*b725ae77Skettenis 	    (win_info->generic.content_size - 2);
112*b725ae77Skettenis 	  sal.symtab = s;
113*b725ae77Skettenis 	  set_current_source_symtab_and_line (&sal);
114*b725ae77Skettenis 	  /*
115*b725ae77Skettenis 	     ** If the focus was in the asm win, put it in the src
116*b725ae77Skettenis 	     ** win if we don't have a split layout
117*b725ae77Skettenis 	   */
118*b725ae77Skettenis 	  if (tui_win_with_focus () == TUI_DISASM_WIN &&
119*b725ae77Skettenis 	      tui_current_layout () != SRC_DISASSEM_COMMAND)
120*b725ae77Skettenis 	    tui_set_win_focus_to (TUI_SRC_WIN);
121*b725ae77Skettenis 	}
122*b725ae77Skettenis     }
123*b725ae77Skettenis 
124*b725ae77Skettenis 
125*b725ae77Skettenis   return;
126*b725ae77Skettenis }
127*b725ae77Skettenis 
128*b725ae77Skettenis 
129*b725ae77Skettenis /* Function to ensure that the source and/or disassemly windows
130*b725ae77Skettenis    reflect the input address.  */
131*b725ae77Skettenis void
tui_update_source_windows_with_addr(CORE_ADDR addr)132*b725ae77Skettenis tui_update_source_windows_with_addr (CORE_ADDR addr)
133*b725ae77Skettenis {
134*b725ae77Skettenis   if (addr != 0)
135*b725ae77Skettenis     {
136*b725ae77Skettenis       struct symtab_and_line sal;
137*b725ae77Skettenis       union tui_line_or_address l;
138*b725ae77Skettenis 
139*b725ae77Skettenis       switch (tui_current_layout ())
140*b725ae77Skettenis 	{
141*b725ae77Skettenis 	case DISASSEM_COMMAND:
142*b725ae77Skettenis 	case DISASSEM_DATA_COMMAND:
143*b725ae77Skettenis 	  tui_show_disassem (addr);
144*b725ae77Skettenis 	  break;
145*b725ae77Skettenis 	case SRC_DISASSEM_COMMAND:
146*b725ae77Skettenis 	  tui_show_disassem_and_update_source (addr);
147*b725ae77Skettenis 	  break;
148*b725ae77Skettenis 	default:
149*b725ae77Skettenis 	  sal = find_pc_line (addr, 0);
150*b725ae77Skettenis 	  l.line_no = sal.line;
151*b725ae77Skettenis 	  tui_show_symtab_source (sal.symtab, l, FALSE);
152*b725ae77Skettenis 	  break;
153*b725ae77Skettenis 	}
154*b725ae77Skettenis     }
155*b725ae77Skettenis   else
156*b725ae77Skettenis     {
157*b725ae77Skettenis       int i;
158*b725ae77Skettenis 
159*b725ae77Skettenis       for (i = 0; i < (tui_source_windows ())->count; i++)
160*b725ae77Skettenis 	{
161*b725ae77Skettenis 	  struct tui_win_info * win_info = (struct tui_win_info *) (tui_source_windows ())->list[i];
162*b725ae77Skettenis 
163*b725ae77Skettenis 	  tui_clear_source_content (win_info, EMPTY_SOURCE_PROMPT);
164*b725ae77Skettenis 	  tui_clear_exec_info_content (win_info);
165*b725ae77Skettenis 	}
166*b725ae77Skettenis     }
167*b725ae77Skettenis }
168*b725ae77Skettenis 
169*b725ae77Skettenis /* Function to ensure that the source and/or disassemly windows
170*b725ae77Skettenis    reflect the input address.  */
171*b725ae77Skettenis void
tui_update_source_windows_with_line(struct symtab * s,int line)172*b725ae77Skettenis tui_update_source_windows_with_line (struct symtab *s, int line)
173*b725ae77Skettenis {
174*b725ae77Skettenis   CORE_ADDR pc;
175*b725ae77Skettenis   union tui_line_or_address l;
176*b725ae77Skettenis 
177*b725ae77Skettenis   switch (tui_current_layout ())
178*b725ae77Skettenis     {
179*b725ae77Skettenis     case DISASSEM_COMMAND:
180*b725ae77Skettenis     case DISASSEM_DATA_COMMAND:
181*b725ae77Skettenis       find_line_pc (s, line, &pc);
182*b725ae77Skettenis       tui_update_source_windows_with_addr (pc);
183*b725ae77Skettenis       break;
184*b725ae77Skettenis     default:
185*b725ae77Skettenis       l.line_no = line;
186*b725ae77Skettenis       tui_show_symtab_source (s, l, FALSE);
187*b725ae77Skettenis       if (tui_current_layout () == SRC_DISASSEM_COMMAND)
188*b725ae77Skettenis 	{
189*b725ae77Skettenis 	  find_line_pc (s, line, &pc);
190*b725ae77Skettenis 	  tui_show_disassem (pc);
191*b725ae77Skettenis 	}
192*b725ae77Skettenis       break;
193*b725ae77Skettenis     }
194*b725ae77Skettenis 
195*b725ae77Skettenis   return;
196*b725ae77Skettenis }
197*b725ae77Skettenis 
198*b725ae77Skettenis void
tui_clear_source_content(struct tui_win_info * win_info,int display_prompt)199*b725ae77Skettenis tui_clear_source_content (struct tui_win_info * win_info, int display_prompt)
200*b725ae77Skettenis {
201*b725ae77Skettenis   if (win_info != NULL)
202*b725ae77Skettenis     {
203*b725ae77Skettenis       int i;
204*b725ae77Skettenis 
205*b725ae77Skettenis       win_info->generic.content_in_use = FALSE;
206*b725ae77Skettenis       tui_erase_source_content (win_info, display_prompt);
207*b725ae77Skettenis       for (i = 0; i < win_info->generic.content_size; i++)
208*b725ae77Skettenis 	{
209*b725ae77Skettenis 	  struct tui_win_element * element =
210*b725ae77Skettenis 	  (struct tui_win_element *) win_info->generic.content[i];
211*b725ae77Skettenis 	  element->which_element.source.has_break = FALSE;
212*b725ae77Skettenis 	  element->which_element.source.is_exec_point = FALSE;
213*b725ae77Skettenis 	}
214*b725ae77Skettenis     }
215*b725ae77Skettenis }
216*b725ae77Skettenis 
217*b725ae77Skettenis 
218*b725ae77Skettenis void
tui_erase_source_content(struct tui_win_info * win_info,int display_prompt)219*b725ae77Skettenis tui_erase_source_content (struct tui_win_info * win_info, int display_prompt)
220*b725ae77Skettenis {
221*b725ae77Skettenis   int x_pos;
222*b725ae77Skettenis   int half_width = (win_info->generic.width - 2) / 2;
223*b725ae77Skettenis 
224*b725ae77Skettenis   if (win_info->generic.handle != (WINDOW *) NULL)
225*b725ae77Skettenis     {
226*b725ae77Skettenis       werase (win_info->generic.handle);
227*b725ae77Skettenis       tui_check_and_display_highlight_if_needed (win_info);
228*b725ae77Skettenis       if (display_prompt == EMPTY_SOURCE_PROMPT)
229*b725ae77Skettenis 	{
230*b725ae77Skettenis 	  char *no_src_str;
231*b725ae77Skettenis 
232*b725ae77Skettenis 	  if (win_info->generic.type == SRC_WIN)
233*b725ae77Skettenis 	    no_src_str = NO_SRC_STRING;
234*b725ae77Skettenis 	  else
235*b725ae77Skettenis 	    no_src_str = NO_DISASSEM_STRING;
236*b725ae77Skettenis 	  if (strlen (no_src_str) >= half_width)
237*b725ae77Skettenis 	    x_pos = 1;
238*b725ae77Skettenis 	  else
239*b725ae77Skettenis 	    x_pos = half_width - strlen (no_src_str);
240*b725ae77Skettenis 	  mvwaddstr (win_info->generic.handle,
241*b725ae77Skettenis 		     (win_info->generic.height / 2),
242*b725ae77Skettenis 		     x_pos,
243*b725ae77Skettenis 		     no_src_str);
244*b725ae77Skettenis 
245*b725ae77Skettenis 	  /* elz: added this function call to set the real contents of
246*b725ae77Skettenis 	     the window to what is on the  screen, so that later calls
247*b725ae77Skettenis 	     to refresh, do display
248*b725ae77Skettenis 	     the correct stuff, and not the old image */
249*b725ae77Skettenis 
250*b725ae77Skettenis 	  tui_set_source_content_nil (win_info, no_src_str);
251*b725ae77Skettenis 	}
252*b725ae77Skettenis       tui_refresh_win (&win_info->generic);
253*b725ae77Skettenis     }
254*b725ae77Skettenis }
255*b725ae77Skettenis 
256*b725ae77Skettenis 
257*b725ae77Skettenis /* Redraw the complete line of a source or disassembly window.  */
258*b725ae77Skettenis static void
tui_show_source_line(struct tui_win_info * win_info,int lineno)259*b725ae77Skettenis tui_show_source_line (struct tui_win_info * win_info, int lineno)
260*b725ae77Skettenis {
261*b725ae77Skettenis   struct tui_win_element * line;
262*b725ae77Skettenis   int x, y;
263*b725ae77Skettenis 
264*b725ae77Skettenis   line = (struct tui_win_element *) win_info->generic.content[lineno - 1];
265*b725ae77Skettenis   if (line->which_element.source.is_exec_point)
266*b725ae77Skettenis     wattron (win_info->generic.handle, A_STANDOUT);
267*b725ae77Skettenis 
268*b725ae77Skettenis   mvwaddstr (win_info->generic.handle, lineno, 1,
269*b725ae77Skettenis              line->which_element.source.line);
270*b725ae77Skettenis   if (line->which_element.source.is_exec_point)
271*b725ae77Skettenis     wattroff (win_info->generic.handle, A_STANDOUT);
272*b725ae77Skettenis 
273*b725ae77Skettenis   /* Clear to end of line but stop before the border.  */
274*b725ae77Skettenis   getyx (win_info->generic.handle, y, x);
275*b725ae77Skettenis   while (x + 1 < win_info->generic.width)
276*b725ae77Skettenis     {
277*b725ae77Skettenis       waddch (win_info->generic.handle, ' ');
278*b725ae77Skettenis       getyx (win_info->generic.handle, y, x);
279*b725ae77Skettenis     }
280*b725ae77Skettenis }
281*b725ae77Skettenis 
282*b725ae77Skettenis void
tui_show_source_content(struct tui_win_info * win_info)283*b725ae77Skettenis tui_show_source_content (struct tui_win_info * win_info)
284*b725ae77Skettenis {
285*b725ae77Skettenis   if (win_info->generic.content_size > 0)
286*b725ae77Skettenis     {
287*b725ae77Skettenis       int lineno;
288*b725ae77Skettenis 
289*b725ae77Skettenis       for (lineno = 1; lineno <= win_info->generic.content_size; lineno++)
290*b725ae77Skettenis         tui_show_source_line (win_info, lineno);
291*b725ae77Skettenis     }
292*b725ae77Skettenis   else
293*b725ae77Skettenis     tui_erase_source_content (win_info, TRUE);
294*b725ae77Skettenis 
295*b725ae77Skettenis   tui_check_and_display_highlight_if_needed (win_info);
296*b725ae77Skettenis   tui_refresh_win (&win_info->generic);
297*b725ae77Skettenis   win_info->generic.content_in_use = TRUE;
298*b725ae77Skettenis }
299*b725ae77Skettenis 
300*b725ae77Skettenis 
301*b725ae77Skettenis /* Scroll the source forward or backward horizontally.  */
302*b725ae77Skettenis void
tui_horizontal_source_scroll(struct tui_win_info * win_info,enum tui_scroll_direction direction,int num_to_scroll)303*b725ae77Skettenis tui_horizontal_source_scroll (struct tui_win_info * win_info,
304*b725ae77Skettenis 			      enum tui_scroll_direction direction,
305*b725ae77Skettenis 			      int num_to_scroll)
306*b725ae77Skettenis {
307*b725ae77Skettenis   if (win_info->generic.content != NULL)
308*b725ae77Skettenis     {
309*b725ae77Skettenis       int offset;
310*b725ae77Skettenis       struct symtab *s;
311*b725ae77Skettenis       struct symtab_and_line cursal = get_current_source_symtab_and_line ();
312*b725ae77Skettenis 
313*b725ae77Skettenis       if (cursal.symtab == (struct symtab *) NULL)
314*b725ae77Skettenis 	s = find_pc_symtab (get_frame_pc (deprecated_selected_frame));
315*b725ae77Skettenis       else
316*b725ae77Skettenis 	s = cursal.symtab;
317*b725ae77Skettenis 
318*b725ae77Skettenis       if (direction == LEFT_SCROLL)
319*b725ae77Skettenis 	offset = win_info->detail.source_info.horizontal_offset + num_to_scroll;
320*b725ae77Skettenis       else
321*b725ae77Skettenis 	{
322*b725ae77Skettenis 	  if ((offset =
323*b725ae77Skettenis 	     win_info->detail.source_info.horizontal_offset - num_to_scroll) < 0)
324*b725ae77Skettenis 	    offset = 0;
325*b725ae77Skettenis 	}
326*b725ae77Skettenis       win_info->detail.source_info.horizontal_offset = offset;
327*b725ae77Skettenis       tui_update_source_window_as_is (win_info, s,
328*b725ae77Skettenis 				      ((struct tui_win_element *)
329*b725ae77Skettenis 				       win_info->generic.content[0])->which_element.source.line_or_addr,
330*b725ae77Skettenis 				      FALSE);
331*b725ae77Skettenis     }
332*b725ae77Skettenis 
333*b725ae77Skettenis   return;
334*b725ae77Skettenis }
335*b725ae77Skettenis 
336*b725ae77Skettenis 
337*b725ae77Skettenis /* Set or clear the has_break flag in the line whose line is line_no.  */
338*b725ae77Skettenis void
tui_set_is_exec_point_at(union tui_line_or_address l,struct tui_win_info * win_info)339*b725ae77Skettenis tui_set_is_exec_point_at (union tui_line_or_address l, struct tui_win_info * win_info)
340*b725ae77Skettenis {
341*b725ae77Skettenis   int changed = 0;
342*b725ae77Skettenis   int i;
343*b725ae77Skettenis   tui_win_content content = (tui_win_content) win_info->generic.content;
344*b725ae77Skettenis 
345*b725ae77Skettenis   i = 0;
346*b725ae77Skettenis   while (i < win_info->generic.content_size)
347*b725ae77Skettenis     {
348*b725ae77Skettenis       int new_state;
349*b725ae77Skettenis 
350*b725ae77Skettenis       if (content[i]->which_element.source.line_or_addr.addr == l.addr)
351*b725ae77Skettenis         new_state = TRUE;
352*b725ae77Skettenis       else
353*b725ae77Skettenis 	new_state = FALSE;
354*b725ae77Skettenis       if (new_state != content[i]->which_element.source.is_exec_point)
355*b725ae77Skettenis         {
356*b725ae77Skettenis           changed++;
357*b725ae77Skettenis           content[i]->which_element.source.is_exec_point = new_state;
358*b725ae77Skettenis           tui_show_source_line (win_info, i + 1);
359*b725ae77Skettenis         }
360*b725ae77Skettenis       i++;
361*b725ae77Skettenis     }
362*b725ae77Skettenis   if (changed)
363*b725ae77Skettenis     tui_refresh_win (&win_info->generic);
364*b725ae77Skettenis }
365*b725ae77Skettenis 
366*b725ae77Skettenis /* Update the execution windows to show the active breakpoints.
367*b725ae77Skettenis    This is called whenever a breakpoint is inserted, removed or
368*b725ae77Skettenis    has its state changed.  */
369*b725ae77Skettenis void
tui_update_all_breakpoint_info(void)370*b725ae77Skettenis tui_update_all_breakpoint_info (void)
371*b725ae77Skettenis {
372*b725ae77Skettenis   struct tui_list *list = tui_source_windows ();
373*b725ae77Skettenis   int i;
374*b725ae77Skettenis 
375*b725ae77Skettenis   for (i = 0; i < list->count; i++)
376*b725ae77Skettenis     {
377*b725ae77Skettenis       struct tui_win_info * win = (struct tui_win_info *) list->list[i];
378*b725ae77Skettenis 
379*b725ae77Skettenis       if (tui_update_breakpoint_info (win, FALSE))
380*b725ae77Skettenis         {
381*b725ae77Skettenis           tui_update_exec_info (win);
382*b725ae77Skettenis         }
383*b725ae77Skettenis     }
384*b725ae77Skettenis }
385*b725ae77Skettenis 
386*b725ae77Skettenis 
387*b725ae77Skettenis /* Scan the source window and the breakpoints to update the
388*b725ae77Skettenis    has_break information for each line.
389*b725ae77Skettenis    Returns 1 if something changed and the execution window
390*b725ae77Skettenis    must be refreshed.  */
391*b725ae77Skettenis int
tui_update_breakpoint_info(struct tui_win_info * win,int current_only)392*b725ae77Skettenis tui_update_breakpoint_info (struct tui_win_info * win, int current_only)
393*b725ae77Skettenis {
394*b725ae77Skettenis   int i;
395*b725ae77Skettenis   int need_refresh = 0;
396*b725ae77Skettenis   struct tui_source_info * src = &win->detail.source_info;
397*b725ae77Skettenis 
398*b725ae77Skettenis   for (i = 0; i < win->generic.content_size; i++)
399*b725ae77Skettenis     {
400*b725ae77Skettenis       struct breakpoint *bp;
401*b725ae77Skettenis       extern struct breakpoint *breakpoint_chain;
402*b725ae77Skettenis       int mode;
403*b725ae77Skettenis       struct tui_source_element* line;
404*b725ae77Skettenis 
405*b725ae77Skettenis       line = &((struct tui_win_element *) win->generic.content[i])->which_element.source;
406*b725ae77Skettenis       if (current_only && !line->is_exec_point)
407*b725ae77Skettenis          continue;
408*b725ae77Skettenis 
409*b725ae77Skettenis       /* Scan each breakpoint to see if the current line has something to
410*b725ae77Skettenis          do with it.  Identify enable/disabled breakpoints as well as
411*b725ae77Skettenis          those that we already hit.  */
412*b725ae77Skettenis       mode = 0;
413*b725ae77Skettenis       for (bp = breakpoint_chain;
414*b725ae77Skettenis            bp != (struct breakpoint *) NULL;
415*b725ae77Skettenis            bp = bp->next)
416*b725ae77Skettenis         {
417*b725ae77Skettenis           if ((win == TUI_SRC_WIN
418*b725ae77Skettenis                && bp->source_file
419*b725ae77Skettenis                && (strcmp (src->filename, bp->source_file) == 0)
420*b725ae77Skettenis                && bp->line_number == line->line_or_addr.line_no)
421*b725ae77Skettenis               || (win == TUI_DISASM_WIN
422*b725ae77Skettenis                   && bp->loc->address == line->line_or_addr.addr))
423*b725ae77Skettenis             {
424*b725ae77Skettenis               if (bp->enable_state == bp_disabled)
425*b725ae77Skettenis                 mode |= TUI_BP_DISABLED;
426*b725ae77Skettenis               else
427*b725ae77Skettenis                 mode |= TUI_BP_ENABLED;
428*b725ae77Skettenis               if (bp->hit_count)
429*b725ae77Skettenis                 mode |= TUI_BP_HIT;
430*b725ae77Skettenis               if (bp->cond)
431*b725ae77Skettenis                 mode |= TUI_BP_CONDITIONAL;
432*b725ae77Skettenis               if (bp->type == bp_hardware_breakpoint)
433*b725ae77Skettenis                 mode |= TUI_BP_HARDWARE;
434*b725ae77Skettenis             }
435*b725ae77Skettenis         }
436*b725ae77Skettenis       if (line->has_break != mode)
437*b725ae77Skettenis         {
438*b725ae77Skettenis           line->has_break = mode;
439*b725ae77Skettenis           need_refresh = 1;
440*b725ae77Skettenis         }
441*b725ae77Skettenis     }
442*b725ae77Skettenis   return need_refresh;
443*b725ae77Skettenis }
444*b725ae77Skettenis 
445*b725ae77Skettenis 
446*b725ae77Skettenis /* Function to initialize the content of the execution info window,
447*b725ae77Skettenis    based upon the input window which is either the source or
448*b725ae77Skettenis    disassembly window.  */
449*b725ae77Skettenis enum tui_status
tui_set_exec_info_content(struct tui_win_info * win_info)450*b725ae77Skettenis tui_set_exec_info_content (struct tui_win_info * win_info)
451*b725ae77Skettenis {
452*b725ae77Skettenis   enum tui_status ret = TUI_SUCCESS;
453*b725ae77Skettenis 
454*b725ae77Skettenis   if (win_info->detail.source_info.execution_info != (struct tui_gen_win_info *) NULL)
455*b725ae77Skettenis     {
456*b725ae77Skettenis       struct tui_gen_win_info * exec_info_ptr = win_info->detail.source_info.execution_info;
457*b725ae77Skettenis 
458*b725ae77Skettenis       if (exec_info_ptr->content == NULL)
459*b725ae77Skettenis 	exec_info_ptr->content =
460*b725ae77Skettenis 	  (void **) tui_alloc_content (win_info->generic.height,
461*b725ae77Skettenis 					 exec_info_ptr->type);
462*b725ae77Skettenis       if (exec_info_ptr->content != NULL)
463*b725ae77Skettenis 	{
464*b725ae77Skettenis 	  int i;
465*b725ae77Skettenis 
466*b725ae77Skettenis           tui_update_breakpoint_info (win_info, 1);
467*b725ae77Skettenis 	  for (i = 0; i < win_info->generic.content_size; i++)
468*b725ae77Skettenis 	    {
469*b725ae77Skettenis 	      struct tui_win_element * element;
470*b725ae77Skettenis 	      struct tui_win_element * src_element;
471*b725ae77Skettenis               int mode;
472*b725ae77Skettenis 
473*b725ae77Skettenis 	      element = (struct tui_win_element *) exec_info_ptr->content[i];
474*b725ae77Skettenis 	      src_element = (struct tui_win_element *) win_info->generic.content[i];
475*b725ae77Skettenis 
476*b725ae77Skettenis               memset(element->which_element.simple_string, ' ',
477*b725ae77Skettenis                      sizeof(element->which_element.simple_string));
478*b725ae77Skettenis               element->which_element.simple_string[TUI_EXECINFO_SIZE - 1] = 0;
479*b725ae77Skettenis 
480*b725ae77Skettenis 	      /* Now update the exec info content based upon the state
481*b725ae77Skettenis                  of each line as indicated by the source content.  */
482*b725ae77Skettenis               mode = src_element->which_element.source.has_break;
483*b725ae77Skettenis               if (mode & TUI_BP_HIT)
484*b725ae77Skettenis                 element->which_element.simple_string[TUI_BP_HIT_POS] =
485*b725ae77Skettenis                   (mode & TUI_BP_HARDWARE) ? 'H' : 'B';
486*b725ae77Skettenis               else if (mode & (TUI_BP_ENABLED | TUI_BP_DISABLED))
487*b725ae77Skettenis                 element->which_element.simple_string[TUI_BP_HIT_POS] =
488*b725ae77Skettenis                   (mode & TUI_BP_HARDWARE) ? 'h' : 'b';
489*b725ae77Skettenis 
490*b725ae77Skettenis               if (mode & TUI_BP_ENABLED)
491*b725ae77Skettenis                 element->which_element.simple_string[TUI_BP_BREAK_POS] = '+';
492*b725ae77Skettenis               else if (mode & TUI_BP_DISABLED)
493*b725ae77Skettenis                 element->which_element.simple_string[TUI_BP_BREAK_POS] = '-';
494*b725ae77Skettenis 
495*b725ae77Skettenis               if (src_element->which_element.source.is_exec_point)
496*b725ae77Skettenis                 element->which_element.simple_string[TUI_EXEC_POS] = '>';
497*b725ae77Skettenis 	    }
498*b725ae77Skettenis 	  exec_info_ptr->content_size = win_info->generic.content_size;
499*b725ae77Skettenis 	}
500*b725ae77Skettenis       else
501*b725ae77Skettenis 	ret = TUI_FAILURE;
502*b725ae77Skettenis     }
503*b725ae77Skettenis 
504*b725ae77Skettenis   return ret;
505*b725ae77Skettenis }
506*b725ae77Skettenis 
507*b725ae77Skettenis 
508*b725ae77Skettenis void
tui_show_exec_info_content(struct tui_win_info * win_info)509*b725ae77Skettenis tui_show_exec_info_content (struct tui_win_info * win_info)
510*b725ae77Skettenis {
511*b725ae77Skettenis   struct tui_gen_win_info * exec_info = win_info->detail.source_info.execution_info;
512*b725ae77Skettenis   int cur_line;
513*b725ae77Skettenis 
514*b725ae77Skettenis   werase (exec_info->handle);
515*b725ae77Skettenis   tui_refresh_win (exec_info);
516*b725ae77Skettenis   for (cur_line = 1; (cur_line <= exec_info->content_size); cur_line++)
517*b725ae77Skettenis     mvwaddstr (exec_info->handle,
518*b725ae77Skettenis 	       cur_line,
519*b725ae77Skettenis 	       0,
520*b725ae77Skettenis 	       ((struct tui_win_element *)
521*b725ae77Skettenis 		exec_info->content[cur_line - 1])->which_element.simple_string);
522*b725ae77Skettenis   tui_refresh_win (exec_info);
523*b725ae77Skettenis   exec_info->content_in_use = TRUE;
524*b725ae77Skettenis }
525*b725ae77Skettenis 
526*b725ae77Skettenis 
527*b725ae77Skettenis void
tui_erase_exec_info_content(struct tui_win_info * win_info)528*b725ae77Skettenis tui_erase_exec_info_content (struct tui_win_info * win_info)
529*b725ae77Skettenis {
530*b725ae77Skettenis   struct tui_gen_win_info * exec_info = win_info->detail.source_info.execution_info;
531*b725ae77Skettenis 
532*b725ae77Skettenis   werase (exec_info->handle);
533*b725ae77Skettenis   tui_refresh_win (exec_info);
534*b725ae77Skettenis }
535*b725ae77Skettenis 
536*b725ae77Skettenis void
tui_clear_exec_info_content(struct tui_win_info * win_info)537*b725ae77Skettenis tui_clear_exec_info_content (struct tui_win_info * win_info)
538*b725ae77Skettenis {
539*b725ae77Skettenis   win_info->detail.source_info.execution_info->content_in_use = FALSE;
540*b725ae77Skettenis   tui_erase_exec_info_content (win_info);
541*b725ae77Skettenis 
542*b725ae77Skettenis   return;
543*b725ae77Skettenis }
544*b725ae77Skettenis 
545*b725ae77Skettenis /* Function to update the execution info window.  */
546*b725ae77Skettenis void
tui_update_exec_info(struct tui_win_info * win_info)547*b725ae77Skettenis tui_update_exec_info (struct tui_win_info * win_info)
548*b725ae77Skettenis {
549*b725ae77Skettenis   tui_set_exec_info_content (win_info);
550*b725ae77Skettenis   tui_show_exec_info_content (win_info);
551*b725ae77Skettenis }
552*b725ae77Skettenis 
553*b725ae77Skettenis enum tui_status
tui_alloc_source_buffer(struct tui_win_info * win_info)554*b725ae77Skettenis tui_alloc_source_buffer (struct tui_win_info *win_info)
555*b725ae77Skettenis {
556*b725ae77Skettenis   char *src_line_buf;
557*b725ae77Skettenis   int i, line_width, max_lines;
558*b725ae77Skettenis   enum tui_status ret = TUI_FAILURE;
559*b725ae77Skettenis 
560*b725ae77Skettenis   max_lines = win_info->generic.height;	/* less the highlight box */
561*b725ae77Skettenis   line_width = win_info->generic.width - 1;
562*b725ae77Skettenis   /*
563*b725ae77Skettenis      ** Allocate the buffer for the source lines.  Do this only once since they
564*b725ae77Skettenis      ** will be re-used for all source displays.  The only other time this will
565*b725ae77Skettenis      ** be done is when a window's size changes.
566*b725ae77Skettenis    */
567*b725ae77Skettenis   if (win_info->generic.content == NULL)
568*b725ae77Skettenis     {
569*b725ae77Skettenis       src_line_buf = (char *) xmalloc ((max_lines * line_width) * sizeof (char));
570*b725ae77Skettenis       if (src_line_buf == (char *) NULL)
571*b725ae77Skettenis 	fputs_unfiltered (
572*b725ae77Skettenis 	   "Unable to Allocate Memory for Source or Disassembly Display.\n",
573*b725ae77Skettenis 			   gdb_stderr);
574*b725ae77Skettenis       else
575*b725ae77Skettenis 	{
576*b725ae77Skettenis 	  /* allocate the content list */
577*b725ae77Skettenis 	  if ((win_info->generic.content =
578*b725ae77Skettenis 	  (void **) tui_alloc_content (max_lines, SRC_WIN)) == NULL)
579*b725ae77Skettenis 	    {
580*b725ae77Skettenis 	      xfree (src_line_buf);
581*b725ae77Skettenis 	      src_line_buf = (char *) NULL;
582*b725ae77Skettenis 	      fputs_unfiltered (
583*b725ae77Skettenis 				 "Unable to Allocate Memory for Source or Disassembly Display.\n",
584*b725ae77Skettenis 				 gdb_stderr);
585*b725ae77Skettenis 	    }
586*b725ae77Skettenis 	}
587*b725ae77Skettenis       for (i = 0; i < max_lines; i++)
588*b725ae77Skettenis 	((struct tui_win_element *)
589*b725ae77Skettenis 	 win_info->generic.content[i])->which_element.source.line =
590*b725ae77Skettenis 	  src_line_buf + (line_width * i);
591*b725ae77Skettenis       ret = TUI_SUCCESS;
592*b725ae77Skettenis     }
593*b725ae77Skettenis   else
594*b725ae77Skettenis     ret = TUI_SUCCESS;
595*b725ae77Skettenis 
596*b725ae77Skettenis   return ret;
597*b725ae77Skettenis }
598*b725ae77Skettenis 
599*b725ae77Skettenis 
600*b725ae77Skettenis /* Answer whether the a particular line number or address is displayed
601*b725ae77Skettenis    in the current source window.  */
602*b725ae77Skettenis int
tui_line_is_displayed(int line,struct tui_win_info * win_info,int check_threshold)603*b725ae77Skettenis tui_line_is_displayed (int line, struct tui_win_info * win_info,
604*b725ae77Skettenis 		       int check_threshold)
605*b725ae77Skettenis {
606*b725ae77Skettenis   int is_displayed = FALSE;
607*b725ae77Skettenis   int i, threshold;
608*b725ae77Skettenis 
609*b725ae77Skettenis   if (check_threshold)
610*b725ae77Skettenis     threshold = SCROLL_THRESHOLD;
611*b725ae77Skettenis   else
612*b725ae77Skettenis     threshold = 0;
613*b725ae77Skettenis   i = 0;
614*b725ae77Skettenis   while (i < win_info->generic.content_size - threshold && !is_displayed)
615*b725ae77Skettenis     {
616*b725ae77Skettenis       is_displayed = (((struct tui_win_element *)
617*b725ae77Skettenis 		      win_info->generic.content[i])->which_element.source.line_or_addr.line_no
618*b725ae77Skettenis 		     == (int) line);
619*b725ae77Skettenis       i++;
620*b725ae77Skettenis     }
621*b725ae77Skettenis 
622*b725ae77Skettenis   return is_displayed;
623*b725ae77Skettenis }
624*b725ae77Skettenis 
625*b725ae77Skettenis 
626*b725ae77Skettenis /* Answer whether the a particular line number or address is displayed
627*b725ae77Skettenis    in the current source window.  */
628*b725ae77Skettenis int
tui_addr_is_displayed(CORE_ADDR addr,struct tui_win_info * win_info,int check_threshold)629*b725ae77Skettenis tui_addr_is_displayed (CORE_ADDR addr, struct tui_win_info * win_info,
630*b725ae77Skettenis 		    int check_threshold)
631*b725ae77Skettenis {
632*b725ae77Skettenis   int is_displayed = FALSE;
633*b725ae77Skettenis   int i, threshold;
634*b725ae77Skettenis 
635*b725ae77Skettenis   if (check_threshold)
636*b725ae77Skettenis     threshold = SCROLL_THRESHOLD;
637*b725ae77Skettenis   else
638*b725ae77Skettenis     threshold = 0;
639*b725ae77Skettenis   i = 0;
640*b725ae77Skettenis   while (i < win_info->generic.content_size - threshold && !is_displayed)
641*b725ae77Skettenis     {
642*b725ae77Skettenis       is_displayed = (((struct tui_win_element *)
643*b725ae77Skettenis 		      win_info->generic.content[i])->which_element.source.line_or_addr.addr
644*b725ae77Skettenis 		     == addr);
645*b725ae77Skettenis       i++;
646*b725ae77Skettenis     }
647*b725ae77Skettenis 
648*b725ae77Skettenis   return is_displayed;
649*b725ae77Skettenis }
650*b725ae77Skettenis 
651*b725ae77Skettenis 
652*b725ae77Skettenis /*****************************************
653*b725ae77Skettenis ** STATIC LOCAL FUNCTIONS               **
654*b725ae77Skettenis ******************************************/
655