2003-03-14 Andrew Cagney <cagney@redhat.com>
[deliverable/binutils-gdb.git] / gdb / tui / tuiRegs.c
CommitLineData
f377b406 1/* TUI display registers in window.
f33c6cbf
AC
2
3 Copyright 1998, 1999, 2000, 2001, 2002 Free Software Foundation,
4 Inc.
5
f377b406 6 Contributed by Hewlett-Packard Company.
c906108c 7
f377b406 8 This file is part of GDB.
c906108c 9
f377b406
SC
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. */
c906108c 24
f33c6cbf
AC
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
4e8f7a8b
DJ
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
c906108c
SS
42#include "defs.h"
43#include "tui.h"
44#include "tuiData.h"
45#include "symtab.h"
46#include "gdbtypes.h"
47#include "gdbcmd.h"
48#include "frame.h"
bc77de56 49#include "regcache.h"
c906108c
SS
50#include "inferior.h"
51#include "target.h"
52#include "tuiLayout.h"
53#include "tuiWin.h"
e8b915dc
SC
54#include "tuiDataWin.h"
55#include "tuiGeneralWin.h"
c46cc7df 56#include "tui-file.h"
c906108c
SS
57
58/*****************************************
59** LOCAL DEFINITIONS **
60******************************************/
61#define DOUBLE_FLOAT_LABEL_WIDTH 6
62#define DOUBLE_FLOAT_LABEL_FMT "%6.6s: "
63#define DOUBLE_FLOAT_VALUE_WIDTH 30 /*min of 16 but may be in sci notation */
64
65#define SINGLE_FLOAT_LABEL_WIDTH 6
66#define SINGLE_FLOAT_LABEL_FMT "%6.6s: "
67#define SINGLE_FLOAT_VALUE_WIDTH 25 /* min of 8 but may be in sci notation */
68
c46cc7df 69#define SINGLE_LABEL_WIDTH 16
c906108c 70#define SINGLE_LABEL_FMT "%10.10s: "
c46cc7df 71#define SINGLE_VALUE_WIDTH 20 /* minimum of 8 but may be in sci notation */
c906108c
SS
72
73/* In the code HP gave Cygnus, this was actually a function call to a
74 PA-specific function, which was supposed to determine whether the
75 target was a 64-bit or 32-bit processor. However, the 64-bit
76 support wasn't complete, so we didn't merge that in, so we leave
77 this here as a stub. */
78#define IS_64BIT 0
79
80/*****************************************
81** STATIC DATA **
82******************************************/
83
84
85/*****************************************
86** STATIC LOCAL FUNCTIONS FORWARD DECLS **
87******************************************/
88static TuiStatus _tuiSetRegsContent
a14ed312 89 (int, int, struct frame_info *, TuiRegisterDisplayType, int);
bc77de56 90static const char *_tuiRegisterName (int);
a14ed312 91static TuiStatus _tuiGetRegisterRawValue (int, char *, struct frame_info *);
c906108c 92static void _tuiSetRegisterElement
a14ed312
KB
93 (int, struct frame_info *, TuiDataElementPtr, int);
94static void _tuiDisplayRegister (int, TuiGenWinInfoPtr, enum precision_type);
c906108c 95static void _tuiRegisterFormat
a14ed312
KB
96 (char *, int, int, TuiDataElementPtr, enum precision_type);
97static TuiStatus _tuiSetGeneralRegsContent (int);
98static TuiStatus _tuiSetSpecialRegsContent (int);
99static TuiStatus _tuiSetGeneralAndSpecialRegsContent (int);
100static TuiStatus _tuiSetFloatRegsContent (TuiRegisterDisplayType, int);
c906108c 101static int _tuiRegValueHasChanged
a14ed312
KB
102 (TuiDataElementPtr, struct frame_info *, char *);
103static void _tuiShowFloat_command (char *, int);
104static void _tuiShowGeneral_command (char *, int);
105static void _tuiShowSpecial_command (char *, int);
e8b915dc 106static void _tui_vShowRegisters_commandSupport (TuiRegisterDisplayType);
a14ed312
KB
107static void _tuiToggleFloatRegs_command (char *, int);
108static void _tuiScrollRegsForward_command (char *, int);
109static void _tuiScrollRegsBackward_command (char *, int);
c906108c
SS
110
111
112
113/*****************************************
114** PUBLIC FUNCTIONS **
115******************************************/
116
117/*
c5aa993b
JM
118 ** tuiLastRegsLineNo()
119 ** Answer the number of the last line in the regs display.
120 ** If there are no registers (-1) is returned.
121 */
c906108c 122int
c906108c 123tuiLastRegsLineNo (void)
c906108c
SS
124{
125 register int numLines = (-1);
126
127 if (dataWin->detail.dataDisplayInfo.regsContentCount > 0)
128 {
129 numLines = (dataWin->detail.dataDisplayInfo.regsContentCount /
130 dataWin->detail.dataDisplayInfo.regsColumnCount);
131 if (dataWin->detail.dataDisplayInfo.regsContentCount %
132 dataWin->detail.dataDisplayInfo.regsColumnCount)
133 numLines++;
134 }
135 return numLines;
136} /* tuiLastRegsLineNo */
137
138
139/*
c5aa993b
JM
140 ** tuiLineFromRegElementNo()
141 ** Answer the line number that the register element at elementNo is
142 ** on. If elementNo is greater than the number of register elements
143 ** there are, -1 is returned.
144 */
c906108c 145int
eca6576c 146tuiLineFromRegElementNo (int elementNo)
c906108c
SS
147{
148 if (elementNo < dataWin->detail.dataDisplayInfo.regsContentCount)
149 {
150 int i, line = (-1);
151
152 i = 1;
153 while (line == (-1))
154 {
155 if (elementNo <
156 (dataWin->detail.dataDisplayInfo.regsColumnCount * i))
157 line = i - 1;
158 else
159 i++;
160 }
161
162 return line;
163 }
164 else
165 return (-1);
166} /* tuiLineFromRegElementNo */
167
168
169/*
c5aa993b
JM
170 ** tuiFirstRegElementNoInLine()
171 ** Answer the index of the first element in lineNo. If lineNo is
172 ** past the register area (-1) is returned.
173 */
c906108c 174int
eca6576c 175tuiFirstRegElementNoInLine (int lineNo)
c906108c
SS
176{
177 if ((lineNo * dataWin->detail.dataDisplayInfo.regsColumnCount)
178 <= dataWin->detail.dataDisplayInfo.regsContentCount)
179 return ((lineNo + 1) *
180 dataWin->detail.dataDisplayInfo.regsColumnCount) -
181 dataWin->detail.dataDisplayInfo.regsColumnCount;
182 else
183 return (-1);
184} /* tuiFirstRegElementNoInLine */
185
186
187/*
c5aa993b
JM
188 ** tuiLastRegElementNoInLine()
189 ** Answer the index of the last element in lineNo. If lineNo is past
190 ** the register area (-1) is returned.
191 */
c906108c 192int
eca6576c 193tuiLastRegElementNoInLine (int lineNo)
c906108c
SS
194{
195 if ((lineNo * dataWin->detail.dataDisplayInfo.regsColumnCount) <=
196 dataWin->detail.dataDisplayInfo.regsContentCount)
197 return ((lineNo + 1) *
198 dataWin->detail.dataDisplayInfo.regsColumnCount) - 1;
199 else
200 return (-1);
201} /* tuiLastRegElementNoInLine */
202
203
204/*
c5aa993b
JM
205 ** tuiCalculateRegsColumnCount
206 ** Calculate the number of columns that should be used to display
207 ** the registers.
208 */
c906108c 209int
eca6576c 210tuiCalculateRegsColumnCount (TuiRegisterDisplayType dpyType)
c906108c
SS
211{
212 int colCount, colWidth;
213
214 if (IS_64BIT || dpyType == TUI_DFLOAT_REGS)
215 colWidth = DOUBLE_FLOAT_VALUE_WIDTH + DOUBLE_FLOAT_LABEL_WIDTH;
216 else
217 {
218 if (dpyType == TUI_SFLOAT_REGS)
219 colWidth = SINGLE_FLOAT_VALUE_WIDTH + SINGLE_FLOAT_LABEL_WIDTH;
220 else
221 colWidth = SINGLE_VALUE_WIDTH + SINGLE_LABEL_WIDTH;
222 }
223 colCount = (dataWin->generic.width - 2) / colWidth;
224
225 return colCount;
226} /* tuiCalulateRegsColumnCount */
227
228
229/*
c5aa993b
JM
230 ** tuiShowRegisters().
231 ** Show the registers int the data window as indicated by dpyType.
232 ** If there is any other registers being displayed, then they are
233 ** cleared. What registers are displayed is dependent upon dpyType.
234 */
c906108c 235void
eca6576c 236tuiShowRegisters (TuiRegisterDisplayType dpyType)
c906108c
SS
237{
238 TuiStatus ret = TUI_FAILURE;
239 int refreshValuesOnly = FALSE;
240
241 /* Say that registers should be displayed, even if there is a problem */
242 dataWin->detail.dataDisplayInfo.displayRegs = TRUE;
243
244 if (target_has_registers)
245 {
246 refreshValuesOnly =
247 (dpyType == dataWin->detail.dataDisplayInfo.regsDisplayType);
248 switch (dpyType)
249 {
250 case TUI_GENERAL_REGS:
251 ret = _tuiSetGeneralRegsContent (refreshValuesOnly);
252 break;
253 case TUI_SFLOAT_REGS:
254 case TUI_DFLOAT_REGS:
255 ret = _tuiSetFloatRegsContent (dpyType, refreshValuesOnly);
256 break;
257
258/* could ifdef out */
259
260 case TUI_SPECIAL_REGS:
261 ret = _tuiSetSpecialRegsContent (refreshValuesOnly);
262 break;
263 case TUI_GENERAL_AND_SPECIAL_REGS:
264 ret = _tuiSetGeneralAndSpecialRegsContent (refreshValuesOnly);
265 break;
266
267/* end of potential if def */
268
269 default:
270 break;
271 }
272 }
273 if (ret == TUI_FAILURE)
274 {
275 dataWin->detail.dataDisplayInfo.regsDisplayType = TUI_UNDEFINED_REGS;
276 tuiEraseDataContent (NO_REGS_STRING);
277 }
278 else
279 {
280 int i;
281
282 /* Clear all notation of changed values */
283 for (i = 0; (i < dataWin->detail.dataDisplayInfo.regsContentCount); i++)
284 {
285 TuiGenWinInfoPtr dataItemWin;
286
287 dataItemWin = &dataWin->detail.dataDisplayInfo.
288 regsContent[i]->whichElement.dataWindow;
289 (&((TuiWinElementPtr)
290 dataItemWin->content[0])->whichElement.data)->highlight = FALSE;
291 }
292 dataWin->detail.dataDisplayInfo.regsDisplayType = dpyType;
293 tuiDisplayAllData ();
294 }
295 (tuiLayoutDef ())->regsDisplayType = dpyType;
296
297 return;
298} /* tuiShowRegisters */
299
300
301/*
c5aa993b
JM
302 ** tuiDisplayRegistersFrom().
303 ** Function to display the registers in the content from
304 ** 'startElementNo' until the end of the register content or the
305 ** end of the display height. No checking for displaying past
306 ** the end of the registers is done here.
307 */
c906108c 308void
eca6576c 309tuiDisplayRegistersFrom (int startElementNo)
c906108c
SS
310{
311 if (dataWin->detail.dataDisplayInfo.regsContent != (TuiWinContent) NULL &&
312 dataWin->detail.dataDisplayInfo.regsContentCount > 0)
313 {
314 register int i = startElementNo;
bc77de56 315 int j, valueCharsWide, itemWinWidth, curY, labelWidth;
c906108c
SS
316 enum precision_type precision;
317
318 precision = (dataWin->detail.dataDisplayInfo.regsDisplayType
319 == TUI_DFLOAT_REGS) ?
320 double_precision : unspecified_precision;
321 if (IS_64BIT ||
322 dataWin->detail.dataDisplayInfo.regsDisplayType == TUI_DFLOAT_REGS)
323 {
324 valueCharsWide = DOUBLE_FLOAT_VALUE_WIDTH;
325 labelWidth = DOUBLE_FLOAT_LABEL_WIDTH;
326 }
327 else
328 {
329 if (dataWin->detail.dataDisplayInfo.regsDisplayType ==
330 TUI_SFLOAT_REGS)
331 {
332 valueCharsWide = SINGLE_FLOAT_VALUE_WIDTH;
333 labelWidth = SINGLE_FLOAT_LABEL_WIDTH;
334 }
335 else
336 {
337 valueCharsWide = SINGLE_VALUE_WIDTH;
338 labelWidth = SINGLE_LABEL_WIDTH;
339 }
340 }
341 itemWinWidth = valueCharsWide + labelWidth;
342 /*
c5aa993b
JM
343 ** Now create each data "sub" window, and write the display into it.
344 */
c906108c
SS
345 curY = 1;
346 while (i < dataWin->detail.dataDisplayInfo.regsContentCount &&
347 curY <= dataWin->generic.viewportHeight)
348 {
349 for (j = 0;
350 (j < dataWin->detail.dataDisplayInfo.regsColumnCount &&
351 i < dataWin->detail.dataDisplayInfo.regsContentCount); j++)
352 {
353 TuiGenWinInfoPtr dataItemWin;
354 TuiDataElementPtr dataElementPtr;
355
c5aa993b 356 /* create the window if necessary */
c906108c
SS
357 dataItemWin = &dataWin->detail.dataDisplayInfo.
358 regsContent[i]->whichElement.dataWindow;
359 dataElementPtr = &((TuiWinElementPtr)
360 dataItemWin->content[0])->whichElement.data;
361 if (dataItemWin->handle == (WINDOW *) NULL)
362 {
363 dataItemWin->height = 1;
364 dataItemWin->width = (precision == double_precision) ?
365 itemWinWidth + 2 : itemWinWidth + 1;
366 dataItemWin->origin.x = (itemWinWidth * j) + 1;
367 dataItemWin->origin.y = curY;
368 makeWindow (dataItemWin, DONT_BOX_WINDOW);
c46cc7df 369 scrollok (dataItemWin->handle, FALSE);
c906108c 370 }
fea14702
SC
371 touchwin (dataItemWin->handle);
372
c906108c 373 /*
c5aa993b
JM
374 ** Get the printable representation of the register
375 ** and display it
376 */
c906108c
SS
377 _tuiDisplayRegister (
378 dataElementPtr->itemNo, dataItemWin, precision);
379 i++; /* next register */
380 }
381 curY++; /* next row; */
382 }
383 }
384
385 return;
386} /* tuiDisplayRegistersFrom */
387
388
389/*
c5aa993b
JM
390 ** tuiDisplayRegElementAtLine().
391 ** Function to display the registers in the content from
392 ** 'startElementNo' on 'startLineNo' until the end of the
393 ** register content or the end of the display height.
394 ** This function checks that we won't display off the end
395 ** of the register display.
396 */
c906108c 397void
eca6576c 398tuiDisplayRegElementAtLine (int startElementNo, int startLineNo)
c906108c
SS
399{
400 if (dataWin->detail.dataDisplayInfo.regsContent != (TuiWinContent) NULL &&
401 dataWin->detail.dataDisplayInfo.regsContentCount > 0)
402 {
403 register int elementNo = startElementNo;
404
405 if (startElementNo != 0 && startLineNo != 0)
406 {
407 register int lastLineNo, firstLineOnLastPage;
408
409 lastLineNo = tuiLastRegsLineNo ();
410 firstLineOnLastPage = lastLineNo - (dataWin->generic.height - 2);
411 if (firstLineOnLastPage < 0)
412 firstLineOnLastPage = 0;
413 /*
c5aa993b
JM
414 ** If there is no other data displayed except registers,
415 ** and the elementNo causes us to scroll past the end of the
416 ** registers, adjust what element to really start the display at.
417 */
c906108c
SS
418 if (dataWin->detail.dataDisplayInfo.dataContentCount <= 0 &&
419 startLineNo > firstLineOnLastPage)
420 elementNo = tuiFirstRegElementNoInLine (firstLineOnLastPage);
421 }
422 tuiDisplayRegistersFrom (elementNo);
423 }
424
425 return;
426} /* tuiDisplayRegElementAtLine */
427
428
429
430/*
c5aa993b
JM
431 ** tuiDisplayRegistersFromLine().
432 ** Function to display the registers starting at line lineNo in
433 ** the data window. Answers the line number that the display
434 ** actually started from. If nothing is displayed (-1) is returned.
435 */
c906108c 436int
eca6576c 437tuiDisplayRegistersFromLine (int lineNo, int forceDisplay)
c906108c 438{
c906108c
SS
439 if (dataWin->detail.dataDisplayInfo.regsContentCount > 0)
440 {
441 int line, elementNo;
442
443 if (lineNo < 0)
444 line = 0;
445 else if (forceDisplay)
446 { /*
c5aa993b
JM
447 ** If we must display regs (forceDisplay is true), then make
448 ** sure that we don't display off the end of the registers.
449 */
c906108c
SS
450 if (lineNo >= tuiLastRegsLineNo ())
451 {
452 if ((line = tuiLineFromRegElementNo (
453 dataWin->detail.dataDisplayInfo.regsContentCount - 1)) < 0)
454 line = 0;
455 }
456 else
457 line = lineNo;
458 }
459 else
460 line = lineNo;
461
462 elementNo = tuiFirstRegElementNoInLine (line);
463 if (elementNo < dataWin->detail.dataDisplayInfo.regsContentCount)
464 tuiDisplayRegElementAtLine (elementNo, line);
465 else
466 line = (-1);
467
468 return line;
469 }
470
471 return (-1); /* nothing was displayed */
472} /* tuiDisplayRegistersFromLine */
473
474
475/*
c5aa993b
JM
476 ** tuiCheckRegisterValues()
477 ** This function check all displayed registers for changes in
478 ** values, given a particular frame. If the values have changed,
479 ** they are updated with the new value and highlighted.
480 */
c906108c 481void
eca6576c 482tuiCheckRegisterValues (struct frame_info *frame)
c906108c
SS
483{
484 if (m_winPtrNotNull (dataWin) && dataWin->generic.isVisible)
485 {
486 if (dataWin->detail.dataDisplayInfo.regsContentCount <= 0 &&
487 dataWin->detail.dataDisplayInfo.displayRegs)
488 tuiShowRegisters ((tuiLayoutDef ())->regsDisplayType);
489 else
490 {
491 int i, j;
492 char rawBuf[MAX_REGISTER_RAW_SIZE];
493
494 for (i = 0;
495 (i < dataWin->detail.dataDisplayInfo.regsContentCount); i++)
496 {
497 TuiDataElementPtr dataElementPtr;
498 TuiGenWinInfoPtr dataItemWinPtr;
499 int wasHilighted;
500
501 dataItemWinPtr = &dataWin->detail.dataDisplayInfo.
502 regsContent[i]->whichElement.dataWindow;
503 dataElementPtr = &((TuiWinElementPtr)
504 dataItemWinPtr->content[0])->whichElement.data;
505 wasHilighted = dataElementPtr->highlight;
506 dataElementPtr->highlight =
507 _tuiRegValueHasChanged (dataElementPtr, frame, &rawBuf[0]);
508 if (dataElementPtr->highlight)
509 {
c46cc7df
SC
510 int size;
511
512 size = REGISTER_RAW_SIZE (dataElementPtr->itemNo);
513 for (j = 0; j < size; j++)
c906108c
SS
514 ((char *) dataElementPtr->value)[j] = rawBuf[j];
515 _tuiDisplayRegister (
516 dataElementPtr->itemNo,
517 dataItemWinPtr,
518 ((dataWin->detail.dataDisplayInfo.regsDisplayType ==
519 TUI_DFLOAT_REGS) ?
520 double_precision : unspecified_precision));
521 }
522 else if (wasHilighted)
523 {
524 dataElementPtr->highlight = FALSE;
525 _tuiDisplayRegister (
526 dataElementPtr->itemNo,
527 dataItemWinPtr,
528 ((dataWin->detail.dataDisplayInfo.regsDisplayType ==
529 TUI_DFLOAT_REGS) ?
530 double_precision : unspecified_precision));
531 }
532 }
533 }
534 }
535 return;
536} /* tuiCheckRegisterValues */
537
538
539/*
c5aa993b
JM
540 ** tuiToggleFloatRegs().
541 */
c906108c 542void
c906108c 543tuiToggleFloatRegs (void)
c906108c
SS
544{
545 TuiLayoutDefPtr layoutDef = tuiLayoutDef ();
546
547 if (layoutDef->floatRegsDisplayType == TUI_SFLOAT_REGS)
548 layoutDef->floatRegsDisplayType = TUI_DFLOAT_REGS;
549 else
550 layoutDef->floatRegsDisplayType = TUI_SFLOAT_REGS;
551
552 if (m_winPtrNotNull (dataWin) && dataWin->generic.isVisible &&
553 (dataWin->detail.dataDisplayInfo.regsDisplayType == TUI_SFLOAT_REGS ||
554 dataWin->detail.dataDisplayInfo.regsDisplayType == TUI_DFLOAT_REGS))
555 tuiShowRegisters (layoutDef->floatRegsDisplayType);
556
557 return;
558} /* tuiToggleFloatRegs */
559
560
561void
fba45db2 562_initialize_tuiRegs (void)
c906108c 563{
41783295 564 if (xdb_commands)
c906108c
SS
565 {
566 add_com ("fr", class_tui, _tuiShowFloat_command,
567 "Display only floating point registers\n");
568 add_com ("gr", class_tui, _tuiShowGeneral_command,
569 "Display only general registers\n");
570 add_com ("sr", class_tui, _tuiShowSpecial_command,
571 "Display only special registers\n");
572 add_com ("+r", class_tui, _tuiScrollRegsForward_command,
573 "Scroll the registers window forward\n");
574 add_com ("-r", class_tui, _tuiScrollRegsBackward_command,
575 "Scroll the register window backward\n");
576 add_com ("tf", class_tui, _tuiToggleFloatRegs_command,
577 "Toggle between single and double precision floating point registers.\n");
578 add_cmd (TUI_FLOAT_REGS_NAME_LOWER,
579 class_tui,
580 _tuiToggleFloatRegs_command,
581 "Toggle between single and double precision floating point \
582registers.\n",
583 &togglelist);
584 }
41783295 585}
c906108c
SS
586
587
588/*****************************************
589** STATIC LOCAL FUNCTIONS **
590******************************************/
591
592
593/*
c5aa993b
JM
594 ** _tuiRegisterName().
595 ** Return the register name.
596 */
bc77de56 597static const char *
eca6576c 598_tuiRegisterName (int regNum)
c906108c 599{
c46cc7df
SC
600 return REGISTER_NAME (regNum);
601}
602extern int pagination_enabled;
c906108c 603
c46cc7df
SC
604static void
605tui_restore_gdbout (void *ui)
606{
607 ui_file_delete (gdb_stdout);
608 gdb_stdout = (struct ui_file*) ui;
609 pagination_enabled = 1;
610}
c906108c
SS
611
612/*
c5aa993b
JM
613 ** _tuiRegisterFormat
614 ** Function to format the register name and value into a buffer,
615 ** suitable for printing or display
616 */
c906108c 617static void
eca6576c
SC
618_tuiRegisterFormat (char *buf, int bufLen, int regNum,
619 TuiDataElementPtr dataElement,
620 enum precision_type precision)
c906108c 621{
d9fcf2fb 622 struct ui_file *stream;
c46cc7df 623 struct ui_file *old_stdout;
bc77de56 624 const char *name;
c46cc7df
SC
625 struct cleanup *cleanups;
626 char *p;
fea14702 627 int pos;
c906108c 628
c46cc7df
SC
629 name = REGISTER_NAME (regNum);
630 if (name == 0)
631 {
632 strcpy (buf, "");
633 return;
634 }
635
636 pagination_enabled = 0;
637 old_stdout = gdb_stdout;
11cf8741 638 stream = tui_sfileopen (bufLen);
c46cc7df
SC
639 gdb_stdout = stream;
640 cleanups = make_cleanup (tui_restore_gdbout, (void*) old_stdout);
6e7f8b9c 641 gdbarch_print_registers_info (current_gdbarch, stream, deprecated_selected_frame,
ad0fd2c8 642 regNum, 1);
c906108c 643
c46cc7df 644 /* Save formatted output in the buffer. */
fea14702
SC
645 p = tui_file_get_strbuf (stream);
646 pos = 0;
647 while (*p && *p == *name++ && bufLen)
648 {
649 *buf++ = *p++;
650 bufLen--;
651 pos++;
652 }
653 while (*p == ' ')
654 p++;
655 while (pos < 8 && bufLen)
656 {
657 *buf++ = ' ';
658 bufLen--;
659 pos++;
660 }
661 strncpy (buf, p, bufLen);
c46cc7df
SC
662
663 /* Remove the possible \n. */
664 p = strchr (buf, '\n');
665 if (p)
666 *p = 0;
667
668 do_cleanups (cleanups);
669}
c906108c
SS
670
671
672#define NUM_GENERAL_REGS 32
673/*
c5aa993b
JM
674 ** _tuiSetGeneralRegsContent().
675 ** Set the content of the data window to consist of the general registers.
676 */
c906108c 677static TuiStatus
eca6576c 678_tuiSetGeneralRegsContent (int refreshValuesOnly)
c906108c
SS
679{
680 return (_tuiSetRegsContent (0,
681 NUM_GENERAL_REGS - 1,
6e7f8b9c 682 deprecated_selected_frame,
c906108c
SS
683 TUI_GENERAL_REGS,
684 refreshValuesOnly));
685
686} /* _tuiSetGeneralRegsContent */
687
688
c46cc7df
SC
689#ifndef PCOQ_HEAD_REGNUM
690#define START_SPECIAL_REGS 0
691#else
c906108c 692#define START_SPECIAL_REGS PCOQ_HEAD_REGNUM
c46cc7df
SC
693#endif
694
c906108c 695/*
c5aa993b
JM
696 ** _tuiSetSpecialRegsContent().
697 ** Set the content of the data window to consist of the special registers.
698 */
c906108c 699static TuiStatus
eca6576c 700_tuiSetSpecialRegsContent (int refreshValuesOnly)
c906108c
SS
701{
702 TuiStatus ret = TUI_FAILURE;
bc77de56 703 int endRegNum;
c906108c
SS
704
705 endRegNum = FP0_REGNUM - 1;
c906108c
SS
706 ret = _tuiSetRegsContent (START_SPECIAL_REGS,
707 endRegNum,
6e7f8b9c 708 deprecated_selected_frame,
c906108c
SS
709 TUI_SPECIAL_REGS,
710 refreshValuesOnly);
711
712 return ret;
713} /* _tuiSetSpecialRegsContent */
714
715
716/*
c5aa993b
JM
717 ** _tuiSetGeneralAndSpecialRegsContent().
718 ** Set the content of the data window to consist of the special registers.
719 */
c906108c 720static TuiStatus
eca6576c 721_tuiSetGeneralAndSpecialRegsContent (int refreshValuesOnly)
c906108c
SS
722{
723 TuiStatus ret = TUI_FAILURE;
bc77de56 724 int endRegNum = (-1);
c906108c
SS
725
726 endRegNum = FP0_REGNUM - 1;
c906108c 727 ret = _tuiSetRegsContent (
6e7f8b9c 728 0, endRegNum, deprecated_selected_frame, TUI_SPECIAL_REGS, refreshValuesOnly);
c906108c
SS
729
730 return ret;
731} /* _tuiSetGeneralAndSpecialRegsContent */
732
733/*
c5aa993b
JM
734 ** _tuiSetFloatRegsContent().
735 ** Set the content of the data window to consist of the float registers.
736 */
c906108c 737static TuiStatus
c46cc7df 738_tuiSetFloatRegsContent (TuiRegisterDisplayType dpyType, int refreshValuesOnly)
c906108c
SS
739{
740 TuiStatus ret = TUI_FAILURE;
bc77de56 741 int startRegNum;
c906108c
SS
742
743 startRegNum = FP0_REGNUM;
c906108c 744 ret = _tuiSetRegsContent (startRegNum,
a728f042 745 NUM_REGS - 1,
6e7f8b9c 746 deprecated_selected_frame,
c906108c
SS
747 dpyType,
748 refreshValuesOnly);
749
750 return ret;
751} /* _tuiSetFloatRegsContent */
752
753
754/*
c5aa993b
JM
755 ** _tuiRegValueHasChanged().
756 ** Answer TRUE if the register's value has changed, FALSE otherwise.
757 ** If TRUE, newValue is filled in with the new value.
758 */
c906108c 759static int
eca6576c
SC
760_tuiRegValueHasChanged (TuiDataElementPtr dataElement,
761 struct frame_info *frame,
762 char *newValue)
c906108c
SS
763{
764 int hasChanged = FALSE;
765
766 if (dataElement->itemNo != UNDEFINED_ITEM &&
767 _tuiRegisterName (dataElement->itemNo) != (char *) NULL)
768 {
769 char rawBuf[MAX_REGISTER_RAW_SIZE];
770 int i;
771
772 if (_tuiGetRegisterRawValue (
773 dataElement->itemNo, rawBuf, frame) == TUI_SUCCESS)
774 {
c46cc7df
SC
775 int size = REGISTER_RAW_SIZE (dataElement->itemNo);
776
777 for (i = 0; (i < size && !hasChanged); i++)
c906108c
SS
778 hasChanged = (((char *) dataElement->value)[i] != rawBuf[i]);
779 if (hasChanged && newValue != (char *) NULL)
780 {
c46cc7df 781 for (i = 0; i < size; i++)
c906108c
SS
782 newValue[i] = rawBuf[i];
783 }
784 }
785 }
786 return hasChanged;
787} /* _tuiRegValueHasChanged */
788
789
790
791/*
c5aa993b
JM
792 ** _tuiGetRegisterRawValue().
793 ** Get the register raw value. The raw value is returned in regValue.
794 */
c906108c 795static TuiStatus
c46cc7df 796_tuiGetRegisterRawValue (int regNum, char *regValue, struct frame_info *frame)
c906108c
SS
797{
798 TuiStatus ret = TUI_FAILURE;
799
800 if (target_has_registers)
801 {
c46cc7df
SC
802 int opt;
803
804 get_saved_register (regValue, &opt, (CORE_ADDR*) NULL, frame,
805 regNum, (enum lval_type*) NULL);
806 if (register_cached (regNum) >= 0)
807 ret = TUI_SUCCESS;
c906108c 808 }
c906108c
SS
809 return ret;
810} /* _tuiGetRegisterRawValue */
811
812
813
814/*
c5aa993b
JM
815 ** _tuiSetRegisterElement().
816 ** Function to initialize a data element with the input and
817 ** the register value.
818 */
c906108c 819static void
eca6576c
SC
820_tuiSetRegisterElement (int regNum, struct frame_info *frame,
821 TuiDataElementPtr dataElement,
822 int refreshValueOnly)
c906108c
SS
823{
824 if (dataElement != (TuiDataElementPtr) NULL)
825 {
826 if (!refreshValueOnly)
827 {
828 dataElement->itemNo = regNum;
829 dataElement->name = _tuiRegisterName (regNum);
830 dataElement->highlight = FALSE;
831 }
832 if (dataElement->value == (Opaque) NULL)
833 dataElement->value = (Opaque) xmalloc (MAX_REGISTER_RAW_SIZE);
834 if (dataElement->value != (Opaque) NULL)
835 _tuiGetRegisterRawValue (regNum, dataElement->value, frame);
836 }
837
838 return;
839} /* _tuiSetRegisterElement */
840
841
842/*
c5aa993b
JM
843 ** _tuiSetRegsContent().
844 ** Set the content of the data window to consist of the registers
845 ** numbered from startRegNum to endRegNum. Note that if
846 ** refreshValuesOnly is TRUE, startRegNum and endRegNum are ignored.
847 */
c906108c 848static TuiStatus
eca6576c
SC
849_tuiSetRegsContent (int startRegNum, int endRegNum,
850 struct frame_info *frame,
851 TuiRegisterDisplayType dpyType,
852 int refreshValuesOnly)
c906108c
SS
853{
854 TuiStatus ret = TUI_FAILURE;
855 int numRegs = endRegNum - startRegNum + 1;
856 int allocatedHere = FALSE;
857
858 if (dataWin->detail.dataDisplayInfo.regsContentCount > 0 &&
859 !refreshValuesOnly)
860 {
861 freeDataContent (dataWin->detail.dataDisplayInfo.regsContent,
862 dataWin->detail.dataDisplayInfo.regsContentCount);
863 dataWin->detail.dataDisplayInfo.regsContentCount = 0;
864 }
865 if (dataWin->detail.dataDisplayInfo.regsContentCount <= 0)
866 {
867 dataWin->detail.dataDisplayInfo.regsContent =
868 allocContent (numRegs, DATA_WIN);
869 allocatedHere = TRUE;
870 }
871
872 if (dataWin->detail.dataDisplayInfo.regsContent != (TuiWinContent) NULL)
873 {
874 int i;
875
876 if (!refreshValuesOnly || allocatedHere)
877 {
878 dataWin->generic.content = (OpaquePtr) NULL;
879 dataWin->generic.contentSize = 0;
880 addContentElements (&dataWin->generic, numRegs);
881 dataWin->detail.dataDisplayInfo.regsContent =
882 (TuiWinContent) dataWin->generic.content;
883 dataWin->detail.dataDisplayInfo.regsContentCount = numRegs;
884 }
885 /*
c5aa993b
JM
886 ** Now set the register names and values
887 */
c906108c
SS
888 for (i = startRegNum; (i <= endRegNum); i++)
889 {
890 TuiGenWinInfoPtr dataItemWin;
891
892 dataItemWin = &dataWin->detail.dataDisplayInfo.
893 regsContent[i - startRegNum]->whichElement.dataWindow;
894 _tuiSetRegisterElement (
895 i,
896 frame,
897 &((TuiWinElementPtr) dataItemWin->content[0])->whichElement.data,
898 !allocatedHere && refreshValuesOnly);
899 }
900 dataWin->detail.dataDisplayInfo.regsColumnCount =
901 tuiCalculateRegsColumnCount (dpyType);
902#ifdef LATER
903 if (dataWin->detail.dataDisplayInfo.dataContentCount > 0)
904 {
905 /* delete all the windows? */
906 /* realloc content equal to dataContentCount + regsContentCount */
907 /* append dataWin->detail.dataDisplayInfo.dataContent to content */
908 }
909#endif
910 dataWin->generic.contentSize =
911 dataWin->detail.dataDisplayInfo.regsContentCount +
912 dataWin->detail.dataDisplayInfo.dataContentCount;
913 ret = TUI_SUCCESS;
914 }
915
916 return ret;
917} /* _tuiSetRegsContent */
918
919
920/*
c5aa993b
JM
921 ** _tuiDisplayRegister().
922 ** Function to display a register in a window. If hilite is TRUE,
923 ** than the value will be displayed in reverse video
924 */
c906108c 925static void
eca6576c
SC
926_tuiDisplayRegister (int regNum,
927 TuiGenWinInfoPtr winInfo, /* the data item window */
928 enum precision_type precision)
c906108c
SS
929{
930 if (winInfo->handle != (WINDOW *) NULL)
931 {
c46cc7df
SC
932 int i;
933 char buf[40];
c906108c
SS
934 int valueCharsWide, labelWidth;
935 TuiDataElementPtr dataElementPtr = &((TuiWinContent)
936 winInfo->content)[0]->whichElement.data;
937
938 if (IS_64BIT ||
939 dataWin->detail.dataDisplayInfo.regsDisplayType == TUI_DFLOAT_REGS)
940 {
941 valueCharsWide = DOUBLE_FLOAT_VALUE_WIDTH;
942 labelWidth = DOUBLE_FLOAT_LABEL_WIDTH;
943 }
944 else
945 {
946 if (dataWin->detail.dataDisplayInfo.regsDisplayType ==
947 TUI_SFLOAT_REGS)
948 {
949 valueCharsWide = SINGLE_FLOAT_VALUE_WIDTH;
950 labelWidth = SINGLE_FLOAT_LABEL_WIDTH;
951 }
952 else
953 {
954 valueCharsWide = SINGLE_VALUE_WIDTH;
955 labelWidth = SINGLE_LABEL_WIDTH;
956 }
957 }
958
959 buf[0] = (char) 0;
960 _tuiRegisterFormat (buf,
961 valueCharsWide + labelWidth,
962 regNum,
963 dataElementPtr,
964 precision);
c46cc7df 965
c906108c
SS
966 if (dataElementPtr->highlight)
967 wstandout (winInfo->handle);
968
c46cc7df
SC
969 wmove (winInfo->handle, 0, 0);
970 for (i = 1; i < winInfo->width; i++)
971 waddch (winInfo->handle, ' ');
c906108c
SS
972 wmove (winInfo->handle, 0, 0);
973 waddstr (winInfo->handle, buf);
974
975 if (dataElementPtr->highlight)
976 wstandend (winInfo->handle);
977 tuiRefreshWin (winInfo);
978 }
979 return;
980} /* _tuiDisplayRegister */
981
982
983static void
e8b915dc 984_tui_vShowRegisters_commandSupport (TuiRegisterDisplayType dpyType)
c906108c 985{
c906108c
SS
986
987 if (m_winPtrNotNull (dataWin) && dataWin->generic.isVisible)
988 { /* Data window already displayed, show the registers */
989 if (dataWin->detail.dataDisplayInfo.regsDisplayType != dpyType)
990 tuiShowRegisters (dpyType);
991 }
992 else
993 (tuiLayoutDef ())->regsDisplayType = dpyType;
994
995 return;
996} /* _tui_vShowRegisters_commandSupport */
997
998
999static void
eca6576c 1000_tuiShowFloat_command (char *arg, int fromTTY)
c906108c
SS
1001{
1002 if (m_winPtrIsNull (dataWin) || !dataWin->generic.isVisible ||
1003 (dataWin->detail.dataDisplayInfo.regsDisplayType != TUI_SFLOAT_REGS &&
1004 dataWin->detail.dataDisplayInfo.regsDisplayType != TUI_DFLOAT_REGS))
e8b915dc 1005 _tui_vShowRegisters_commandSupport ((tuiLayoutDef ())->floatRegsDisplayType);
c906108c
SS
1006
1007 return;
1008} /* _tuiShowFloat_command */
1009
1010
1011static void
eca6576c 1012_tuiShowGeneral_command (char *arg, int fromTTY)
c906108c 1013{
e8b915dc
SC
1014 _tui_vShowRegisters_commandSupport (TUI_GENERAL_REGS);
1015}
c906108c
SS
1016
1017
1018static void
eca6576c 1019_tuiShowSpecial_command (char *arg, int fromTTY)
c906108c 1020{
e8b915dc
SC
1021 _tui_vShowRegisters_commandSupport (TUI_SPECIAL_REGS);
1022}
c906108c
SS
1023
1024
1025static void
eca6576c 1026_tuiToggleFloatRegs_command (char *arg, int fromTTY)
c906108c
SS
1027{
1028 if (m_winPtrNotNull (dataWin) && dataWin->generic.isVisible)
e8b915dc 1029 tuiToggleFloatRegs ();
c906108c
SS
1030 else
1031 {
1032 TuiLayoutDefPtr layoutDef = tuiLayoutDef ();
1033
1034 if (layoutDef->floatRegsDisplayType == TUI_SFLOAT_REGS)
1035 layoutDef->floatRegsDisplayType = TUI_DFLOAT_REGS;
1036 else
1037 layoutDef->floatRegsDisplayType = TUI_SFLOAT_REGS;
1038 }
1039
1040
1041 return;
1042} /* _tuiToggleFloatRegs_command */
1043
1044
1045static void
eca6576c 1046_tuiScrollRegsForward_command (char *arg, int fromTTY)
c906108c 1047{
e8b915dc
SC
1048 tui_scroll (FORWARD_SCROLL, dataWin, 1);
1049}
c906108c
SS
1050
1051
1052static void
eca6576c 1053_tuiScrollRegsBackward_command (char *arg, int fromTTY)
c906108c 1054{
e8b915dc
SC
1055 tui_scroll (BACKWARD_SCROLL, dataWin, 1);
1056}
This page took 0.429834 seconds and 4 git commands to generate.