ce45d28d02420dde7a52f42901295a40318a6156
[deliverable/binutils-gdb.git] / readline / terminal.c
1 /* terminal.c -- controlling the terminal with termcap. */
2
3 /* Copyright (C) 1996 Free Software Foundation, Inc.
4
5 This file is part of the GNU Readline Library, a library for
6 reading lines of text with interactive input and history editing.
7
8 The GNU Readline Library is free software; you can redistribute it
9 and/or modify it under the terms of the GNU General Public License
10 as published by the Free Software Foundation; either version 2, or
11 (at your option) any later version.
12
13 The GNU Readline Library is distributed in the hope that it will be
14 useful, but WITHOUT ANY WARRANTY; without even the implied warranty
15 of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 The GNU General Public License is often shipped with GNU software, and
19 is generally kept in a file called COPYING or LICENSE. If you do not
20 have a copy of the license, write to the Free Software Foundation,
21 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
22 #define READLINE_LIBRARY
23
24 #if defined (HAVE_CONFIG_H)
25 # include <config.h>
26 #endif
27
28 #include <sys/types.h>
29 #include "posixstat.h"
30 #include <fcntl.h>
31 #if defined (HAVE_SYS_FILE_H)
32 # include <sys/file.h>
33 #endif /* HAVE_SYS_FILE_H */
34
35 #if defined (HAVE_UNISTD_H)
36 # include <unistd.h>
37 #endif /* HAVE_UNISTD_H */
38
39 #if defined (HAVE_STDLIB_H)
40 # include <stdlib.h>
41 #else
42 # include "ansi_stdlib.h"
43 #endif /* HAVE_STDLIB_H */
44
45 #if defined (HAVE_LOCALE_H)
46 # include <locale.h>
47 #endif
48
49 #include <stdio.h>
50
51 /* System-specific feature definitions and include files. */
52 #include "rldefs.h"
53
54 #if defined (GWINSZ_IN_SYS_IOCTL) && !defined (TIOCGWINSZ)
55 # include <sys/ioctl.h>
56 #endif /* GWINSZ_IN_SYS_IOCTL && !TIOCGWINSZ */
57
58 #ifdef __MSDOS__
59 # include <pc.h>
60 #endif
61
62 #include "rltty.h"
63 #include "tcap.h"
64
65 /* Some standard library routines. */
66 #include "readline.h"
67 #include "history.h"
68
69 #include "rlprivate.h"
70 #include "rlshell.h"
71 #include "xmalloc.h"
72
73 #if defined (__MINGW32__)
74 # include <windows.h>
75 # include <wincon.h>
76 #endif
77
78 #define CUSTOM_REDISPLAY_FUNC() (rl_redisplay_function != rl_redisplay)
79 #define CUSTOM_INPUT_FUNC() (rl_getc_function != rl_getc)
80
81 /* **************************************************************** */
82 /* */
83 /* Terminal and Termcap */
84 /* */
85 /* **************************************************************** */
86
87 #ifndef __MSDOS__
88 static char *term_buffer = (char *)NULL;
89 static char *term_string_buffer = (char *)NULL;
90
91 /* Non-zero means this terminal can't really do anything. */
92 static int dumb_term;
93 #endif /* !__MSDOS__ */
94
95 static int tcap_initialized;
96
97 #if !defined (__linux__)
98 # if defined (__EMX__) || defined (NEED_EXTERN_PC)
99 extern
100 # endif /* __EMX__ || NEED_EXTERN_PC */
101 char PC, *BC, *UP;
102 #endif /* __linux__ */
103
104 /* Some strings to control terminal actions. These are output by tputs (). */
105 char *_rl_term_clreol;
106 char *_rl_term_clrpag;
107 char *_rl_term_cr;
108 char *_rl_term_backspace;
109 char *_rl_term_goto;
110 char *_rl_term_pc;
111
112 /* Non-zero if we determine that the terminal can do character insertion. */
113 int _rl_terminal_can_insert = 0;
114
115 /* How to insert characters. */
116 char *_rl_term_im;
117 char *_rl_term_ei;
118 char *_rl_term_ic;
119 char *_rl_term_ip;
120 char *_rl_term_IC;
121
122 /* How to delete characters. */
123 char *_rl_term_dc;
124 char *_rl_term_DC;
125
126 #if defined (HACK_TERMCAP_MOTION)
127 char *_rl_term_forward_char;
128 #endif /* HACK_TERMCAP_MOTION */
129
130 /* How to go up a line. */
131 char *_rl_term_up;
132
133 /* A visible bell; char if the terminal can be made to flash the screen. */
134 static char *_rl_visible_bell;
135
136 /* Non-zero means the terminal can auto-wrap lines. */
137 int _rl_term_autowrap;
138
139 /* Non-zero means that this terminal has a meta key. */
140 static int term_has_meta;
141
142 /* The sequences to write to turn on and off the meta key, if this
143 terminal has one. */
144 static char *_rl_term_mm;
145 static char *_rl_term_mo;
146
147 /* The key sequences output by the arrow keys, if this terminal has any. */
148 static char *_rl_term_ku;
149 static char *_rl_term_kd;
150 static char *_rl_term_kr;
151 static char *_rl_term_kl;
152
153 /* How to initialize and reset the arrow keys, if this terminal has any. */
154 static char *_rl_term_ks;
155 static char *_rl_term_ke;
156
157 /* The key sequences sent by the Home and End keys, if any. */
158 static char *_rl_term_kh;
159 static char *_rl_term_kH;
160 static char *_rl_term_at7; /* @7 */
161
162 /* Insert key */
163 static char *_rl_term_kI;
164
165 /* Cursor control */
166 static char *_rl_term_vs; /* very visible */
167 static char *_rl_term_ve; /* normal */
168
169 static void bind_termcap_arrow_keys PARAMS((Keymap));
170
171 /* Variables that hold the screen dimensions, used by the display code. */
172 int _rl_screenwidth, _rl_screenheight, _rl_screenchars;
173
174 /* Non-zero means the user wants to enable the keypad. */
175 int _rl_enable_keypad;
176
177 /* Non-zero means the user wants to enable a meta key. */
178 int _rl_enable_meta = 1;
179
180 #if defined (__EMX__)
181 static void
182 _emx_get_screensize (swp, shp)
183 int *swp, *shp;
184 {
185 int sz[2];
186
187 _scrsize (sz);
188
189 if (swp)
190 *swp = sz[0];
191 if (shp)
192 *shp = sz[1];
193 }
194 #endif
195
196 /* Get readline's idea of the screen size. TTY is a file descriptor open
197 to the terminal. If IGNORE_ENV is true, we do not pay attention to the
198 values of $LINES and $COLUMNS. The tests for TERM_STRING_BUFFER being
199 non-null serve to check whether or not we have initialized termcap. */
200 void
201 _rl_get_screen_size (tty, ignore_env)
202 int tty, ignore_env;
203 {
204 char *ss;
205 #if defined (TIOCGWINSZ)
206 struct winsize window_size;
207 #endif /* TIOCGWINSZ */
208
209 #if defined (TIOCGWINSZ)
210 if (ioctl (tty, TIOCGWINSZ, &window_size) == 0)
211 {
212 _rl_screenwidth = (int) window_size.ws_col;
213 _rl_screenheight = (int) window_size.ws_row;
214 }
215 #endif /* TIOCGWINSZ */
216
217 /* For MinGW, we get the console size from the Windows API. */
218 #if defined (__MINGW32__)
219 HANDLE hConOut = GetStdHandle (STD_OUTPUT_HANDLE);
220 if (hConOut != INVALID_HANDLE_VALUE)
221 {
222 CONSOLE_SCREEN_BUFFER_INFO scr;
223 if (GetConsoleScreenBufferInfo (hConOut, &scr))
224 {
225 _rl_screenwidth = scr.dwSize.X;
226 _rl_screenheight = scr.srWindow.Bottom - scr.srWindow.Top + 1;
227 }
228 }
229 #endif
230
231 #if defined (__EMX__)
232 _emx_get_screensize (&_rl_screenwidth, &_rl_screenheight);
233 #endif
234
235 /* Environment variable COLUMNS overrides setting of "co" if IGNORE_ENV
236 is unset. */
237 if (_rl_screenwidth <= 0)
238 {
239 if (ignore_env == 0 && (ss = sh_get_env_value ("COLUMNS")))
240 _rl_screenwidth = atoi (ss);
241
242 #if defined (__DJGPP__)
243 if (_rl_screenwidth <= 0)
244 _rl_screenwidth = ScreenCols ();
245 #else
246 if (_rl_screenwidth <= 0 && term_string_buffer)
247 _rl_screenwidth = tgetnum ("co");
248 #endif
249 }
250
251 /* Environment variable LINES overrides setting of "li" if IGNORE_ENV
252 is unset. */
253 if (_rl_screenheight <= 0)
254 {
255 if (ignore_env == 0 && (ss = sh_get_env_value ("LINES")))
256 _rl_screenheight = atoi (ss);
257
258 #if defined (__DJGPP__)
259 if (_rl_screenheight <= 0)
260 _rl_screenheight = ScreenRows ();
261 #else
262 if (_rl_screenheight <= 0 && term_string_buffer)
263 _rl_screenheight = tgetnum ("li");
264 #endif
265 }
266
267 /* If all else fails, default to 80x24 terminal. */
268 if (_rl_screenwidth <= 1)
269 _rl_screenwidth = 80;
270
271 if (_rl_screenheight <= 0)
272 _rl_screenheight = 24;
273
274 /* If we're being compiled as part of bash, set the environment
275 variables $LINES and $COLUMNS to new values. Otherwise, just
276 do a pair of putenv () or setenv () calls. */
277 sh_set_lines_and_columns (_rl_screenheight, _rl_screenwidth);
278
279 if (_rl_term_autowrap == 0)
280 _rl_screenwidth--;
281
282 _rl_screenchars = _rl_screenwidth * _rl_screenheight;
283 }
284
285 void
286 _rl_set_screen_size (rows, cols)
287 int rows, cols;
288 {
289 if (rows == 0 || cols == 0)
290 return;
291
292 _rl_screenheight = rows;
293 _rl_screenwidth = cols;
294
295 if (_rl_term_autowrap == 0)
296 _rl_screenwidth--;
297
298 _rl_screenchars = _rl_screenwidth * _rl_screenheight;
299 }
300
301 void
302 rl_set_screen_size (rows, cols)
303 int rows, cols;
304 {
305 _rl_set_screen_size (rows, cols);
306 }
307
308 void
309 rl_get_screen_size (rows, cols)
310 int *rows, *cols;
311 {
312 if (rows)
313 *rows = _rl_screenheight;
314 if (cols)
315 *cols = _rl_screenwidth;
316 }
317
318 void
319 rl_resize_terminal ()
320 {
321 if (readline_echoing_p)
322 {
323 _rl_get_screen_size (fileno (rl_instream), 1);
324 if (CUSTOM_REDISPLAY_FUNC ())
325 rl_forced_update_display ();
326 else
327 _rl_redisplay_after_sigwinch ();
328 }
329 }
330
331 struct _tc_string {
332 const char *tc_var;
333 char **tc_value;
334 };
335
336 /* This should be kept sorted, just in case we decide to change the
337 search algorithm to something smarter. */
338 static struct _tc_string tc_strings[] =
339 {
340 { "@7", &_rl_term_at7 },
341 { "DC", &_rl_term_DC },
342 { "IC", &_rl_term_IC },
343 { "ce", &_rl_term_clreol },
344 { "cl", &_rl_term_clrpag },
345 { "cr", &_rl_term_cr },
346 { "dc", &_rl_term_dc },
347 { "ei", &_rl_term_ei },
348 { "ic", &_rl_term_ic },
349 { "im", &_rl_term_im },
350 { "kH", &_rl_term_kH }, /* home down ?? */
351 { "kI", &_rl_term_kI }, /* insert */
352 { "kd", &_rl_term_kd },
353 { "ke", &_rl_term_ke }, /* end keypad mode */
354 { "kh", &_rl_term_kh }, /* home */
355 { "kl", &_rl_term_kl },
356 { "kr", &_rl_term_kr },
357 { "ks", &_rl_term_ks }, /* start keypad mode */
358 { "ku", &_rl_term_ku },
359 { "le", &_rl_term_backspace },
360 { "mm", &_rl_term_mm },
361 { "mo", &_rl_term_mo },
362 #if defined (HACK_TERMCAP_MOTION)
363 { "nd", &_rl_term_forward_char },
364 #endif
365 { "pc", &_rl_term_pc },
366 { "up", &_rl_term_up },
367 { "vb", &_rl_visible_bell },
368 { "vs", &_rl_term_vs },
369 { "ve", &_rl_term_ve },
370 };
371
372 #define NUM_TC_STRINGS (sizeof (tc_strings) / sizeof (struct _tc_string))
373
374 /* Read the desired terminal capability strings into BP. The capabilities
375 are described in the TC_STRINGS table. */
376 static void
377 get_term_capabilities (bp)
378 char **bp;
379 {
380 #if !defined (__DJGPP__) /* XXX - doesn't DJGPP have a termcap library? */
381 register int i;
382
383 for (i = 0; i < NUM_TC_STRINGS; i++)
384 # ifdef __LCC__
385 *(tc_strings[i].tc_value) = tgetstr ((char *)tc_strings[i].tc_var, bp);
386 # else
387 *(tc_strings[i].tc_value) = tgetstr (tc_strings[i].tc_var, bp);
388 # endif
389 #endif
390 tcap_initialized = 1;
391 }
392
393 int
394 _rl_init_terminal_io (terminal_name)
395 const char *terminal_name;
396 {
397 const char *term;
398 char *buffer;
399 int tty, tgetent_ret;
400
401 term = terminal_name ? terminal_name : sh_get_env_value ("TERM");
402 _rl_term_clrpag = _rl_term_cr = _rl_term_clreol = (char *)NULL;
403 tty = rl_instream ? fileno (rl_instream) : 0;
404 _rl_screenwidth = _rl_screenheight = 0;
405
406 if (term == 0)
407 term = "dumb";
408
409 #ifdef __MSDOS__
410 _rl_term_im = _rl_term_ei = _rl_term_ic = _rl_term_IC = (char *)NULL;
411 _rl_term_up = _rl_term_dc = _rl_term_DC = _rl_visible_bell = (char *)NULL;
412 _rl_term_ku = _rl_term_kd = _rl_term_kl = _rl_term_kr = (char *)NULL;
413 _rl_term_mm = _rl_term_mo = (char *)NULL;
414 _rl_terminal_can_insert = term_has_meta = _rl_term_autowrap = 0;
415 _rl_term_cr = "\r";
416 _rl_term_clreol = _rl_term_clrpag = _rl_term_backspace = (char *)NULL;
417 _rl_term_goto = _rl_term_pc = _rl_term_ip = (char *)NULL;
418 _rl_term_ks = _rl_term_ke =_rl_term_vs = _rl_term_ve = (char *)NULL;
419 _rl_term_kh = _rl_term_kH = _rl_term_at7 = _rl_term_kI = (char *)NULL;
420 #if defined(HACK_TERMCAP_MOTION)
421 _rl_term_forward_char = (char *)NULL;
422 #endif
423
424 _rl_get_screen_size (tty, 0);
425 #else /* !__MSDOS__ */
426 /* I've separated this out for later work on not calling tgetent at all
427 if the calling application has supplied a custom redisplay function,
428 (and possibly if the application has supplied a custom input function). */
429 if (CUSTOM_REDISPLAY_FUNC())
430 {
431 tgetent_ret = -1;
432 }
433 else
434 {
435 if (term_string_buffer == 0)
436 term_string_buffer = (char *)xmalloc(2032);
437
438 if (term_buffer == 0)
439 term_buffer = (char *)xmalloc(4080);
440
441 buffer = term_string_buffer;
442
443 tgetent_ret = tgetent (term_buffer, term);
444 }
445
446 if (tgetent_ret <= 0)
447 {
448 FREE (term_string_buffer);
449 FREE (term_buffer);
450 buffer = term_buffer = term_string_buffer = (char *)NULL;
451
452 _rl_term_autowrap = 0; /* used by _rl_get_screen_size */
453
454 #if defined (__EMX__)
455 _emx_get_screensize (&_rl_screenwidth, &_rl_screenheight);
456 _rl_screenwidth--;
457 #else /* !__EMX__ */
458 _rl_get_screen_size (tty, 0);
459 #endif /* !__EMX__ */
460
461 /* Defaults. */
462 if (_rl_screenwidth <= 0 || _rl_screenheight <= 0)
463 {
464 _rl_screenwidth = 79;
465 _rl_screenheight = 24;
466 }
467
468 /* Everything below here is used by the redisplay code (tputs). */
469 _rl_screenchars = _rl_screenwidth * _rl_screenheight;
470 _rl_term_cr = "\r";
471 _rl_term_im = _rl_term_ei = _rl_term_ic = _rl_term_IC = (char *)NULL;
472 _rl_term_up = _rl_term_dc = _rl_term_DC = _rl_visible_bell = (char *)NULL;
473 _rl_term_ku = _rl_term_kd = _rl_term_kl = _rl_term_kr = (char *)NULL;
474 _rl_term_kh = _rl_term_kH = _rl_term_kI = (char *)NULL;
475 _rl_term_ks = _rl_term_ke = _rl_term_at7 = (char *)NULL;
476 _rl_term_mm = _rl_term_mo = (char *)NULL;
477 _rl_term_ve = _rl_term_vs = (char *)NULL;
478 #if defined (HACK_TERMCAP_MOTION)
479 term_forward_char = (char *)NULL;
480 #endif
481 _rl_terminal_can_insert = term_has_meta = 0;
482
483 /* Reasonable defaults for tgoto(). Readline currently only uses
484 tgoto if _rl_term_IC or _rl_term_DC is defined, but just in case we
485 change that later... */
486 PC = '\0';
487 BC = _rl_term_backspace = "\b";
488 UP = _rl_term_up;
489
490 return 0;
491 }
492
493 get_term_capabilities (&buffer);
494
495 /* Set up the variables that the termcap library expects the application
496 to provide. */
497 PC = _rl_term_pc ? *_rl_term_pc : 0;
498 BC = _rl_term_backspace;
499 UP = _rl_term_up;
500
501 if (!_rl_term_cr)
502 _rl_term_cr = "\r";
503
504 _rl_term_autowrap = tgetflag ("am") && tgetflag ("xn");
505
506 _rl_get_screen_size (tty, 0);
507
508 /* "An application program can assume that the terminal can do
509 character insertion if *any one of* the capabilities `IC',
510 `im', `ic' or `ip' is provided." But we can't do anything if
511 only `ip' is provided, so... */
512 _rl_terminal_can_insert = (_rl_term_IC || _rl_term_im || _rl_term_ic);
513
514 /* Check to see if this terminal has a meta key and clear the capability
515 variables if there is none. */
516 term_has_meta = (tgetflag ("km") || tgetflag ("MT"));
517 if (!term_has_meta)
518 _rl_term_mm = _rl_term_mo = (char *)NULL;
519
520 #endif /* !__MSDOS__ */
521
522 /* Attempt to find and bind the arrow keys. Do not override already
523 bound keys in an overzealous attempt, however. */
524
525 bind_termcap_arrow_keys (emacs_standard_keymap);
526
527 #if defined (VI_MODE)
528 bind_termcap_arrow_keys (vi_movement_keymap);
529 bind_termcap_arrow_keys (vi_insertion_keymap);
530 #endif /* VI_MODE */
531
532 return 0;
533 }
534
535 /* Bind the arrow key sequences from the termcap description in MAP. */
536 static void
537 bind_termcap_arrow_keys (map)
538 Keymap map;
539 {
540 Keymap xkeymap;
541
542 xkeymap = _rl_keymap;
543 _rl_keymap = map;
544
545 _rl_bind_if_unbound (_rl_term_ku, rl_get_previous_history);
546 _rl_bind_if_unbound (_rl_term_kd, rl_get_next_history);
547 _rl_bind_if_unbound (_rl_term_kr, rl_forward);
548 _rl_bind_if_unbound (_rl_term_kl, rl_backward);
549
550 _rl_bind_if_unbound (_rl_term_kh, rl_beg_of_line); /* Home */
551 _rl_bind_if_unbound (_rl_term_at7, rl_end_of_line); /* End */
552
553 _rl_keymap = xkeymap;
554 }
555
556 char *
557 rl_get_termcap (cap)
558 const char *cap;
559 {
560 register int i;
561
562 if (tcap_initialized == 0)
563 return ((char *)NULL);
564 for (i = 0; i < NUM_TC_STRINGS; i++)
565 {
566 if (tc_strings[i].tc_var[0] == cap[0] && strcmp (tc_strings[i].tc_var, cap) == 0)
567 return *(tc_strings[i].tc_value);
568 }
569 return ((char *)NULL);
570 }
571
572 /* Re-initialize the terminal considering that the TERM/TERMCAP variable
573 has changed. */
574 int
575 rl_reset_terminal (terminal_name)
576 const char *terminal_name;
577 {
578 _rl_init_terminal_io (terminal_name);
579 return 0;
580 }
581
582 /* A function for the use of tputs () */
583 #ifdef _MINIX
584 void
585 _rl_output_character_function (c)
586 int c;
587 {
588 putc (c, _rl_out_stream);
589 }
590 #else /* !_MINIX */
591 int
592 _rl_output_character_function (c)
593 int c;
594 {
595 return putc (c, _rl_out_stream);
596 }
597 #endif /* !_MINIX */
598
599 /* Write COUNT characters from STRING to the output stream. */
600 void
601 _rl_output_some_chars (string, count)
602 const char *string;
603 int count;
604 {
605 fwrite (string, 1, count, _rl_out_stream);
606 }
607
608 /* Move the cursor back. */
609 int
610 _rl_backspace (count)
611 int count;
612 {
613 register int i;
614
615 #ifndef __MSDOS__
616 if (_rl_term_backspace)
617 for (i = 0; i < count; i++)
618 tputs (_rl_term_backspace, 1, _rl_output_character_function);
619 else
620 #endif
621 for (i = 0; i < count; i++)
622 putc ('\b', _rl_out_stream);
623 return 0;
624 }
625
626 /* Move to the start of the next line. */
627 int
628 rl_crlf ()
629 {
630 #if defined (NEW_TTY_DRIVER)
631 if (_rl_term_cr)
632 tputs (_rl_term_cr, 1, _rl_output_character_function);
633 #endif /* NEW_TTY_DRIVER */
634 putc ('\n', _rl_out_stream);
635 return 0;
636 }
637
638 /* Ring the terminal bell. */
639 int
640 rl_ding ()
641 {
642 if (readline_echoing_p)
643 {
644 switch (_rl_bell_preference)
645 {
646 case NO_BELL:
647 default:
648 break;
649 case VISIBLE_BELL:
650 #ifdef __MSDOS__
651 ScreenVisualBell ();
652 break;
653 #else
654 if (_rl_visible_bell)
655 {
656 tputs (_rl_visible_bell, 1, _rl_output_character_function);
657 break;
658 }
659 #endif
660 /* FALLTHROUGH */
661 case AUDIBLE_BELL:
662 fprintf (stderr, "\007");
663 fflush (stderr);
664 break;
665 }
666 return (0);
667 }
668 return (-1);
669 }
670
671 /* **************************************************************** */
672 /* */
673 /* Controlling the Meta Key and Keypad */
674 /* */
675 /* **************************************************************** */
676
677 void
678 _rl_enable_meta_key ()
679 {
680 #if !defined (__DJGPP__)
681 if (term_has_meta && _rl_term_mm)
682 tputs (_rl_term_mm, 1, _rl_output_character_function);
683 #endif
684 }
685
686 void
687 _rl_control_keypad (on)
688 int on;
689 {
690 #if !defined (__DJGPP__)
691 if (on && _rl_term_ks)
692 tputs (_rl_term_ks, 1, _rl_output_character_function);
693 else if (!on && _rl_term_ke)
694 tputs (_rl_term_ke, 1, _rl_output_character_function);
695 #endif
696 }
697
698 /* **************************************************************** */
699 /* */
700 /* Controlling the Cursor */
701 /* */
702 /* **************************************************************** */
703
704 /* Set the cursor appropriately depending on IM, which is one of the
705 insert modes (insert or overwrite). Insert mode gets the normal
706 cursor. Overwrite mode gets a very visible cursor. Only does
707 anything if we have both capabilities. */
708 void
709 _rl_set_cursor (im, force)
710 int im, force;
711 {
712 #ifndef __MSDOS__
713 if (_rl_term_ve && _rl_term_vs)
714 {
715 if (force || im != rl_insert_mode)
716 {
717 if (im == RL_IM_OVERWRITE)
718 tputs (_rl_term_vs, 1, _rl_output_character_function);
719 else
720 tputs (_rl_term_ve, 1, _rl_output_character_function);
721 }
722 }
723 #endif
724 }
This page took 0.060832 seconds and 3 git commands to generate.