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

Subversion Repositories openrisc_me

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

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

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

powered by: WebSVN 2.1.0

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