Add back gdb_pretty_print_insn
[deliverable/binutils-gdb.git] / gdb / tui / tui-io.c
CommitLineData
f377b406 1/* TUI support I/O functions.
f33c6cbf 2
61baf725 3 Copyright (C) 1998-2017 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"
a198b876 43
4a1bcc8c
MK
44/* This redefines CTRL if it is not already defined, so it must come
45 after terminal state releated include files like <term.h> and
46 "gdb_curses.h". */
47#include "readline/readline.h"
48
bcdf1568
AC
49int
50key_is_start_sequence (int ch)
51{
52 return (ch == 27);
53}
54
55int
56key_is_end_sequence (int ch)
57{
58 return (ch == 126);
59}
60
61int
62key_is_backspace (int ch)
63{
64 return (ch == 8);
65}
66
ec6f8892
SC
67/* Use definition from readline 4.3. */
68#undef CTRL_CHAR
08ef48c5
MS
69#define CTRL_CHAR(c) \
70 ((c) < control_character_threshold && (((c) & 0x80) == 0))
ec6f8892 71
a198b876
SC
72/* This file controls the IO interactions between gdb and curses.
73 When the TUI is enabled, gdb has two modes a curses and a standard
74 mode.
75
1cc6d956
MS
76 In curses mode, the gdb outputs are made in a curses command
77 window. For this, the gdb_stdout and gdb_stderr are redirected to
78 the specific ui_file implemented by TUI. The output is handled by
79 tui_puts(). The input is also controlled by curses with
80 tui_getc(). The readline library uses this function to get its
81 input. Several readline hooks are installed to redirect readline
82 output to the TUI (see also the note below).
a198b876
SC
83
84 In normal mode, the gdb outputs are restored to their origin, that
85 is as if TUI is not used. Readline also uses its original getc()
86 function with stdin.
87
1cc6d956
MS
88 Note SCz/2001-07-21: the current readline is not clean in its
89 management of the output. Even if we install a redisplay handler,
90 it sometimes writes on a stdout file. It is important to redirect
91 every output produced by readline, otherwise the curses window will
92 be garbled. This is implemented with a pipe that TUI reads and
93 readline writes to. A gdb input handler is created so that reading
94 the pipe is handled automatically. This will probably not work on
95 non-Unix platforms. The best fix is to make readline clean enougth
96 so that is never write on stdout.
97
98 Note SCz/2002-09-01: we now use more readline hooks and it seems
99 that with them we don't need the pipe anymore (verified by creating
100 the pipe and closing its end so that write causes a SIGPIPE). The
101 old pipe code is still there and can be conditionally removed by
8cee930b
SC
102 #undef TUI_USE_PIPE_FOR_READLINE. */
103
104/* For gdb 5.3, prefer to continue the pipe hack as a backup wheel. */
a156a290 105#ifdef HAVE_PIPE
8cee930b 106#define TUI_USE_PIPE_FOR_READLINE
a156a290 107#endif
1cc6d956 108/* #undef TUI_USE_PIPE_FOR_READLINE */
a198b876
SC
109
110/* TUI output files. */
111static struct ui_file *tui_stdout;
112static struct ui_file *tui_stderr;
2b68e2c5 113struct ui_out *tui_out;
a198b876
SC
114
115/* GDB output files in non-curses mode. */
116static struct ui_file *tui_old_stdout;
117static struct ui_file *tui_old_stderr;
112e8700 118cli_ui_out *tui_old_uiout;
a198b876
SC
119
120/* Readline previous hooks. */
840ed64d
JK
121static rl_getc_func_t *tui_old_rl_getc_function;
122static rl_voidfunc_t *tui_old_rl_redisplay_function;
123static rl_vintfunc_t *tui_old_rl_prep_terminal;
124static rl_voidfunc_t *tui_old_rl_deprep_terminal;
ef0b411a 125static rl_compdisp_func_t *tui_old_rl_display_matches_hook;
cc88a640 126static int tui_old_rl_echoing_p;
a198b876
SC
127
128/* Readline output stream.
129 Should be removed when readline is clean. */
130static FILE *tui_rl_outstream;
131static FILE *tui_old_rl_outstream;
8cee930b 132#ifdef TUI_USE_PIPE_FOR_READLINE
a198b876 133static int tui_readline_pipe[2];
8cee930b 134#endif
c906108c 135
57266a33
SC
136/* The last gdb prompt that was registered in readline.
137 This may be the main gdb prompt or a secondary prompt. */
138static char *tui_rl_saved_prompt;
139
8cee930b
SC
140static void
141tui_putc (char c)
142{
143 char buf[2];
144
145 buf[0] = c;
146 buf[1] = 0;
147 tui_puts (buf);
148}
c906108c 149
518be979
DE
150/* Print the string in the curses command window.
151 The output is buffered. It is up to the caller to refresh the screen
152 if necessary. */
153
c906108c 154void
a198b876 155tui_puts (const char *string)
c906108c 156{
a198b876
SC
157 static int tui_skip_line = -1;
158 char c;
159 WINDOW *w;
c906108c 160
6d012f14 161 w = TUI_CMD_WIN->generic.handle;
a198b876 162 while ((c = *string++) != 0)
c906108c 163 {
a198b876
SC
164 /* Catch annotation and discard them. We need two \032 and
165 discard until a \n is seen. */
166 if (c == '\032')
167 {
168 tui_skip_line++;
169 }
170 else if (tui_skip_line != 1)
171 {
172 tui_skip_line = -1;
312809f8
EZ
173 /* Expand TABs, since ncurses on MS-Windows doesn't. */
174 if (c == '\t')
175 {
cecc8b99 176 int col;
312809f8 177
cecc8b99 178 col = getcurx (w);
312809f8
EZ
179 do
180 {
181 waddch (w, ' ');
182 col++;
183 } while ((col % 8) != 0);
184 }
185 else
186 waddch (w, c);
a198b876
SC
187 }
188 else if (c == '\n')
189 tui_skip_line = -1;
190 }
6f1cb6ea 191 TUI_CMD_WIN->detail.command_info.start_line = getcury (w);
a198b876
SC
192}
193
194/* Readline callback.
195 Redisplay the command line with its prompt after readline has
196 changed the edited text. */
e09d2eba 197void
a198b876
SC
198tui_redisplay_readline (void)
199{
200 int prev_col;
201 int height;
cecc8b99 202 int col;
a198b876
SC
203 int c_pos;
204 int c_line;
205 int in;
206 WINDOW *w;
e6a959d6 207 const char *prompt;
a198b876 208 int start_line;
e3da6fc5
SC
209
210 /* Detect when we temporarily left SingleKey and now the readline
1cc6d956 211 edit buffer is empty, automatically restore the SingleKey
9b8d6827
SC
212 mode. The restore must only be done if the command has finished.
213 The command could call prompt_for_continue and we must not
214 restore SingleKey so that the prompt and normal keymap are used. */
215 if (tui_current_key_mode == TUI_ONE_COMMAND_MODE && rl_end == 0
dbf30ca3 216 && !gdb_in_secondary_prompt_p (current_ui))
6d012f14 217 tui_set_key_mode (TUI_SINGLE_KEY_MODE);
e3da6fc5 218
6d012f14 219 if (tui_current_key_mode == TUI_SINGLE_KEY_MODE)
e09d2eba
SC
220 prompt = "";
221 else
57266a33 222 prompt = tui_rl_saved_prompt;
a198b876
SC
223
224 c_pos = -1;
225 c_line = -1;
6d012f14
AC
226 w = TUI_CMD_WIN->generic.handle;
227 start_line = TUI_CMD_WIN->detail.command_info.start_line;
a198b876
SC
228 wmove (w, start_line, 0);
229 prev_col = 0;
230 height = 1;
231 for (in = 0; prompt && prompt[in]; in++)
232 {
233 waddch (w, prompt[in]);
cecc8b99 234 col = getcurx (w);
588dcc3e 235 if (col <= prev_col)
a198b876
SC
236 height++;
237 prev_col = col;
238 }
588dcc3e 239 for (in = 0; in <= rl_end; in++)
a198b876
SC
240 {
241 unsigned char c;
242
a198b876
SC
243 if (in == rl_point)
244 {
245 getyx (w, c_line, c_pos);
246 }
247
588dcc3e
PP
248 if (in == rl_end)
249 break;
250
251 c = (unsigned char) rl_line_buffer[in];
a198b876
SC
252 if (CTRL_CHAR (c) || c == RUBOUT)
253 {
254 waddch (w, '^');
255 waddch (w, CTRL_CHAR (c) ? UNCTRL (c) : '?');
256 }
312809f8
EZ
257 else if (c == '\t')
258 {
259 /* Expand TABs, since ncurses on MS-Windows doesn't. */
cecc8b99 260 col = getcurx (w);
312809f8
EZ
261 do
262 {
263 waddch (w, ' ');
264 col++;
265 } while ((col % 8) != 0);
266 }
c906108c
SS
267 else
268 {
a198b876 269 waddch (w, c);
c906108c 270 }
a198b876 271 if (c == '\n')
6f1cb6ea 272 TUI_CMD_WIN->detail.command_info.start_line = getcury (w);
cecc8b99 273 col = getcurx (w);
a198b876
SC
274 if (col < prev_col)
275 height++;
276 prev_col = col;
c906108c 277 }
a198b876 278 wclrtobot (w);
6f1cb6ea 279 TUI_CMD_WIN->detail.command_info.start_line = getcury (w);
a198b876 280 if (c_line >= 0)
6f1cb6ea 281 wmove (w, c_line, c_pos);
6d012f14 282 TUI_CMD_WIN->detail.command_info.start_line -= height - 1;
a198b876 283
a198b876
SC
284 wrefresh (w);
285 fflush(stdout);
286}
287
1cc6d956
MS
288/* Readline callback to prepare the terminal. It is called once each
289 time we enter readline. Terminal is already setup in curses
290 mode. */
a198b876 291static void
88fa91b4 292tui_prep_terminal (int notused1)
c906108c 293{
57266a33
SC
294 /* Save the prompt registered in readline to correctly display it.
295 (we can't use gdb_prompt() due to secondary prompts and can't use
296 rl_prompt because it points to an alloca buffer). */
297 xfree (tui_rl_saved_prompt);
36d6eb95 298 tui_rl_saved_prompt = rl_prompt != NULL ? xstrdup (rl_prompt) : NULL;
a198b876 299}
c906108c 300
1cc6d956
MS
301/* Readline callback to restore the terminal. It is called once each
302 time we leave readline. There is nothing to do in curses mode. */
a198b876
SC
303static void
304tui_deprep_terminal (void)
305{
306}
c906108c 307
8cee930b 308#ifdef TUI_USE_PIPE_FOR_READLINE
a198b876
SC
309/* Read readline output pipe and feed the command window with it.
310 Should be removed when readline is clean. */
311static void
01f69b38 312tui_readline_output (int error, gdb_client_data data)
a198b876
SC
313{
314 int size;
315 char buf[256];
c906108c 316
a198b876
SC
317 size = read (tui_readline_pipe[0], buf, sizeof (buf) - 1);
318 if (size > 0 && tui_active)
c906108c 319 {
a198b876
SC
320 buf[size] = 0;
321 tui_puts (buf);
c906108c 322 }
a198b876 323}
8cee930b
SC
324#endif
325
82083d6d 326/* TUI version of displayer.crlf. */
8cee930b 327
82083d6d
DE
328static void
329tui_mld_crlf (const struct match_list_displayer *displayer)
8cee930b 330{
82083d6d 331 tui_putc ('\n');
8cee930b
SC
332}
333
82083d6d 334/* TUI version of displayer.putch. */
8cee930b 335
82083d6d
DE
336static void
337tui_mld_putch (const struct match_list_displayer *displayer, int ch)
8cee930b 338{
82083d6d 339 tui_putc (ch);
8cee930b
SC
340}
341
82083d6d
DE
342/* TUI version of displayer.puts. */
343
344static void
345tui_mld_puts (const struct match_list_displayer *displayer, const char *s)
8cee930b 346{
82083d6d
DE
347 tui_puts (s);
348}
8cee930b 349
82083d6d
DE
350/* TUI version of displayer.flush. */
351
352static void
353tui_mld_flush (const struct match_list_displayer *displayer)
354{
355 wrefresh (TUI_CMD_WIN->generic.handle);
8cee930b
SC
356}
357
82083d6d 358/* TUI version of displayer.erase_entire_line. */
8cee930b 359
8cee930b 360static void
82083d6d 361tui_mld_erase_entire_line (const struct match_list_displayer *displayer)
8cee930b 362{
82083d6d 363 WINDOW *w = TUI_CMD_WIN->generic.handle;
6f1cb6ea 364 int cur_y = getcury (w);
8cee930b 365
6f1cb6ea 366 wmove (w, cur_y, 0);
82083d6d 367 wclrtoeol (w);
6f1cb6ea 368 wmove (w, cur_y, 0);
82083d6d 369}
8cee930b 370
82083d6d 371/* TUI version of displayer.beep. */
8cee930b 372
82083d6d
DE
373static void
374tui_mld_beep (const struct match_list_displayer *displayer)
375{
376 beep ();
377}
378
379/* Helper function for tui_mld_read_key.
380 This temporarily replaces tui_getc for use during tab-completion
381 match list display. */
382
383static int
384tui_mld_getc (FILE *fp)
385{
386 WINDOW *w = TUI_CMD_WIN->generic.handle;
387 int c = wgetch (w);
8cee930b 388
82083d6d
DE
389 return c;
390}
8cee930b 391
82083d6d 392/* TUI version of displayer.read_key. */
8cee930b 393
82083d6d
DE
394static int
395tui_mld_read_key (const struct match_list_displayer *displayer)
396{
397 rl_getc_func_t *prev = rl_getc_function;
398 int c;
8cee930b 399
82083d6d
DE
400 /* We can't use tui_getc as we need NEWLINE to not get emitted. */
401 rl_getc_function = tui_mld_getc;
402 c = rl_read_key ();
403 rl_getc_function = prev;
404 return c;
405}
8cee930b 406
82083d6d
DE
407/* TUI version of rl_completion_display_matches_hook.
408 See gdb_display_match_list for a description of the arguments. */
8cee930b 409
82083d6d
DE
410static void
411tui_rl_display_match_list (char **matches, int len, int max)
412{
413 struct match_list_displayer displayer;
414
415 rl_get_screen_size (&displayer.height, &displayer.width);
416 displayer.crlf = tui_mld_crlf;
417 displayer.putch = tui_mld_putch;
418 displayer.puts = tui_mld_puts;
419 displayer.flush = tui_mld_flush;
420 displayer.erase_entire_line = tui_mld_erase_entire_line;
421 displayer.beep = tui_mld_beep;
422 displayer.read_key = tui_mld_read_key;
423
424 gdb_display_match_list (matches, len, max, &displayer);
8cee930b 425}
a198b876
SC
426
427/* Setup the IO for curses or non-curses mode.
428 - In non-curses mode, readline and gdb use the standard input and
429 standard output/error directly.
430 - In curses mode, the standard output/error is controlled by TUI
431 with the tui_stdout and tui_stderr. The output is redirected in
432 the curses command window. Several readline callbacks are installed
433 so that readline asks for its input to the curses command window
434 with wgetch(). */
435void
436tui_setup_io (int mode)
437{
cc88a640
JK
438 extern int _rl_echoing_p;
439
a198b876 440 if (mode)
c906108c 441 {
a198b876
SC
442 /* Redirect readline to TUI. */
443 tui_old_rl_redisplay_function = rl_redisplay_function;
444 tui_old_rl_deprep_terminal = rl_deprep_term_function;
445 tui_old_rl_prep_terminal = rl_prep_term_function;
446 tui_old_rl_getc_function = rl_getc_function;
ef0b411a 447 tui_old_rl_display_matches_hook = rl_completion_display_matches_hook;
a198b876 448 tui_old_rl_outstream = rl_outstream;
cc88a640 449 tui_old_rl_echoing_p = _rl_echoing_p;
a198b876
SC
450 rl_redisplay_function = tui_redisplay_readline;
451 rl_deprep_term_function = tui_deprep_terminal;
452 rl_prep_term_function = tui_prep_terminal;
453 rl_getc_function = tui_getc;
cc88a640 454 _rl_echoing_p = 0;
a198b876
SC
455 rl_outstream = tui_rl_outstream;
456 rl_prompt = 0;
8cee930b
SC
457 rl_completion_display_matches_hook = tui_rl_display_match_list;
458 rl_already_prompted = 0;
a198b876
SC
459
460 /* Keep track of previous gdb output. */
461 tui_old_stdout = gdb_stdout;
462 tui_old_stderr = gdb_stderr;
112e8700
SM
463 tui_old_uiout = dynamic_cast<cli_ui_out *> (current_uiout);
464 gdb_assert (tui_old_uiout != nullptr);
a198b876
SC
465
466 /* Reconfigure gdb output. */
467 gdb_stdout = tui_stdout;
468 gdb_stderr = tui_stderr;
469 gdb_stdlog = gdb_stdout; /* for moment */
470 gdb_stdtarg = gdb_stderr; /* for moment */
8d4d924b 471 gdb_stdtargerr = gdb_stderr; /* for moment */
79a45e25 472 current_uiout = tui_out;
9d876a16
SC
473
474 /* Save tty for SIGCONT. */
475 savetty ();
c906108c 476 }
a198b876 477 else
c906108c 478 {
a198b876
SC
479 /* Restore gdb output. */
480 gdb_stdout = tui_old_stdout;
481 gdb_stderr = tui_old_stderr;
482 gdb_stdlog = gdb_stdout; /* for moment */
483 gdb_stdtarg = gdb_stderr; /* for moment */
8d4d924b 484 gdb_stdtargerr = gdb_stderr; /* for moment */
79a45e25 485 current_uiout = tui_old_uiout;
a198b876
SC
486
487 /* Restore readline. */
488 rl_redisplay_function = tui_old_rl_redisplay_function;
489 rl_deprep_term_function = tui_old_rl_deprep_terminal;
490 rl_prep_term_function = tui_old_rl_prep_terminal;
491 rl_getc_function = tui_old_rl_getc_function;
ef0b411a 492 rl_completion_display_matches_hook = tui_old_rl_display_matches_hook;
a198b876 493 rl_outstream = tui_old_rl_outstream;
cc88a640 494 _rl_echoing_p = tui_old_rl_echoing_p;
bd9b0abf 495 rl_already_prompted = 0;
9d876a16
SC
496
497 /* Save tty for SIGCONT. */
498 savetty ();
499 }
500}
501
502#ifdef SIGCONT
503/* Catch SIGCONT to restore the terminal and refresh the screen. */
504static void
505tui_cont_sig (int sig)
506{
507 if (tui_active)
508 {
509 /* Restore the terminal setting because another process (shell)
510 might have changed it. */
511 resetty ();
512
513 /* Force a refresh of the screen. */
a21fcd8f 514 tui_refresh_all_win ();
d75e970c 515
6d012f14 516 wrefresh (TUI_CMD_WIN->generic.handle);
c906108c 517 }
9d876a16 518 signal (sig, tui_cont_sig);
a198b876 519}
9d876a16 520#endif
c906108c 521
a198b876
SC
522/* Initialize the IO for gdb in curses mode. */
523void
d02c80cd 524tui_initialize_io (void)
a198b876 525{
9d876a16
SC
526#ifdef SIGCONT
527 signal (SIGCONT, tui_cont_sig);
528#endif
529
a198b876
SC
530 /* Create tui output streams. */
531 tui_stdout = tui_fileopen (stdout);
532 tui_stderr = tui_fileopen (stderr);
533 tui_out = tui_out_new (tui_stdout);
534
43df09d9 535 /* Create the default UI. */
4801a9a3 536 tui_old_uiout = cli_out_new (gdb_stdout);
a198b876 537
8cee930b 538#ifdef TUI_USE_PIPE_FOR_READLINE
1cc6d956
MS
539 /* Temporary solution for readline writing to stdout: redirect
540 readline output in a pipe, read that pipe and output the content
541 in the curses command window. */
614c279d 542 if (gdb_pipe_cloexec (tui_readline_pipe) != 0)
e0e6bcab
GB
543 error (_("Cannot create pipe for readline"));
544
a198b876
SC
545 tui_rl_outstream = fdopen (tui_readline_pipe[1], "w");
546 if (tui_rl_outstream == 0)
e0e6bcab
GB
547 error (_("Cannot redirect readline output"));
548
0f59c96f 549 setvbuf (tui_rl_outstream, (char*) NULL, _IOLBF, 0);
c906108c 550
a198b876
SC
551#ifdef O_NONBLOCK
552 (void) fcntl (tui_readline_pipe[0], F_SETFL, O_NONBLOCK);
c906108c 553#else
a198b876
SC
554#ifdef O_NDELAY
555 (void) fcntl (tui_readline_pipe[0], F_SETFL, O_NDELAY);
c906108c 556#endif
a198b876 557#endif
a198b876 558 add_file_handler (tui_readline_pipe[0], tui_readline_output, 0);
8cee930b
SC
559#else
560 tui_rl_outstream = stdout;
561#endif
a198b876
SC
562}
563
1cc6d956
MS
564/* Get a character from the command window. This is called from the
565 readline package. */
a198b876
SC
566int
567tui_getc (FILE *fp)
568{
569 int ch;
570 WINDOW *w;
571
6d012f14 572 w = TUI_CMD_WIN->generic.handle;
a198b876 573
8cee930b 574#ifdef TUI_USE_PIPE_FOR_READLINE
a198b876 575 /* Flush readline output. */
01f69b38 576 tui_readline_output (0, 0);
8cee930b
SC
577#endif
578
a198b876 579 ch = wgetch (w);
c906108c 580
1cc6d956
MS
581 /* The \n must be echoed because it will not be printed by
582 readline. */
a198b876
SC
583 if (ch == '\n')
584 {
585 /* When hitting return with an empty input, gdb executes the last
586 command. If we emit a newline, this fills up the command window
587 with empty lines with gdb prompt at beginning. Instead of that,
588 stay on the same line but provide a visual effect to show the
589 user we recognized the command. */
dbf30ca3 590 if (rl_end == 0 && !gdb_in_secondary_prompt_p (current_ui))
a198b876 591 {
6f1cb6ea 592 wmove (w, getcury (w), 0);
a198b876
SC
593
594 /* Clear the line. This will blink the gdb prompt since
595 it will be redrawn at the same line. */
596 wclrtoeol (w);
597 wrefresh (w);
598 napms (20);
599 }
600 else
601 {
d9080678
PP
602 /* Move cursor to the end of the command line before emitting the
603 newline. We need to do so because when ncurses outputs a newline
604 it truncates any text that appears past the end of the cursor. */
6f1cb6ea
PP
605 int px, py;
606 getyx (w, py, px);
d9080678
PP
607 px += rl_end - rl_point;
608 py += px / TUI_CMD_WIN->generic.width;
609 px %= TUI_CMD_WIN->generic.width;
610 wmove (w, py, px);
7a8bcb88 611 tui_putc ('\n');
a198b876
SC
612 }
613 }
614
69efdff1
PP
615 /* Handle prev/next/up/down here. */
616 ch = tui_dispatch_ctrl_char (ch);
a198b876 617
a198b876
SC
618 if (ch == KEY_BACKSPACE)
619 return '\b';
d64e57fa 620
3c216924 621 if (current_ui->command_editing && key_is_start_sequence (ch))
d64e57fa
PP
622 {
623 int ch_pending;
624
625 nodelay (w, TRUE);
626 ch_pending = wgetch (w);
627 nodelay (w, FALSE);
628
629 /* If we have pending input following a start sequence, call the stdin
630 event handler again because ncurses may have already read and stored
631 the input into its internal buffer, meaning that we won't get an stdin
632 event for it. If we don't compensate for this missed stdin event, key
633 sequences as Alt_F (^[f) will not behave promptly.
634
635 (We only compensates for the missed 2nd byte of a key sequence because
636 2-byte sequences are by far the most commonly used. ncurses may have
637 buffered a larger, 3+-byte key sequence though it remains to be seen
638 whether it is useful to compensate for all the bytes of such
639 sequences.) */
640 if (ch_pending != ERR)
641 {
642 ungetch (ch_pending);
643 call_stdin_event_handler_again_p = 1;
644 }
645 }
646
c906108c 647 return ch;
a198b876 648}
c906108c 649
312809f8
EZ
650/* Utility function to expand TABs in a STRING into spaces. STRING
651 will be displayed starting at column COL, and is assumed to include
652 no newlines. The returned expanded string is malloc'ed. */
653
654char *
655tui_expand_tabs (const char *string, int col)
656{
b1a0f704 657 int n_adjust, ncol;
312809f8
EZ
658 const char *s;
659 char *ret, *q;
660
661 /* 1. How many additional characters do we need? */
b1a0f704 662 for (ncol = col, n_adjust = 0, s = string; s; )
312809f8
EZ
663 {
664 s = strpbrk (s, "\t");
665 if (s)
666 {
b1a0f704 667 ncol += (s - string) + n_adjust;
312809f8
EZ
668 /* Adjustment for the next tab stop, minus one for the TAB
669 we replace with spaces. */
b1a0f704 670 n_adjust += 8 - (ncol % 8) - 1;
312809f8
EZ
671 s++;
672 }
673 }
674
675 /* Allocate the copy. */
224c3ddb 676 ret = q = (char *) xmalloc (strlen (string) + n_adjust + 1);
312809f8
EZ
677
678 /* 2. Copy the original string while replacing TABs with spaces. */
b1a0f704 679 for (ncol = col, s = string; s; )
312809f8 680 {
cd46431b 681 const char *s1 = strpbrk (s, "\t");
312809f8
EZ
682 if (s1)
683 {
684 if (s1 > s)
685 {
686 strncpy (q, s, s1 - s);
687 q += s1 - s;
b1a0f704 688 ncol += s1 - s;
312809f8
EZ
689 }
690 do {
691 *q++ = ' ';
b1a0f704
EZ
692 ncol++;
693 } while ((ncol % 8) != 0);
312809f8
EZ
694 s1++;
695 }
696 else
697 strcpy (q, s);
698 s = s1;
699 }
700
701 return ret;
702}
This page took 1.750533 seconds and 4 git commands to generate.