OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [gdb-7.2/] [gdb/] [tui/] [tui-winsource.c] - Blame information for rev 330

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.