1 /* TUI support I/O functions.
2 
3    Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software
4    Foundation, 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 #include "defs.h"
26 #include "terminal.h"
27 #include "target.h"
28 #include "event-loop.h"
29 #include "event-top.h"
30 #include "command.h"
31 #include "top.h"
32 #include "readline/readline.h"
33 #include "tui/tui.h"
34 #include "tui/tui-data.h"
35 #include "tui/tui-io.h"
36 #include "tui/tui-command.h"
37 #include "tui/tui-win.h"
38 #include "tui/tui-wingeneral.h"
39 #include "tui/tui-file.h"
40 #include "ui-out.h"
41 #include "cli-out.h"
42 #include <fcntl.h>
43 #include <signal.h>
44 #include <stdio.h>
45 
46 #include "gdb_curses.h"
47 
48 int
key_is_start_sequence(int ch)49 key_is_start_sequence (int ch)
50 {
51   return (ch == 27);
52 }
53 
54 int
key_is_end_sequence(int ch)55 key_is_end_sequence (int ch)
56 {
57   return (ch == 126);
58 }
59 
60 int
key_is_backspace(int ch)61 key_is_backspace (int ch)
62 {
63   return (ch == 8);
64 }
65 
66 int
key_is_command_char(int ch)67 key_is_command_char (int ch)
68 {
69   return ((ch == KEY_NPAGE) || (ch == KEY_PPAGE)
70 	  || (ch == KEY_LEFT) || (ch == KEY_RIGHT)
71 	  || (ch == KEY_UP) || (ch == KEY_DOWN)
72 	  || (ch == KEY_SF) || (ch == KEY_SR)
73 	  || (ch == (int)'\f') || key_is_start_sequence (ch));
74 }
75 
76 /* Use definition from readline 4.3.  */
77 #undef CTRL_CHAR
78 #define CTRL_CHAR(c) ((c) < control_character_threshold && (((c) & 0x80) == 0))
79 
80 /* This file controls the IO interactions between gdb and curses.
81    When the TUI is enabled, gdb has two modes a curses and a standard
82    mode.
83 
84    In curses mode, the gdb outputs are made in a curses command window.
85    For this, the gdb_stdout and gdb_stderr are redirected to the specific
86    ui_file implemented by TUI.  The output is handled by tui_puts().
87    The input is also controlled by curses with tui_getc().  The readline
88    library uses this function to get its input.  Several readline hooks
89    are installed to redirect readline output to the TUI (see also the
90    note below).
91 
92    In normal mode, the gdb outputs are restored to their origin, that
93    is as if TUI is not used.  Readline also uses its original getc()
94    function with stdin.
95 
96    Note SCz/2001-07-21: the current readline is not clean in its management of
97    the output.  Even if we install a redisplay handler, it sometimes writes on
98    a stdout file.  It is important to redirect every output produced by
99    readline, otherwise the curses window will be garbled.  This is implemented
100    with a pipe that TUI reads and readline writes to.  A gdb input handler
101    is created so that reading the pipe is handled automatically.
102    This will probably not work on non-Unix platforms.  The best fix is
103    to make readline clean enougth so that is never write on stdout.
104 
105    Note SCz/2002-09-01: we now use more readline hooks and it seems that
106    with them we don't need the pipe anymore (verified by creating the pipe
107    and closing its end so that write causes a SIGPIPE).  The old pipe code
108    is still there and can be conditionally removed by
109    #undef TUI_USE_PIPE_FOR_READLINE.  */
110 
111 /* For gdb 5.3, prefer to continue the pipe hack as a backup wheel.  */
112 #define TUI_USE_PIPE_FOR_READLINE
113 /*#undef TUI_USE_PIPE_FOR_READLINE*/
114 
115 /* TUI output files.  */
116 static struct ui_file *tui_stdout;
117 static struct ui_file *tui_stderr;
118 struct ui_out *tui_out;
119 
120 /* GDB output files in non-curses mode.  */
121 static struct ui_file *tui_old_stdout;
122 static struct ui_file *tui_old_stderr;
123 struct ui_out *tui_old_uiout;
124 
125 /* Readline previous hooks.  */
126 static Function *tui_old_rl_getc_function;
127 static VFunction *tui_old_rl_redisplay_function;
128 static VFunction *tui_old_rl_prep_terminal;
129 static VFunction *tui_old_rl_deprep_terminal;
130 static int tui_old_readline_echoing_p;
131 
132 /* Readline output stream.
133    Should be removed when readline is clean.  */
134 static FILE *tui_rl_outstream;
135 static FILE *tui_old_rl_outstream;
136 #ifdef TUI_USE_PIPE_FOR_READLINE
137 static int tui_readline_pipe[2];
138 #endif
139 
140 /* The last gdb prompt that was registered in readline.
141    This may be the main gdb prompt or a secondary prompt.  */
142 static char *tui_rl_saved_prompt;
143 
144 static unsigned int tui_handle_resize_during_io (unsigned int);
145 
146 static void
tui_putc(char c)147 tui_putc (char c)
148 {
149   char buf[2];
150 
151   buf[0] = c;
152   buf[1] = 0;
153   tui_puts (buf);
154 }
155 
156 /* Print the string in the curses command window.  */
157 void
tui_puts(const char * string)158 tui_puts (const char *string)
159 {
160   static int tui_skip_line = -1;
161   char c;
162   WINDOW *w;
163 
164   w = TUI_CMD_WIN->generic.handle;
165   while ((c = *string++) != 0)
166     {
167       /* Catch annotation and discard them.  We need two \032 and
168          discard until a \n is seen.  */
169       if (c == '\032')
170         {
171           tui_skip_line++;
172         }
173       else if (tui_skip_line != 1)
174         {
175           tui_skip_line = -1;
176           waddch (w, c);
177         }
178       else if (c == '\n')
179         tui_skip_line = -1;
180     }
181   getyx (w, TUI_CMD_WIN->detail.command_info.cur_line,
182          TUI_CMD_WIN->detail.command_info.curch);
183   TUI_CMD_WIN->detail.command_info.start_line = TUI_CMD_WIN->detail.command_info.cur_line;
184 
185   /* We could defer the following.  */
186   wrefresh (w);
187   fflush (stdout);
188 }
189 
190 /* Readline callback.
191    Redisplay the command line with its prompt after readline has
192    changed the edited text.  */
193 void
tui_redisplay_readline(void)194 tui_redisplay_readline (void)
195 {
196   int prev_col;
197   int height;
198   int col, line;
199   int c_pos;
200   int c_line;
201   int in;
202   WINDOW *w;
203   char *prompt;
204   int start_line;
205 
206   /* Detect when we temporarily left SingleKey and now the readline
207      edit buffer is empty, automatically restore the SingleKey mode.  */
208   if (tui_current_key_mode == TUI_ONE_COMMAND_MODE && rl_end == 0)
209     tui_set_key_mode (TUI_SINGLE_KEY_MODE);
210 
211   if (tui_current_key_mode == TUI_SINGLE_KEY_MODE)
212     prompt = "";
213   else
214     prompt = tui_rl_saved_prompt;
215 
216   c_pos = -1;
217   c_line = -1;
218   w = TUI_CMD_WIN->generic.handle;
219   start_line = TUI_CMD_WIN->detail.command_info.start_line;
220   wmove (w, start_line, 0);
221   prev_col = 0;
222   height = 1;
223   for (in = 0; prompt && prompt[in]; in++)
224     {
225       waddch (w, prompt[in]);
226       getyx (w, line, col);
227       if (col < prev_col)
228         height++;
229       prev_col = col;
230     }
231   for (in = 0; in < rl_end; in++)
232     {
233       unsigned char c;
234 
235       c = (unsigned char) rl_line_buffer[in];
236       if (in == rl_point)
237 	{
238           getyx (w, c_line, c_pos);
239 	}
240 
241       if (CTRL_CHAR (c) || c == RUBOUT)
242 	{
243           waddch (w, '^');
244           waddch (w, CTRL_CHAR (c) ? UNCTRL (c) : '?');
245 	}
246       else
247 	{
248           waddch (w, c);
249 	}
250       if (c == '\n')
251         {
252           getyx (w, TUI_CMD_WIN->detail.command_info.start_line,
253                  TUI_CMD_WIN->detail.command_info.curch);
254         }
255       getyx (w, line, col);
256       if (col < prev_col)
257         height++;
258       prev_col = col;
259     }
260   wclrtobot (w);
261   getyx (w, TUI_CMD_WIN->detail.command_info.start_line,
262          TUI_CMD_WIN->detail.command_info.curch);
263   if (c_line >= 0)
264     {
265       wmove (w, c_line, c_pos);
266       TUI_CMD_WIN->detail.command_info.cur_line = c_line;
267       TUI_CMD_WIN->detail.command_info.curch = c_pos;
268     }
269   TUI_CMD_WIN->detail.command_info.start_line -= height - 1;
270 
271   wrefresh (w);
272   fflush(stdout);
273 }
274 
275 /* Readline callback to prepare the terminal.  It is called once
276    each time we enter readline.  Terminal is already setup in curses mode.  */
277 static void
tui_prep_terminal(int notused1)278 tui_prep_terminal (int notused1)
279 {
280   /* Save the prompt registered in readline to correctly display it.
281      (we can't use gdb_prompt() due to secondary prompts and can't use
282      rl_prompt because it points to an alloca buffer).  */
283   xfree (tui_rl_saved_prompt);
284   tui_rl_saved_prompt = xstrdup (rl_prompt);
285 }
286 
287 /* Readline callback to restore the terminal.  It is called once
288    each time we leave readline.  There is nothing to do in curses mode.  */
289 static void
tui_deprep_terminal(void)290 tui_deprep_terminal (void)
291 {
292 }
293 
294 #ifdef TUI_USE_PIPE_FOR_READLINE
295 /* Read readline output pipe and feed the command window with it.
296    Should be removed when readline is clean.  */
297 static void
tui_readline_output(int code,gdb_client_data data)298 tui_readline_output (int code, gdb_client_data data)
299 {
300   int size;
301   char buf[256];
302 
303   size = read (tui_readline_pipe[0], buf, sizeof (buf) - 1);
304   if (size > 0 && tui_active)
305     {
306       buf[size] = 0;
307       tui_puts (buf);
308     }
309 }
310 #endif
311 
312 /* Return the portion of PATHNAME that should be output when listing
313    possible completions.  If we are hacking filename completion, we
314    are only interested in the basename, the portion following the
315    final slash.  Otherwise, we return what we were passed.
316 
317    Comes from readline/complete.c  */
318 static char *
printable_part(char * pathname)319 printable_part (char *pathname)
320 {
321   char *temp;
322 
323   temp = rl_filename_completion_desired ? strrchr (pathname, '/') : (char *)NULL;
324 #if defined (__MSDOS__)
325   if (rl_filename_completion_desired && temp == 0 && isalpha (pathname[0]) && pathname[1] == ':')
326     temp = pathname + 1;
327 #endif
328   return (temp ? ++temp : pathname);
329 }
330 
331 /* Output TO_PRINT to rl_outstream.  If VISIBLE_STATS is defined and we
332    are using it, check for and output a single character for `special'
333    filenames.  Return the number of characters we output. */
334 
335 #define PUTX(c) \
336     do { \
337       if (CTRL_CHAR (c)) \
338         { \
339           tui_puts ("^"); \
340           tui_putc (UNCTRL (c)); \
341           printed_len += 2; \
342         } \
343       else if (c == RUBOUT) \
344 	{ \
345 	  tui_puts ("^?"); \
346 	  printed_len += 2; \
347 	} \
348       else \
349 	{ \
350 	  tui_putc (c); \
351 	  printed_len++; \
352 	} \
353     } while (0)
354 
355 static int
print_filename(char * to_print,char * full_pathname)356 print_filename (char *to_print, char *full_pathname)
357 {
358   int printed_len = 0;
359   char *s;
360 
361   for (s = to_print; *s; s++)
362     {
363       PUTX (*s);
364     }
365   return printed_len;
366 }
367 
368 /* The user must press "y" or "n".  Non-zero return means "y" pressed.
369    Comes from readline/complete.c  */
370 static int
get_y_or_n(void)371 get_y_or_n (void)
372 {
373   extern int _rl_abort_internal ();
374   int c;
375 
376   for (;;)
377     {
378       c = rl_read_key ();
379       if (c == 'y' || c == 'Y' || c == ' ')
380 	return (1);
381       if (c == 'n' || c == 'N' || c == RUBOUT)
382 	return (0);
383       if (c == ABORT_CHAR)
384 	_rl_abort_internal ();
385       beep ();
386     }
387 }
388 
389 /* A convenience function for displaying a list of strings in
390    columnar format on readline's output stream.  MATCHES is the list
391    of strings, in argv format, LEN is the number of strings in MATCHES,
392    and MAX is the length of the longest string in MATCHES.
393 
394    Comes from readline/complete.c and modified to write in
395    the TUI command window using tui_putc/tui_puts.  */
396 static void
tui_rl_display_match_list(char ** matches,int len,int max)397 tui_rl_display_match_list (char **matches, int len, int max)
398 {
399   typedef int QSFUNC (const void *, const void *);
400   extern int _rl_qsort_string_compare (char **, char **);
401   extern int _rl_print_completions_horizontally;
402 
403   int count, limit, printed_len;
404   int i, j, k, l;
405   char *temp;
406 
407   /* Screen dimension correspond to the TUI command window.  */
408   int screenwidth = TUI_CMD_WIN->generic.width;
409 
410   /* If there are many items, then ask the user if she really wants to
411      see them all. */
412   if (len >= rl_completion_query_items)
413     {
414       char msg[256];
415 
416       sprintf (msg, "\nDisplay all %d possibilities? (y or n)", len);
417       tui_puts (msg);
418       if (get_y_or_n () == 0)
419 	{
420 	  tui_puts ("\n");
421 	  return;
422 	}
423     }
424 
425   /* How many items of MAX length can we fit in the screen window? */
426   max += 2;
427   limit = screenwidth / max;
428   if (limit != 1 && (limit * max == screenwidth))
429     limit--;
430 
431   /* Avoid a possible floating exception.  If max > screenwidth,
432      limit will be 0 and a divide-by-zero fault will result. */
433   if (limit == 0)
434     limit = 1;
435 
436   /* How many iterations of the printing loop? */
437   count = (len + (limit - 1)) / limit;
438 
439   /* Watch out for special case.  If LEN is less than LIMIT, then
440      just do the inner printing loop.
441 	   0 < len <= limit  implies  count = 1. */
442 
443   /* Sort the items if they are not already sorted. */
444   if (rl_ignore_completion_duplicates == 0)
445     qsort (matches + 1, len, sizeof (char *),
446            (QSFUNC *)_rl_qsort_string_compare);
447 
448   tui_putc ('\n');
449 
450   if (_rl_print_completions_horizontally == 0)
451     {
452       /* Print the sorted items, up-and-down alphabetically, like ls. */
453       for (i = 1; i <= count; i++)
454 	{
455 	  for (j = 0, l = i; j < limit; j++)
456 	    {
457 	      if (l > len || matches[l] == 0)
458 		break;
459 	      else
460 		{
461 		  temp = printable_part (matches[l]);
462 		  printed_len = print_filename (temp, matches[l]);
463 
464 		  if (j + 1 < limit)
465 		    for (k = 0; k < max - printed_len; k++)
466 		      tui_putc (' ');
467 		}
468 	      l += count;
469 	    }
470 	  tui_putc ('\n');
471 	}
472     }
473   else
474     {
475       /* Print the sorted items, across alphabetically, like ls -x. */
476       for (i = 1; matches[i]; i++)
477 	{
478 	  temp = printable_part (matches[i]);
479 	  printed_len = print_filename (temp, matches[i]);
480 	  /* Have we reached the end of this line? */
481 	  if (matches[i+1])
482 	    {
483 	      if (i && (limit > 1) && (i % limit) == 0)
484 		tui_putc ('\n');
485 	      else
486 		for (k = 0; k < max - printed_len; k++)
487 		  tui_putc (' ');
488 	    }
489 	}
490       tui_putc ('\n');
491     }
492 }
493 
494 /* Setup the IO for curses or non-curses mode.
495    - In non-curses mode, readline and gdb use the standard input and
496    standard output/error directly.
497    - In curses mode, the standard output/error is controlled by TUI
498    with the tui_stdout and tui_stderr.  The output is redirected in
499    the curses command window.  Several readline callbacks are installed
500    so that readline asks for its input to the curses command window
501    with wgetch().  */
502 void
tui_setup_io(int mode)503 tui_setup_io (int mode)
504 {
505   extern int readline_echoing_p;
506 
507   if (mode)
508     {
509       /* Redirect readline to TUI.  */
510       tui_old_rl_redisplay_function = rl_redisplay_function;
511       tui_old_rl_deprep_terminal = rl_deprep_term_function;
512       tui_old_rl_prep_terminal = rl_prep_term_function;
513       tui_old_rl_getc_function = rl_getc_function;
514       tui_old_rl_outstream = rl_outstream;
515       tui_old_readline_echoing_p = readline_echoing_p;
516       rl_redisplay_function = tui_redisplay_readline;
517       rl_deprep_term_function = tui_deprep_terminal;
518       rl_prep_term_function = tui_prep_terminal;
519       rl_getc_function = tui_getc;
520       readline_echoing_p = 0;
521       rl_outstream = tui_rl_outstream;
522       rl_prompt = 0;
523       rl_completion_display_matches_hook = tui_rl_display_match_list;
524       rl_already_prompted = 0;
525 
526       /* Keep track of previous gdb output.  */
527       tui_old_stdout = gdb_stdout;
528       tui_old_stderr = gdb_stderr;
529       tui_old_uiout = uiout;
530 
531       /* Reconfigure gdb output.  */
532       gdb_stdout = tui_stdout;
533       gdb_stderr = tui_stderr;
534       gdb_stdlog = gdb_stdout;	/* for moment */
535       gdb_stdtarg = gdb_stderr;	/* for moment */
536       uiout = tui_out;
537 
538       /* Save tty for SIGCONT.  */
539       savetty ();
540     }
541   else
542     {
543       /* Restore gdb output.  */
544       gdb_stdout = tui_old_stdout;
545       gdb_stderr = tui_old_stderr;
546       gdb_stdlog = gdb_stdout;	/* for moment */
547       gdb_stdtarg = gdb_stderr;	/* for moment */
548       uiout = tui_old_uiout;
549 
550       /* Restore readline.  */
551       rl_redisplay_function = tui_old_rl_redisplay_function;
552       rl_deprep_term_function = tui_old_rl_deprep_terminal;
553       rl_prep_term_function = tui_old_rl_prep_terminal;
554       rl_getc_function = tui_old_rl_getc_function;
555       rl_outstream = tui_old_rl_outstream;
556       rl_completion_display_matches_hook = 0;
557       readline_echoing_p = tui_old_readline_echoing_p;
558       rl_already_prompted = 0;
559 
560       /* Save tty for SIGCONT.  */
561       savetty ();
562     }
563 }
564 
565 #ifdef SIGCONT
566 /* Catch SIGCONT to restore the terminal and refresh the screen.  */
567 static void
tui_cont_sig(int sig)568 tui_cont_sig (int sig)
569 {
570   if (tui_active)
571     {
572       /* Restore the terminal setting because another process (shell)
573          might have changed it.  */
574       resetty ();
575 
576       /* Force a refresh of the screen.  */
577       tui_refresh_all_win ();
578 
579       /* Update cursor position on the screen.  */
580       wmove (TUI_CMD_WIN->generic.handle,
581              TUI_CMD_WIN->detail.command_info.start_line,
582              TUI_CMD_WIN->detail.command_info.curch);
583       wrefresh (TUI_CMD_WIN->generic.handle);
584     }
585   signal (sig, tui_cont_sig);
586 }
587 #endif
588 
589 /* Initialize the IO for gdb in curses mode.  */
590 void
tui_initialize_io(void)591 tui_initialize_io (void)
592 {
593 #ifdef SIGCONT
594   signal (SIGCONT, tui_cont_sig);
595 #endif
596 
597   /* Create tui output streams.  */
598   tui_stdout = tui_fileopen (stdout);
599   tui_stderr = tui_fileopen (stderr);
600   tui_out = tui_out_new (tui_stdout);
601 
602   /* Create the default UI.  It is not created because we installed
603      a init_ui_hook.  */
604   tui_old_uiout = uiout = cli_out_new (gdb_stdout);
605 
606 #ifdef TUI_USE_PIPE_FOR_READLINE
607   /* Temporary solution for readline writing to stdout:
608      redirect readline output in a pipe, read that pipe and
609      output the content in the curses command window.  */
610   if (pipe (tui_readline_pipe) != 0)
611     {
612       fprintf_unfiltered (gdb_stderr, "Cannot create pipe for readline");
613       exit (1);
614     }
615   tui_rl_outstream = fdopen (tui_readline_pipe[1], "w");
616   if (tui_rl_outstream == 0)
617     {
618       fprintf_unfiltered (gdb_stderr, "Cannot redirect readline output");
619       exit (1);
620     }
621   setvbuf (tui_rl_outstream, (char*) NULL, _IOLBF, 0);
622 
623 #ifdef O_NONBLOCK
624   (void) fcntl (tui_readline_pipe[0], F_SETFL, O_NONBLOCK);
625 #else
626 #ifdef O_NDELAY
627   (void) fcntl (tui_readline_pipe[0], F_SETFL, O_NDELAY);
628 #endif
629 #endif
630   add_file_handler (tui_readline_pipe[0], tui_readline_output, 0);
631 #else
632   tui_rl_outstream = stdout;
633 #endif
634 }
635 
636 /* Get a character from the command window.  This is called from the readline
637    package.  */
638 int
tui_getc(FILE * fp)639 tui_getc (FILE *fp)
640 {
641   int ch;
642   WINDOW *w;
643 
644   w = TUI_CMD_WIN->generic.handle;
645 
646 #ifdef TUI_USE_PIPE_FOR_READLINE
647   /* Flush readline output.  */
648   tui_readline_output (GDB_READABLE, 0);
649 #endif
650 
651   ch = wgetch (w);
652   ch = tui_handle_resize_during_io (ch);
653 
654   /* The \n must be echoed because it will not be printed by readline.  */
655   if (ch == '\n')
656     {
657       /* When hitting return with an empty input, gdb executes the last
658          command.  If we emit a newline, this fills up the command window
659          with empty lines with gdb prompt at beginning.  Instead of that,
660          stay on the same line but provide a visual effect to show the
661          user we recognized the command.  */
662       if (rl_end == 0)
663         {
664           wmove (w, TUI_CMD_WIN->detail.command_info.cur_line, 0);
665 
666           /* Clear the line.  This will blink the gdb prompt since
667              it will be redrawn at the same line.  */
668           wclrtoeol (w);
669           wrefresh (w);
670           napms (20);
671         }
672       else
673         {
674           wmove (w, TUI_CMD_WIN->detail.command_info.cur_line,
675                  TUI_CMD_WIN->detail.command_info.curch);
676           waddch (w, ch);
677         }
678     }
679 
680   if (key_is_command_char (ch))
681     {				/* Handle prev/next/up/down here */
682       ch = tui_dispatch_ctrl_char (ch);
683     }
684 
685   if (ch == '\n' || ch == '\r' || ch == '\f')
686     TUI_CMD_WIN->detail.command_info.curch = 0;
687   if (ch == KEY_BACKSPACE)
688     return '\b';
689 
690   return ch;
691 }
692 
693 
694 /* Cleanup when a resize has occured.
695    Returns the character that must be processed.  */
696 static unsigned int
tui_handle_resize_during_io(unsigned int original_ch)697 tui_handle_resize_during_io (unsigned int original_ch)
698 {
699   if (tui_win_resized ())
700     {
701       tui_refresh_all_win ();
702       dont_repeat ();
703       tui_set_win_resized_to (FALSE);
704       return '\n';
705     }
706   else
707     return original_ch;
708 }
709