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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-7.1/] [gdb/] [tui/] [tui-winsource.c] - Blame information for rev 318

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

Line No. Rev Author Line
1 227 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
          element->which_element.source.has_break = FALSE;
226
          element->which_element.source.is_exec_point = FALSE;
227
        }
228
    }
229
}
230
 
231
 
232
void
233
tui_erase_source_content (struct tui_win_info *win_info,
234
                          int display_prompt)
235
{
236
  int x_pos;
237
  int half_width = (win_info->generic.width - 2) / 2;
238
 
239
  if (win_info->generic.handle != (WINDOW *) NULL)
240
    {
241
      werase (win_info->generic.handle);
242
      tui_check_and_display_highlight_if_needed (win_info);
243
      if (display_prompt == EMPTY_SOURCE_PROMPT)
244
        {
245
          char *no_src_str;
246
 
247
          if (win_info->generic.type == SRC_WIN)
248
            no_src_str = NO_SRC_STRING;
249
          else
250
            no_src_str = NO_DISASSEM_STRING;
251
          if (strlen (no_src_str) >= half_width)
252
            x_pos = 1;
253
          else
254
            x_pos = half_width - strlen (no_src_str);
255
          mvwaddstr (win_info->generic.handle,
256
                     (win_info->generic.height / 2),
257
                     x_pos,
258
                     no_src_str);
259
 
260
          /* elz: Added this function call to set the real contents of
261
             the window to what is on the screen, so that later calls
262
             to refresh, do display the correct stuff, and not the old
263
             image.  */
264
 
265
          tui_set_source_content_nil (win_info, no_src_str);
266
        }
267
      tui_refresh_win (&win_info->generic);
268
    }
269
}
270
 
271
 
272
/* Redraw the complete line of a source or disassembly window.  */
273
static void
274
tui_show_source_line (struct tui_win_info *win_info, int lineno)
275
{
276
  struct tui_win_element *line;
277
  int x, y;
278
 
279
  line = (struct tui_win_element *) win_info->generic.content[lineno - 1];
280
  if (line->which_element.source.is_exec_point)
281
    wattron (win_info->generic.handle, A_STANDOUT);
282
 
283
  mvwaddstr (win_info->generic.handle, lineno, 1,
284
             line->which_element.source.line);
285
  if (line->which_element.source.is_exec_point)
286
    wattroff (win_info->generic.handle, A_STANDOUT);
287
 
288
  /* Clear to end of line but stop before the border.  */
289
  getyx (win_info->generic.handle, y, x);
290
  while (x + 1 < win_info->generic.width)
291
    {
292
      waddch (win_info->generic.handle, ' ');
293
      getyx (win_info->generic.handle, y, x);
294
    }
295
}
296
 
297
void
298
tui_show_source_content (struct tui_win_info *win_info)
299
{
300
  if (win_info->generic.content_size > 0)
301
    {
302
      int lineno;
303
 
304
      for (lineno = 1; lineno <= win_info->generic.content_size; lineno++)
305
        tui_show_source_line (win_info, lineno);
306
    }
307
  else
308
    tui_erase_source_content (win_info, TRUE);
309
 
310
  tui_check_and_display_highlight_if_needed (win_info);
311
  tui_refresh_win (&win_info->generic);
312
  win_info->generic.content_in_use = TRUE;
313
}
314
 
315
 
316
/* Scroll the source forward or backward horizontally.  */
317
void
318
tui_horizontal_source_scroll (struct tui_win_info *win_info,
319
                              enum tui_scroll_direction direction,
320
                              int num_to_scroll)
321
{
322
  if (win_info->generic.content != NULL)
323
    {
324
      struct gdbarch *gdbarch = win_info->detail.source_info.gdbarch;
325
      int offset;
326
      struct symtab *s = NULL;
327
 
328
      if (win_info->generic.type == SRC_WIN)
329
        {
330
          struct symtab_and_line cursal = get_current_source_symtab_and_line ();
331
          if (cursal.symtab == NULL)
332
            s = find_pc_symtab (get_frame_pc (get_selected_frame (NULL)));
333
          else
334
            s = cursal.symtab;
335
        }
336
 
337
      if (direction == LEFT_SCROLL)
338
        offset = win_info->detail.source_info.horizontal_offset + num_to_scroll;
339
      else
340
        {
341
          if ((offset =
342
             win_info->detail.source_info.horizontal_offset - num_to_scroll) < 0)
343
            offset = 0;
344
        }
345
      win_info->detail.source_info.horizontal_offset = offset;
346
      tui_update_source_window_as_is (win_info, gdbarch, s,
347
                                      ((struct tui_win_element *)
348
                                       win_info->generic.content[0])->which_element.source.line_or_addr,
349
                                      FALSE);
350
    }
351
 
352
  return;
353
}
354
 
355
 
356
/* Set or clear the has_break flag in the line whose line is
357
   line_no.  */
358
 
359
void
360
tui_set_is_exec_point_at (struct tui_line_or_address l,
361
                          struct tui_win_info *win_info)
362
{
363
  int changed = 0;
364
  int i;
365
  tui_win_content content = (tui_win_content) win_info->generic.content;
366
 
367
  i = 0;
368
  while (i < win_info->generic.content_size)
369
    {
370
      int new_state;
371
      struct tui_line_or_address content_loa =
372
        content[i]->which_element.source.line_or_addr;
373
 
374
      gdb_assert (l.loa == LOA_ADDRESS || l.loa == LOA_LINE);
375
      gdb_assert (content_loa.loa == LOA_LINE
376
                  || content_loa.loa == LOA_ADDRESS);
377
      if (content_loa.loa == l.loa
378
          && ((l.loa == LOA_LINE && content_loa.u.line_no == l.u.line_no)
379
              || (content_loa.u.addr == l.u.addr)))
380
        new_state = TRUE;
381
      else
382
        new_state = FALSE;
383
      if (new_state != content[i]->which_element.source.is_exec_point)
384
        {
385
          changed++;
386
          content[i]->which_element.source.is_exec_point = new_state;
387
          tui_show_source_line (win_info, i + 1);
388
        }
389
      i++;
390
    }
391
  if (changed)
392
    tui_refresh_win (&win_info->generic);
393
}
394
 
395
/* Update the execution windows to show the active breakpoints.
396
   This is called whenever a breakpoint is inserted, removed or
397
   has its state changed.  */
398
void
399
tui_update_all_breakpoint_info (void)
400
{
401
  struct tui_list *list = tui_source_windows ();
402
  int i;
403
 
404
  for (i = 0; i < list->count; i++)
405
    {
406
      struct tui_win_info *win = list->list[i];
407
 
408
      if (tui_update_breakpoint_info (win, FALSE))
409
        {
410
          tui_update_exec_info (win);
411
        }
412
    }
413
}
414
 
415
 
416
/* Scan the source window and the breakpoints to update the has_break
417
   information for each line.
418
 
419
   Returns 1 if something changed and the execution window must be
420
   refreshed.  */
421
 
422
int
423
tui_update_breakpoint_info (struct tui_win_info *win,
424
                            int current_only)
425
{
426
  int i;
427
  int need_refresh = 0;
428
  struct tui_source_info *src = &win->detail.source_info;
429
 
430
  for (i = 0; i < win->generic.content_size; i++)
431
    {
432
      struct breakpoint *bp;
433
      extern struct breakpoint *breakpoint_chain;
434
      int mode;
435
      struct tui_source_element *line;
436
 
437
      line = &((struct tui_win_element *) win->generic.content[i])->which_element.source;
438
      if (current_only && !line->is_exec_point)
439
         continue;
440
 
441
      /* Scan each breakpoint to see if the current line has something to
442
         do with it.  Identify enable/disabled breakpoints as well as
443
         those that we already hit.  */
444
      mode = 0;
445
      for (bp = breakpoint_chain;
446
           bp != (struct breakpoint *) NULL;
447
           bp = bp->next)
448
        {
449
          gdb_assert (line->line_or_addr.loa == LOA_LINE
450
                      || line->line_or_addr.loa == LOA_ADDRESS);
451
          if ((win == TUI_SRC_WIN
452
               && bp->source_file
453
               && (strcmp (src->filename, bp->source_file) == 0)
454
               && line->line_or_addr.loa == LOA_LINE
455
               && bp->line_number == line->line_or_addr.u.line_no)
456
              || (win == TUI_DISASM_WIN
457
                  && line->line_or_addr.loa == LOA_ADDRESS
458
                  && bp->loc != NULL
459
                  && bp->loc->address == line->line_or_addr.u.addr))
460
            {
461
              if (bp->enable_state == bp_disabled)
462
                mode |= TUI_BP_DISABLED;
463
              else
464
                mode |= TUI_BP_ENABLED;
465
              if (bp->hit_count)
466
                mode |= TUI_BP_HIT;
467
              if (bp->loc->cond)
468
                mode |= TUI_BP_CONDITIONAL;
469
              if (bp->type == bp_hardware_breakpoint)
470
                mode |= TUI_BP_HARDWARE;
471
            }
472
        }
473
      if (line->has_break != mode)
474
        {
475
          line->has_break = mode;
476
          need_refresh = 1;
477
        }
478
    }
479
  return need_refresh;
480
}
481
 
482
 
483
/* Function to initialize the content of the execution info window,
484
   based upon the input window which is either the source or
485
   disassembly window.  */
486
enum tui_status
487
tui_set_exec_info_content (struct tui_win_info *win_info)
488
{
489
  enum tui_status ret = TUI_SUCCESS;
490
 
491
  if (win_info->detail.source_info.execution_info != (struct tui_gen_win_info *) NULL)
492
    {
493
      struct tui_gen_win_info *exec_info_ptr = win_info->detail.source_info.execution_info;
494
 
495
      if (exec_info_ptr->content == NULL)
496
        exec_info_ptr->content =
497
          (void **) tui_alloc_content (win_info->generic.height,
498
                                         exec_info_ptr->type);
499
      if (exec_info_ptr->content != NULL)
500
        {
501
          int i;
502
 
503
          tui_update_breakpoint_info (win_info, 1);
504
          for (i = 0; i < win_info->generic.content_size; i++)
505
            {
506
              struct tui_win_element *element;
507
              struct tui_win_element *src_element;
508
              int mode;
509
 
510
              element = (struct tui_win_element *) exec_info_ptr->content[i];
511
              src_element = (struct tui_win_element *) win_info->generic.content[i];
512
 
513
              memset(element->which_element.simple_string, ' ',
514
                     sizeof(element->which_element.simple_string));
515
              element->which_element.simple_string[TUI_EXECINFO_SIZE - 1] = 0;
516
 
517
              /* Now update the exec info content based upon the state
518
                 of each line as indicated by the source content.  */
519
              mode = src_element->which_element.source.has_break;
520
              if (mode & TUI_BP_HIT)
521
                element->which_element.simple_string[TUI_BP_HIT_POS] =
522
                  (mode & TUI_BP_HARDWARE) ? 'H' : 'B';
523
              else if (mode & (TUI_BP_ENABLED | TUI_BP_DISABLED))
524
                element->which_element.simple_string[TUI_BP_HIT_POS] =
525
                  (mode & TUI_BP_HARDWARE) ? 'h' : 'b';
526
 
527
              if (mode & TUI_BP_ENABLED)
528
                element->which_element.simple_string[TUI_BP_BREAK_POS] = '+';
529
              else if (mode & TUI_BP_DISABLED)
530
                element->which_element.simple_string[TUI_BP_BREAK_POS] = '-';
531
 
532
              if (src_element->which_element.source.is_exec_point)
533
                element->which_element.simple_string[TUI_EXEC_POS] = '>';
534
            }
535
          exec_info_ptr->content_size = win_info->generic.content_size;
536
        }
537
      else
538
        ret = TUI_FAILURE;
539
    }
540
 
541
  return ret;
542
}
543
 
544
 
545
void
546
tui_show_exec_info_content (struct tui_win_info *win_info)
547
{
548
  struct tui_gen_win_info *exec_info = win_info->detail.source_info.execution_info;
549
  int cur_line;
550
 
551
  werase (exec_info->handle);
552
  tui_refresh_win (exec_info);
553
  for (cur_line = 1; (cur_line <= exec_info->content_size); cur_line++)
554
    mvwaddstr (exec_info->handle,
555
               cur_line,
556
               0,
557
               ((struct tui_win_element *)
558
                exec_info->content[cur_line - 1])->which_element.simple_string);
559
  tui_refresh_win (exec_info);
560
  exec_info->content_in_use = TRUE;
561
}
562
 
563
 
564
void
565
tui_erase_exec_info_content (struct tui_win_info *win_info)
566
{
567
  struct tui_gen_win_info *exec_info = win_info->detail.source_info.execution_info;
568
 
569
  werase (exec_info->handle);
570
  tui_refresh_win (exec_info);
571
}
572
 
573
void
574
tui_clear_exec_info_content (struct tui_win_info *win_info)
575
{
576
  win_info->detail.source_info.execution_info->content_in_use = FALSE;
577
  tui_erase_exec_info_content (win_info);
578
 
579
  return;
580
}
581
 
582
/* Function to update the execution info window.  */
583
void
584
tui_update_exec_info (struct tui_win_info *win_info)
585
{
586
  tui_set_exec_info_content (win_info);
587
  tui_show_exec_info_content (win_info);
588
}
589
 
590
enum tui_status
591
tui_alloc_source_buffer (struct tui_win_info *win_info)
592
{
593
  char *src_line_buf;
594
  int i, line_width, max_lines;
595
 
596
  max_lines = win_info->generic.height; /* Less the highlight box.  */
597
  line_width = win_info->generic.width - 1;
598
  /*
599
   * Allocate the buffer for the source lines.  Do this only once
600
   * since they will be re-used for all source displays.  The only
601
   * other time this will be done is when a window's size changes.
602
   */
603
  if (win_info->generic.content == NULL)
604
    {
605
      src_line_buf = (char *)
606
        xmalloc ((max_lines * line_width) * sizeof (char));
607
      if (src_line_buf == (char *) NULL)
608
        {
609
          fputs_unfiltered ("Unable to Allocate Memory for Source or Disassembly Display.\n",
610
                            gdb_stderr);
611
          return TUI_FAILURE;
612
        }
613
      /* Allocate the content list.  */
614
      if ((win_info->generic.content =
615
           (void **) tui_alloc_content (max_lines, SRC_WIN)) == NULL)
616
        {
617
          xfree (src_line_buf);
618
          fputs_unfiltered ("Unable to Allocate Memory for Source or Disassembly Display.\n",
619
                            gdb_stderr);
620
          return TUI_FAILURE;
621
        }
622
      for (i = 0; i < max_lines; i++)
623
        ((struct tui_win_element *)
624
         win_info->generic.content[i])->which_element.source.line =
625
          src_line_buf + (line_width * i);
626
    }
627
 
628
  return TUI_SUCCESS;
629
}
630
 
631
 
632
/* Answer whether the a particular line number or address is displayed
633
   in the current source window.  */
634
int
635
tui_line_is_displayed (int line,
636
                       struct tui_win_info *win_info,
637
                       int check_threshold)
638
{
639
  int is_displayed = FALSE;
640
  int i, threshold;
641
 
642
  if (check_threshold)
643
    threshold = SCROLL_THRESHOLD;
644
  else
645
    threshold = 0;
646
  i = 0;
647
  while (i < win_info->generic.content_size - threshold
648
         && !is_displayed)
649
    {
650
      is_displayed = (((struct tui_win_element *)
651
                       win_info->generic.content[i])->which_element.source.line_or_addr.loa
652
                      == LOA_LINE)
653
        && (((struct tui_win_element *)
654
             win_info->generic.content[i])->which_element.source.line_or_addr.u.line_no
655
            == (int) line);
656
      i++;
657
    }
658
 
659
  return is_displayed;
660
}
661
 
662
 
663
/* Answer whether the a particular line number or address is displayed
664
   in the current source window.  */
665
int
666
tui_addr_is_displayed (CORE_ADDR addr,
667
                       struct tui_win_info *win_info,
668
                       int check_threshold)
669
{
670
  int is_displayed = FALSE;
671
  int i, threshold;
672
 
673
  if (check_threshold)
674
    threshold = SCROLL_THRESHOLD;
675
  else
676
    threshold = 0;
677
  i = 0;
678
  while (i < win_info->generic.content_size - threshold
679
         && !is_displayed)
680
    {
681
      is_displayed = (((struct tui_win_element *)
682
                       win_info->generic.content[i])->which_element.source.line_or_addr.loa
683
                      == LOA_ADDRESS)
684
        && (((struct tui_win_element *)
685
             win_info->generic.content[i])->which_element.source.line_or_addr.u.addr
686
            == addr);
687
      i++;
688
    }
689
 
690
  return is_displayed;
691
}
692
 
693
 
694
/*****************************************
695
** STATIC LOCAL FUNCTIONS               **
696
******************************************/

powered by: WebSVN 2.1.0

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