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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.3/] [gdb/] [tui/] [tuiStack.c] - Blame information for rev 1774

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

Line No. Rev Author Line
1 1181 sfurman
/* TUI display locator.
2
 
3
   Copyright 1998, 1999, 2000, 2001, 2002 Free Software Foundation,
4
   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 2 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, write to the Free Software
22
   Foundation, Inc., 59 Temple Place - Suite 330,
23
   Boston, MA 02111-1307, USA.  */
24
 
25
/* FIXME: cagney/2002-02-28: The GDB coding standard indicates that
26
   "defs.h" should be included first.  Unfortunatly some systems
27
   (currently Debian GNU/Linux) include the <stdbool.h> via <curses.h>
28
   and they clash with "bfd.h"'s definiton of true/false.  The correct
29
   fix is to remove true/false from "bfd.h", however, until that
30
   happens, hack around it by including "config.h" and <curses.h>
31
   first.  */
32
 
33
#include "config.h"
34
#ifdef HAVE_NCURSES_H       
35
#include <ncurses.h>
36
#else
37
#ifdef HAVE_CURSES_H
38
#include <curses.h>
39
#endif
40
#endif
41
 
42
#include "defs.h"
43
#include "symtab.h"
44
#include "breakpoint.h"
45
#include "frame.h"
46
#include "command.h"
47
#include "inferior.h"
48
#include "target.h"
49
#include "top.h"
50
 
51
#include "tui.h"
52
#include "tuiData.h"
53
#include "tuiStack.h"
54
#include "tuiGeneralWin.h"
55
#include "tuiSource.h"
56
#include "tuiSourceWin.h"
57
#include "tui-file.h"
58
 
59
 
60
/* Get a printable name for the function at the address.
61
   The symbol name is demangled if demangling is turned on.
62
   Returns a pointer to a static area holding the result.  */
63
static char* tui_get_function_from_frame (struct frame_info *fi);
64
 
65
/* Set the filename portion of the locator.  */
66
static void tui_set_locator_filename (const char *filename);
67
 
68
/* Update the locator, with the provided arguments.  */
69
static void tui_set_locator_info (const char *filename, const char *procname,
70
                                  int lineno, CORE_ADDR addr);
71
 
72
static void tui_update_command (char *, int);
73
 
74
 
75
/* Create the status line to display as much information as we
76
   can on this single line: target name, process number, current
77
   function, current line, current PC, SingleKey mode.  */
78
static char*
79
tui_make_status_line (TuiLocatorElement* loc)
80
{
81
  char* string;
82
  char line_buf[50], *pname;
83
  char* buf;
84
  int status_size;
85
  int i, proc_width;
86
  const char* pid_name;
87
  const char* pc_buf;
88
  int target_width;
89
  int pid_width;
90
  int line_width;
91
  int pc_width;
92
  struct ui_file *pc_out;
93
 
94
  if (ptid_equal (inferior_ptid, null_ptid))
95
    pid_name = "No process";
96
  else
97
    pid_name = target_pid_to_str (inferior_ptid);
98
 
99
  target_width = strlen (target_shortname);
100
  if (target_width > MAX_TARGET_WIDTH)
101
    target_width = MAX_TARGET_WIDTH;
102
 
103
  pid_width = strlen (pid_name);
104
  if (pid_width > MAX_PID_WIDTH)
105
    pid_width = MAX_PID_WIDTH;
106
 
107
  status_size = termWidth ();
108
  string = (char *) xmalloc (status_size + 1);
109
  buf = (char*) alloca (status_size + 1);
110
 
111
  /* Translate line number and obtain its size.  */
112
  if (loc->lineNo > 0)
113
    sprintf (line_buf, "%d", loc->lineNo);
114
  else
115
    strcpy (line_buf, "??");
116
  line_width = strlen (line_buf);
117
  if (line_width < MIN_LINE_WIDTH)
118
    line_width = MIN_LINE_WIDTH;
119
 
120
  /* Translate PC address.  */
121
  pc_out = tui_sfileopen (128);
122
  print_address_numeric (loc->addr, 1, pc_out);
123
  pc_buf = tui_file_get_strbuf (pc_out);
124
  pc_width = strlen (pc_buf);
125
 
126
  /* First determine the amount of proc name width we have available.
127
     The +1 are for a space separator between fields.
128
     The -1 are to take into account the \0 counted by sizeof.  */
129
  proc_width = (status_size
130
                - (target_width + 1)
131
                - (pid_width + 1)
132
                - (sizeof (PROC_PREFIX) - 1 + 1)
133
                - (sizeof (LINE_PREFIX) - 1 + line_width + 1)
134
                - (sizeof (PC_PREFIX) - 1 + pc_width + 1)
135
                - (tui_current_key_mode == tui_single_key_mode
136
                   ? (sizeof (SINGLE_KEY) - 1 + 1)
137
                   : 0));
138
 
139
  /* If there is no room to print the function name, try by removing
140
     some fields.  */
141
  if (proc_width < MIN_PROC_WIDTH)
142
    {
143
      proc_width += target_width + 1;
144
      target_width = 0;
145
      if (proc_width < MIN_PROC_WIDTH)
146
        {
147
          proc_width += pid_width + 1;
148
          pid_width = 0;
149
          if (proc_width <= MIN_PROC_WIDTH)
150
            {
151
              proc_width += pc_width + sizeof (PC_PREFIX) - 1 + 1;
152
              pc_width = 0;
153
              if (proc_width < 0)
154
                {
155
                  proc_width += line_width + sizeof (LINE_PREFIX) - 1 + 1;
156
                  line_width = 0;
157
                  if (proc_width < 0)
158
                    proc_width = 0;
159
                }
160
            }
161
        }
162
    }
163
 
164
  /* Now convert elements to string form */
165
  pname = loc->procName;
166
 
167
  /* Now create the locator line from the string version
168
     of the elements.  We could use sprintf() here but
169
     that wouldn't ensure that we don't overrun the size
170
     of the allocated buffer.  strcat_to_buf() will.  */
171
  *string = (char) 0;
172
 
173
  if (target_width > 0)
174
    {
175
      sprintf (buf, "%*.*s ",
176
               -target_width, target_width, target_shortname);
177
      strcat_to_buf (string, status_size, buf);
178
    }
179
  if (pid_width > 0)
180
    {
181
      sprintf (buf, "%*.*s ",
182
               -pid_width, pid_width, pid_name);
183
      strcat_to_buf (string, status_size, buf);
184
    }
185
 
186
  /* Show whether we are in SingleKey mode.  */
187
  if (tui_current_key_mode == tui_single_key_mode)
188
    {
189
      strcat_to_buf (string, status_size, SINGLE_KEY);
190
      strcat_to_buf (string, status_size, " ");
191
    }
192
 
193
  /* procedure/class name */
194
  if (proc_width > 0)
195
    {
196
      if (strlen (pname) > proc_width)
197
        sprintf (buf, "%s%*.*s* ", PROC_PREFIX,
198
                 1 - proc_width, proc_width - 1, pname);
199
      else
200
        sprintf (buf, "%s%*.*s ", PROC_PREFIX,
201
                 -proc_width, proc_width, pname);
202
      strcat_to_buf (string, status_size, buf);
203
    }
204
 
205
  if (line_width > 0)
206
    {
207
      sprintf (buf, "%s%*.*s ", LINE_PREFIX,
208
               -line_width, line_width, line_buf);
209
      strcat_to_buf (string, status_size, buf);
210
    }
211
  if (pc_width > 0)
212
    {
213
      strcat_to_buf (string, status_size, PC_PREFIX);
214
      strcat_to_buf (string, status_size, pc_buf);
215
    }
216
 
217
 
218
  for (i = strlen (string); i < status_size; i++)
219
    string[i] = ' ';
220
  string[status_size] = (char) 0;
221
 
222
  ui_file_delete (pc_out);
223
  return string;
224
}
225
 
226
/* Get a printable name for the function at the address.
227
   The symbol name is demangled if demangling is turned on.
228
   Returns a pointer to a static area holding the result.  */
229
static char*
230
tui_get_function_from_frame (struct frame_info *fi)
231
{
232
  static char name[256];
233
  struct ui_file *stream = tui_sfileopen (256);
234
  char *p;
235
 
236
  print_address_symbolic (fi->pc, stream, demangle, "");
237
  p = tui_file_get_strbuf (stream);
238
 
239
  /* Use simple heuristics to isolate the function name.  The symbol can
240
     be demangled and we can have function parameters.  Remove them because
241
     the status line is too short to display them.  */
242
  if (*p == '<')
243
    p++;
244
  strncpy (name, p, sizeof (name));
245
  p = strchr (name, '(');
246
  if (!p)
247
    p = strchr (name, '>');
248
  if (p)
249
    *p = 0;
250
  p = strchr (name, '+');
251
  if (p)
252
    *p = 0;
253
  ui_file_delete (stream);
254
  return name;
255
}
256
 
257
/*
258
   ** tuiShowLocatorContent()
259
 */
260
void
261
tuiShowLocatorContent (void)
262
{
263
  char *string;
264
  TuiGenWinInfoPtr locator;
265
 
266
  locator = locatorWinInfoPtr ();
267
 
268
  if (m_genWinPtrNotNull (locator) && locator->handle != (WINDOW *) NULL)
269
    {
270
      TuiWinElementPtr element;
271
 
272
      element = (TuiWinElementPtr) locator->content[0];
273
 
274
      string = tui_make_status_line (&element->whichElement.locator);
275
      wmove (locator->handle, 0, 0);
276
      wstandout (locator->handle);
277
      waddstr (locator->handle, string);
278
      wclrtoeol (locator->handle);
279
      wstandend (locator->handle);
280
      tuiRefreshWin (locator);
281
      wmove (locator->handle, 0, 0);
282
      xfree (string);
283
      locator->contentInUse = TRUE;
284
    }
285
}
286
 
287
 
288
/* Set the filename portion of the locator.  */
289
static void
290
tui_set_locator_filename (const char *filename)
291
{
292
  TuiGenWinInfoPtr locator = locatorWinInfoPtr ();
293
  TuiLocatorElementPtr element;
294
 
295
  if (locator->content[0] == (Opaque) NULL)
296
    {
297
      tui_set_locator_info (filename, NULL, 0, 0);
298
      return;
299
    }
300
 
301
  element = &((TuiWinElementPtr) locator->content[0])->whichElement.locator;
302
  element->fileName[0] = 0;
303
  strcat_to_buf (element->fileName, MAX_LOCATOR_ELEMENT_LEN, filename);
304
}
305
 
306
/* Update the locator, with the provided arguments.  */
307
static void
308
tui_set_locator_info (const char *filename, const char *procname, int lineno,
309
                      CORE_ADDR addr)
310
{
311
  TuiGenWinInfoPtr locator = locatorWinInfoPtr ();
312
  TuiLocatorElementPtr element;
313
 
314
  /* Allocate the locator content if necessary.  */
315
  if (locator->contentSize <= 0)
316
    {
317
      locator->content = (OpaquePtr) allocContent (1, locator->type);
318
      locator->contentSize = 1;
319
    }
320
 
321
  element = &((TuiWinElementPtr) locator->content[0])->whichElement.locator;
322
  element->procName[0] = (char) 0;
323
  strcat_to_buf (element->procName, MAX_LOCATOR_ELEMENT_LEN, procname);
324
  element->lineNo = lineno;
325
  element->addr = addr;
326
  tui_set_locator_filename (filename);
327
}
328
 
329
/* Update only the filename portion of the locator.  */
330
void
331
tuiUpdateLocatorFilename (const char *filename)
332
{
333
  tui_set_locator_filename (filename);
334
  tuiShowLocatorContent ();
335
}
336
 
337
/* Function to print the frame information for the TUI.  */
338
void
339
tuiShowFrameInfo (struct frame_info *fi)
340
{
341
  TuiWinInfoPtr winInfo;
342
  register int i;
343
 
344
  if (fi)
345
    {
346
      register int startLine, i;
347
      CORE_ADDR low;
348
      TuiGenWinInfoPtr locator = locatorWinInfoPtr ();
349
      int sourceAlreadyDisplayed;
350
      struct symtab_and_line sal;
351
 
352
      sal = find_pc_line (fi->pc,
353
                          (fi->next != (struct frame_info *) NULL &&
354
                           !fi->next->signal_handler_caller &&
355
                           !frame_in_dummy (fi->next)));
356
 
357
      sourceAlreadyDisplayed = sal.symtab != 0
358
        && tuiSourceIsDisplayed (sal.symtab->filename);
359
      tui_set_locator_info (sal.symtab == 0 ? "??" : sal.symtab->filename,
360
                            tui_get_function_from_frame (fi),
361
                            sal.line,
362
                            fi->pc);
363
      tuiShowLocatorContent ();
364
      startLine = 0;
365
      for (i = 0; i < (sourceWindows ())->count; i++)
366
        {
367
          TuiWhichElement *item;
368
          winInfo = (TuiWinInfoPtr) (sourceWindows ())->list[i];
369
 
370
          item = &((TuiWinElementPtr) locator->content[0])->whichElement;
371
          if (winInfo == srcWin)
372
            {
373
              startLine = (item->locator.lineNo -
374
                           (winInfo->generic.viewportHeight / 2)) + 1;
375
              if (startLine <= 0)
376
                startLine = 1;
377
            }
378
          else
379
            {
380
              if (find_pc_partial_function (fi->pc, (char **) NULL, &low, (CORE_ADDR) NULL) == 0)
381
                error ("No function contains program counter for selected frame.\n");
382
              else
383
                low = tuiGetLowDisassemblyAddress (low, fi->pc);
384
            }
385
 
386
          if (winInfo == srcWin)
387
            {
388
              TuiLineOrAddress l;
389
              l.lineNo = startLine;
390
              if (!(sourceAlreadyDisplayed
391
                    && tuiLineIsDisplayed (item->locator.lineNo, winInfo, TRUE)))
392
                tuiUpdateSourceWindow (winInfo, sal.symtab, l, TRUE);
393
              else
394
                {
395
                  l.lineNo = item->locator.lineNo;
396
                  tuiSetIsExecPointAt (l, winInfo);
397
                }
398
            }
399
          else
400
            {
401
              if (winInfo == disassemWin)
402
                {
403
                  TuiLineOrAddress a;
404
                  a.addr = low;
405
                  if (!tuiAddrIsDisplayed (item->locator.addr, winInfo, TRUE))
406
                    tuiUpdateSourceWindow (winInfo, sal.symtab, a, TRUE);
407
                  else
408
                    {
409
                      a.addr = item->locator.addr;
410
                      tuiSetIsExecPointAt (a, winInfo);
411
                    }
412
                }
413
            }
414
          tuiUpdateExecInfo (winInfo);
415
        }
416
    }
417
  else
418
    {
419
      tui_set_locator_info (NULL, NULL, 0, (CORE_ADDR) 0);
420
      tuiShowLocatorContent ();
421
      for (i = 0; i < (sourceWindows ())->count; i++)
422
        {
423
          winInfo = (TuiWinInfoPtr) (sourceWindows ())->list[i];
424
          tuiClearSourceContent (winInfo, EMPTY_SOURCE_PROMPT);
425
          tuiUpdateExecInfo (winInfo);
426
        }
427
    }
428
}
429
 
430
/* Function to initialize gdb commands, for tui window stack manipulation.  */
431
void
432
_initialize_tuiStack (void)
433
{
434
  add_com ("update", class_tui, tui_update_command,
435
           "Update the source window and locator to display the current "
436
           "execution point.\n");
437
}
438
 
439
/* Command to update the display with the current execution point.  */
440
static void
441
tui_update_command (char *arg, int from_tty)
442
{
443
  char cmd[sizeof("frame 0")];
444
 
445
  strcpy (cmd, "frame 0");
446
  execute_command (cmd, from_tty);
447
}

powered by: WebSVN 2.1.0

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