HAMMER 60I/Many: Mirroring
[dragonfly.git] / contrib / readline-5.0 / input.c
blob044338e879b5cf43b2c261a2ebaab981d0a9f434
1 /* input.c -- character input functions for readline. */
3 /* Copyright (C) 1994 Free Software Foundation, Inc.
5 This file is part of the GNU Readline Library, a library for
6 reading lines of text with interactive input and history editing.
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.
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.
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
24 #if defined (__TANDEM)
25 # include <floss.h>
26 #endif
28 #if defined (HAVE_CONFIG_H)
29 # include <config.h>
30 #endif
32 #include <sys/types.h>
33 #include <fcntl.h>
34 #if defined (HAVE_SYS_FILE_H)
35 # include <sys/file.h>
36 #endif /* HAVE_SYS_FILE_H */
38 #if defined (HAVE_UNISTD_H)
39 # include <unistd.h>
40 #endif /* HAVE_UNISTD_H */
42 #if defined (HAVE_STDLIB_H)
43 # include <stdlib.h>
44 #else
45 # include "ansi_stdlib.h"
46 #endif /* HAVE_STDLIB_H */
48 #if defined (HAVE_SELECT)
49 # if !defined (HAVE_SYS_SELECT_H) || !defined (M_UNIX)
50 # include <sys/time.h>
51 # endif
52 #endif /* HAVE_SELECT */
53 #if defined (HAVE_SYS_SELECT_H)
54 # include <sys/select.h>
55 #endif
57 #if defined (FIONREAD_IN_SYS_IOCTL)
58 # include <sys/ioctl.h>
59 #endif
61 #include <stdio.h>
62 #include <errno.h>
64 #if !defined (errno)
65 extern int errno;
66 #endif /* !errno */
68 /* System-specific feature definitions and include files. */
69 #include "rldefs.h"
70 #include "rlmbutil.h"
72 /* Some standard library routines. */
73 #include "readline.h"
75 #include "rlprivate.h"
76 #include "rlshell.h"
77 #include "xmalloc.h"
79 /* What kind of non-blocking I/O do we have? */
80 #if !defined (O_NDELAY) && defined (O_NONBLOCK)
81 # define O_NDELAY O_NONBLOCK /* Posix style */
82 #endif
84 /* Non-null means it is a pointer to a function to run while waiting for
85 character input. */
86 rl_hook_func_t *rl_event_hook = (rl_hook_func_t *)NULL;
88 rl_getc_func_t *rl_getc_function = rl_getc;
90 static int _keyboard_input_timeout = 100000; /* 0.1 seconds; it's in usec */
92 static int ibuffer_space PARAMS((void));
93 static int rl_get_char PARAMS((int *));
94 static int rl_gather_tyi PARAMS((void));
96 /* **************************************************************** */
97 /* */
98 /* Character Input Buffering */
99 /* */
100 /* **************************************************************** */
102 static int pop_index, push_index;
103 static unsigned char ibuffer[512];
104 static int ibuffer_len = sizeof (ibuffer) - 1;
106 #define any_typein (push_index != pop_index)
109 _rl_any_typein ()
111 return any_typein;
114 /* Return the amount of space available in the buffer for stuffing
115 characters. */
116 static int
117 ibuffer_space ()
119 if (pop_index > push_index)
120 return (pop_index - push_index - 1);
121 else
122 return (ibuffer_len - (push_index - pop_index));
125 /* Get a key from the buffer of characters to be read.
126 Return the key in KEY.
127 Result is KEY if there was a key, or 0 if there wasn't. */
128 static int
129 rl_get_char (key)
130 int *key;
132 if (push_index == pop_index)
133 return (0);
135 *key = ibuffer[pop_index++];
137 if (pop_index >= ibuffer_len)
138 pop_index = 0;
140 return (1);
143 /* Stuff KEY into the *front* of the input buffer.
144 Returns non-zero if successful, zero if there is
145 no space left in the buffer. */
147 _rl_unget_char (key)
148 int key;
150 if (ibuffer_space ())
152 pop_index--;
153 if (pop_index < 0)
154 pop_index = ibuffer_len - 1;
155 ibuffer[pop_index] = key;
156 return (1);
158 return (0);
162 _rl_pushed_input_available ()
164 return (push_index != pop_index);
167 /* If a character is available to be read, then read it and stuff it into
168 IBUFFER. Otherwise, just return. Returns number of characters read
169 (0 if none available) and -1 on error (EIO). */
170 static int
171 rl_gather_tyi ()
173 int tty;
174 register int tem, result;
175 int chars_avail, k;
176 char input;
177 #if defined(HAVE_SELECT)
178 fd_set readfds, exceptfds;
179 struct timeval timeout;
180 #endif
182 tty = fileno (rl_instream);
184 #if defined (HAVE_SELECT)
185 FD_ZERO (&readfds);
186 FD_ZERO (&exceptfds);
187 FD_SET (tty, &readfds);
188 FD_SET (tty, &exceptfds);
189 timeout.tv_sec = 0;
190 timeout.tv_usec = _keyboard_input_timeout;
191 result = select (tty + 1, &readfds, (fd_set *)NULL, &exceptfds, &timeout);
192 if (result <= 0)
193 return 0; /* Nothing to read. */
194 #endif
196 result = -1;
197 #if defined (FIONREAD)
198 errno = 0;
199 result = ioctl (tty, FIONREAD, &chars_avail);
200 if (result == -1 && errno == EIO)
201 return -1;
202 #endif
204 #if defined (O_NDELAY)
205 if (result == -1)
207 tem = fcntl (tty, F_GETFL, 0);
209 fcntl (tty, F_SETFL, (tem | O_NDELAY));
210 chars_avail = read (tty, &input, 1);
212 fcntl (tty, F_SETFL, tem);
213 if (chars_avail == -1 && errno == EAGAIN)
214 return 0;
215 if (chars_avail == 0) /* EOF */
217 rl_stuff_char (EOF);
218 return (0);
221 #endif /* O_NDELAY */
223 /* If there's nothing available, don't waste time trying to read
224 something. */
225 if (chars_avail <= 0)
226 return 0;
228 tem = ibuffer_space ();
230 if (chars_avail > tem)
231 chars_avail = tem;
233 /* One cannot read all of the available input. I can only read a single
234 character at a time, or else programs which require input can be
235 thwarted. If the buffer is larger than one character, I lose.
236 Damn! */
237 if (tem < ibuffer_len)
238 chars_avail = 0;
240 if (result != -1)
242 while (chars_avail--)
244 k = (*rl_getc_function) (rl_instream);
245 rl_stuff_char (k);
246 if (k == NEWLINE || k == RETURN)
247 break;
250 else
252 if (chars_avail)
253 rl_stuff_char (input);
256 return 1;
260 rl_set_keyboard_input_timeout (u)
261 int u;
263 int o;
265 o = _keyboard_input_timeout;
266 if (u > 0)
267 _keyboard_input_timeout = u;
268 return (o);
271 /* Is there input available to be read on the readline input file
272 descriptor? Only works if the system has select(2) or FIONREAD.
273 Uses the value of _keyboard_input_timeout as the timeout; if another
274 readline function wants to specify a timeout and not leave it up to
275 the user, it should use _rl_input_queued(timeout_value_in_microseconds)
276 instead. */
278 _rl_input_available ()
280 #if defined(HAVE_SELECT)
281 fd_set readfds, exceptfds;
282 struct timeval timeout;
283 #endif
284 #if !defined (HAVE_SELECT) && defined(FIONREAD)
285 int chars_avail;
286 #endif
287 int tty;
289 tty = fileno (rl_instream);
291 #if defined (HAVE_SELECT)
292 FD_ZERO (&readfds);
293 FD_ZERO (&exceptfds);
294 FD_SET (tty, &readfds);
295 FD_SET (tty, &exceptfds);
296 timeout.tv_sec = 0;
297 timeout.tv_usec = _keyboard_input_timeout;
298 return (select (tty + 1, &readfds, (fd_set *)NULL, &exceptfds, &timeout) > 0);
299 #else
301 #if defined (FIONREAD)
302 if (ioctl (tty, FIONREAD, &chars_avail) == 0)
303 return (chars_avail);
304 #endif
306 #endif
308 return 0;
312 _rl_input_queued (t)
313 int t;
315 int old_timeout, r;
317 old_timeout = rl_set_keyboard_input_timeout (t);
318 r = _rl_input_available ();
319 rl_set_keyboard_input_timeout (old_timeout);
320 return r;
323 void
324 _rl_insert_typein (c)
325 int c;
327 int key, t, i;
328 char *string;
330 i = key = 0;
331 string = (char *)xmalloc (ibuffer_len + 1);
332 string[i++] = (char) c;
334 while ((t = rl_get_char (&key)) &&
335 _rl_keymap[key].type == ISFUNC &&
336 _rl_keymap[key].function == rl_insert)
337 string[i++] = key;
339 if (t)
340 _rl_unget_char (key);
342 string[i] = '\0';
343 rl_insert_text (string);
344 free (string);
347 /* Add KEY to the buffer of characters to be read. Returns 1 if the
348 character was stuffed correctly; 0 otherwise. */
350 rl_stuff_char (key)
351 int key;
353 if (ibuffer_space () == 0)
354 return 0;
356 if (key == EOF)
358 key = NEWLINE;
359 rl_pending_input = EOF;
360 RL_SETSTATE (RL_STATE_INPUTPENDING);
362 ibuffer[push_index++] = key;
363 if (push_index >= ibuffer_len)
364 push_index = 0;
366 return 1;
369 /* Make C be the next command to be executed. */
371 rl_execute_next (c)
372 int c;
374 rl_pending_input = c;
375 RL_SETSTATE (RL_STATE_INPUTPENDING);
376 return 0;
379 /* Clear any pending input pushed with rl_execute_next() */
381 rl_clear_pending_input ()
383 rl_pending_input = 0;
384 RL_UNSETSTATE (RL_STATE_INPUTPENDING);
385 return 0;
388 /* **************************************************************** */
389 /* */
390 /* Character Input */
391 /* */
392 /* **************************************************************** */
394 /* Read a key, including pending input. */
396 rl_read_key ()
398 int c;
400 rl_key_sequence_length++;
402 if (rl_pending_input)
404 c = rl_pending_input;
405 rl_clear_pending_input ();
407 else
409 /* If input is coming from a macro, then use that. */
410 if (c = _rl_next_macro_key ())
411 return (c);
413 /* If the user has an event function, then call it periodically. */
414 if (rl_event_hook)
416 while (rl_event_hook && rl_get_char (&c) == 0)
418 (*rl_event_hook) ();
419 if (rl_done) /* XXX - experimental */
420 return ('\n');
421 if (rl_gather_tyi () < 0) /* XXX - EIO */
423 rl_done = 1;
424 return ('\n');
428 else
430 if (rl_get_char (&c) == 0)
431 c = (*rl_getc_function) (rl_instream);
435 return (c);
439 rl_getc (stream)
440 FILE *stream;
442 int result;
443 unsigned char c;
445 while (1)
447 result = read (fileno (stream), &c, sizeof (unsigned char));
449 if (result == sizeof (unsigned char))
450 return (c);
452 /* If zero characters are returned, then the file that we are
453 reading from is empty! Return EOF in that case. */
454 if (result == 0)
455 return (EOF);
457 #if defined (__BEOS__)
458 if (errno == EINTR)
459 continue;
460 #endif
462 #if defined (EWOULDBLOCK)
463 # define X_EWOULDBLOCK EWOULDBLOCK
464 #else
465 # define X_EWOULDBLOCK -99
466 #endif
468 #if defined (EAGAIN)
469 # define X_EAGAIN EAGAIN
470 #else
471 # define X_EAGAIN -99
472 #endif
474 if (errno == X_EWOULDBLOCK || errno == X_EAGAIN)
476 if (sh_unset_nodelay_mode (fileno (stream)) < 0)
477 return (EOF);
478 continue;
481 #undef X_EWOULDBLOCK
482 #undef X_EAGAIN
484 /* If the error that we received was SIGINT, then try again,
485 this is simply an interrupted system call to read ().
486 Otherwise, some error ocurred, also signifying EOF. */
487 if (errno != EINTR)
488 return (EOF);
492 #if defined (HANDLE_MULTIBYTE)
493 /* read multibyte char */
495 _rl_read_mbchar (mbchar, size)
496 char *mbchar;
497 int size;
499 int mb_len = 0;
500 size_t mbchar_bytes_length;
501 wchar_t wc;
502 mbstate_t ps, ps_back;
504 memset(&ps, 0, sizeof (mbstate_t));
505 memset(&ps_back, 0, sizeof (mbstate_t));
507 while (mb_len < size)
509 RL_SETSTATE(RL_STATE_MOREINPUT);
510 mbchar[mb_len++] = rl_read_key ();
511 RL_UNSETSTATE(RL_STATE_MOREINPUT);
513 mbchar_bytes_length = mbrtowc (&wc, mbchar, mb_len, &ps);
514 if (mbchar_bytes_length == (size_t)(-1))
515 break; /* invalid byte sequence for the current locale */
516 else if (mbchar_bytes_length == (size_t)(-2))
518 /* shorted bytes */
519 ps = ps_back;
520 continue;
522 else if (mbchar_bytes_length > (size_t)(0))
523 break;
526 return mb_len;
529 /* Read a multibyte-character string whose first character is FIRST into
530 the buffer MB of length MBLEN. Returns the last character read, which
531 may be FIRST. Used by the search functions, among others. Very similar
532 to _rl_read_mbchar. */
534 _rl_read_mbstring (first, mb, mblen)
535 int first;
536 char *mb;
537 int mblen;
539 int i, c;
540 mbstate_t ps;
542 c = first;
543 memset (mb, 0, mblen);
544 for (i = 0; i < mblen; i++)
546 mb[i] = (char)c;
547 memset (&ps, 0, sizeof (mbstate_t));
548 if (_rl_get_char_len (mb, &ps) == -2)
550 /* Read more for multibyte character */
551 RL_SETSTATE (RL_STATE_MOREINPUT);
552 c = rl_read_key ();
553 RL_UNSETSTATE (RL_STATE_MOREINPUT);
555 else
556 break;
558 return c;
560 #endif /* HANDLE_MULTIBYTE */