source: trunk/third/readline/input.c @ 12992

Revision 12992, 10.1 KB checked in by kcr, 26 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r12991, which included commits to RCS files with non-trunk default branches.
RevLine 
[12991]1/* input.c -- character input functions for readline. */
2
3/* Copyright (C) 1994 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   675 Mass Ave, Cambridge, MA 02139, 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 <fcntl.h>
30#if defined (HAVE_SYS_FILE_H)
31#  include <sys/file.h>
32#endif /* HAVE_SYS_FILE_H */
33
34#if defined (HAVE_UNISTD_H)
35#  include <unistd.h>
36#endif /* HAVE_UNISTD_H */
37
38#if defined (HAVE_STDLIB_H)
39#  include <stdlib.h>
40#else
41#  include "ansi_stdlib.h"
42#endif /* HAVE_STDLIB_H */
43
44#if defined (HAVE_SELECT)
45#  if !defined (HAVE_SYS_SELECT_H) || !defined (M_UNIX)
46#    include <sys/time.h>
47#  endif
48#endif /* HAVE_SELECT */
49#if defined (HAVE_SYS_SELECT_H)
50#  include <sys/select.h>
51#endif
52
53#if defined (FIONREAD_IN_SYS_IOCTL)
54#  include <sys/ioctl.h>
55#endif
56
57#include <stdio.h>
58#include <errno.h>
59
60#if !defined (errno)
61extern int errno;
62#endif /* !errno */
63
64/* System-specific feature definitions and include files. */
65#include "rldefs.h"
66
67/* Some standard library routines. */
68#include "readline.h"
69
70/* What kind of non-blocking I/O do we have? */
71#if !defined (O_NDELAY) && defined (O_NONBLOCK)
72#  define O_NDELAY O_NONBLOCK   /* Posix style */
73#endif
74
75/* Functions imported from other files in the library. */
76extern char *xmalloc (), *xrealloc ();
77
78/* Variables and functions from macro.c. */
79extern void _rl_add_macro_char ();
80extern void _rl_with_macro_input ();
81extern int _rl_next_macro_key ();
82extern int _rl_defining_kbd_macro;
83
84#if defined (VI_MODE)
85extern void _rl_vi_set_last ();
86extern int _rl_vi_textmod_command ();
87#endif /* VI_MODE */
88
89extern FILE *rl_instream, *rl_outstream;
90extern Function *rl_last_func;
91extern int rl_key_sequence_length;
92extern int rl_pending_input;
93extern int rl_editing_mode;
94
95extern Keymap _rl_keymap;
96
97extern int _rl_convert_meta_chars_to_ascii;
98
99#if defined (__GO32__)
100#  include <pc.h>
101#endif /* __GO32__ */
102
103/* Non-null means it is a pointer to a function to run while waiting for
104   character input. */
105Function *rl_event_hook = (Function *)NULL;
106
107Function *rl_getc_function = rl_getc;
108
109/* **************************************************************** */
110/*                                                                  */
111/*                      Character Input Buffering                   */
112/*                                                                  */
113/* **************************************************************** */
114
115static int pop_index, push_index;
116static unsigned char ibuffer[512];
117static int ibuffer_len = sizeof (ibuffer) - 1;
118
119#define any_typein (push_index != pop_index)
120
121int
122_rl_any_typein ()
123{
124  return any_typein;
125}
126
127/* Return the amount of space available in the buffer for stuffing
128   characters. */
129static int
130ibuffer_space ()
131{
132  if (pop_index > push_index)
133    return (pop_index - push_index - 1);
134  else
135    return (ibuffer_len - (push_index - pop_index));
136}
137
138/* Get a key from the buffer of characters to be read.
139   Return the key in KEY.
140   Result is KEY if there was a key, or 0 if there wasn't. */
141static int
142rl_get_char (key)
143     int *key;
144{
145  if (push_index == pop_index)
146    return (0);
147
148  *key = ibuffer[pop_index++];
149
150  if (pop_index >= ibuffer_len)
151    pop_index = 0;
152
153  return (1);
154}
155
156/* Stuff KEY into the *front* of the input buffer.
157   Returns non-zero if successful, zero if there is
158   no space left in the buffer. */
159static int
160rl_unget_char (key)
161     int key;
162{
163  if (ibuffer_space ())
164    {
165      pop_index--;
166      if (pop_index < 0)
167        pop_index = ibuffer_len - 1;
168      ibuffer[pop_index] = key;
169      return (1);
170    }
171  return (0);
172}
173
174/* If a character is available to be read, then read it
175   and stuff it into IBUFFER.  Otherwise, just return. */
176static void
177rl_gather_tyi ()
178{
179#if defined (__GO32__)
180  char input;
181
182  if (isatty (0) && kbhit () && ibuffer_space ())
183    {
184      int i;
185      i = (*rl_getc_function) (rl_instream);
186      rl_stuff_char (i);
187    }
188#else /* !__GO32__ */
189
190  int tty;
191  register int tem, result;
192  int chars_avail;
193  char input;
194#if defined(HAVE_SELECT)
195  fd_set readfds, exceptfds;
196  struct timeval timeout;
197#endif
198
199  tty = fileno (rl_instream);
200
201#if defined (HAVE_SELECT)
202  FD_ZERO (&readfds);
203  FD_ZERO (&exceptfds);
204  FD_SET (tty, &readfds);
205  FD_SET (tty, &exceptfds);
206  timeout.tv_sec = 0;
207  timeout.tv_usec = 100000;     /* 0.1 seconds */
208  if (select (tty + 1, &readfds, (fd_set *)NULL, &exceptfds, &timeout) <= 0)
209    return;     /* Nothing to read. */
210#endif
211
212  result = -1;
213#if defined (FIONREAD)
214  result = ioctl (tty, FIONREAD, &chars_avail);
215#endif
216
217#if defined (O_NDELAY)
218  if (result == -1)
219    {
220      tem = fcntl (tty, F_GETFL, 0);
221
222      fcntl (tty, F_SETFL, (tem | O_NDELAY));
223      chars_avail = read (tty, &input, 1);
224
225      fcntl (tty, F_SETFL, tem);
226      if (chars_avail == -1 && errno == EAGAIN)
227        return;
228    }
229#endif /* O_NDELAY */
230
231  /* If there's nothing available, don't waste time trying to read
232     something. */
233  if (chars_avail <= 0)
234    return;
235
236  tem = ibuffer_space ();
237
238  if (chars_avail > tem)
239    chars_avail = tem;
240
241  /* One cannot read all of the available input.  I can only read a single
242     character at a time, or else programs which require input can be
243     thwarted.  If the buffer is larger than one character, I lose.
244     Damn! */
245  if (tem < ibuffer_len)
246    chars_avail = 0;
247
248  if (result != -1)
249    {
250      while (chars_avail--)
251        rl_stuff_char ((*rl_getc_function) (rl_instream));
252    }
253  else
254    {
255      if (chars_avail)
256        rl_stuff_char (input);
257    }
258#endif /* !__GO32__ */
259}
260
261/* Is there input available to be read on the readline input file
262   descriptor?  Only works if the system has select(2) or FIONREAD. */
263int
264_rl_input_available ()
265{
266#if defined(HAVE_SELECT)
267  fd_set readfds, exceptfds;
268  struct timeval timeout;
269#endif
270#if defined(FIONREAD)
271  int chars_avail;
272#endif
273  int tty;
274
275  tty = fileno (rl_instream);
276
277#if defined (HAVE_SELECT)
278  FD_ZERO (&readfds);
279  FD_ZERO (&exceptfds);
280  FD_SET (tty, &readfds);
281  FD_SET (tty, &exceptfds);
282  timeout.tv_sec = 0;
283  timeout.tv_usec = 100000;     /* 0.1 seconds */
284  return (select (tty + 1, &readfds, (fd_set *)NULL, &exceptfds, &timeout) > 0);
285#endif
286
287#if defined (FIONREAD)
288  if (ioctl (tty, FIONREAD, &chars_avail) == 0)
289    return (chars_avail);
290#endif
291
292  return 0;
293}
294
295void
296_rl_insert_typein (c)
297     int c;     
298{       
299  int key, t, i;
300  char *string;
301
302  i = key = 0;
303  string = xmalloc (ibuffer_len + 1);
304  string[i++] = (char) c;
305
306  while ((t = rl_get_char (&key)) &&
307         _rl_keymap[key].type == ISFUNC &&
308         _rl_keymap[key].function == rl_insert)
309    string[i++] = key;
310
311  if (t)
312    rl_unget_char (key);
313
314  string[i] = '\0';
315  rl_insert_text (string);
316  free (string);
317}
318
319/* Add KEY to the buffer of characters to be read.  Returns 1 if the
320   character was stuffed correctly; 0 otherwise. */
321int
322rl_stuff_char (key)
323     int key;
324{
325  if (ibuffer_space () == 0)
326    return 0;
327
328  if (key == EOF)
329    {
330      key = NEWLINE;
331      rl_pending_input = EOF;
332    }
333  ibuffer[push_index++] = key;
334  if (push_index >= ibuffer_len)
335    push_index = 0;
336
337  return 1;
338}
339
340/* Make C be the next command to be executed. */
341int
342rl_execute_next (c)
343     int c;
344{
345  rl_pending_input = c;
346  return 0;
347}
348
349/* **************************************************************** */
350/*                                                                  */
351/*                           Character Input                        */
352/*                                                                  */
353/* **************************************************************** */
354
355/* Read a key, including pending input. */
356int
357rl_read_key ()
358{
359  int c;
360
361  rl_key_sequence_length++;
362
363  if (rl_pending_input)
364    {
365      c = rl_pending_input;
366      rl_pending_input = 0;
367    }
368  else
369    {
370      /* If input is coming from a macro, then use that. */
371      if (c = _rl_next_macro_key ())
372        return (c);
373
374      /* If the user has an event function, then call it periodically. */
375      if (rl_event_hook)
376        {
377          while (rl_event_hook && rl_get_char (&c) == 0)
378            {
379              (*rl_event_hook) ();
380              rl_gather_tyi ();
381            }
382        }
383      else
384        {
385          if (rl_get_char (&c) == 0)
386            c = (*rl_getc_function) (rl_instream);
387        }
388    }
389
390  return (c);
391}
392
393int
394rl_getc (stream)
395     FILE *stream;
396{
397  int result, flags;
398  unsigned char c;
399
400#if defined (__GO32__)
401  if (isatty (0))
402    return (getkey () & 0x7F);
403#endif /* __GO32__ */
404
405  while (1)
406    {
407      result = read (fileno (stream), &c, sizeof (unsigned char));
408
409      if (result == sizeof (unsigned char))
410        return (c);
411
412      /* If zero characters are returned, then the file that we are
413         reading from is empty!  Return EOF in that case. */
414      if (result == 0)
415        return (EOF);
416
417#if defined (__BEOS__)
418      if (errno == EINTR)
419        continue;
420#endif
421
422#if defined (EWOULDBLOCK)
423      if (errno == EWOULDBLOCK)
424        {
425          if ((flags = fcntl (fileno (stream), F_GETFL, 0)) < 0)
426            return (EOF);
427          if (flags & O_NDELAY)
428            {
429              flags &= ~O_NDELAY;
430              fcntl (fileno (stream), F_SETFL, flags);
431              continue;
432            }
433          continue;
434        }
435#endif /* EWOULDBLOCK */
436
437#if defined (_POSIX_VERSION) && defined (EAGAIN) && defined (O_NONBLOCK)
438      if (errno == EAGAIN)
439        {
440          if ((flags = fcntl (fileno (stream), F_GETFL, 0)) < 0)
441            return (EOF);
442          if (flags & O_NONBLOCK)
443            {
444              flags &= ~O_NONBLOCK;
445              fcntl (fileno (stream), F_SETFL, flags);
446              continue;
447            }
448        }
449#endif /* _POSIX_VERSION && EAGAIN && O_NONBLOCK */
450
451#if !defined (__GO32__)
452      /* If the error that we received was SIGINT, then try again,
453         this is simply an interrupted system call to read ().
454         Otherwise, some error ocurred, also signifying EOF. */
455      if (errno != EINTR)
456        return (EOF);
457#endif /* !__GO32__ */
458    }
459}
Note: See TracBrowser for help on using the repository browser.