2001-07-17 Elena Zannoni <ezannoni@redhat.com>
[deliverable/binutils-gdb.git] / gdb / tui / tui.c
CommitLineData
f377b406
SC
1/* General functions for the WDB TUI.
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
SS
21
22#include <stdio.h>
23#include <stdlib.h>
24#include <ctype.h>
25#include <malloc.h>
c906108c
SS
26#ifdef HAVE_TERM_H
27#include <term.h>
28#endif
29#include <signal.h>
30#include <fcntl.h>
31#include <termio.h>
32#include <setjmp.h>
33#include "defs.h"
34#include "gdbcmd.h"
35#include "tui.h"
36#include "tuiData.h"
37#include "tuiLayout.h"
38#include "tuiIO.h"
39#include "tuiRegs.h"
40#include "tuiWin.h"
41
42/* The Solaris header files seem to provide no declaration for this at
43 all when __STDC__ is defined. This shouldn't conflict with
44 anything. */
45extern char *tgoto ();
46
47/***********************
48** Local Definitions
49************************/
50#define FILEDES 2
51/* Solaris <sys/termios.h> defines CTRL. */
52#ifndef CTRL
53#define CTRL(x) (x & ~0140)
54#endif
55#define CHK(val, dft) (val<=0 ? dft : val)
56
57#define TOGGLE_USAGE "Usage:toggle breakpoints"
58#define TUI_TOGGLE_USAGE "Usage:\ttoggle $fregs\n\ttoggle breakpoints"
59
60/*****************************
61** Local static forward decls
62******************************/
a14ed312
KB
63static void _tuiReset (void);
64static void _toggle_command (char *, int);
65static void _tui_vToggle_command (va_list);
66static Opaque _tui_vDo (TuiOpaqueFuncPtr, va_list);
c906108c
SS
67
68
69
70/***********************
71** Public Functions
72************************/
73
74/*
c5aa993b
JM
75 ** tuiInit().
76 */
c906108c 77void
c906108c 78tuiInit (char *argv0)
c906108c
SS
79{
80 extern void init_page_info ();
a14ed312 81extern void initialize_tui_files (void);
c906108c
SS
82
83 initialize_tui_files ();
84 initializeStaticData ();
85 initscr ();
86 refresh ();
87 setTermHeightTo (LINES);
88 setTermWidthTo (COLS);
89 tuiInitWindows ();
90 wrefresh (cmdWin->generic.handle);
91 init_page_info ();
92 /* Don't hook debugger output if doing command-window
93 * the XDB way. However, one thing we do want to do in
94 * XDB style is set up the scrolling region to be
95 * the bottom of the screen (tuiTermUnsetup()).
c5aa993b 96 */
c906108c 97 fputs_unfiltered_hook = NULL;
c906108c 98 rl_initialize (); /* need readline initialization to
c5aa993b
JM
99 * create termcap sequences
100 */
c906108c
SS
101 tuiTermUnsetup (1, cmdWin->detail.commandInfo.curch);
102
103 return;
104} /* tuiInit */
105
106
107/*
c5aa993b
JM
108 ** tuiInitWindows().
109 */
c906108c 110void
c906108c 111tuiInitWindows (void)
c906108c
SS
112{
113 TuiWinType type;
114
115 tuiSetLocatorContent (0);
116 showLayout (SRC_COMMAND);
117 keypad (cmdWin->generic.handle, TRUE);
118 echo ();
119 crmode ();
120 nl ();
121 tuiSetWinFocusTo (srcWin);
122
123 return;
124} /* tuiInitWindows */
125
126
127/*
c5aa993b
JM
128 ** tuiCleanUp().
129 ** Kill signal handler and cleanup termination method
130 */
c906108c 131void
c906108c 132tuiResetScreen (void)
c906108c
SS
133{
134 TuiWinType type = SRC_WIN;
135
136 keypad (cmdWin->generic.handle, FALSE);
137 for (; type < MAX_MAJOR_WINDOWS; type++)
138 {
139 if (m_winPtrNotNull (winList[type]) &&
140 winList[type]->generic.type != UNDEFINED_WIN &&
141 !winList[type]->generic.isVisible)
142 tuiDelWindow (winList[type]);
143 }
144 endwin ();
145 initscr ();
146 refresh ();
147 echo ();
148 crmode ();
149 nl ();
150
151 return;
152} /* tuiResetScreen */
153
154
155/*
c5aa993b
JM
156 ** tuiCleanUp().
157 ** Kill signal handler and cleanup termination method
158 */
c906108c 159void
c906108c 160tuiCleanUp (void)
c906108c
SS
161{
162 char *buffer;
163 extern char *term_cursor_move;
164
165 signal (SIGINT, SIG_IGN);
166 tuiTermSetup (0); /* Restore scrolling region to whole screen */
167 keypad (cmdWin->generic.handle, FALSE);
168 freeAllWindows ();
169 endwin ();
170 buffer = tgoto (term_cursor_move, 0, termHeight ());
171 tputs (buffer, 1, putchar);
172 _tuiReset ();
173
174 return;
175} /* tuiCleanUp */
176
177
178/*
c5aa993b
JM
179 ** tuiError().
180 */
c906108c 181void
eca6576c 182tuiError (char *string, int exitGdb)
c906108c
SS
183{
184 puts_unfiltered (string);
185 if (exitGdb)
186 {
187 tuiCleanUp ();
188 exit (-1);
189 }
190
191 return;
192} /* tuiError */
193
194
195/*
c5aa993b
JM
196 ** tui_vError()
197 ** tuiError with args in a va_list.
198 */
c906108c 199void
eca6576c 200tui_vError (va_list args)
c906108c
SS
201{
202 char *string;
203 int exitGdb;
204
205 string = va_arg (args, char *);
206 exitGdb = va_arg (args, int);
207
208 tuiError (string, exitGdb);
209
210 return;
211} /* tui_vError */
212
213
214/*
c5aa993b
JM
215 ** tuiFree()
216 ** Wrapper on top of free() to ensure that input address is greater than 0x0
217 */
c906108c 218void
eca6576c 219tuiFree (char *ptr)
c906108c
SS
220{
221 if (ptr != (char *) NULL)
222 {
b8c9b27d 223 xfree (ptr);
c906108c
SS
224 }
225
226 return;
227} /* tuiFree */
228
229
230/* tuiGetLowDisassemblyAddress().
c5aa993b
JM
231 ** Determine what the low address will be to display in the TUI's
232 ** disassembly window. This may or may not be the same as the
233 ** low address input.
234 */
c906108c 235Opaque
eca6576c 236tuiGetLowDisassemblyAddress (Opaque low, Opaque pc)
c906108c
SS
237{
238 int line;
239 Opaque newLow;
240
241 /*
c5aa993b
JM
242 ** Determine where to start the disassembly so that the pc is about in the
243 ** middle of the viewport.
244 */
c906108c
SS
245 for (line = 0, newLow = pc;
246 (newLow > low &&
247 line < (tuiDefaultWinViewportHeight (DISASSEM_WIN,
248 DISASSEM_COMMAND) / 2));)
249 {
250 bfd_byte buffer[4];
251
252 newLow -= sizeof (bfd_getb32 (buffer));
253 line++;
254 }
255
256 return newLow;
257} /* tuiGetLowDisassemblyAddress */
258
259
260/* tui_vGetLowDisassemblyAddress().
c5aa993b
JM
261 ** Determine what the low address will be to display in the TUI's
262 ** disassembly window with args in a va_list.
263 */
c906108c 264Opaque
eca6576c 265tui_vGetLowDisassemblyAddress (va_list args)
c906108c
SS
266{
267 int line;
268 Opaque newLow;
269 Opaque low;
270 Opaque pc;
271
272 low = va_arg (args, Opaque);
273 pc = va_arg (args, Opaque);
274
275 return (tuiGetLowDisassemblyAddress (low, pc));
276
277} /* tui_vGetLowDisassemblyAddress */
278
279
280/*
c5aa993b
JM
281 ** tuiDo().
282 ** General purpose function to execute a tui function. Transitions
283 ** between curses and the are handled here. This function is called
284 ** by non-tui gdb functions.
285 **
286 ** Errors are caught here.
287 ** If there is no error, the value returned by 'func' is returned.
288 ** If there is an error, then zero is returned.
289 **
290 ** Must not be called with immediate_quit in effect (bad things might
291 ** happen, say we got a signal in the middle of a memcpy to quit_return).
292 ** This is an OK restriction; with very few exceptions immediate_quit can
293 ** be replaced by judicious use of QUIT.
294 */
c906108c 295Opaque
eca6576c 296tuiDo (TuiOpaqueFuncPtr func, ...)
c906108c
SS
297{
298 extern int terminal_is_ours;
299
300 Opaque ret = (Opaque) NULL;
301
302 /* It is an error to be tuiDo'ing if we
303 * don't own the terminal.
c5aa993b 304 */
c906108c
SS
305 if (!terminal_is_ours)
306 return ret;
307
308 if (tui_version)
309 {
310 va_list args;
311
c906108c 312 va_start (args, func);
c906108c
SS
313 ret = _tui_vDo (func, args);
314 va_end (args);
315 }
316
317 return ret;
318} /* tuiDo */
319
320
321/*
c5aa993b
JM
322 ** tuiDoAndReturnToTop().
323 ** General purpose function to execute a tui function. Transitions
324 ** between curses and the are handled here. This function is called
325 ** by non-tui gdb functions who wish to reset gdb to the top level.
326 ** After the tuiDo is performed, a return to the top level occurs.
327 **
328 ** Errors are caught here.
329 ** If there is no error, the value returned by 'func' is returned.
330 ** If there is an error, then zero is returned.
331 **
332 ** Must not be called with immediate_quit in effect (bad things might
333 ** happen, say we got a signal in the middle of a memcpy to quit_return).
334 ** This is an OK restriction; with very few exceptions immediate_quit can
335 ** be replaced by judicious use of QUIT.
336 **
337 */
c906108c 338Opaque
eca6576c 339tuiDoAndReturnToTop (TuiOpaqueFuncPtr func, ...)
c906108c
SS
340{
341 extern int terminal_is_ours;
342
343 Opaque ret = (Opaque) NULL;
344
345 /* It is an error to be tuiDo'ing if we
346 * don't own the terminal.
c5aa993b 347 */
c906108c
SS
348 if (!terminal_is_ours)
349 return ret;
350
351 if (tui_version)
352 {
353 va_list args;
354
c906108c 355 va_start (args, func);
c906108c
SS
356 ret = _tui_vDo (func, args);
357
358 /* force a return to the top level */
359 return_to_top_level (RETURN_ERROR);
360 }
361
362 return ret;
363} /* tuiDoAndReturnToTop */
364
365
366void
eca6576c 367tui_vSelectSourceSymtab (va_list args)
c906108c
SS
368{
369 struct symtab *s = va_arg (args, struct symtab *);
370
371 select_source_symtab (s);
372 return;
373} /* tui_vSelectSourceSymtab */
374
375
376/*
c5aa993b
JM
377 ** _initialize_tui().
378 ** Function to initialize gdb commands, for tui window manipulation.
379 */
c906108c 380void
fba45db2 381_initialize_tui (void)
c906108c
SS
382{
383#if 0
384 if (tui_version)
385 {
386 add_com ("toggle", class_tui, _toggle_command,
387 "Toggle Terminal UI Features\n\
388Usage: Toggle $fregs\n\
389\tToggles between single and double precision floating point registers.\n");
390 }
391#endif
392 char *helpStr;
393
394 if (tui_version)
395 helpStr = "Toggle Specified Features\n\
396Usage:\ttoggle $fregs\n\ttoggle breakpoints";
397 else
398 helpStr = "Toggle Specified Features\nUsage:toggle breakpoints";
399 add_abbrev_prefix_cmd ("toggle",
400 class_tui,
401 _toggle_command,
402 helpStr,
403 &togglelist,
404 "toggle ",
405 1,
406 &cmdlist);
c5aa993b 407} /* _initialize_tui */
c906108c
SS
408
409
410/*
c5aa993b
JM
411 ** va_catch_errors().
412 ** General purpose function to execute a function, catching errors.
413 ** If there is no error, the value returned by 'func' is returned.
414 ** If there is error, then zero is returned.
415 ** Note that 'func' must take a variable argument list as well.
416 **
417 ** Must not be called with immediate_quit in effect (bad things might
418 ** happen, say we got a signal in the middle of a memcpy to quit_return).
419 ** This is an OK restriction; with very few exceptions immediate_quit can
420 ** be replaced by judicious use of QUIT.
421 */
c906108c 422Opaque
eca6576c 423va_catch_errors (TuiOpaqueFuncPtr func, va_list args)
c906108c
SS
424{
425 Opaque ret = (Opaque) NULL;
426
427 /*
c5aa993b
JM
428 ** We could have used catch_errors(), but it doesn't handle variable args.
429 ** Also, for the tui, we always want to catch all errors, so we don't
430 ** need to pass a mask, or an error string.
431 */
c906108c
SS
432 jmp_buf saved_error;
433 jmp_buf saved_quit;
434 jmp_buf tmp_jmp;
435 struct cleanup *saved_cleanup_chain;
436 char *saved_error_pre_print;
437 char *saved_quit_pre_print;
438 extern jmp_buf error_return;
439 extern jmp_buf quit_return;
440
441 saved_cleanup_chain = save_cleanups ();
442 saved_error_pre_print = error_pre_print;
443 saved_quit_pre_print = quit_pre_print;
444
445 memcpy ((char *) saved_error, (char *) error_return, sizeof (jmp_buf));
446 error_pre_print = "";
447 memcpy (saved_quit, quit_return, sizeof (jmp_buf));
448 quit_pre_print = "";
449
450 if (setjmp (tmp_jmp) == 0)
451 {
452 va_list argList = args;
453 memcpy (error_return, tmp_jmp, sizeof (jmp_buf));
454 memcpy (quit_return, tmp_jmp, sizeof (jmp_buf));
455 ret = func (argList);
456 }
457 restore_cleanups (saved_cleanup_chain);
458 memcpy (error_return, saved_error, sizeof (jmp_buf));
459 error_pre_print = saved_error_pre_print;
460 memcpy (quit_return, saved_quit, sizeof (jmp_buf));
461 quit_pre_print = saved_quit_pre_print;
462
463 return ret;
464}
465
466/*
c5aa993b
JM
467 ** vcatch_errors().
468 ** Catch errors occurring in tui or non tui function, handling
469 ** variable param lists. Note that 'func' must take a variable
470 ** argument list as well.
471 */
c906108c 472Opaque
eca6576c 473vcatch_errors (OpaqueFuncPtr func, ...)
c906108c
SS
474{
475 Opaque ret = (Opaque) NULL;
476 va_list args;
c906108c
SS
477 va_start (args, func);
478/*
c5aa993b
JM
479 va_arg(args, OpaqueFuncPtr);
480 */
c906108c
SS
481 ret = va_catch_errors (func, args);
482 va_end (args);
483
484 return ret;
485}
486
487
488void
eca6576c 489strcat_to_buf (char *buf, int buflen, char *itemToAdd)
c906108c
SS
490{
491 if (itemToAdd != (char *) NULL && buf != (char *) NULL)
492 {
493 if ((strlen (buf) + strlen (itemToAdd)) <= buflen)
494 strcat (buf, itemToAdd);
495 else
496 strncat (buf, itemToAdd, (buflen - strlen (buf)));
497 }
498
499 return;
500} /* strcat_to_buf */
501
502/* VARARGS */
503void
eca6576c 504strcat_to_buf_with_fmt (char *buf, int bufLen, char *format, ...)
c906108c
SS
505{
506 char *linebuffer;
507 struct cleanup *old_cleanups;
508 va_list args;
c906108c 509 va_start (args, format);
c906108c 510 vasprintf (&linebuffer, format, args);
b8c9b27d 511 old_cleanups = make_cleanup (xfree, linebuffer);
c906108c
SS
512 strcat_to_buf (buf, bufLen, linebuffer);
513 do_cleanups (old_cleanups);
514 va_end (args);
515}
516
517
518
519
520
521/***********************
522** Static Functions
523************************/
524
525
526/*
c5aa993b
JM
527 ** _tui_vDo().
528 ** General purpose function to execute a tui function. Transitions
529 ** between curses and the are handled here. This function is called
530 ** by non-tui gdb functions.
531 **
532 ** Errors are caught here.
533 ** If there is no error, the value returned by 'func' is returned.
534 ** If there is an error, then zero is returned.
535 **
536 ** Must not be called with immediate_quit in effect (bad things might
537 ** happen, say we got a signal in the middle of a memcpy to quit_return).
538 ** This is an OK restriction; with very few exceptions immediate_quit can
539 ** be replaced by judicious use of QUIT.
540 */
c906108c 541static Opaque
eca6576c 542_tui_vDo (TuiOpaqueFuncPtr func, va_list args)
c906108c
SS
543{
544 extern int terminal_is_ours;
545
546 Opaque ret = (Opaque) NULL;
547
548 /* It is an error to be tuiDo'ing if we
549 * don't own the terminal.
c5aa993b 550 */
c906108c
SS
551 if (!terminal_is_ours)
552 return ret;
553
554 if (tui_version)
555 {
556 /* If doing command window the "XDB way" (command window
557 * is unmanaged by curses...
c5aa993b 558 */
c906108c
SS
559 /* Set up terminal for TUI */
560 tuiTermSetup (1);
561
562 ret = va_catch_errors (func, args);
563
564 /* Set up terminal for command window */
565 tuiTermUnsetup (1, cmdWin->detail.commandInfo.curch);
566 }
567
568 return ret;
569} /* _tui_vDo */
570
571
572static void
eca6576c 573_toggle_command (char *arg, int fromTTY)
c906108c
SS
574{
575 printf_filtered ("Specify feature to toggle.\n%s\n",
576 (tui_version) ? TUI_TOGGLE_USAGE : TOGGLE_USAGE);
577/*
c5aa993b
JM
578 tuiDo((TuiOpaqueFuncPtr)_Toggle_command, arg, fromTTY);
579 */
c906108c
SS
580}
581
582/*
c5aa993b
JM
583 ** _tui_vToggle_command().
584 */
c906108c 585static void
eca6576c 586_tui_vToggle_command (va_list args)
c906108c
SS
587{
588 char *arg;
589 int fromTTY;
590
591 arg = va_arg (args, char *);
592
593 if (arg == (char *) NULL)
594 printf_filtered (TOGGLE_USAGE);
595 else
596 {
597 char *ptr = (char *) tuiStrDup (arg);
598 int i;
599
600 for (i = 0; (ptr[i]); i++)
601 ptr[i] = toupper (arg[i]);
602
603 if (subsetCompare (ptr, TUI_FLOAT_REGS_NAME))
604 tuiToggleFloatRegs ();
605/* else if (subsetCompare(ptr, "ANOTHER TOGGLE OPTION"))
c5aa993b
JM
606 ...
607 */
c906108c
SS
608 else
609 printf_filtered (TOGGLE_USAGE);
610 tuiFree (ptr);
611 }
612
613 return;
614} /* _tuiToggle_command */
615
616
617static void
c906108c 618_tuiReset (void)
c906108c
SS
619{
620 struct termio mode;
621
622 /*
c5aa993b
JM
623 ** reset the teletype mode bits to a sensible state.
624 ** Copied tset.c
625 */
c906108c
SS
626#if ! defined (USG) && defined (TIOCGETC)
627 struct tchars tbuf;
628#endif /* !USG && TIOCGETC */
629#ifdef UCB_NTTY
630 struct ltchars ltc;
631
632 if (ldisc == NTTYDISC)
633 {
634 ioctl (FILEDES, TIOCGLTC, &ltc);
635 ltc.t_suspc = CHK (ltc.t_suspc, CTRL ('Z'));
636 ltc.t_dsuspc = CHK (ltc.t_dsuspc, CTRL ('Y'));
637 ltc.t_rprntc = CHK (ltc.t_rprntc, CTRL ('R'));
638 ltc.t_flushc = CHK (ltc.t_flushc, CTRL ('O'));
639 ltc.t_werasc = CHK (ltc.t_werasc, CTRL ('W'));
640 ltc.t_lnextc = CHK (ltc.t_lnextc, CTRL ('V'));
641 ioctl (FILEDES, TIOCSLTC, &ltc);
642 }
643#endif /* UCB_NTTY */
644#ifndef USG
645#ifdef TIOCGETC
646 ioctl (FILEDES, TIOCGETC, &tbuf);
647 tbuf.t_intrc = CHK (tbuf.t_intrc, CTRL ('?'));
648 tbuf.t_quitc = CHK (tbuf.t_quitc, CTRL ('\\'));
649 tbuf.t_startc = CHK (tbuf.t_startc, CTRL ('Q'));
650 tbuf.t_stopc = CHK (tbuf.t_stopc, CTRL ('S'));
651 tbuf.t_eofc = CHK (tbuf.t_eofc, CTRL ('D'));
652 /* brkc is left alone */
653 ioctl (FILEDES, TIOCSETC, &tbuf);
654#endif /* TIOCGETC */
655 mode.sg_flags &= ~(RAW
656#ifdef CBREAK
657 | CBREAK
658#endif /* CBREAK */
659 | VTDELAY | ALLDELAY);
660 mode.sg_flags |= XTABS | ECHO | CRMOD | ANYP;
c5aa993b 661#else /*USG */
c906108c
SS
662 ioctl (FILEDES, TCGETA, &mode);
663 mode.c_cc[VINTR] = CHK (mode.c_cc[VINTR], CTRL ('?'));
664 mode.c_cc[VQUIT] = CHK (mode.c_cc[VQUIT], CTRL ('\\'));
665 mode.c_cc[VEOF] = CHK (mode.c_cc[VEOF], CTRL ('D'));
666
667 mode.c_iflag &= ~(IGNBRK | PARMRK | INPCK | INLCR | IGNCR | IUCLC | IXOFF);
668 mode.c_iflag |= (BRKINT | ISTRIP | ICRNL | IXON);
669 mode.c_oflag &= ~(OLCUC | OCRNL | ONOCR | ONLRET | OFILL | OFDEL |
670 NLDLY | CRDLY | TABDLY | BSDLY | VTDLY | FFDLY);
671 mode.c_oflag |= (OPOST | ONLCR);
672 mode.c_cflag &= ~(CSIZE | PARODD | CLOCAL);
673#ifndef hp9000s800
674 mode.c_cflag |= (CS8 | CREAD);
c5aa993b 675#else /*hp9000s800 */
c906108c
SS
676 mode.c_cflag |= (CS8 | CSTOPB | CREAD);
677#endif /* hp9000s800 */
678 mode.c_lflag &= ~(XCASE | ECHONL | NOFLSH);
679 mode.c_lflag |= (ISIG | ICANON | ECHO | ECHOK);
680 ioctl (FILEDES, TCSETAW, &mode);
681#endif /* USG */
682
683 return;
684} /* _tuiReset */
This page took 0.153163 seconds and 4 git commands to generate.