Initial import from FreeBSD RELENG_4:
[dragonfly.git] / contrib / gdb / gdb / tui / tuiStack.c
1 /*
2 ** This module contains functions for displaying the locator information in the locator window.
3 */
4
5 #include "defs.h"
6 #include "symtab.h"
7 #include "breakpoint.h"
8 #include "frame.h"
9
10 #include "tui.h"
11 #include "tuiData.h"
12 #include "tuiStack.h"
13 #include "tuiSourceWin.h"
14
15
16 /*****************************************
17 ** STATIC LOCAL FUNCTIONS FORWARD DECLS    **
18 ******************************************/
19
20 static char *_getFuncNameFromFrame PARAMS ((struct frame_info *));
21 static void _tuiUpdateLocation_command PARAMS ((char *, int));
22
23
24
25 /*****************************************
26 ** PUBLIC FUNCTION                        **
27 ******************************************/
28
29 /*
30 ** tuiClearLocatorDisplay()
31 */
32 void
33 #ifdef __STDC__
34 tuiClearLocatorDisplay (void)
35 #else
36 tuiClearLocatorDisplay ()
37 #endif
38 {
39   TuiGenWinInfoPtr locator = locatorWinInfoPtr ();
40   int i;
41
42   if (locator->handle != (WINDOW *) NULL)
43     {
44       /* No need to werase, since writing a line of
45          * blanks which we do below, is equivalent.
46          */
47       /* werase(locator->handle); */
48       wmove (locator->handle, 0, 0);
49       wstandout (locator->handle);
50       for (i = 0; i < locator->width; i++)
51         waddch (locator->handle, ' ');
52       wstandend (locator->handle);
53       tuiRefreshWin (locator);
54       wmove (locator->handle, 0, 0);
55       locator->contentInUse = FALSE;
56     }
57
58   return;
59 }                               /* tuiClearLocatorDisplay */
60
61
62 /*
63 ** tuiShowLocatorContent()
64 */
65 void
66 #ifdef __STDC__
67 tuiShowLocatorContent (void)
68 #else
69 tuiShowLocatorContent ()
70 #endif
71 {
72   char *string;
73   TuiGenWinInfoPtr locator;
74
75   locator = locatorWinInfoPtr ();
76
77   if (m_genWinPtrNotNull (locator) && locator->handle != (WINDOW *) NULL)
78     {
79       string = displayableWinContentAt (locator, 0);
80       if (string != (char *) NULL)
81         {
82           wmove (locator->handle, 0, 0);
83           wstandout (locator->handle);
84           waddstr (locator->handle, string);
85           wstandend (locator->handle);
86           tuiRefreshWin (locator);
87           wmove (locator->handle, 0, 0);
88           if (string != nullStr ())
89             tuiFree (string);
90           locator->contentInUse = TRUE;
91         }
92     }
93
94   return;
95 }                               /* tuiShowLocatorContent */
96
97
98 /*
99 ** tuiSetLocatorInfo().
100 **        Function to update the locator, with the provided arguments.
101 */
102 void
103 #ifdef __STDC__
104 tuiSetLocatorInfo (
105                     char *fname,
106                     char *procname,
107                     int lineNo,
108                     Opaque addr,
109                     TuiLocatorElementPtr element)
110 #else
111 tuiSetLocatorInfo (fname, procname, lineNo, addr, element)
112      char *fname;
113      char *procname;
114      int lineNo;
115      Opaque addr;
116      TuiLocatorElementPtr element;
117 #endif
118 {
119 #ifdef COMMENT
120   /* first free the old info */
121   if (element->fileName)
122     tuiFree (element->fileName);
123   if (element->procName)
124     tuiFree (element->procName);
125
126   if (fname == (char *) NULL)
127     element->fileName = fname;
128   else
129     element->fileName = tuiStrDup (fname);
130   if (procname == (char *) NULL)
131     element->procName = procname;
132   else
133     element->procName = tuiStrDup (procname);
134 #else
135   element->fileName[0] = (char) 0;
136   element->procName[0] = (char) 0;
137   strcat_to_buf (element->fileName, MAX_LOCATOR_ELEMENT_LEN, fname);
138   strcat_to_buf (element->procName, MAX_LOCATOR_ELEMENT_LEN, procname);
139 #endif
140   element->lineNo = lineNo;
141   element->addr = (Opaque) addr;
142
143   return;
144 }                               /* tuiSetLocatorInfo */
145
146
147 /*
148 ** tuiUpdateLocatorFilename().
149 **        Update only the filename portion of the locator.
150 */
151 void
152 #ifdef __STDC__
153 tuiUpdateLocatorFilename (
154                            char *fileName)
155 #else
156 tuiUpdateLocatorFilename (fileName)
157      char *fileName;
158 #endif
159 {
160   TuiGenWinInfoPtr locator = locatorWinInfoPtr ();
161
162   if (locator->content[0] == (Opaque) NULL)
163     tuiSetLocatorContent ((struct frame_info *) NULL);
164   ((TuiWinElementPtr) locator->content[0])->whichElement.locator.fileName[0] = (char) 0;
165   strcat_to_buf (((TuiWinElementPtr) locator->content[0])->whichElement.locator.fileName,
166                  MAX_LOCATOR_ELEMENT_LEN,
167                  fileName);
168
169   tuiShowLocatorContent ();
170
171   return;
172 }                               /* tuiUpdateLocatorFilename */
173
174
175 /*
176 ** tui_vUpdateLocatorFilename().
177 **        Update only the filename portion of the locator with args in a va_list.
178 */
179 void
180 #ifdef __STDC__
181 tui_vUpdateLocatorFilename (
182                              va_list args)
183 #else
184 tui_vUpdateLocatorFilename (args)
185      va_list args;
186 #endif
187 {
188   char *fileName;
189
190   fileName = va_arg (args, char *);
191   tuiUpdateLocatorFilename (fileName);
192
193   return;
194 }                               /* tui_vUpdateLocatorFilename */
195
196
197 /*
198 ** tuiSwitchFilename().
199 **   Update the filename portion of the locator. Clear the other info in locator.
200 ** (elz)
201 */
202 void
203 #ifdef __STDC__
204 tuiSwitchFilename (
205                     char *fileName)
206 #else
207 tuiSwitchFilename (fileName)
208      char *fileName;
209 #endif
210 {
211   TuiGenWinInfoPtr locator = locatorWinInfoPtr ();
212
213   if (locator->content[0] == (Opaque) NULL)
214     tuiSetLocatorContent ((struct frame_info *) NULL);
215   ((TuiWinElementPtr) locator->content[0])->whichElement.locator.fileName[0] = (char) 0;
216
217   tuiSetLocatorInfo (fileName,
218                      (char *) NULL,
219                      0,
220                      (Opaque) NULL,
221            &((TuiWinElementPtr) locator->content[0])->whichElement.locator);
222
223   tuiShowLocatorContent ();
224
225   return;
226 }                               /* tuiSwitchFilename */
227
228
229 /*
230 ** tuiGetLocatorFilename().
231 **   Get the filename portion of the locator.
232 ** (elz)
233 */
234 void
235 #ifdef __STDC__
236 tuiGetLocatorFilename (
237                         TuiGenWinInfoPtr locator,
238                         char **filename)
239 #else
240 tuiGetLocatorFilename (locator, filename)
241      TuiGenWinInfoPtr locator;
242      char **filename;
243 #endif
244 {
245
246   /* the current filename could be non known, in which case the xmalloc would
247      allocate no memory, because the length would be 0 */
248   if (((TuiWinElementPtr) locator->content[0])->whichElement.locator.fileName)
249     {
250       int name_length =
251       strlen (((TuiWinElementPtr) locator->content[0])->whichElement.locator.fileName);
252
253       (*filename) = (char *) xmalloc (name_length + 1);
254       strcpy ((*filename),
255               ((TuiWinElementPtr) locator->content[0])->whichElement.locator.fileName);
256     }
257
258   return;
259 }                               /* tuiGetLocatorFilename */
260
261
262 /*
263 ** tuiUpdateLocatorInfoFromFrame().
264 **        Function to update the locator, with the information extracted from frameInfo
265 */
266 void
267 #ifdef __STDC__
268 tuiUpdateLocatorInfoFromFrame (
269                                 struct frame_info *frameInfo,
270                                 TuiLocatorElementPtr element)
271 #else
272 tuiUpdateLocatorInfoFromFrame (frameInfo, element)
273      struct frame_info *frameInfo;
274      TuiLocatorElementPtr element;
275 #endif
276 {
277   struct symtab_and_line symtabAndLine;
278
279   /* now get the new info */
280   symtabAndLine = find_pc_line (frameInfo->pc,
281                            (frameInfo->next != (struct frame_info *) NULL &&
282                             !frameInfo->next->signal_handler_caller &&
283                             !frame_in_dummy (frameInfo->next)));
284   if (symtabAndLine.symtab && symtabAndLine.symtab->filename)
285     tuiSetLocatorInfo (symtabAndLine.symtab->filename,
286                        _getFuncNameFromFrame (frameInfo),
287                        symtabAndLine.line,
288                        (Opaque) frameInfo->pc,
289                        element);
290   else
291     tuiSetLocatorInfo ((char *) NULL,
292                        _getFuncNameFromFrame (frameInfo),
293                        0,
294                        (Opaque) frameInfo->pc,
295                        element);
296
297   return;
298 }                               /* tuiUpdateLocatorInfoFromFrame */
299
300
301 /*
302 ** tuiSetLocatorContent().
303 **        Function to set the content of the locator
304 */
305 void
306 #ifdef __STDC__
307 tuiSetLocatorContent (
308                        struct frame_info *frameInfo)
309 #else
310 tuiSetLocatorContent (frameInfo)
311      struct frame_info *frameInfo;
312 #endif
313 {
314   TuiGenWinInfoPtr locator = locatorWinInfoPtr ();
315   TuiWinElementPtr element;
316   struct symtab_and_line symtabAndLine;
317
318   /* Allocate the element if necessary */
319   if (locator->contentSize <= 0)
320     {
321       TuiWinContent contentPtr;
322
323       if ((locator->content = (OpaquePtr) allocContent (1, locator->type)) == (OpaquePtr) NULL)
324         error ("Unable to Allocate Memory to Display Location.");
325       locator->contentSize = 1;
326     }
327
328   if (frameInfo != (struct frame_info *) NULL)
329     tuiUpdateLocatorInfoFromFrame (frameInfo,
330            &((TuiWinElementPtr) locator->content[0])->whichElement.locator);
331   else
332     tuiSetLocatorInfo ((char *) NULL,
333                        (char *) NULL,
334                        0,
335                        (Opaque) NULL,
336            &((TuiWinElementPtr) locator->content[0])->whichElement.locator);
337   return;
338 }                               /* tuiSetLocatorContent */
339
340
341 /*
342 ** tuiUpdateLocatorDisplay().
343 **        Function to update the locator display
344 */
345 void
346 #ifdef __STDC__
347 tuiUpdateLocatorDisplay (
348                           struct frame_info *frameInfo)
349 #else
350 tuiUpdateLocatorDisplay (frameInfo)
351      struct frame_info *frameInfo;
352 #endif
353 {
354   tuiClearLocatorDisplay ();
355   tuiSetLocatorContent (frameInfo);
356   tuiShowLocatorContent ();
357
358   return;
359 }                               /* tuiUpdateLocatorDisplay */
360
361
362 /*
363 ** tuiShowFrameInfo().
364 **        Function to print the frame inforrmation for the TUI.
365 */
366 void
367 #ifdef __STDC__
368 tuiShowFrameInfo (
369                    struct frame_info *fi)
370 #else
371 tuiShowFrameInfo (fi)
372      struct frame_info *fi;
373 #endif
374 {
375   TuiWinInfoPtr winInfo;
376   register int i;
377
378   if (fi)
379     {
380       register int startLine, i;
381       register struct symtab *s;
382       CORE_ADDR low;
383       TuiGenWinInfoPtr locator = locatorWinInfoPtr ();
384       int sourceAlreadyDisplayed;
385
386
387       s = find_pc_symtab (fi->pc);
388       sourceAlreadyDisplayed = tuiSourceIsDisplayed (s->filename);
389       tuiUpdateLocatorDisplay (fi);
390       for (i = 0; i < (sourceWindows ())->count; i++)
391         {
392           winInfo = (TuiWinInfoPtr) (sourceWindows ())->list[i];
393           if (winInfo == srcWin)
394             {
395               startLine =
396                 (((TuiWinElementPtr) locator->content[0])->whichElement.locator.lineNo -
397                  (winInfo->generic.viewportHeight / 2)) + 1;
398               if (startLine <= 0)
399                 startLine = 1;
400             }
401           else
402             {
403               if (find_pc_partial_function (fi->pc, (char **) NULL, &low, (CORE_ADDR) NULL) == 0)
404                 error ("No function contains program counter for selected frame.\n");
405               else
406                 low = (CORE_ADDR) tuiGetLowDisassemblyAddress ((Opaque) low, (Opaque) fi->pc);
407             }
408
409           if (winInfo == srcWin)
410             {
411               if (!(sourceAlreadyDisplayed && m_tuiLineDisplayedWithinThreshold (
412                                                                     winInfo,
413                                                                                   ((TuiWinElementPtr) locator->content[0])->whichElement.locator.lineNo)))
414                 tuiUpdateSourceWindow (winInfo, s, (Opaque) startLine, TRUE);
415               else
416                 tuiSetIsExecPointAt ((Opaque)
417                                      ((TuiWinElementPtr) locator->content[0])->whichElement.locator.lineNo,
418                                      winInfo);
419             }
420           else
421             {
422               if (winInfo == disassemWin)
423                 {
424                   if (!m_tuiLineDisplayedWithinThreshold (winInfo,
425                                                           ((TuiWinElementPtr) locator->content[0])->whichElement.locator.addr))
426                     tuiUpdateSourceWindow (winInfo, s, (Opaque) low, TRUE);
427                   else
428                     tuiSetIsExecPointAt ((Opaque)
429                                          ((TuiWinElementPtr) locator->content[0])->whichElement.locator.addr,
430                                          winInfo);
431                 }
432             }
433           tuiUpdateExecInfo (winInfo);
434         }
435     }
436   else
437     {
438       tuiUpdateLocatorDisplay (fi);
439       for (i = 0; i < (sourceWindows ())->count; i++)
440         {
441           winInfo = (TuiWinInfoPtr) (sourceWindows ())->list[i];
442           tuiClearSourceContent (winInfo, EMPTY_SOURCE_PROMPT);
443           tuiUpdateExecInfo (winInfo);
444         }
445     }
446
447   return;
448 }                               /* tuiShowFrameInfo */
449
450
451 /*
452 ** tui_vShowFrameInfo().
453 **        Function to print the frame inforrmation for the TUI with args in a va_list.
454 */
455 void
456 #ifdef __STDC__
457 tui_vShowFrameInfo (
458                      va_list args)
459 #else
460 tui_vShowFrameInfo (args)
461      va_list args;
462 #endif
463 {
464   struct frame_info *fi;
465
466   fi = va_arg (args, struct frame_info *);
467   tuiShowFrameInfo (fi);
468
469   return;
470 }                               /* tui_vShowFrameInfo */
471
472
473 /*
474 ** _initialize_tuiStack().
475 **      Function to initialize gdb commands, for tui window stack manipulation.
476 */
477 void
478 _initialize_tuiStack ()
479 {
480   if (tui_version)
481     {
482       add_com ("update", class_tui, _tuiUpdateLocation_command,
483                "Update the source window and locator to display the current execution point.\n");
484     }
485
486   return;
487 }                               /* _initialize_tuiStack */
488
489
490 /*****************************************
491 ** STATIC LOCAL FUNCTIONS                 **
492 ******************************************/
493
494 /*
495 **    _getFuncNameFromFrame().
496 */
497 static char *
498 #ifdef __STDC__
499 _getFuncNameFromFrame (
500                         struct frame_info *frameInfo)
501 #else
502 _getFuncNameFromFrame (frameInfo)
503      struct frame_info *frameInfo;
504 #endif
505 {
506   char *funcName = (char *) NULL;
507
508   find_pc_partial_function (frameInfo->pc,
509                             &funcName,
510                             (CORE_ADDR *) NULL,
511                             (CORE_ADDR *) NULL);
512   return funcName;
513 }                               /* _getFuncNameFromFrame */
514
515
516 /*
517 ** _tuiUpdateLocation_command().
518 **        Command to update the display with the current execution point
519 */
520 static void
521 #ifdef __STDC__
522 _tuiUpdateLocation_command (
523                              char *arg,
524                              int fromTTY)
525 #else
526 _tuiUpdateLocation_command (arg, fromTTY)
527      char *arg;
528      int fromTTY;
529 #endif
530 {
531 #ifndef TRY
532   extern void frame_command PARAMS ((char *, int));
533   frame_command ("0", FALSE);
534 #else
535   struct frame_info *curFrame;
536
537   /* Obtain the current execution point */
538   if ((curFrame = get_current_frame ()) != (struct frame_info *) NULL)
539     {
540       struct frame_info *frame;
541       int curLevel = 0;
542
543       for (frame = get_prev_frame (curLevel);
544            (frame != (struct frame_info *) NULL && (frame != curFrame));
545            frame = get_prev_frame (frame))
546         curLevel++;
547
548       if (curFrame != (struct frame_info *) NULL)
549         print_frame_info (frame, curLevel, 0, 1);
550     }
551 #endif
552
553   return;
554 }                               /* _tuiUpdateLocation_command */