5a84d08a28394f8248bcc810e6753d33aad4e906
[deliverable/binutils-gdb.git] / gdb / tui / tui-io.c
1 /* TUI support I/O functions.
2
3 Copyright (C) 1998-2018 Free Software Foundation, Inc.
4
5 Contributed by Hewlett-Packard Company.
6
7 This file is part of GDB.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>. */
21
22 #include "defs.h"
23 #include "target.h"
24 #include "event-loop.h"
25 #include "event-top.h"
26 #include "command.h"
27 #include "top.h"
28 #include "tui/tui.h"
29 #include "tui/tui-data.h"
30 #include "tui/tui-io.h"
31 #include "tui/tui-command.h"
32 #include "tui/tui-win.h"
33 #include "tui/tui-wingeneral.h"
34 #include "tui/tui-file.h"
35 #include "tui/tui-out.h"
36 #include "ui-out.h"
37 #include "cli-out.h"
38 #include <fcntl.h>
39 #include <signal.h>
40 #include "filestuff.h"
41 #include "completer.h"
42 #include "gdb_curses.h"
43 #include <map>
44
45 /* This redefines CTRL if it is not already defined, so it must come
46 after terminal state releated include files like <term.h> and
47 "gdb_curses.h". */
48 #include "readline/readline.h"
49
50 static int tui_getc (FILE *fp);
51
52 static int
53 key_is_start_sequence (int ch)
54 {
55 return (ch == 27);
56 }
57
58 /* Use definition from readline 4.3. */
59 #undef CTRL_CHAR
60 #define CTRL_CHAR(c) \
61 ((c) < control_character_threshold && (((c) & 0x80) == 0))
62
63 /* This file controls the IO interactions between gdb and curses.
64 When the TUI is enabled, gdb has two modes a curses and a standard
65 mode.
66
67 In curses mode, the gdb outputs are made in a curses command
68 window. For this, the gdb_stdout and gdb_stderr are redirected to
69 the specific ui_file implemented by TUI. The output is handled by
70 tui_puts(). The input is also controlled by curses with
71 tui_getc(). The readline library uses this function to get its
72 input. Several readline hooks are installed to redirect readline
73 output to the TUI (see also the note below).
74
75 In normal mode, the gdb outputs are restored to their origin, that
76 is as if TUI is not used. Readline also uses its original getc()
77 function with stdin.
78
79 Note SCz/2001-07-21: the current readline is not clean in its
80 management of the output. Even if we install a redisplay handler,
81 it sometimes writes on a stdout file. It is important to redirect
82 every output produced by readline, otherwise the curses window will
83 be garbled. This is implemented with a pipe that TUI reads and
84 readline writes to. A gdb input handler is created so that reading
85 the pipe is handled automatically. This will probably not work on
86 non-Unix platforms. The best fix is to make readline clean enougth
87 so that is never write on stdout.
88
89 Note SCz/2002-09-01: we now use more readline hooks and it seems
90 that with them we don't need the pipe anymore (verified by creating
91 the pipe and closing its end so that write causes a SIGPIPE). The
92 old pipe code is still there and can be conditionally removed by
93 #undef TUI_USE_PIPE_FOR_READLINE. */
94
95 /* For gdb 5.3, prefer to continue the pipe hack as a backup wheel. */
96 #ifdef HAVE_PIPE
97 #define TUI_USE_PIPE_FOR_READLINE
98 #endif
99 /* #undef TUI_USE_PIPE_FOR_READLINE */
100
101 /* TUI output files. */
102 static struct ui_file *tui_stdout;
103 static struct ui_file *tui_stderr;
104 struct ui_out *tui_out;
105
106 /* GDB output files in non-curses mode. */
107 static struct ui_file *tui_old_stdout;
108 static struct ui_file *tui_old_stderr;
109 cli_ui_out *tui_old_uiout;
110
111 /* Readline previous hooks. */
112 static rl_getc_func_t *tui_old_rl_getc_function;
113 static rl_voidfunc_t *tui_old_rl_redisplay_function;
114 static rl_vintfunc_t *tui_old_rl_prep_terminal;
115 static rl_voidfunc_t *tui_old_rl_deprep_terminal;
116 static rl_compdisp_func_t *tui_old_rl_display_matches_hook;
117 static int tui_old_rl_echoing_p;
118
119 /* Readline output stream.
120 Should be removed when readline is clean. */
121 static FILE *tui_rl_outstream;
122 static FILE *tui_old_rl_outstream;
123 #ifdef TUI_USE_PIPE_FOR_READLINE
124 static int tui_readline_pipe[2];
125 #endif
126
127 /* The last gdb prompt that was registered in readline.
128 This may be the main gdb prompt or a secondary prompt. */
129 static char *tui_rl_saved_prompt;
130
131 /* Print a character in the curses command window. The output is
132 buffered. It is up to the caller to refresh the screen if
133 necessary. */
134
135 static void
136 do_tui_putc (WINDOW *w, char c)
137 {
138 static int tui_skip_line = -1;
139
140 /* Catch annotation and discard them. We need two \032 and discard
141 until a \n is seen. */
142 if (c == '\032')
143 {
144 tui_skip_line++;
145 }
146 else if (tui_skip_line != 1)
147 {
148 tui_skip_line = -1;
149 /* Expand TABs, since ncurses on MS-Windows doesn't. */
150 if (c == '\t')
151 {
152 int col;
153
154 col = getcurx (w);
155 do
156 {
157 waddch (w, ' ');
158 col++;
159 }
160 while ((col % 8) != 0);
161 }
162 else
163 waddch (w, c);
164 }
165 else if (c == '\n')
166 tui_skip_line = -1;
167 }
168
169 /* Update the cached value of the command window's start line based on
170 the window's current Y coordinate. */
171
172 static void
173 update_cmdwin_start_line ()
174 {
175 TUI_CMD_WIN->detail.command_info.start_line
176 = getcury (TUI_CMD_WIN->generic.handle);
177 }
178
179 /* Print a character in the curses command window. The output is
180 buffered. It is up to the caller to refresh the screen if
181 necessary. */
182
183 static void
184 tui_putc (char c)
185 {
186 WINDOW *w = TUI_CMD_WIN->generic.handle;
187
188 do_tui_putc (w, c);
189 update_cmdwin_start_line ();
190 }
191
192 /* This maps colors to their corresponding color index. */
193
194 static std::map<ui_file_style::color, int> color_map;
195
196 /* This holds a pair of colors and is used to track the mapping
197 between a color pair index and the actual colors. */
198
199 struct color_pair
200 {
201 int fg;
202 int bg;
203
204 bool operator< (const color_pair &o) const
205 {
206 return fg < o.fg || (fg == o.fg && bg < o.bg);
207 }
208 };
209
210 /* This maps pairs of colors to their corresponding color pair
211 index. */
212
213 static std::map<color_pair, int> color_pair_map;
214
215 /* This is indexed by ANSI color offset from the base color, and holds
216 the corresponding curses color constant. */
217
218 static const int curses_colors[] = {
219 COLOR_BLACK,
220 COLOR_RED,
221 COLOR_GREEN,
222 COLOR_YELLOW,
223 COLOR_BLUE,
224 COLOR_MAGENTA,
225 COLOR_CYAN,
226 COLOR_WHITE
227 };
228
229 /* Given a color, find its index. */
230
231 static bool
232 get_color (const ui_file_style::color &color, int *result)
233 {
234 if (color.is_none ())
235 *result = -1;
236 else if (color.is_basic ())
237 *result = curses_colors[color.get_value ()];
238 else
239 {
240 auto it = color_map.find (color);
241 if (it == color_map.end ())
242 {
243 /* The first 8 colors are standard. */
244 int next = color_map.size () + 8;
245 if (next >= COLORS)
246 return false;
247 uint8_t rgb[3];
248 color.get_rgb (rgb);
249 /* We store RGB as 0..255, but curses wants 0..1000. */
250 if (init_color (next, rgb[0] * 1000 / 255, rgb[1] * 1000 / 255,
251 rgb[2] * 1000 / 255) == ERR)
252 return false;
253 color_map[color] = next;
254 *result = next;
255 }
256 else
257 *result = it->second;
258 }
259 return true;
260 }
261
262 /* The most recently emitted color pair. */
263
264 static int last_color_pair = -1;
265
266 /* The most recently applied style. */
267
268 static ui_file_style last_style;
269
270 /* Given two colors, return their color pair index; making a new one
271 if necessary. */
272
273 static int
274 get_color_pair (int fg, int bg)
275 {
276 color_pair c = { fg, bg };
277 auto it = color_pair_map.find (c);
278 if (it == color_pair_map.end ())
279 {
280 /* Color pair 0 is our default color, so new colors start at
281 1. */
282 int next = color_pair_map.size () + 1;
283 /* Curses has a limited number of available color pairs. Fall
284 back to the default if we've used too many. */
285 if (next >= COLOR_PAIRS)
286 return 0;
287 init_pair (next, fg, bg);
288 color_pair_map[c] = next;
289 return next;
290 }
291 return it->second;
292 }
293
294 /* Apply an ANSI escape sequence from BUF to W. BUF must start with
295 the ESC character. If BUF does not start with an ANSI escape,
296 return 0. Otherwise, apply the sequence if it is recognized, or
297 simply ignore it if not. In this case, the number of bytes read
298 from BUF is returned. */
299
300 static size_t
301 apply_ansi_escape (WINDOW *w, const char *buf)
302 {
303 ui_file_style style = last_style;
304 size_t n_read;
305
306 if (!style.parse (buf, &n_read))
307 return n_read;
308
309 /* Reset. */
310 wattron (w, A_NORMAL);
311 wattroff (w, A_BOLD);
312 wattroff (w, A_DIM);
313 wattroff (w, A_REVERSE);
314 if (last_color_pair != -1)
315 wattroff (w, COLOR_PAIR (last_color_pair));
316 wattron (w, COLOR_PAIR (0));
317
318 const ui_file_style::color &fg = style.get_foreground ();
319 const ui_file_style::color &bg = style.get_background ();
320 if (!fg.is_none () || !bg.is_none ())
321 {
322 int fgi, bgi;
323 if (get_color (fg, &fgi) && get_color (bg, &bgi))
324 {
325 int pair = get_color_pair (fgi, bgi);
326 if (last_color_pair != -1)
327 wattroff (w, COLOR_PAIR (last_color_pair));
328 wattron (w, COLOR_PAIR (pair));
329 last_color_pair = pair;
330 }
331 }
332
333 switch (style.get_intensity ())
334 {
335 case ui_file_style::NORMAL:
336 break;
337
338 case ui_file_style::BOLD:
339 wattron (w, A_BOLD);
340 break;
341
342 case ui_file_style::DIM:
343 wattron (w, A_DIM);
344 break;
345
346 default:
347 gdb_assert_not_reached ("invalid intensity");
348 }
349
350 if (style.is_reverse ())
351 wattron (w, A_REVERSE);
352
353 last_style = style;
354 return n_read;
355 }
356
357 /* Print LENGTH characters from the buffer pointed to by BUF to the
358 curses command window. The output is buffered. It is up to the
359 caller to refresh the screen if necessary. */
360
361 void
362 tui_write (const char *buf, size_t length)
363 {
364 /* We need this to be \0-terminated for the regexp matching. */
365 std::string copy (buf, length);
366 tui_puts (copy.c_str ());
367 }
368
369 static void
370 tui_puts_internal (const char *string, int *height)
371 {
372 WINDOW *w = TUI_CMD_WIN->generic.handle;
373 char c;
374 int prev_col = 0;
375
376 while ((c = *string++) != 0)
377 {
378 if (c == '\1' || c == '\2')
379 {
380 /* Ignore these, they are readline escape-marking
381 sequences. */
382 }
383 else
384 {
385 if (c == '\033')
386 {
387 size_t bytes_read = apply_ansi_escape (w, string - 1);
388 if (bytes_read > 0)
389 {
390 string = string + bytes_read - 1;
391 continue;
392 }
393 }
394 do_tui_putc (w, c);
395
396 if (height != nullptr)
397 {
398 int col = getcurx (w);
399 if (col <= prev_col)
400 ++*height;
401 prev_col = col;
402 }
403 }
404 }
405 update_cmdwin_start_line ();
406 }
407
408 /* Print a string in the curses command window. The output is
409 buffered. It is up to the caller to refresh the screen if
410 necessary. */
411
412 void
413 tui_puts (const char *string)
414 {
415 tui_puts_internal (string, nullptr);
416 }
417
418 /* Readline callback.
419 Redisplay the command line with its prompt after readline has
420 changed the edited text. */
421 void
422 tui_redisplay_readline (void)
423 {
424 int prev_col;
425 int height;
426 int col;
427 int c_pos;
428 int c_line;
429 int in;
430 WINDOW *w;
431 const char *prompt;
432 int start_line;
433
434 /* Detect when we temporarily left SingleKey and now the readline
435 edit buffer is empty, automatically restore the SingleKey
436 mode. The restore must only be done if the command has finished.
437 The command could call prompt_for_continue and we must not
438 restore SingleKey so that the prompt and normal keymap are used. */
439 if (tui_current_key_mode == TUI_ONE_COMMAND_MODE && rl_end == 0
440 && !gdb_in_secondary_prompt_p (current_ui))
441 tui_set_key_mode (TUI_SINGLE_KEY_MODE);
442
443 if (tui_current_key_mode == TUI_SINGLE_KEY_MODE)
444 prompt = "";
445 else
446 prompt = tui_rl_saved_prompt;
447
448 c_pos = -1;
449 c_line = -1;
450 w = TUI_CMD_WIN->generic.handle;
451 start_line = TUI_CMD_WIN->detail.command_info.start_line;
452 wmove (w, start_line, 0);
453 prev_col = 0;
454 height = 1;
455 if (prompt != nullptr)
456 tui_puts_internal (prompt, &height);
457
458 prev_col = getcurx (w);
459 for (in = 0; in <= rl_end; in++)
460 {
461 unsigned char c;
462
463 if (in == rl_point)
464 {
465 getyx (w, c_line, c_pos);
466 }
467
468 if (in == rl_end)
469 break;
470
471 c = (unsigned char) rl_line_buffer[in];
472 if (CTRL_CHAR (c) || c == RUBOUT)
473 {
474 waddch (w, '^');
475 waddch (w, CTRL_CHAR (c) ? UNCTRL (c) : '?');
476 }
477 else if (c == '\t')
478 {
479 /* Expand TABs, since ncurses on MS-Windows doesn't. */
480 col = getcurx (w);
481 do
482 {
483 waddch (w, ' ');
484 col++;
485 } while ((col % 8) != 0);
486 }
487 else
488 {
489 waddch (w, c);
490 }
491 if (c == '\n')
492 TUI_CMD_WIN->detail.command_info.start_line = getcury (w);
493 col = getcurx (w);
494 if (col < prev_col)
495 height++;
496 prev_col = col;
497 }
498 wclrtobot (w);
499 TUI_CMD_WIN->detail.command_info.start_line = getcury (w);
500 if (c_line >= 0)
501 wmove (w, c_line, c_pos);
502 TUI_CMD_WIN->detail.command_info.start_line -= height - 1;
503
504 wrefresh (w);
505 fflush(stdout);
506 }
507
508 /* Readline callback to prepare the terminal. It is called once each
509 time we enter readline. Terminal is already setup in curses
510 mode. */
511 static void
512 tui_prep_terminal (int notused1)
513 {
514 /* Save the prompt registered in readline to correctly display it.
515 (we can't use gdb_prompt() due to secondary prompts and can't use
516 rl_prompt because it points to an alloca buffer). */
517 xfree (tui_rl_saved_prompt);
518 tui_rl_saved_prompt = rl_prompt != NULL ? xstrdup (rl_prompt) : NULL;
519 }
520
521 /* Readline callback to restore the terminal. It is called once each
522 time we leave readline. There is nothing to do in curses mode. */
523 static void
524 tui_deprep_terminal (void)
525 {
526 }
527
528 #ifdef TUI_USE_PIPE_FOR_READLINE
529 /* Read readline output pipe and feed the command window with it.
530 Should be removed when readline is clean. */
531 static void
532 tui_readline_output (int error, gdb_client_data data)
533 {
534 int size;
535 char buf[256];
536
537 size = read (tui_readline_pipe[0], buf, sizeof (buf) - 1);
538 if (size > 0 && tui_active)
539 {
540 buf[size] = 0;
541 tui_puts (buf);
542 }
543 }
544 #endif
545
546 /* TUI version of displayer.crlf. */
547
548 static void
549 tui_mld_crlf (const struct match_list_displayer *displayer)
550 {
551 tui_putc ('\n');
552 }
553
554 /* TUI version of displayer.putch. */
555
556 static void
557 tui_mld_putch (const struct match_list_displayer *displayer, int ch)
558 {
559 tui_putc (ch);
560 }
561
562 /* TUI version of displayer.puts. */
563
564 static void
565 tui_mld_puts (const struct match_list_displayer *displayer, const char *s)
566 {
567 tui_puts (s);
568 }
569
570 /* TUI version of displayer.flush. */
571
572 static void
573 tui_mld_flush (const struct match_list_displayer *displayer)
574 {
575 wrefresh (TUI_CMD_WIN->generic.handle);
576 }
577
578 /* TUI version of displayer.erase_entire_line. */
579
580 static void
581 tui_mld_erase_entire_line (const struct match_list_displayer *displayer)
582 {
583 WINDOW *w = TUI_CMD_WIN->generic.handle;
584 int cur_y = getcury (w);
585
586 wmove (w, cur_y, 0);
587 wclrtoeol (w);
588 wmove (w, cur_y, 0);
589 }
590
591 /* TUI version of displayer.beep. */
592
593 static void
594 tui_mld_beep (const struct match_list_displayer *displayer)
595 {
596 beep ();
597 }
598
599 /* A wrapper for wgetch that enters nonl mode. We We normally want
600 curses' "nl" mode, but when reading from the user, we'd like to
601 differentiate between C-j and C-m, because some users bind these
602 keys differently in their .inputrc. So, put curses into nonl mode
603 just when reading from the user. See PR tui/20819. */
604
605 static int
606 gdb_wgetch (WINDOW *win)
607 {
608 nonl ();
609 int r = wgetch (win);
610 nl ();
611 return r;
612 }
613
614 /* Helper function for tui_mld_read_key.
615 This temporarily replaces tui_getc for use during tab-completion
616 match list display. */
617
618 static int
619 tui_mld_getc (FILE *fp)
620 {
621 WINDOW *w = TUI_CMD_WIN->generic.handle;
622 int c = gdb_wgetch (w);
623
624 return c;
625 }
626
627 /* TUI version of displayer.read_key. */
628
629 static int
630 tui_mld_read_key (const struct match_list_displayer *displayer)
631 {
632 rl_getc_func_t *prev = rl_getc_function;
633 int c;
634
635 /* We can't use tui_getc as we need NEWLINE to not get emitted. */
636 rl_getc_function = tui_mld_getc;
637 c = rl_read_key ();
638 rl_getc_function = prev;
639 return c;
640 }
641
642 /* TUI version of rl_completion_display_matches_hook.
643 See gdb_display_match_list for a description of the arguments. */
644
645 static void
646 tui_rl_display_match_list (char **matches, int len, int max)
647 {
648 struct match_list_displayer displayer;
649
650 rl_get_screen_size (&displayer.height, &displayer.width);
651 displayer.crlf = tui_mld_crlf;
652 displayer.putch = tui_mld_putch;
653 displayer.puts = tui_mld_puts;
654 displayer.flush = tui_mld_flush;
655 displayer.erase_entire_line = tui_mld_erase_entire_line;
656 displayer.beep = tui_mld_beep;
657 displayer.read_key = tui_mld_read_key;
658
659 gdb_display_match_list (matches, len, max, &displayer);
660 }
661
662 /* Setup the IO for curses or non-curses mode.
663 - In non-curses mode, readline and gdb use the standard input and
664 standard output/error directly.
665 - In curses mode, the standard output/error is controlled by TUI
666 with the tui_stdout and tui_stderr. The output is redirected in
667 the curses command window. Several readline callbacks are installed
668 so that readline asks for its input to the curses command window
669 with wgetch(). */
670 void
671 tui_setup_io (int mode)
672 {
673 extern int _rl_echoing_p;
674
675 if (mode)
676 {
677 /* Redirect readline to TUI. */
678 tui_old_rl_redisplay_function = rl_redisplay_function;
679 tui_old_rl_deprep_terminal = rl_deprep_term_function;
680 tui_old_rl_prep_terminal = rl_prep_term_function;
681 tui_old_rl_getc_function = rl_getc_function;
682 tui_old_rl_display_matches_hook = rl_completion_display_matches_hook;
683 tui_old_rl_outstream = rl_outstream;
684 tui_old_rl_echoing_p = _rl_echoing_p;
685 rl_redisplay_function = tui_redisplay_readline;
686 rl_deprep_term_function = tui_deprep_terminal;
687 rl_prep_term_function = tui_prep_terminal;
688 rl_getc_function = tui_getc;
689 _rl_echoing_p = 0;
690 rl_outstream = tui_rl_outstream;
691 rl_prompt = 0;
692 rl_completion_display_matches_hook = tui_rl_display_match_list;
693 rl_already_prompted = 0;
694
695 /* Keep track of previous gdb output. */
696 tui_old_stdout = gdb_stdout;
697 tui_old_stderr = gdb_stderr;
698 tui_old_uiout = dynamic_cast<cli_ui_out *> (current_uiout);
699 gdb_assert (tui_old_uiout != nullptr);
700
701 /* Reconfigure gdb output. */
702 gdb_stdout = tui_stdout;
703 gdb_stderr = tui_stderr;
704 gdb_stdlog = gdb_stdout; /* for moment */
705 gdb_stdtarg = gdb_stderr; /* for moment */
706 gdb_stdtargerr = gdb_stderr; /* for moment */
707 current_uiout = tui_out;
708
709 /* Save tty for SIGCONT. */
710 savetty ();
711 }
712 else
713 {
714 /* Restore gdb output. */
715 gdb_stdout = tui_old_stdout;
716 gdb_stderr = tui_old_stderr;
717 gdb_stdlog = gdb_stdout; /* for moment */
718 gdb_stdtarg = gdb_stderr; /* for moment */
719 gdb_stdtargerr = gdb_stderr; /* for moment */
720 current_uiout = tui_old_uiout;
721
722 /* Restore readline. */
723 rl_redisplay_function = tui_old_rl_redisplay_function;
724 rl_deprep_term_function = tui_old_rl_deprep_terminal;
725 rl_prep_term_function = tui_old_rl_prep_terminal;
726 rl_getc_function = tui_old_rl_getc_function;
727 rl_completion_display_matches_hook = tui_old_rl_display_matches_hook;
728 rl_outstream = tui_old_rl_outstream;
729 _rl_echoing_p = tui_old_rl_echoing_p;
730 rl_already_prompted = 0;
731
732 /* Save tty for SIGCONT. */
733 savetty ();
734
735 /* Clean up color information. */
736 last_color_pair = -1;
737 last_style = ui_file_style ();
738 color_map.clear ();
739 color_pair_map.clear ();
740 }
741 }
742
743 #ifdef SIGCONT
744 /* Catch SIGCONT to restore the terminal and refresh the screen. */
745 static void
746 tui_cont_sig (int sig)
747 {
748 if (tui_active)
749 {
750 /* Restore the terminal setting because another process (shell)
751 might have changed it. */
752 resetty ();
753
754 /* Force a refresh of the screen. */
755 tui_refresh_all_win ();
756
757 wrefresh (TUI_CMD_WIN->generic.handle);
758 }
759 signal (sig, tui_cont_sig);
760 }
761 #endif
762
763 /* Initialize the IO for gdb in curses mode. */
764 void
765 tui_initialize_io (void)
766 {
767 #ifdef SIGCONT
768 signal (SIGCONT, tui_cont_sig);
769 #endif
770
771 /* Create tui output streams. */
772 tui_stdout = new tui_file (stdout);
773 tui_stderr = new tui_file (stderr);
774 tui_out = tui_out_new (tui_stdout);
775
776 /* Create the default UI. */
777 tui_old_uiout = cli_out_new (gdb_stdout);
778
779 #ifdef TUI_USE_PIPE_FOR_READLINE
780 /* Temporary solution for readline writing to stdout: redirect
781 readline output in a pipe, read that pipe and output the content
782 in the curses command window. */
783 if (gdb_pipe_cloexec (tui_readline_pipe) != 0)
784 error (_("Cannot create pipe for readline"));
785
786 tui_rl_outstream = fdopen (tui_readline_pipe[1], "w");
787 if (tui_rl_outstream == 0)
788 error (_("Cannot redirect readline output"));
789
790 setvbuf (tui_rl_outstream, (char*) NULL, _IOLBF, 0);
791
792 #ifdef O_NONBLOCK
793 (void) fcntl (tui_readline_pipe[0], F_SETFL, O_NONBLOCK);
794 #else
795 #ifdef O_NDELAY
796 (void) fcntl (tui_readline_pipe[0], F_SETFL, O_NDELAY);
797 #endif
798 #endif
799 add_file_handler (tui_readline_pipe[0], tui_readline_output, 0);
800 #else
801 tui_rl_outstream = stdout;
802 #endif
803 }
804
805 /* Get a character from the command window. This is called from the
806 readline package. */
807 static int
808 tui_getc (FILE *fp)
809 {
810 int ch;
811 WINDOW *w;
812
813 w = TUI_CMD_WIN->generic.handle;
814
815 #ifdef TUI_USE_PIPE_FOR_READLINE
816 /* Flush readline output. */
817 tui_readline_output (0, 0);
818 #endif
819
820 ch = gdb_wgetch (w);
821
822 /* The \n must be echoed because it will not be printed by
823 readline. */
824 if (ch == '\n')
825 {
826 /* When hitting return with an empty input, gdb executes the last
827 command. If we emit a newline, this fills up the command window
828 with empty lines with gdb prompt at beginning. Instead of that,
829 stay on the same line but provide a visual effect to show the
830 user we recognized the command. */
831 if (rl_end == 0 && !gdb_in_secondary_prompt_p (current_ui))
832 {
833 wmove (w, getcury (w), 0);
834
835 /* Clear the line. This will blink the gdb prompt since
836 it will be redrawn at the same line. */
837 wclrtoeol (w);
838 wrefresh (w);
839 napms (20);
840 }
841 else
842 {
843 /* Move cursor to the end of the command line before emitting the
844 newline. We need to do so because when ncurses outputs a newline
845 it truncates any text that appears past the end of the cursor. */
846 int px, py;
847 getyx (w, py, px);
848 px += rl_end - rl_point;
849 py += px / TUI_CMD_WIN->generic.width;
850 px %= TUI_CMD_WIN->generic.width;
851 wmove (w, py, px);
852 tui_putc ('\n');
853 }
854 }
855
856 /* Handle prev/next/up/down here. */
857 ch = tui_dispatch_ctrl_char (ch);
858
859 if (ch == KEY_BACKSPACE)
860 return '\b';
861
862 if (current_ui->command_editing && key_is_start_sequence (ch))
863 {
864 int ch_pending;
865
866 nodelay (w, TRUE);
867 ch_pending = gdb_wgetch (w);
868 nodelay (w, FALSE);
869
870 /* If we have pending input following a start sequence, call the stdin
871 event handler again because ncurses may have already read and stored
872 the input into its internal buffer, meaning that we won't get an stdin
873 event for it. If we don't compensate for this missed stdin event, key
874 sequences as Alt_F (^[f) will not behave promptly.
875
876 (We only compensates for the missed 2nd byte of a key sequence because
877 2-byte sequences are by far the most commonly used. ncurses may have
878 buffered a larger, 3+-byte key sequence though it remains to be seen
879 whether it is useful to compensate for all the bytes of such
880 sequences.) */
881 if (ch_pending != ERR)
882 {
883 ungetch (ch_pending);
884 call_stdin_event_handler_again_p = 1;
885 }
886 }
887
888 return ch;
889 }
890
891 /* Utility function to expand TABs in a STRING into spaces. STRING
892 will be displayed starting at column COL, and is assumed to include
893 no newlines. The returned expanded string is malloc'ed. */
894
895 char *
896 tui_expand_tabs (const char *string, int col)
897 {
898 int n_adjust, ncol;
899 const char *s;
900 char *ret, *q;
901
902 /* 1. How many additional characters do we need? */
903 for (ncol = col, n_adjust = 0, s = string; s; )
904 {
905 s = strpbrk (s, "\t");
906 if (s)
907 {
908 ncol += (s - string) + n_adjust;
909 /* Adjustment for the next tab stop, minus one for the TAB
910 we replace with spaces. */
911 n_adjust += 8 - (ncol % 8) - 1;
912 s++;
913 }
914 }
915
916 /* Allocate the copy. */
917 ret = q = (char *) xmalloc (strlen (string) + n_adjust + 1);
918
919 /* 2. Copy the original string while replacing TABs with spaces. */
920 for (ncol = col, s = string; s; )
921 {
922 const char *s1 = strpbrk (s, "\t");
923 if (s1)
924 {
925 if (s1 > s)
926 {
927 strncpy (q, s, s1 - s);
928 q += s1 - s;
929 ncol += s1 - s;
930 }
931 do {
932 *q++ = ' ';
933 ncol++;
934 } while ((ncol % 8) != 0);
935 s1++;
936 }
937 else
938 strcpy (q, s);
939 s = s1;
940 }
941
942 return ret;
943 }
This page took 0.048747 seconds and 4 git commands to generate.