Commit | Line | Data |
---|---|---|
f377b406 SC |
1 | /* TUI display locator. |
2 | Copyright 1998, 1999, 2000, 2001 Free Software Foundation, Inc. | |
3 | Contributed by Hewlett-Packard Company. | |
4 | ||
5 | This file is part of GDB. | |
6 | ||
7 | This program is free software; you can redistribute it and/or modify | |
8 | it under the terms of the GNU General Public License as published by | |
9 | the Free Software Foundation; either version 2 of the License, or | |
10 | (at your option) any later version. | |
11 | ||
12 | This program is distributed in the hope that it will be useful, | |
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | GNU General Public License for more details. | |
16 | ||
17 | You should have received a copy of the GNU General Public License | |
18 | along with this program; if not, write to the Free Software | |
19 | Foundation, Inc., 59 Temple Place - Suite 330, | |
20 | Boston, MA 02111-1307, USA. */ | |
c906108c | 21 | |
4e8f7a8b DJ |
22 | /* If we need <curses.h>, we must include it before we get "bfd.h". */ |
23 | #include "config.h" | |
24 | #ifdef HAVE_NCURSES_H | |
25 | #include <ncurses.h> | |
26 | #else | |
27 | #ifdef HAVE_CURSES_H | |
28 | #include <curses.h> | |
29 | #endif | |
30 | #endif | |
31 | ||
c906108c SS |
32 | #include "defs.h" |
33 | #include "symtab.h" | |
34 | #include "breakpoint.h" | |
35 | #include "frame.h" | |
75fd9bc1 | 36 | #include "command.h" |
c906108c SS |
37 | |
38 | #include "tui.h" | |
39 | #include "tuiData.h" | |
40 | #include "tuiStack.h" | |
75fd9bc1 SC |
41 | #include "tuiGeneralWin.h" |
42 | #include "tuiSource.h" | |
c906108c SS |
43 | #include "tuiSourceWin.h" |
44 | ||
45 | ||
46 | /***************************************** | |
47 | ** STATIC LOCAL FUNCTIONS FORWARD DECLS ** | |
48 | ******************************************/ | |
49 | ||
a14ed312 KB |
50 | static char *_getFuncNameFromFrame (struct frame_info *); |
51 | static void _tuiUpdateLocation_command (char *, int); | |
c906108c SS |
52 | |
53 | ||
54 | ||
55 | /***************************************** | |
56 | ** PUBLIC FUNCTION ** | |
57 | ******************************************/ | |
58 | ||
59 | /* | |
c5aa993b JM |
60 | ** tuiClearLocatorDisplay() |
61 | */ | |
c906108c | 62 | void |
c906108c | 63 | tuiClearLocatorDisplay (void) |
c906108c SS |
64 | { |
65 | TuiGenWinInfoPtr locator = locatorWinInfoPtr (); | |
66 | int i; | |
67 | ||
68 | if (locator->handle != (WINDOW *) NULL) | |
69 | { | |
70 | /* No need to werase, since writing a line of | |
71 | * blanks which we do below, is equivalent. | |
c5aa993b | 72 | */ |
c906108c SS |
73 | /* werase(locator->handle); */ |
74 | wmove (locator->handle, 0, 0); | |
75 | wstandout (locator->handle); | |
76 | for (i = 0; i < locator->width; i++) | |
77 | waddch (locator->handle, ' '); | |
78 | wstandend (locator->handle); | |
79 | tuiRefreshWin (locator); | |
80 | wmove (locator->handle, 0, 0); | |
81 | locator->contentInUse = FALSE; | |
82 | } | |
83 | ||
84 | return; | |
85 | } /* tuiClearLocatorDisplay */ | |
86 | ||
87 | ||
88 | /* | |
c5aa993b JM |
89 | ** tuiShowLocatorContent() |
90 | */ | |
c906108c | 91 | void |
c906108c | 92 | tuiShowLocatorContent (void) |
c906108c SS |
93 | { |
94 | char *string; | |
95 | TuiGenWinInfoPtr locator; | |
96 | ||
97 | locator = locatorWinInfoPtr (); | |
98 | ||
99 | if (m_genWinPtrNotNull (locator) && locator->handle != (WINDOW *) NULL) | |
100 | { | |
101 | string = displayableWinContentAt (locator, 0); | |
102 | if (string != (char *) NULL) | |
103 | { | |
104 | wmove (locator->handle, 0, 0); | |
105 | wstandout (locator->handle); | |
106 | waddstr (locator->handle, string); | |
107 | wstandend (locator->handle); | |
108 | tuiRefreshWin (locator); | |
109 | wmove (locator->handle, 0, 0); | |
110 | if (string != nullStr ()) | |
111 | tuiFree (string); | |
112 | locator->contentInUse = TRUE; | |
113 | } | |
114 | } | |
115 | ||
116 | return; | |
117 | } /* tuiShowLocatorContent */ | |
118 | ||
119 | ||
c7c228ed | 120 | /* Update the locator, with the provided arguments. */ |
c906108c | 121 | void |
eca6576c | 122 | tuiSetLocatorInfo (char *fname, char *procname, int lineNo, |
c774cec6 | 123 | CORE_ADDR addr, TuiLocatorElementPtr element) |
c906108c | 124 | { |
c906108c SS |
125 | element->fileName[0] = (char) 0; |
126 | element->procName[0] = (char) 0; | |
127 | strcat_to_buf (element->fileName, MAX_LOCATOR_ELEMENT_LEN, fname); | |
128 | strcat_to_buf (element->procName, MAX_LOCATOR_ELEMENT_LEN, procname); | |
c906108c | 129 | element->lineNo = lineNo; |
c774cec6 | 130 | element->addr = addr; |
c7c228ed | 131 | } |
c906108c SS |
132 | |
133 | ||
134 | /* | |
c5aa993b JM |
135 | ** tuiUpdateLocatorFilename(). |
136 | ** Update only the filename portion of the locator. | |
137 | */ | |
c906108c | 138 | void |
c6f60bcd | 139 | tuiUpdateLocatorFilename (const char *fileName) |
c906108c SS |
140 | { |
141 | TuiGenWinInfoPtr locator = locatorWinInfoPtr (); | |
142 | ||
143 | if (locator->content[0] == (Opaque) NULL) | |
144 | tuiSetLocatorContent ((struct frame_info *) NULL); | |
145 | ((TuiWinElementPtr) locator->content[0])->whichElement.locator.fileName[0] = (char) 0; | |
146 | strcat_to_buf (((TuiWinElementPtr) locator->content[0])->whichElement.locator.fileName, | |
147 | MAX_LOCATOR_ELEMENT_LEN, | |
148 | fileName); | |
149 | ||
150 | tuiShowLocatorContent (); | |
151 | ||
152 | return; | |
153 | } /* tuiUpdateLocatorFilename */ | |
154 | ||
c906108c | 155 | /* |
c5aa993b JM |
156 | ** tuiSwitchFilename(). |
157 | ** Update the filename portion of the locator. Clear the other info in locator. | |
158 | ** (elz) | |
159 | */ | |
c906108c | 160 | void |
eca6576c | 161 | tuiSwitchFilename (char *fileName) |
c906108c SS |
162 | { |
163 | TuiGenWinInfoPtr locator = locatorWinInfoPtr (); | |
164 | ||
165 | if (locator->content[0] == (Opaque) NULL) | |
166 | tuiSetLocatorContent ((struct frame_info *) NULL); | |
167 | ((TuiWinElementPtr) locator->content[0])->whichElement.locator.fileName[0] = (char) 0; | |
168 | ||
169 | tuiSetLocatorInfo (fileName, | |
170 | (char *) NULL, | |
171 | 0, | |
c774cec6 | 172 | (CORE_ADDR) 0, |
c906108c SS |
173 | &((TuiWinElementPtr) locator->content[0])->whichElement.locator); |
174 | ||
175 | tuiShowLocatorContent (); | |
176 | ||
177 | return; | |
178 | } /* tuiSwitchFilename */ | |
179 | ||
180 | ||
181 | /* | |
c5aa993b JM |
182 | ** tuiGetLocatorFilename(). |
183 | ** Get the filename portion of the locator. | |
184 | ** (elz) | |
185 | */ | |
c906108c | 186 | void |
eca6576c | 187 | tuiGetLocatorFilename (TuiGenWinInfoPtr locator, char **filename) |
c906108c SS |
188 | { |
189 | ||
190 | /* the current filename could be non known, in which case the xmalloc would | |
191 | allocate no memory, because the length would be 0 */ | |
192 | if (((TuiWinElementPtr) locator->content[0])->whichElement.locator.fileName) | |
193 | { | |
194 | int name_length = | |
195 | strlen (((TuiWinElementPtr) locator->content[0])->whichElement.locator.fileName); | |
196 | ||
197 | (*filename) = (char *) xmalloc (name_length + 1); | |
198 | strcpy ((*filename), | |
199 | ((TuiWinElementPtr) locator->content[0])->whichElement.locator.fileName); | |
200 | } | |
201 | ||
202 | return; | |
203 | } /* tuiGetLocatorFilename */ | |
204 | ||
205 | ||
206 | /* | |
c5aa993b JM |
207 | ** tuiUpdateLocatorInfoFromFrame(). |
208 | ** Function to update the locator, with the information extracted from frameInfo | |
209 | */ | |
c906108c | 210 | void |
eca6576c SC |
211 | tuiUpdateLocatorInfoFromFrame (struct frame_info *frameInfo, |
212 | TuiLocatorElementPtr element) | |
c906108c SS |
213 | { |
214 | struct symtab_and_line symtabAndLine; | |
215 | ||
216 | /* now get the new info */ | |
217 | symtabAndLine = find_pc_line (frameInfo->pc, | |
218 | (frameInfo->next != (struct frame_info *) NULL && | |
219 | !frameInfo->next->signal_handler_caller && | |
220 | !frame_in_dummy (frameInfo->next))); | |
221 | if (symtabAndLine.symtab && symtabAndLine.symtab->filename) | |
222 | tuiSetLocatorInfo (symtabAndLine.symtab->filename, | |
223 | _getFuncNameFromFrame (frameInfo), | |
224 | symtabAndLine.line, | |
c774cec6 | 225 | frameInfo->pc, |
c906108c SS |
226 | element); |
227 | else | |
228 | tuiSetLocatorInfo ((char *) NULL, | |
229 | _getFuncNameFromFrame (frameInfo), | |
230 | 0, | |
c774cec6 | 231 | frameInfo->pc, |
c906108c SS |
232 | element); |
233 | ||
234 | return; | |
235 | } /* tuiUpdateLocatorInfoFromFrame */ | |
236 | ||
237 | ||
238 | /* | |
c5aa993b JM |
239 | ** tuiSetLocatorContent(). |
240 | ** Function to set the content of the locator | |
241 | */ | |
c906108c | 242 | void |
eca6576c | 243 | tuiSetLocatorContent (struct frame_info *frameInfo) |
c906108c SS |
244 | { |
245 | TuiGenWinInfoPtr locator = locatorWinInfoPtr (); | |
246 | TuiWinElementPtr element; | |
247 | struct symtab_and_line symtabAndLine; | |
248 | ||
249 | /* Allocate the element if necessary */ | |
250 | if (locator->contentSize <= 0) | |
251 | { | |
252 | TuiWinContent contentPtr; | |
253 | ||
254 | if ((locator->content = (OpaquePtr) allocContent (1, locator->type)) == (OpaquePtr) NULL) | |
255 | error ("Unable to Allocate Memory to Display Location."); | |
256 | locator->contentSize = 1; | |
257 | } | |
258 | ||
259 | if (frameInfo != (struct frame_info *) NULL) | |
260 | tuiUpdateLocatorInfoFromFrame (frameInfo, | |
261 | &((TuiWinElementPtr) locator->content[0])->whichElement.locator); | |
262 | else | |
263 | tuiSetLocatorInfo ((char *) NULL, | |
264 | (char *) NULL, | |
265 | 0, | |
c774cec6 | 266 | (CORE_ADDR) 0, |
c906108c SS |
267 | &((TuiWinElementPtr) locator->content[0])->whichElement.locator); |
268 | return; | |
269 | } /* tuiSetLocatorContent */ | |
270 | ||
271 | ||
272 | /* | |
c5aa993b JM |
273 | ** tuiUpdateLocatorDisplay(). |
274 | ** Function to update the locator display | |
275 | */ | |
c906108c | 276 | void |
eca6576c | 277 | tuiUpdateLocatorDisplay (struct frame_info *frameInfo) |
c906108c SS |
278 | { |
279 | tuiClearLocatorDisplay (); | |
280 | tuiSetLocatorContent (frameInfo); | |
281 | tuiShowLocatorContent (); | |
282 | ||
283 | return; | |
284 | } /* tuiUpdateLocatorDisplay */ | |
285 | ||
286 | ||
287 | /* | |
c5aa993b JM |
288 | ** tuiShowFrameInfo(). |
289 | ** Function to print the frame inforrmation for the TUI. | |
290 | */ | |
c906108c | 291 | void |
eca6576c | 292 | tuiShowFrameInfo (struct frame_info *fi) |
c906108c SS |
293 | { |
294 | TuiWinInfoPtr winInfo; | |
295 | register int i; | |
296 | ||
297 | if (fi) | |
298 | { | |
299 | register int startLine, i; | |
300 | register struct symtab *s; | |
301 | CORE_ADDR low; | |
302 | TuiGenWinInfoPtr locator = locatorWinInfoPtr (); | |
303 | int sourceAlreadyDisplayed; | |
304 | ||
305 | ||
306 | s = find_pc_symtab (fi->pc); | |
75fd9bc1 SC |
307 | if (s == 0) |
308 | return; | |
309 | ||
a4b99e53 | 310 | startLine = 0; |
c906108c SS |
311 | sourceAlreadyDisplayed = tuiSourceIsDisplayed (s->filename); |
312 | tuiUpdateLocatorDisplay (fi); | |
313 | for (i = 0; i < (sourceWindows ())->count; i++) | |
314 | { | |
a4b99e53 | 315 | TuiWhichElement *item; |
c906108c | 316 | winInfo = (TuiWinInfoPtr) (sourceWindows ())->list[i]; |
a4b99e53 SC |
317 | |
318 | item = &((TuiWinElementPtr) locator->content[0])->whichElement; | |
c906108c SS |
319 | if (winInfo == srcWin) |
320 | { | |
a4b99e53 SC |
321 | startLine = (item->locator.lineNo - |
322 | (winInfo->generic.viewportHeight / 2)) + 1; | |
c906108c SS |
323 | if (startLine <= 0) |
324 | startLine = 1; | |
325 | } | |
326 | else | |
327 | { | |
328 | if (find_pc_partial_function (fi->pc, (char **) NULL, &low, (CORE_ADDR) NULL) == 0) | |
329 | error ("No function contains program counter for selected frame.\n"); | |
330 | else | |
c774cec6 | 331 | low = tuiGetLowDisassemblyAddress (low, fi->pc); |
c906108c SS |
332 | } |
333 | ||
334 | if (winInfo == srcWin) | |
335 | { | |
a4b99e53 SC |
336 | TuiLineOrAddress l; |
337 | l.lineNo = startLine; | |
338 | if (!(sourceAlreadyDisplayed | |
339 | && tuiLineIsDisplayed (item->locator.lineNo, winInfo, TRUE))) | |
340 | tuiUpdateSourceWindow (winInfo, s, l, TRUE); | |
c906108c | 341 | else |
a4b99e53 SC |
342 | { |
343 | l.lineNo = item->locator.lineNo; | |
344 | tuiSetIsExecPointAt (l, winInfo); | |
345 | } | |
c906108c SS |
346 | } |
347 | else | |
348 | { | |
349 | if (winInfo == disassemWin) | |
350 | { | |
a4b99e53 SC |
351 | TuiLineOrAddress a; |
352 | a.addr = low; | |
353 | if (!tuiAddrIsDisplayed (item->locator.addr, winInfo, TRUE)) | |
354 | tuiUpdateSourceWindow (winInfo, s, a, TRUE); | |
c906108c | 355 | else |
a4b99e53 SC |
356 | { |
357 | a.addr = item->locator.addr; | |
358 | tuiSetIsExecPointAt (a, winInfo); | |
359 | } | |
c906108c SS |
360 | } |
361 | } | |
362 | tuiUpdateExecInfo (winInfo); | |
363 | } | |
364 | } | |
365 | else | |
366 | { | |
367 | tuiUpdateLocatorDisplay (fi); | |
368 | for (i = 0; i < (sourceWindows ())->count; i++) | |
369 | { | |
370 | winInfo = (TuiWinInfoPtr) (sourceWindows ())->list[i]; | |
371 | tuiClearSourceContent (winInfo, EMPTY_SOURCE_PROMPT); | |
372 | tuiUpdateExecInfo (winInfo); | |
373 | } | |
374 | } | |
375 | ||
376 | return; | |
377 | } /* tuiShowFrameInfo */ | |
378 | ||
c906108c | 379 | /* |
c5aa993b JM |
380 | ** _initialize_tuiStack(). |
381 | ** Function to initialize gdb commands, for tui window stack manipulation. | |
382 | */ | |
c906108c | 383 | void |
fba45db2 | 384 | _initialize_tuiStack (void) |
c906108c | 385 | { |
41783295 SC |
386 | add_com ("update", class_tui, _tuiUpdateLocation_command, |
387 | "Update the source window and locator to display the current execution point.\n"); | |
388 | } | |
c906108c SS |
389 | |
390 | ||
391 | /***************************************** | |
392 | ** STATIC LOCAL FUNCTIONS ** | |
393 | ******************************************/ | |
394 | ||
395 | /* | |
c5aa993b JM |
396 | ** _getFuncNameFromFrame(). |
397 | */ | |
c906108c | 398 | static char * |
eca6576c | 399 | _getFuncNameFromFrame (struct frame_info *frameInfo) |
c906108c SS |
400 | { |
401 | char *funcName = (char *) NULL; | |
402 | ||
403 | find_pc_partial_function (frameInfo->pc, | |
404 | &funcName, | |
405 | (CORE_ADDR *) NULL, | |
406 | (CORE_ADDR *) NULL); | |
407 | return funcName; | |
408 | } /* _getFuncNameFromFrame */ | |
409 | ||
410 | ||
411 | /* | |
c5aa993b JM |
412 | ** _tuiUpdateLocation_command(). |
413 | ** Command to update the display with the current execution point | |
414 | */ | |
c906108c | 415 | static void |
eca6576c | 416 | _tuiUpdateLocation_command (char *arg, int fromTTY) |
c906108c SS |
417 | { |
418 | #ifndef TRY | |
a14ed312 | 419 | extern void frame_command (char *, int); |
c906108c SS |
420 | frame_command ("0", FALSE); |
421 | #else | |
422 | struct frame_info *curFrame; | |
423 | ||
424 | /* Obtain the current execution point */ | |
425 | if ((curFrame = get_current_frame ()) != (struct frame_info *) NULL) | |
426 | { | |
427 | struct frame_info *frame; | |
428 | int curLevel = 0; | |
429 | ||
430 | for (frame = get_prev_frame (curLevel); | |
431 | (frame != (struct frame_info *) NULL && (frame != curFrame)); | |
432 | frame = get_prev_frame (frame)) | |
433 | curLevel++; | |
434 | ||
435 | if (curFrame != (struct frame_info *) NULL) | |
436 | print_frame_info (frame, curLevel, 0, 1); | |
437 | } | |
438 | #endif | |
439 | ||
440 | return; | |
441 | } /* _tuiUpdateLocation_command */ |