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