* Copyright (c) 1992 The Regents of the University of California.
* This code is derived from software contributed to Berkeley by
* Christos Zoulas of Cornell University.
* %sccs.include.redist.c%
#if !defined(lint) && !defined(SCCSID)
static char sccsid
[] = "@(#)read.c 5.2 (Berkeley) %G%";
#endif /* not lint && not SCCSID */
* read.c: Clean this junk up! This is horrible code.
* Terminal read functions
private int read__fixio
__P((int, int));
private int read_preread
__P((EditLine
*));
private int read_getcmd
__P((EditLine
*, el_action_t
*, char *));
if (el
->el_line
.cursor
> el
->el_line
.lastchar
)
(void) fprintf(el
->el_errfile
, "cursor > lastchar\r\n");
if (el
->el_line
.cursor
< el
->el_line
.buffer
)
(void) fprintf(el
->el_errfile
, "cursor < buffer\r\n");
if (el
->el_line
.cursor
> el
->el_line
.limit
)
(void) fprintf(el
->el_errfile
, "cursor > limit\r\n");
if (el
->el_line
.lastchar
> el
->el_line
.limit
)
(void) fprintf(el
->el_errfile
, "lastchar > limit\r\n");
if (el
->el_line
.limit
!= &el
->el_line
.buffer
[EL_BUFSIZ
- 2])
(void) fprintf(el
->el_errfile
, "limit != &buffer[EL_BUFSIZ-2]\r\n");
* Try to recover from a read error
case -1: /* Make sure that the code is reachable */
#if defined(POSIX) && defined(EAGAIN)
# if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
# endif /* EWOULDBLOCK && EWOULDBLOCK != EAGAIN */
#endif /* POSIX && EAGAIN */
# if defined(F_SETFL) && defined(O_NDELAY)
if ((e
= fcntl(fd
, F_GETFL
, 0)) == -1)
if (fcntl(fd
, F_SETFL
, e
& ~O_NDELAY
) == -1)
# endif /* F_SETFL && O_NDELAY */
if (ioctl(fd
, FIONBIO
, (ioctl_t
) &e
) == -1)
* Try to read the stuff in the input queue;
if (el
->el_chared
.c_macro
.nline
) {
el_free((ptr_t
) el
->el_chared
.c_macro
.nline
);
el
->el_chared
.c_macro
.nline
= NULL
;
if (el
->el_tty
.t_mode
== ED_IO
)
(void) ioctl(el
->el_infd
, FIONREAD
, (ioctl_t
) &chrs
);
chrs
= read(el
->el_infd
, buf
, (size_t) MIN(chrs
, EL_BUFSIZ
- 1));
el
->el_chared
.c_macro
.nline
= strdup(buf
);
el_push(el
->el_chared
.c_macro
.nline
);
c_macro_t
*ma
= &el
->el_chared
.c_macro
;
if (str
!= NULL
&& ma
->level
+ 1 < EL_MAXMACRO
) {
ma
->macro
[ma
->level
] = (char *) str
;
* Return next command from the input stream.
read_getcmd(el
, cmdnum
, ch
)
while (cmd
== 0 || cmd
== ED_SEQUENCE_LEAD_IN
) {
if ((num
= el_getc(el
, ch
)) != 1) /* if EOF or error */
el
->el_state
.metanext
= 0;
if (el
->el_state
.metanext
) {
el
->el_state
.metanext
= 0;
cmd
= el
->el_map
.current
[(unsigned char) *ch
];
if (cmd
== ED_SEQUENCE_LEAD_IN
) {
switch (key_get(el
, ch
, &val
)) {
/* XXX: In the future to run a user function */
if (el
->el_map
.alt
== NULL
)
el
->el_map
.current
= el
->el_map
.key
;
c_macro_t
*ma
= &el
->el_chared
.c_macro
;
if (*ma
->macro
[ma
->level
] == 0) {
*cp
= *ma
->macro
[ma
->level
]++ & 0377;
if (*ma
->macro
[ma
->level
] == 0) { /* Needed for QuoteMode On */
(void) fprintf(el
->el_errfile
, "Turning raw mode on\n");
if (tty_rawmode(el
) < 0) /* make sure the tty is set up correctly */
(void) fprintf(el
->el_errfile
, "Reading a character\n");
while ((num_read
= read(el
->el_infd
, (char *) &tcp
, 1)) == -1)
if (!tried
&& read__fixio(el
->el_infd
, errno
) == 0)
(void) fprintf(el
->el_errfile
, "Got it %c\n", tcp
);
int num
; /* how many chars we have read at NL */
if (el
->el_flags
& HANDLE_SIGNALS
)
re_clear_display(el
); /* reset the display stuff */
if (el
->el_tty
.t_mode
== EX_IO
&& ma
->level
< 0) {
(void) ioctl(el
->el_infd
, FIONREAD
, (ioctl_t
) &chrs
);
if (tty_rawmode(el
) < 0) {
re_refresh(el
); /* print the prompt */
for (num
= OKCMD
; num
== OKCMD
;) { /* while still editing this line */
if ((num
= read_getcmd(el
, &cmdnum
, &ch
)) != OKCMD
) {
(void) fprintf(el
->el_errfile
, "Returning from el_gets %d\n", num
);
if (cmdnum
>= el
->el_map
.nfunc
) { /* BUG CHECK command */
(void) fprintf(el
->el_errfile
,
"ERROR: illegal command from key 0%o\r\n", ch
);
continue; /* try again */
/* now do the real command */
for (b
= el
->el_map
.help
; b
->name
; b
++)
(void) fprintf(el
->el_errfile
, "Executing %s\n", b
->name
);
(void) fprintf(el
->el_errfile
, "Error command = %d\n", cmdnum
);
retval
= (*el
->el_map
.func
[cmdnum
])(el
, ch
);
/* save the last command here */
el
->el_state
.lastcmd
= cmdnum
;
/* use any return value */
el
->el_state
.argument
= 1;
el
->el_state
.doingarg
= 0;
el
->el_state
.argument
= 1;
el
->el_state
.doingarg
= 0;
case CC_NORM
: /* normal char */
el
->el_state
.argument
= 1;
el
->el_state
.doingarg
= 0;
case CC_ARGHACK
: /* Suggested by Rich Salz */
/* <rsalz@pineapple.bbn.com> */
break; /* keep going... */
case CC_EOF
: /* end of file typed */
case CC_NEWLINE
: /* normal end of line */
num
= el
->el_line
.lastchar
- el
->el_line
.buffer
;
case CC_FATAL
: /* fatal error, reset to known state */
(void) fprintf(el
->el_errfile
, "*** editor fatal ERROR ***\r\n\n");
/* put (real) cursor in a known place */
re_clear_display(el
); /* reset the display stuff */
ch_reset(el
); /* reset the input pointers */
re_refresh(el
); /* print the prompt again */
el
->el_state
.argument
= 1;
el
->el_state
.doingarg
= 0;
default: /* functions we don't know about */
(void) fprintf(el
->el_errfile
, "*** editor ERROR ***\r\n\n");
el
->el_state
.argument
= 1;
el
->el_state
.doingarg
= 0;
(void) tty_cookedmode(el
); /* make sure the tty is set up correctly */
term__flush(); /* flush any buffered output */
if (el
->el_flags
& HANDLE_SIGNALS
)
return num
? el
->el_line
.buffer
: NULL
;