diff options
author | obrien <obrien@FreeBSD.org> | 2001-10-01 08:41:27 +0000 |
---|---|---|
committer | obrien <obrien@FreeBSD.org> | 2001-10-01 08:41:27 +0000 |
commit | 90300f853673b3879ab4d6a60683ff69b564c58b (patch) | |
tree | f9436ba88ca8f8420af319b0a12dd175381b507b /lib/libedit/read.c | |
parent | f805e363ed51ace3356b37eb173c3d6435c35022 (diff) | |
download | FreeBSD-src-90300f853673b3879ab4d6a60683ff69b564c58b.zip FreeBSD-src-90300f853673b3879ab4d6a60683ff69b564c58b.tar.gz |
+ Sync with NetBSD, bringing in feature enhancements.
+ Convert to ANSI-C function definitions
+ style(9)
Submitted by: kris
Diffstat (limited to 'lib/libedit/read.c')
-rw-r--r-- | lib/libedit/read.c | 655 |
1 files changed, 362 insertions, 293 deletions
diff --git a/lib/libedit/read.c b/lib/libedit/read.c index 959d91f..6b9d716 100644 --- a/lib/libedit/read.c +++ b/lib/libedit/read.c @@ -32,16 +32,16 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. + * + * $NetBSD: read.c,v 1.18 2000/11/11 22:18:58 christos Exp $ */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); #if !defined(lint) && !defined(SCCSID) -#if 0 static char sccsid[] = "@(#)read.c 8.1 (Berkeley) 6/4/93"; -#endif #endif /* not lint && not SCCSID */ +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + /* * read.c: Clean this junk up! This is horrible code. * Terminal read functions @@ -53,85 +53,91 @@ static char sccsid[] = "@(#)read.c 8.1 (Berkeley) 6/4/93"; #include <stdlib.h> #include "el.h" -#define OKCMD -1 +#define OKCMD -1 -private int read__fixio __P((int, int)); -private int read_preread __P((EditLine *)); -private int read_getcmd __P((EditLine *, el_action_t *, char *)); +private int read__fixio(int, int); +private int read_preread(EditLine *); +private int read_getcmd(EditLine *, el_action_t *, char *); +private int read_char(EditLine *, char *); #ifdef DEBUG_EDIT private void -read_debug(el) - EditLine *el; +read_debug(EditLine *el) { - 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"); + 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"); } #endif /* DEBUG_EDIT */ + /* read__fixio(): * Try to recover from a read error */ +/* ARGSUSED */ private int -read__fixio(fd, e) - int fd, e; +read__fixio(int fd, int e) { - switch (e) { - case -1: /* Make sure that the code is reachable */ + + switch (e) { + case -1: /* Make sure that the code is reachable */ #ifdef EWOULDBLOCK - case EWOULDBLOCK: -# ifndef TRY_AGAIN -# define TRY_AGAIN -# endif + case EWOULDBLOCK: +#ifndef TRY_AGAIN +#define TRY_AGAIN +#endif #endif /* EWOULDBLOCK */ #if defined(POSIX) && defined(EAGAIN) -# if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN - case EAGAIN: -# ifndef TRY_AGAIN -# define TRY_AGAIN -# endif -# endif /* EWOULDBLOCK && EWOULDBLOCK != EAGAIN */ +#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN + case EAGAIN: +#ifndef TRY_AGAIN +#define TRY_AGAIN +#endif +#endif /* EWOULDBLOCK && EWOULDBLOCK != EAGAIN */ #endif /* POSIX && EAGAIN */ - e = 0; + e = 0; #ifdef TRY_AGAIN -# if defined(F_SETFL) && defined(O_NDELAY) - if ((e = fcntl(fd, F_GETFL, 0)) == -1) - return -1; - - if (fcntl(fd, F_SETFL, e & ~O_NDELAY) == -1) - return -1; - else - e = 1; -# endif /* F_SETFL && O_NDELAY */ - -# ifdef FIONBIO - if (ioctl(fd, FIONBIO, (ioctl_t) &e) == -1) - return -1; - else - e = 1; -# endif /* FIONBIO */ +#if defined(F_SETFL) && defined(O_NDELAY) + if ((e = fcntl(fd, F_GETFL, 0)) == -1) + return (-1); + + if (fcntl(fd, F_SETFL, e & ~O_NDELAY) == -1) + return (-1); + else + e = 1; +#endif /* F_SETFL && O_NDELAY */ + +#ifdef FIONBIO + { + int zero = 0; + + if (ioctl(fd, FIONBIO, (ioctl_t) & zero) == -1) + return (-1); + else + e = 1; + } +#endif /* FIONBIO */ #endif /* TRY_AGAIN */ - return e ? 0 : -1; + return (e ? 0 : -1); - case EINTR: - return 0; + case EINTR: + return (0); - default: - return -1; - } + default: + return (-1); + } } @@ -139,34 +145,33 @@ read__fixio(fd, e) * Try to read the stuff in the input queue; */ private int -read_preread(el) - EditLine *el; +read_preread(EditLine *el) { - int chrs = 0; + int chrs = 0; - 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) - return 0; + 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) + return (0); #ifdef FIONREAD - (void) ioctl(el->el_infd, FIONREAD, (ioctl_t) &chrs); - if (chrs > 0) { - char buf[EL_BUFSIZ]; - - chrs = read(el->el_infd, buf, (size_t) MIN(chrs, EL_BUFSIZ - 1)); + (void) ioctl(el->el_infd, FIONREAD, (ioctl_t) & chrs); if (chrs > 0) { - buf[chrs] = '\0'; - el->el_chared.c_macro.nline = strdup(buf); - el_push(el->el_chared.c_macro.nline); + char buf[EL_BUFSIZ]; + + chrs = read(el->el_infd, buf, + (size_t) MIN(chrs, EL_BUFSIZ - 1)); + if (chrs > 0) { + buf[chrs] = '\0'; + el->el_chared.c_macro.nline = strdup(buf); + el_push(el, el->el_chared.c_macro.nline); + } } - } -#endif /* FIONREAD */ +#endif /* FIONREAD */ - return chrs > 0; + return (chrs > 0); } @@ -174,20 +179,18 @@ read_preread(el) * Push a macro */ public void -el_push(el, str) - EditLine *el; - const char *str; +el_push(EditLine *el, const char *str) { - c_macro_t *ma = &el->el_chared.c_macro; - - if (str != NULL && ma->level + 1 < EL_MAXMACRO) { - ma->level++; - ma->macro[ma->level] = (char *) str; - } - else { - term_beep(el); - term__flush(); - } + c_macro_t *ma = &el->el_chared.c_macro; + + if (str != NULL && ma->level + 1 < EL_MAXMACRO) { + ma->level++; + /* LINTED const cast */ + ma->macro[ma->level] = (char *) str; + } else { + term_beep(el); + term__flush(); + } } @@ -195,57 +198,74 @@ el_push(el, str) * Return next command from the input stream. */ private int -read_getcmd(el, cmdnum, ch) - EditLine *el; - el_action_t *cmdnum; - char *ch; +read_getcmd(EditLine *el, el_action_t *cmdnum, char *ch) { - el_action_t cmd = ED_UNASSIGNED; - int num; + el_action_t cmd = ED_UNASSIGNED; + int num; - while (cmd == ED_UNASSIGNED || cmd == ED_SEQUENCE_LEAD_IN) { - if ((num = el_getc(el, ch)) != 1) /* if EOF or error */ - return num; + while (cmd == ED_UNASSIGNED || cmd == ED_SEQUENCE_LEAD_IN) { + if ((num = el_getc(el, ch)) != 1) /* if EOF or error */ + return (num); #ifdef KANJI - if ((*ch & 0200)) { - el->el_state.metanext = 0; - cmd = CcViMap[' ']; - break; - } - else + if ((*ch & 0200)) { + el->el_state.metanext = 0; + cmd = CcViMap[' ']; + break; + } else #endif /* KANJI */ - if (el->el_state.metanext) { - el->el_state.metanext = 0; - *ch |= 0200; - } - cmd = el->el_map.current[(unsigned char) *ch]; - if (cmd == ED_SEQUENCE_LEAD_IN) { - key_value_t val; - switch (key_get(el, ch, &val)) { - case XK_CMD: - cmd = val.cmd; - break; - case XK_STR: - el_push(el, val.str); - break; + if (el->el_state.metanext) { + el->el_state.metanext = 0; + *ch |= 0200; + } + cmd = el->el_map.current[(unsigned char) *ch]; + if (cmd == ED_SEQUENCE_LEAD_IN) { + key_value_t val; + switch (key_get(el, ch, &val)) { + case XK_CMD: + cmd = val.cmd; + break; + case XK_STR: + el_push(el, val.str); + break; #ifdef notyet - case XK_EXE: - /* XXX: In the future to run a user function */ - RunCommand(val.str); - break; + case XK_EXE: + /* XXX: In the future to run a user function */ + RunCommand(val.str); + break; #endif - default: - abort(); - break; - } + default: + EL_ABORT((el->el_errfile, "Bad XK_ type \n")); + break; + } + } + if (el->el_map.alt == NULL) + el->el_map.current = el->el_map.key; } - if (el->el_map.alt == NULL) - el->el_map.current = el->el_map.key; - } - *cmdnum = cmd; - return OKCMD; + *cmdnum = cmd; + return (OKCMD); +} + + +/* read_char(): + * Read a character from the tty. + */ +private int +read_char(EditLine *el, char *cp) +{ + int num_read; + int tried = 0; + + while ((num_read = read(el->el_infd, cp, 1)) == -1) + if (!tried && read__fixio(el->el_infd, errno) == 0) + tried = 1; + else { + *cp = '\0'; + return (-1); + } + + return (num_read); } @@ -253,198 +273,247 @@ read_getcmd(el, cmdnum, ch) * Read a character */ public int -el_getc(el, cp) - EditLine *el; - char *cp; +el_getc(EditLine *el, char *cp) { - int num_read; - unsigned char tcp; - int tried = 0; + int num_read; + c_macro_t *ma = &el->el_chared.c_macro; - c_macro_t *ma = &el->el_chared.c_macro; - - term__flush(); - for (;;) { - if (ma->level < 0) { - if (!read_preread(el)) - break; - } - if (ma->level < 0) - break; - - if (*ma->macro[ma->level] == 0) { - ma->level--; - continue; - } - *cp = *ma->macro[ma->level]++ & 0377; - if (*ma->macro[ma->level] == 0) { /* Needed for QuoteMode On */ - ma->level--; + term__flush(); + for (;;) { + if (ma->level < 0) { + if (!read_preread(el)) + break; + } + if (ma->level < 0) + break; + + if (*ma->macro[ma->level] == 0) { + ma->level--; + continue; + } + *cp = *ma->macro[ma->level]++ & 0377; + if (*ma->macro[ma->level] == 0) { /* Needed for QuoteMode + * On */ + ma->level--; + } + return (1); } - return 1; - } #ifdef DEBUG_READ - (void) fprintf(el->el_errfile, "Turning raw mode on\n"); + (void) fprintf(el->el_errfile, "Turning raw mode on\n"); #endif /* DEBUG_READ */ - if (tty_rawmode(el) < 0) /* make sure the tty is set up correctly */ - return 0; + if (tty_rawmode(el) < 0)/* make sure the tty is set up correctly */ + return (0); #ifdef DEBUG_READ - (void) fprintf(el->el_errfile, "Reading a character\n"); + (void) fprintf(el->el_errfile, "Reading a character\n"); #endif /* DEBUG_READ */ - while ((num_read = read(el->el_infd, (char *) &tcp, 1)) == -1) - if (!tried && read__fixio(el->el_infd, errno) == 0) - tried = 1; - else { - *cp = '\0'; - return -1; - } + num_read = read_char(el, cp); #ifdef DEBUG_READ - (void) fprintf(el->el_errfile, "Got it %c\n", tcp); + (void) fprintf(el->el_errfile, "Got it %c\n", *cp); #endif /* DEBUG_READ */ - *cp = tcp; - return num_read; + return (num_read); } - public const char * -el_gets(el, nread) - EditLine *el; - int *nread; +el_gets(EditLine *el, int *nread) { - int retval; - el_action_t cmdnum = 0; - int num; /* how many chars we have read at NL */ - char ch; - - if (el->el_flags & HANDLE_SIGNALS) - sig_set(el); - - re_clear_display(el); /* reset the display stuff */ - ch_reset(el); - + int retval; + el_action_t cmdnum = 0; + int num; /* how many chars we have read at NL */ + char ch; #ifdef FIONREAD - if (el->el_tty.t_mode == EX_IO && ma->level < 0) { - long chrs = 0; + c_macro_t *ma = &el->el_chared.c_macro; +#endif /* FIONREAD */ - (void) ioctl(el->el_infd, FIONREAD, (ioctl_t) &chrs); - if (chrs == 0) { - if (tty_rawmode(el) < 0) { + if (el->el_flags & HANDLE_SIGNALS) + sig_set(el); + + if (el->el_flags & NO_TTY) { + char *cp = el->el_line.buffer; + size_t idx; + + while (read_char(el, cp) == 1) { + /* make sure there is space for next character */ + if (cp + 1 >= el->el_line.limit) { + idx = (cp - el->el_line.buffer); + if (!ch_enlargebufs(el, 2)) + break; + cp = &el->el_line.buffer[idx]; + } + cp++; + if (cp[-1] == '\r' || cp[-1] == '\n') + break; + } + + el->el_line.cursor = el->el_line.lastchar = cp; + *cp = '\0'; if (nread) - *nread = 0; - return NULL; - } + *nread = el->el_line.cursor - el->el_line.buffer; + return (el->el_line.buffer); } - } -#endif /* FIONREAD */ + re_clear_display(el); /* reset the display stuff */ + ch_reset(el); - re_refresh(el); /* print the prompt */ +#ifdef FIONREAD + if (el->el_tty.t_mode == EX_IO && ma->level < 0) { + long chrs = 0; + + (void) ioctl(el->el_infd, FIONREAD, (ioctl_t) & chrs); + if (chrs == 0) { + if (tty_rawmode(el) < 0) { + if (nread) + *nread = 0; + return (NULL); + } + } + } +#endif /* FIONREAD */ - for (num = OKCMD; num == OKCMD;) { /* while still editing this line */ + re_refresh(el); /* print the prompt */ + + if (el->el_flags & EDIT_DISABLED) { + char *cp = el->el_line.buffer; + size_t idx; + + term__flush(); + + while (read_char(el, cp) == 1) { + /* make sure there is space next character */ + if (cp + 1 >= el->el_line.limit) { + idx = (cp - el->el_line.buffer); + if (!ch_enlargebufs(el, 2)) + break; + cp = &el->el_line.buffer[idx]; + } + cp++; + if (cp[-1] == '\r' || cp[-1] == '\n') + break; + } + + el->el_line.cursor = el->el_line.lastchar = cp; + *cp = '\0'; + if (nread) + *nread = el->el_line.cursor - el->el_line.buffer; + return (el->el_line.buffer); + } + for (num = OKCMD; num == OKCMD;) { /* while still editing this + * line */ #ifdef DEBUG_EDIT - read_debug(el); + read_debug(el); #endif /* DEBUG_EDIT */ - /* if EOF or error */ - if ((num = read_getcmd(el, &cmdnum, &ch)) != OKCMD) { + /* if EOF or error */ + if ((num = read_getcmd(el, &cmdnum, &ch)) != OKCMD) { #ifdef DEBUG_READ - (void) fprintf(el->el_errfile, "Returning from el_gets %d\n", num); + (void) fprintf(el->el_errfile, + "Returning from el_gets %d\n", num); #endif /* DEBUG_READ */ - break; - } - - if (cmdnum >= el->el_map.nfunc) { /* BUG CHECK command */ + break; + } + if ((int) cmdnum >= el->el_map.nfunc) { /* BUG CHECK command */ #ifdef DEBUG_EDIT - (void) fprintf(el->el_errfile, - "ERROR: illegal command from key 0%o\r\n", ch); + (void) fprintf(el->el_errfile, + "ERROR: illegal command from key 0%o\r\n", ch); #endif /* DEBUG_EDIT */ - continue; /* try again */ - } - - /* now do the real command */ + continue; /* try again */ + } + /* now do the real command */ #ifdef DEBUG_READ - { - el_bindings_t *b; - for (b = el->el_map.help; b->name; b++) - if (b->func == cmdnum) - break; - if (b->name) - (void) fprintf(el->el_errfile, "Executing %s\n", b->name); - else - (void) fprintf(el->el_errfile, "Error command = %d\n", cmdnum); - } + { + el_bindings_t *b; + for (b = el->el_map.help; b->name; b++) + if (b->func == cmdnum) + break; + if (b->name) + (void) fprintf(el->el_errfile, + "Executing %s\n", b->name); + else + (void) fprintf(el->el_errfile, + "Error command = %d\n", cmdnum); + } #endif /* DEBUG_READ */ - retval = (*el->el_map.func[cmdnum])(el, ch); - - /* save the last command here */ - el->el_state.lastcmd = cmdnum; - - /* use any return value */ - switch (retval) { - case CC_CURSOR: - el->el_state.argument = 1; - el->el_state.doingarg = 0; - re_refresh_cursor(el); - break; - - case CC_REDISPLAY: - re_clear_lines(el); - re_clear_display(el); - /* FALLTHROUGH */ - - case CC_REFRESH: - el->el_state.argument = 1; - el->el_state.doingarg = 0; - re_refresh(el); - break; - - case CC_NORM: /* normal char */ - el->el_state.argument = 1; - el->el_state.doingarg = 0; - break; - - case CC_ARGHACK: /* Suggested by Rich Salz */ - /* <rsalz@pineapple.bbn.com> */ - break; /* keep going... */ - - case CC_EOF: /* end of file typed */ - num = 0; - break; - - case CC_NEWLINE: /* normal end of line */ - num = el->el_line.lastchar - el->el_line.buffer; - break; - - case CC_FATAL: /* fatal error, reset to known state */ + retval = (*el->el_map.func[cmdnum]) (el, ch); + + /* save the last command here */ + el->el_state.lastcmd = cmdnum; + + /* use any return value */ + switch (retval) { + case CC_CURSOR: + el->el_state.argument = 1; + el->el_state.doingarg = 0; + re_refresh_cursor(el); + break; + + case CC_REDISPLAY: + re_clear_lines(el); + re_clear_display(el); + /* FALLTHROUGH */ + + case CC_REFRESH: + el->el_state.argument = 1; + el->el_state.doingarg = 0; + re_refresh(el); + break; + + case CC_REFRESH_BEEP: + el->el_state.argument = 1; + el->el_state.doingarg = 0; + re_refresh(el); + term_beep(el); + break; + + case CC_NORM: /* normal char */ + el->el_state.argument = 1; + el->el_state.doingarg = 0; + break; + + case CC_ARGHACK: /* Suggested by Rich Salz */ + /* <rsalz@pineapple.bbn.com> */ + break; /* keep going... */ + + case CC_EOF: /* end of file typed */ + num = 0; + break; + + case CC_NEWLINE: /* normal end of line */ + num = el->el_line.lastchar - el->el_line.buffer; + break; + + case CC_FATAL: /* fatal error, reset to known state */ #ifdef DEBUG_READ - (void) fprintf(el->el_errfile, "*** editor fatal ERROR ***\r\n\n"); + (void) fprintf(el->el_errfile, + "*** editor fatal ERROR ***\r\n\n"); #endif /* DEBUG_READ */ - /* 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; - break; - - case CC_ERROR: - default: /* functions we don't know about */ + /* 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; + break; + + case CC_ERROR: + default: /* functions we don't know about */ #ifdef DEBUG_READ - (void) fprintf(el->el_errfile, "*** editor ERROR ***\r\n\n"); + (void) fprintf(el->el_errfile, + "*** editor ERROR ***\r\n\n"); #endif /* DEBUG_READ */ - el->el_state.argument = 1; - el->el_state.doingarg = 0; - term_beep(el); - term__flush(); - break; + el->el_state.argument = 1; + el->el_state.doingarg = 0; + term_beep(el); + term__flush(); + break; + } } - } - - term__flush(); /* flush any buffered output */ - (void) tty_cookedmode(el); /* make sure the tty is set up correctly */ - if (el->el_flags & HANDLE_SIGNALS) - sig_clr(el); - if (nread) - *nread = num; - return num ? el->el_line.buffer : NULL; + + term__flush(); /* flush any buffered output */ + /* make sure the tty is set up correctly */ + (void) tty_cookedmode(el); + if (el->el_flags & HANDLE_SIGNALS) + sig_clr(el); + if (nread) + *nread = num; + return (num ? el->el_line.buffer : NULL); } |