Use wclrtoeol in tui_show_source_line
[deliverable/binutils-gdb.git] / gdb / tui / tui-io.c
CommitLineData
f377b406 1/* TUI support I/O functions.
f33c6cbf 2
e2882c85 3 Copyright (C) 1998-2018 Free Software Foundation, Inc.
f33c6cbf 4
f377b406
SC
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
a9762ec7 11 the Free Software Foundation; either version 3 of the License, or
f377b406
SC
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
a9762ec7 20 along with this program. If not, see <http://www.gnu.org/licenses/>. */
c906108c 21
c906108c 22#include "defs.h"
a198b876
SC
23#include "target.h"
24#include "event-loop.h"
e09d2eba 25#include "event-top.h"
a198b876
SC
26#include "command.h"
27#include "top.h"
d7b2e967
AC
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"
112e8700 35#include "tui/tui-out.h"
a198b876
SC
36#include "ui-out.h"
37#include "cli-out.h"
38#include <fcntl.h>
9d876a16 39#include <signal.h>
614c279d 40#include "filestuff.h"
82083d6d 41#include "completer.h"
6a83354a 42#include "gdb_curses.h"
1d1d0bf7 43#include <map>
a198b876 44
4a1bcc8c
MK
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
84371624
TT
50static int tui_getc (FILE *fp);
51
52static int
bcdf1568
AC
53key_is_start_sequence (int ch)
54{
55 return (ch == 27);
56}
57
ec6f8892
SC
58/* Use definition from readline 4.3. */
59#undef CTRL_CHAR
08ef48c5
MS
60#define CTRL_CHAR(c) \
61 ((c) < control_character_threshold && (((c) & 0x80) == 0))
ec6f8892 62
a198b876
SC
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
1cc6d956
MS
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).
a198b876
SC
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
1cc6d956
MS
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
8cee930b
SC
93 #undef TUI_USE_PIPE_FOR_READLINE. */
94
95/* For gdb 5.3, prefer to continue the pipe hack as a backup wheel. */
a156a290 96#ifdef HAVE_PIPE
8cee930b 97#define TUI_USE_PIPE_FOR_READLINE
a156a290 98#endif
1cc6d956 99/* #undef TUI_USE_PIPE_FOR_READLINE */
a198b876
SC
100
101/* TUI output files. */
102static struct ui_file *tui_stdout;
103static struct ui_file *tui_stderr;
2b68e2c5 104struct ui_out *tui_out;
a198b876
SC
105
106/* GDB output files in non-curses mode. */
107static struct ui_file *tui_old_stdout;
108static struct ui_file *tui_old_stderr;
112e8700 109cli_ui_out *tui_old_uiout;
a198b876
SC
110
111/* Readline previous hooks. */
840ed64d
JK
112static rl_getc_func_t *tui_old_rl_getc_function;
113static rl_voidfunc_t *tui_old_rl_redisplay_function;
114static rl_vintfunc_t *tui_old_rl_prep_terminal;
115static rl_voidfunc_t *tui_old_rl_deprep_terminal;
ef0b411a 116static rl_compdisp_func_t *tui_old_rl_display_matches_hook;
cc88a640 117static int tui_old_rl_echoing_p;
a198b876
SC
118
119/* Readline output stream.
120 Should be removed when readline is clean. */
121static FILE *tui_rl_outstream;
122static FILE *tui_old_rl_outstream;
8cee930b 123#ifdef TUI_USE_PIPE_FOR_READLINE
a198b876 124static int tui_readline_pipe[2];
8cee930b 125#endif
c906108c 126
57266a33
SC
127/* The last gdb prompt that was registered in readline.
128 This may be the main gdb prompt or a secondary prompt. */
129static char *tui_rl_saved_prompt;
130
9753a2f6
PA
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
135static void
136do_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
172static void
173update_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
8cee930b
SC
183static void
184tui_putc (char c)
185{
9753a2f6 186 WINDOW *w = TUI_CMD_WIN->generic.handle;
8cee930b 187
9753a2f6
PA
188 do_tui_putc (w, c);
189 update_cmdwin_start_line ();
8cee930b 190}
c906108c 191
1d1d0bf7
TT
192/* This maps colors to their corresponding color index. */
193
194static 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
199struct 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
213static 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
218static 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
231static bool
232get_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
264static int last_color_pair = -1;
265
266/* The most recently applied style. */
267
268static ui_file_style last_style;
269
270/* Given two colors, return their color pair index; making a new one
271 if necessary. */
272
273static int
274get_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
300static size_t
301apply_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
9753a2f6
PA
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
361void
362tui_write (const char *buf, size_t length)
1d1d0bf7
TT
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
369static void
370tui_puts_internal (const char *string, int *height)
9753a2f6
PA
371{
372 WINDOW *w = TUI_CMD_WIN->generic.handle;
1d1d0bf7
TT
373 char c;
374 int prev_col = 0;
9753a2f6 375
1d1d0bf7
TT
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 }
9753a2f6
PA
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. */
518be979 411
c906108c 412void
a198b876 413tui_puts (const char *string)
c906108c 414{
1d1d0bf7 415 tui_puts_internal (string, nullptr);
a198b876
SC
416}
417
418/* Readline callback.
419 Redisplay the command line with its prompt after readline has
420 changed the edited text. */
e09d2eba 421void
a198b876
SC
422tui_redisplay_readline (void)
423{
424 int prev_col;
425 int height;
cecc8b99 426 int col;
a198b876
SC
427 int c_pos;
428 int c_line;
429 int in;
430 WINDOW *w;
e6a959d6 431 const char *prompt;
a198b876 432 int start_line;
e3da6fc5
SC
433
434 /* Detect when we temporarily left SingleKey and now the readline
1cc6d956 435 edit buffer is empty, automatically restore the SingleKey
9b8d6827
SC
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
dbf30ca3 440 && !gdb_in_secondary_prompt_p (current_ui))
6d012f14 441 tui_set_key_mode (TUI_SINGLE_KEY_MODE);
e3da6fc5 442
6d012f14 443 if (tui_current_key_mode == TUI_SINGLE_KEY_MODE)
e09d2eba
SC
444 prompt = "";
445 else
57266a33 446 prompt = tui_rl_saved_prompt;
a198b876
SC
447
448 c_pos = -1;
449 c_line = -1;
6d012f14
AC
450 w = TUI_CMD_WIN->generic.handle;
451 start_line = TUI_CMD_WIN->detail.command_info.start_line;
a198b876
SC
452 wmove (w, start_line, 0);
453 prev_col = 0;
454 height = 1;
1d1d0bf7
TT
455 if (prompt != nullptr)
456 tui_puts_internal (prompt, &height);
457
458 prev_col = getcurx (w);
588dcc3e 459 for (in = 0; in <= rl_end; in++)
a198b876
SC
460 {
461 unsigned char c;
462
a198b876
SC
463 if (in == rl_point)
464 {
465 getyx (w, c_line, c_pos);
466 }
467
588dcc3e
PP
468 if (in == rl_end)
469 break;
470
471 c = (unsigned char) rl_line_buffer[in];
a198b876
SC
472 if (CTRL_CHAR (c) || c == RUBOUT)
473 {
474 waddch (w, '^');
475 waddch (w, CTRL_CHAR (c) ? UNCTRL (c) : '?');
476 }
312809f8
EZ
477 else if (c == '\t')
478 {
479 /* Expand TABs, since ncurses on MS-Windows doesn't. */
cecc8b99 480 col = getcurx (w);
312809f8
EZ
481 do
482 {
483 waddch (w, ' ');
484 col++;
485 } while ((col % 8) != 0);
486 }
c906108c
SS
487 else
488 {
a198b876 489 waddch (w, c);
c906108c 490 }
a198b876 491 if (c == '\n')
6f1cb6ea 492 TUI_CMD_WIN->detail.command_info.start_line = getcury (w);
cecc8b99 493 col = getcurx (w);
a198b876
SC
494 if (col < prev_col)
495 height++;
496 prev_col = col;
c906108c 497 }
a198b876 498 wclrtobot (w);
6f1cb6ea 499 TUI_CMD_WIN->detail.command_info.start_line = getcury (w);
a198b876 500 if (c_line >= 0)
6f1cb6ea 501 wmove (w, c_line, c_pos);
6d012f14 502 TUI_CMD_WIN->detail.command_info.start_line -= height - 1;
a198b876 503
a198b876
SC
504 wrefresh (w);
505 fflush(stdout);
506}
507
1cc6d956
MS
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. */
a198b876 511static void
88fa91b4 512tui_prep_terminal (int notused1)
c906108c 513{
57266a33
SC
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);
36d6eb95 518 tui_rl_saved_prompt = rl_prompt != NULL ? xstrdup (rl_prompt) : NULL;
a198b876 519}
c906108c 520
1cc6d956
MS
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. */
a198b876
SC
523static void
524tui_deprep_terminal (void)
525{
526}
c906108c 527
8cee930b 528#ifdef TUI_USE_PIPE_FOR_READLINE
a198b876
SC
529/* Read readline output pipe and feed the command window with it.
530 Should be removed when readline is clean. */
531static void
01f69b38 532tui_readline_output (int error, gdb_client_data data)
a198b876
SC
533{
534 int size;
535 char buf[256];
c906108c 536
a198b876
SC
537 size = read (tui_readline_pipe[0], buf, sizeof (buf) - 1);
538 if (size > 0 && tui_active)
c906108c 539 {
a198b876
SC
540 buf[size] = 0;
541 tui_puts (buf);
c906108c 542 }
a198b876 543}
8cee930b
SC
544#endif
545
82083d6d 546/* TUI version of displayer.crlf. */
8cee930b 547
82083d6d
DE
548static void
549tui_mld_crlf (const struct match_list_displayer *displayer)
8cee930b 550{
82083d6d 551 tui_putc ('\n');
8cee930b
SC
552}
553
82083d6d 554/* TUI version of displayer.putch. */
8cee930b 555
82083d6d
DE
556static void
557tui_mld_putch (const struct match_list_displayer *displayer, int ch)
8cee930b 558{
82083d6d 559 tui_putc (ch);
8cee930b
SC
560}
561
82083d6d
DE
562/* TUI version of displayer.puts. */
563
564static void
565tui_mld_puts (const struct match_list_displayer *displayer, const char *s)
8cee930b 566{
82083d6d
DE
567 tui_puts (s);
568}
8cee930b 569
82083d6d
DE
570/* TUI version of displayer.flush. */
571
572static void
573tui_mld_flush (const struct match_list_displayer *displayer)
574{
575 wrefresh (TUI_CMD_WIN->generic.handle);
8cee930b
SC
576}
577
82083d6d 578/* TUI version of displayer.erase_entire_line. */
8cee930b 579
8cee930b 580static void
82083d6d 581tui_mld_erase_entire_line (const struct match_list_displayer *displayer)
8cee930b 582{
82083d6d 583 WINDOW *w = TUI_CMD_WIN->generic.handle;
6f1cb6ea 584 int cur_y = getcury (w);
8cee930b 585
6f1cb6ea 586 wmove (w, cur_y, 0);
82083d6d 587 wclrtoeol (w);
6f1cb6ea 588 wmove (w, cur_y, 0);
82083d6d 589}
8cee930b 590
82083d6d 591/* TUI version of displayer.beep. */
8cee930b 592
82083d6d
DE
593static void
594tui_mld_beep (const struct match_list_displayer *displayer)
595{
596 beep ();
597}
598
7a956928
TT
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
605static int
606gdb_wgetch (WINDOW *win)
607{
608 nonl ();
609 int r = wgetch (win);
610 nl ();
611 return r;
612}
613
82083d6d
DE
614/* Helper function for tui_mld_read_key.
615 This temporarily replaces tui_getc for use during tab-completion
616 match list display. */
617
618static int
619tui_mld_getc (FILE *fp)
620{
621 WINDOW *w = TUI_CMD_WIN->generic.handle;
7a956928 622 int c = gdb_wgetch (w);
8cee930b 623
82083d6d
DE
624 return c;
625}
8cee930b 626
82083d6d 627/* TUI version of displayer.read_key. */
8cee930b 628
82083d6d
DE
629static int
630tui_mld_read_key (const struct match_list_displayer *displayer)
631{
632 rl_getc_func_t *prev = rl_getc_function;
633 int c;
8cee930b 634
82083d6d
DE
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}
8cee930b 641
82083d6d
DE
642/* TUI version of rl_completion_display_matches_hook.
643 See gdb_display_match_list for a description of the arguments. */
8cee930b 644
82083d6d
DE
645static void
646tui_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);
8cee930b 660}
a198b876
SC
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(). */
670void
671tui_setup_io (int mode)
672{
cc88a640
JK
673 extern int _rl_echoing_p;
674
a198b876 675 if (mode)
c906108c 676 {
a198b876
SC
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;
ef0b411a 682 tui_old_rl_display_matches_hook = rl_completion_display_matches_hook;
a198b876 683 tui_old_rl_outstream = rl_outstream;
cc88a640 684 tui_old_rl_echoing_p = _rl_echoing_p;
a198b876
SC
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;
cc88a640 689 _rl_echoing_p = 0;
a198b876
SC
690 rl_outstream = tui_rl_outstream;
691 rl_prompt = 0;
8cee930b
SC
692 rl_completion_display_matches_hook = tui_rl_display_match_list;
693 rl_already_prompted = 0;
a198b876
SC
694
695 /* Keep track of previous gdb output. */
696 tui_old_stdout = gdb_stdout;
697 tui_old_stderr = gdb_stderr;
112e8700
SM
698 tui_old_uiout = dynamic_cast<cli_ui_out *> (current_uiout);
699 gdb_assert (tui_old_uiout != nullptr);
a198b876
SC
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 */
8d4d924b 706 gdb_stdtargerr = gdb_stderr; /* for moment */
79a45e25 707 current_uiout = tui_out;
9d876a16
SC
708
709 /* Save tty for SIGCONT. */
710 savetty ();
c906108c 711 }
a198b876 712 else
c906108c 713 {
a198b876
SC
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 */
8d4d924b 719 gdb_stdtargerr = gdb_stderr; /* for moment */
79a45e25 720 current_uiout = tui_old_uiout;
a198b876
SC
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;
ef0b411a 727 rl_completion_display_matches_hook = tui_old_rl_display_matches_hook;
a198b876 728 rl_outstream = tui_old_rl_outstream;
cc88a640 729 _rl_echoing_p = tui_old_rl_echoing_p;
bd9b0abf 730 rl_already_prompted = 0;
9d876a16
SC
731
732 /* Save tty for SIGCONT. */
733 savetty ();
1d1d0bf7
TT
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 ();
9d876a16
SC
740 }
741}
742
743#ifdef SIGCONT
744/* Catch SIGCONT to restore the terminal and refresh the screen. */
745static void
746tui_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. */
a21fcd8f 755 tui_refresh_all_win ();
d75e970c 756
6d012f14 757 wrefresh (TUI_CMD_WIN->generic.handle);
c906108c 758 }
9d876a16 759 signal (sig, tui_cont_sig);
a198b876 760}
9d876a16 761#endif
c906108c 762
a198b876
SC
763/* Initialize the IO for gdb in curses mode. */
764void
d02c80cd 765tui_initialize_io (void)
a198b876 766{
9d876a16
SC
767#ifdef SIGCONT
768 signal (SIGCONT, tui_cont_sig);
769#endif
770
a198b876 771 /* Create tui output streams. */
d7e74731
PA
772 tui_stdout = new tui_file (stdout);
773 tui_stderr = new tui_file (stderr);
a198b876
SC
774 tui_out = tui_out_new (tui_stdout);
775
43df09d9 776 /* Create the default UI. */
4801a9a3 777 tui_old_uiout = cli_out_new (gdb_stdout);
a198b876 778
8cee930b 779#ifdef TUI_USE_PIPE_FOR_READLINE
1cc6d956
MS
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. */
614c279d 783 if (gdb_pipe_cloexec (tui_readline_pipe) != 0)
e0e6bcab
GB
784 error (_("Cannot create pipe for readline"));
785
a198b876
SC
786 tui_rl_outstream = fdopen (tui_readline_pipe[1], "w");
787 if (tui_rl_outstream == 0)
e0e6bcab
GB
788 error (_("Cannot redirect readline output"));
789
0f59c96f 790 setvbuf (tui_rl_outstream, (char*) NULL, _IOLBF, 0);
c906108c 791
a198b876
SC
792#ifdef O_NONBLOCK
793 (void) fcntl (tui_readline_pipe[0], F_SETFL, O_NONBLOCK);
c906108c 794#else
a198b876
SC
795#ifdef O_NDELAY
796 (void) fcntl (tui_readline_pipe[0], F_SETFL, O_NDELAY);
c906108c 797#endif
a198b876 798#endif
a198b876 799 add_file_handler (tui_readline_pipe[0], tui_readline_output, 0);
8cee930b
SC
800#else
801 tui_rl_outstream = stdout;
802#endif
a198b876
SC
803}
804
1cc6d956
MS
805/* Get a character from the command window. This is called from the
806 readline package. */
84371624 807static int
a198b876
SC
808tui_getc (FILE *fp)
809{
810 int ch;
811 WINDOW *w;
812
6d012f14 813 w = TUI_CMD_WIN->generic.handle;
a198b876 814
8cee930b 815#ifdef TUI_USE_PIPE_FOR_READLINE
a198b876 816 /* Flush readline output. */
01f69b38 817 tui_readline_output (0, 0);
8cee930b
SC
818#endif
819
7a956928 820 ch = gdb_wgetch (w);
c906108c 821
1cc6d956
MS
822 /* The \n must be echoed because it will not be printed by
823 readline. */
a198b876
SC
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. */
dbf30ca3 831 if (rl_end == 0 && !gdb_in_secondary_prompt_p (current_ui))
a198b876 832 {
6f1cb6ea 833 wmove (w, getcury (w), 0);
a198b876
SC
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 {
d9080678
PP
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. */
6f1cb6ea
PP
846 int px, py;
847 getyx (w, py, px);
d9080678
PP
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);
7a8bcb88 852 tui_putc ('\n');
a198b876
SC
853 }
854 }
855
69efdff1
PP
856 /* Handle prev/next/up/down here. */
857 ch = tui_dispatch_ctrl_char (ch);
a198b876 858
a198b876
SC
859 if (ch == KEY_BACKSPACE)
860 return '\b';
d64e57fa 861
3c216924 862 if (current_ui->command_editing && key_is_start_sequence (ch))
d64e57fa
PP
863 {
864 int ch_pending;
865
866 nodelay (w, TRUE);
7a956928 867 ch_pending = gdb_wgetch (w);
d64e57fa
PP
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
c906108c 888 return ch;
a198b876 889}
c906108c 890
312809f8
EZ
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
895char *
896tui_expand_tabs (const char *string, int col)
897{
b1a0f704 898 int n_adjust, ncol;
312809f8
EZ
899 const char *s;
900 char *ret, *q;
901
902 /* 1. How many additional characters do we need? */
b1a0f704 903 for (ncol = col, n_adjust = 0, s = string; s; )
312809f8
EZ
904 {
905 s = strpbrk (s, "\t");
906 if (s)
907 {
b1a0f704 908 ncol += (s - string) + n_adjust;
312809f8
EZ
909 /* Adjustment for the next tab stop, minus one for the TAB
910 we replace with spaces. */
b1a0f704 911 n_adjust += 8 - (ncol % 8) - 1;
312809f8
EZ
912 s++;
913 }
914 }
915
916 /* Allocate the copy. */
224c3ddb 917 ret = q = (char *) xmalloc (strlen (string) + n_adjust + 1);
312809f8
EZ
918
919 /* 2. Copy the original string while replacing TABs with spaces. */
b1a0f704 920 for (ncol = col, s = string; s; )
312809f8 921 {
cd46431b 922 const char *s1 = strpbrk (s, "\t");
312809f8
EZ
923 if (s1)
924 {
925 if (s1 > s)
926 {
927 strncpy (q, s, s1 - s);
928 q += s1 - s;
b1a0f704 929 ncol += s1 - s;
312809f8
EZ
930 }
931 do {
932 *q++ = ' ';
b1a0f704
EZ
933 ncol++;
934 } while ((ncol % 8) != 0);
312809f8
EZ
935 s1++;
936 }
937 else
938 strcpy (q, s);
939 s = s1;
940 }
941
942 return ret;
943}
This page took 2.019649 seconds and 4 git commands to generate.