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-stack.c] - Blame information for rev 157

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 24 jeremybenn
/* TUI display locator.
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 "symtab.h"
25
#include "breakpoint.h"
26
#include "frame.h"
27
#include "command.h"
28
#include "inferior.h"
29
#include "target.h"
30
#include "top.h"
31
#include "gdb_string.h"
32
#include "tui/tui.h"
33
#include "tui/tui-data.h"
34
#include "tui/tui-stack.h"
35
#include "tui/tui-wingeneral.h"
36
#include "tui/tui-source.h"
37
#include "tui/tui-winsource.h"
38
#include "tui/tui-file.h"
39
 
40
#include "gdb_curses.h"
41
 
42
/* Get a printable name for the function at the address.
43
   The symbol name is demangled if demangling is turned on.
44
   Returns a pointer to a static area holding the result.  */
45
static char *tui_get_function_from_frame (struct frame_info *fi);
46
 
47
/* Set the filename portion of the locator.  */
48
static void tui_set_locator_filename (const char *filename);
49
 
50
/* Update the locator, with the provided arguments.  */
51
static void tui_set_locator_info (const char *filename,
52
                                  const char *procname,
53
                                  int lineno, CORE_ADDR addr);
54
 
55
static void tui_update_command (char *, int);
56
 
57
 
58
/* Create the status line to display as much information as we can on
59
   this single line: target name, process number, current function,
60
   current line, current PC, SingleKey mode.  */
61
static char*
62
tui_make_status_line (struct tui_locator_element *loc)
63
{
64
  char *string;
65
  char line_buf[50], *pname;
66
  char *buf;
67
  int status_size;
68
  int i, proc_width;
69
  const char *pid_name;
70
  const char *pc_buf;
71
  int target_width;
72
  int pid_width;
73
  int line_width;
74
  int pc_width;
75
  struct ui_file *pc_out;
76
 
77
  if (ptid_equal (inferior_ptid, null_ptid))
78
    pid_name = "No process";
79
  else
80
    pid_name = target_pid_to_str (inferior_ptid);
81
 
82
  target_width = strlen (target_shortname);
83
  if (target_width > MAX_TARGET_WIDTH)
84
    target_width = MAX_TARGET_WIDTH;
85
 
86
  pid_width = strlen (pid_name);
87
  if (pid_width > MAX_PID_WIDTH)
88
    pid_width = MAX_PID_WIDTH;
89
 
90
  status_size = tui_term_width ();
91
  string = (char *) xmalloc (status_size + 1);
92
  buf = (char*) alloca (status_size + 1);
93
 
94
  /* Translate line number and obtain its size.  */
95
  if (loc->line_no > 0)
96
    sprintf (line_buf, "%d", loc->line_no);
97
  else
98
    strcpy (line_buf, "??");
99
  line_width = strlen (line_buf);
100
  if (line_width < MIN_LINE_WIDTH)
101
    line_width = MIN_LINE_WIDTH;
102
 
103
  /* Translate PC address.  */
104
  pc_out = tui_sfileopen (128);
105
  deprecated_print_address_numeric (loc->addr, 1, pc_out);
106
  pc_buf = tui_file_get_strbuf (pc_out);
107
  pc_width = strlen (pc_buf);
108
 
109
  /* First determine the amount of proc name width we have available.
110
     The +1 are for a space separator between fields.
111
     The -1 are to take into account the \0 counted by sizeof.  */
112
  proc_width = (status_size
113
                - (target_width + 1)
114
                - (pid_width + 1)
115
                - (sizeof (PROC_PREFIX) - 1 + 1)
116
                - (sizeof (LINE_PREFIX) - 1 + line_width + 1)
117
                - (sizeof (PC_PREFIX) - 1 + pc_width + 1)
118
                - (tui_current_key_mode == TUI_SINGLE_KEY_MODE
119
                   ? (sizeof (SINGLE_KEY) - 1 + 1)
120
                   : 0));
121
 
122
  /* If there is no room to print the function name, try by removing
123
     some fields.  */
124
  if (proc_width < MIN_PROC_WIDTH)
125
    {
126
      proc_width += target_width + 1;
127
      target_width = 0;
128
      if (proc_width < MIN_PROC_WIDTH)
129
        {
130
          proc_width += pid_width + 1;
131
          pid_width = 0;
132
          if (proc_width <= MIN_PROC_WIDTH)
133
            {
134
              proc_width += pc_width + sizeof (PC_PREFIX) - 1 + 1;
135
              pc_width = 0;
136
              if (proc_width < 0)
137
                {
138
                  proc_width += line_width + sizeof (LINE_PREFIX) - 1 + 1;
139
                  line_width = 0;
140
                  if (proc_width < 0)
141
                    proc_width = 0;
142
                }
143
            }
144
        }
145
    }
146
 
147
  /* Now convert elements to string form.  */
148
  pname = loc->proc_name;
149
 
150
  /* Now create the locator line from the string version of the
151
     elements.  We could use sprintf() here but that wouldn't ensure
152
     that we don't overrun the size of the allocated buffer.
153
     strcat_to_buf() will.  */
154
  *string = (char) 0;
155
 
156
  if (target_width > 0)
157
    {
158
      sprintf (buf, "%*.*s ",
159
               -target_width, target_width, target_shortname);
160
      strcat_to_buf (string, status_size, buf);
161
    }
162
  if (pid_width > 0)
163
    {
164
      sprintf (buf, "%*.*s ",
165
               -pid_width, pid_width, pid_name);
166
      strcat_to_buf (string, status_size, buf);
167
    }
168
 
169
  /* Show whether we are in SingleKey mode.  */
170
  if (tui_current_key_mode == TUI_SINGLE_KEY_MODE)
171
    {
172
      strcat_to_buf (string, status_size, SINGLE_KEY);
173
      strcat_to_buf (string, status_size, " ");
174
    }
175
 
176
  /* Procedure/class name.  */
177
  if (proc_width > 0)
178
    {
179
      if (strlen (pname) > proc_width)
180
        sprintf (buf, "%s%*.*s* ", PROC_PREFIX,
181
                 1 - proc_width, proc_width - 1, pname);
182
      else
183
        sprintf (buf, "%s%*.*s ", PROC_PREFIX,
184
                 -proc_width, proc_width, pname);
185
      strcat_to_buf (string, status_size, buf);
186
    }
187
 
188
  if (line_width > 0)
189
    {
190
      sprintf (buf, "%s%*.*s ", LINE_PREFIX,
191
               -line_width, line_width, line_buf);
192
      strcat_to_buf (string, status_size, buf);
193
    }
194
  if (pc_width > 0)
195
    {
196
      strcat_to_buf (string, status_size, PC_PREFIX);
197
      strcat_to_buf (string, status_size, pc_buf);
198
    }
199
 
200
 
201
  for (i = strlen (string); i < status_size; i++)
202
    string[i] = ' ';
203
  string[status_size] = (char) 0;
204
 
205
  ui_file_delete (pc_out);
206
  return string;
207
}
208
 
209
/* Get a printable name for the function at the address.  The symbol
210
   name is demangled if demangling is turned on.  Returns a pointer to
211
   a static area holding the result.  */
212
static char*
213
tui_get_function_from_frame (struct frame_info *fi)
214
{
215
  static char name[256];
216
  struct ui_file *stream = tui_sfileopen (256);
217
  char *p;
218
 
219
  print_address_symbolic (get_frame_pc (fi), stream, demangle, "");
220
  p = tui_file_get_strbuf (stream);
221
 
222
  /* Use simple heuristics to isolate the function name.  The symbol
223
     can be demangled and we can have function parameters.  Remove
224
     them because the status line is too short to display them.  */
225
  if (*p == '<')
226
    p++;
227
  strncpy (name, p, sizeof (name));
228
  p = strchr (name, '(');
229
  if (!p)
230
    p = strchr (name, '>');
231
  if (p)
232
    *p = 0;
233
  p = strchr (name, '+');
234
  if (p)
235
    *p = 0;
236
  ui_file_delete (stream);
237
  return name;
238
}
239
 
240
void
241
tui_show_locator_content (void)
242
{
243
  char *string;
244
  struct tui_gen_win_info *locator;
245
 
246
  locator = tui_locator_win_info_ptr ();
247
 
248
  if (locator != NULL && locator->handle != (WINDOW *) NULL)
249
    {
250
      struct tui_win_element *element;
251
 
252
      element = (struct tui_win_element *) locator->content[0];
253
 
254
      string = tui_make_status_line (&element->which_element.locator);
255
      wmove (locator->handle, 0, 0);
256
      wstandout (locator->handle);
257
      waddstr (locator->handle, string);
258
      wclrtoeol (locator->handle);
259
      wstandend (locator->handle);
260
      tui_refresh_win (locator);
261
      wmove (locator->handle, 0, 0);
262
      xfree (string);
263
      locator->content_in_use = TRUE;
264
    }
265
}
266
 
267
 
268
/* Set the filename portion of the locator.  */
269
static void
270
tui_set_locator_filename (const char *filename)
271
{
272
  struct tui_gen_win_info *locator = tui_locator_win_info_ptr ();
273
  struct tui_locator_element *element;
274
 
275
  if (locator->content[0] == NULL)
276
    {
277
      tui_set_locator_info (filename, NULL, 0, 0);
278
      return;
279
    }
280
 
281
  element = &((struct tui_win_element *) locator->content[0])->which_element.locator;
282
  element->file_name[0] = 0;
283
  strcat_to_buf (element->file_name, MAX_LOCATOR_ELEMENT_LEN, filename);
284
}
285
 
286
/* Update the locator, with the provided arguments.  */
287
static void
288
tui_set_locator_info (const char *filename,
289
                      const char *procname,
290
                      int lineno,
291
                      CORE_ADDR addr)
292
{
293
  struct tui_gen_win_info *locator = tui_locator_win_info_ptr ();
294
  struct tui_locator_element *element;
295
 
296
  /* Allocate the locator content if necessary.  */
297
  if (locator->content_size <= 0)
298
    {
299
      locator->content = (void **) tui_alloc_content (1, locator->type);
300
      locator->content_size = 1;
301
    }
302
 
303
  element = &((struct tui_win_element *) locator->content[0])->which_element.locator;
304
  element->proc_name[0] = (char) 0;
305
  strcat_to_buf (element->proc_name, MAX_LOCATOR_ELEMENT_LEN, procname);
306
  element->line_no = lineno;
307
  element->addr = addr;
308
  tui_set_locator_filename (filename);
309
}
310
 
311
/* Update only the filename portion of the locator.  */
312
void
313
tui_update_locator_filename (const char *filename)
314
{
315
  tui_set_locator_filename (filename);
316
  tui_show_locator_content ();
317
}
318
 
319
/* Function to print the frame information for the TUI.  */
320
void
321
tui_show_frame_info (struct frame_info *fi)
322
{
323
  struct tui_win_info *win_info;
324
  int i;
325
 
326
  if (fi)
327
    {
328
      int start_line, i;
329
      CORE_ADDR low;
330
      struct tui_gen_win_info *locator = tui_locator_win_info_ptr ();
331
      int source_already_displayed;
332
      struct symtab_and_line sal;
333
 
334
      find_frame_sal (fi, &sal);
335
 
336
      source_already_displayed = sal.symtab != 0
337
        && tui_source_is_displayed (sal.symtab->filename);
338
      tui_set_locator_info (sal.symtab == 0 ? "??" : sal.symtab->filename,
339
                            tui_get_function_from_frame (fi),
340
                            sal.line,
341
                            get_frame_pc (fi));
342
      tui_show_locator_content ();
343
      start_line = 0;
344
      for (i = 0; i < (tui_source_windows ())->count; i++)
345
        {
346
          union tui_which_element *item;
347
          win_info = (tui_source_windows ())->list[i];
348
 
349
          item = &((struct tui_win_element *) locator->content[0])->which_element;
350
          if (win_info == TUI_SRC_WIN)
351
            {
352
              start_line = (item->locator.line_no -
353
                           (win_info->generic.viewport_height / 2)) + 1;
354
              if (start_line <= 0)
355
                start_line = 1;
356
            }
357
          else
358
            {
359
              if (find_pc_partial_function (get_frame_pc (fi), (char **) NULL,
360
                                            &low, (CORE_ADDR) 0) == 0)
361
                error (_("No function contains program counter for selected frame."));
362
              else
363
                low = tui_get_low_disassembly_address (low, get_frame_pc (fi));
364
            }
365
 
366
          if (win_info == TUI_SRC_WIN)
367
            {
368
              struct tui_line_or_address l;
369
              l.loa = LOA_LINE;
370
              l.u.line_no = start_line;
371
              if (!(source_already_displayed
372
                    && tui_line_is_displayed (item->locator.line_no, win_info, TRUE)))
373
                tui_update_source_window (win_info, sal.symtab, l, TRUE);
374
              else
375
                {
376
                  l.u.line_no = item->locator.line_no;
377
                  tui_set_is_exec_point_at (l, win_info);
378
                }
379
            }
380
          else
381
            {
382
              if (win_info == TUI_DISASM_WIN)
383
                {
384
                  struct tui_line_or_address a;
385
                  a.loa = LOA_ADDRESS;
386
                  a.u.addr = low;
387
                  if (!tui_addr_is_displayed (item->locator.addr, win_info, TRUE))
388
                    tui_update_source_window (win_info, sal.symtab, a, TRUE);
389
                  else
390
                    {
391
                      a.u.addr = item->locator.addr;
392
                      tui_set_is_exec_point_at (a, win_info);
393
                    }
394
                }
395
            }
396
          tui_update_exec_info (win_info);
397
        }
398
    }
399
  else
400
    {
401
      tui_set_locator_info (NULL, NULL, 0, (CORE_ADDR) 0);
402
      tui_show_locator_content ();
403
      for (i = 0; i < (tui_source_windows ())->count; i++)
404
        {
405
          win_info = (tui_source_windows ())->list[i];
406
          tui_clear_source_content (win_info, EMPTY_SOURCE_PROMPT);
407
          tui_update_exec_info (win_info);
408
        }
409
    }
410
}
411
 
412
/* Function to initialize gdb commands, for tui window stack
413
   manipulation.  */
414
void
415
_initialize_tui_stack (void)
416
{
417
  add_com ("update", class_tui, tui_update_command, _("\
418
Update the source window and locator to display the current execution point.\n"));
419
}
420
 
421
/* Command to update the display with the current execution point.  */
422
static void
423
tui_update_command (char *arg, int from_tty)
424
{
425
  char cmd[sizeof("frame 0")];
426
 
427
  strcpy (cmd, "frame 0");
428
  execute_command (cmd, from_tty);
429
}

powered by: WebSVN 2.1.0

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