11573Srgrimes/*- 21573Srgrimes * Copyright (c) 1992, 1993 31573Srgrimes * The Regents of the University of California. All rights reserved. 41573Srgrimes * 51573Srgrimes * This code is derived from software contributed to Berkeley by 61573Srgrimes * Christos Zoulas of Cornell University. 71573Srgrimes * 81573Srgrimes * Redistribution and use in source and binary forms, with or without 91573Srgrimes * modification, are permitted provided that the following conditions 101573Srgrimes * are met: 111573Srgrimes * 1. Redistributions of source code must retain the above copyright 121573Srgrimes * notice, this list of conditions and the following disclaimer. 131573Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 141573Srgrimes * notice, this list of conditions and the following disclaimer in the 151573Srgrimes * documentation and/or other materials provided with the distribution. 16148834Sstefanf * 3. Neither the name of the University nor the names of its contributors 171573Srgrimes * may be used to endorse or promote products derived from this software 181573Srgrimes * without specific prior written permission. 191573Srgrimes * 201573Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 211573Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 221573Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 231573Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 241573Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 251573Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 261573Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 271573Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 281573Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 291573Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 301573Srgrimes * SUCH DAMAGE. 3184260Sobrien * 32237448Spfg * $NetBSD: read.c,v 1.52 2009/07/22 15:57:00 christos Exp $ 331573Srgrimes */ 341573Srgrimes 3560773Simp#if !defined(lint) && !defined(SCCSID) 361573Srgrimesstatic char sccsid[] = "@(#)read.c 8.1 (Berkeley) 6/4/93"; 3760773Simp#endif /* not lint && not SCCSID */ 3884260Sobrien#include <sys/cdefs.h> 3984260Sobrien__FBSDID("$FreeBSD$"); 4084260Sobrien 411573Srgrimes/* 421573Srgrimes * read.c: Clean this junk up! This is horrible code. 431573Srgrimes * Terminal read functions 441573Srgrimes */ 451573Srgrimes#include "sys.h" 4660770Simp#include <errno.h> 4766562Sbrian#include <fcntl.h> 481573Srgrimes#include <unistd.h> 491573Srgrimes#include <stdlib.h> 501573Srgrimes#include "el.h" 511573Srgrimes 52238173Spfg#define OKCMD -1 531573Srgrimes 5484260Sobrienprivate int read__fixio(int, int); 5584260Sobrienprivate int read_preread(EditLine *); 56148834Sstefanfprivate int read_char(EditLine *, char *); 5784260Sobrienprivate int read_getcmd(EditLine *, el_action_t *, char *); 58167464Sstefanfprivate void read_pop(c_macro_t *); 591573Srgrimes 60148834Sstefanf/* read_init(): 61148834Sstefanf * Initialize the read stuff 62148834Sstefanf */ 63148834Sstefanfprotected int 64148834Sstefanfread_init(EditLine *el) 65148834Sstefanf{ 66148834Sstefanf /* builtin read_char */ 67148834Sstefanf el->el_read.read_char = read_char; 68148834Sstefanf return 0; 69148834Sstefanf} 70148834Sstefanf 71148834Sstefanf 72148834Sstefanf/* el_read_setfn(): 73148834Sstefanf * Set the read char function to the one provided. 74148834Sstefanf * If it is set to EL_BUILTIN_GETCFN, then reset to the builtin one. 75148834Sstefanf */ 76148834Sstefanfprotected int 77148834Sstefanfel_read_setfn(EditLine *el, el_rfunc_t rc) 78148834Sstefanf{ 79148834Sstefanf el->el_read.read_char = (rc == EL_BUILTIN_GETCFN) ? read_char : rc; 80148834Sstefanf return 0; 81148834Sstefanf} 82148834Sstefanf 83148834Sstefanf 84148834Sstefanf/* el_read_getfn(): 85148834Sstefanf * return the current read char function, or EL_BUILTIN_GETCFN 86148834Sstefanf * if it is the default one 87148834Sstefanf */ 88148834Sstefanfprotected el_rfunc_t 89148834Sstefanfel_read_getfn(EditLine *el) 90148834Sstefanf{ 91148834Sstefanf return (el->el_read.read_char == read_char) ? 92148834Sstefanf EL_BUILTIN_GETCFN : el->el_read.read_char; 93148834Sstefanf} 94148834Sstefanf 95148834Sstefanf 96148834Sstefanf#ifndef MIN 97148834Sstefanf#define MIN(A,B) ((A) < (B) ? (A) : (B)) 98148834Sstefanf#endif 99148834Sstefanf 1001573Srgrimes#ifdef DEBUG_EDIT 1011573Srgrimesprivate void 10284260Sobrienread_debug(EditLine *el) 1031573Srgrimes{ 1041573Srgrimes 10584260Sobrien if (el->el_line.cursor > el->el_line.lastchar) 10684260Sobrien (void) fprintf(el->el_errfile, "cursor > lastchar\r\n"); 10784260Sobrien if (el->el_line.cursor < el->el_line.buffer) 10884260Sobrien (void) fprintf(el->el_errfile, "cursor < buffer\r\n"); 10984260Sobrien if (el->el_line.cursor > el->el_line.limit) 11084260Sobrien (void) fprintf(el->el_errfile, "cursor > limit\r\n"); 11184260Sobrien if (el->el_line.lastchar > el->el_line.limit) 11284260Sobrien (void) fprintf(el->el_errfile, "lastchar > limit\r\n"); 11384260Sobrien if (el->el_line.limit != &el->el_line.buffer[EL_BUFSIZ - 2]) 11484260Sobrien (void) fprintf(el->el_errfile, "limit != &buffer[EL_BUFSIZ-2]\r\n"); 1151573Srgrimes} 1161573Srgrimes#endif /* DEBUG_EDIT */ 1171573Srgrimes 11884260Sobrien 1191573Srgrimes/* read__fixio(): 1201573Srgrimes * Try to recover from a read error 1211573Srgrimes */ 12284260Sobrien/* ARGSUSED */ 1231573Srgrimesprivate int 124148834Sstefanfread__fixio(int fd __unused, int e) 1251573Srgrimes{ 1261573Srgrimes 12784260Sobrien switch (e) { 12884260Sobrien case -1: /* Make sure that the code is reachable */ 12984260Sobrien 1301573Srgrimes#ifdef EWOULDBLOCK 13184260Sobrien case EWOULDBLOCK: 13284260Sobrien#ifndef TRY_AGAIN 13384260Sobrien#define TRY_AGAIN 13484260Sobrien#endif 1351573Srgrimes#endif /* EWOULDBLOCK */ 1361573Srgrimes 1371573Srgrimes#if defined(POSIX) && defined(EAGAIN) 13884260Sobrien#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN 13984260Sobrien case EAGAIN: 14084260Sobrien#ifndef TRY_AGAIN 14184260Sobrien#define TRY_AGAIN 14284260Sobrien#endif 14384260Sobrien#endif /* EWOULDBLOCK && EWOULDBLOCK != EAGAIN */ 1441573Srgrimes#endif /* POSIX && EAGAIN */ 1451573Srgrimes 14684260Sobrien e = 0; 1471573Srgrimes#ifdef TRY_AGAIN 14884260Sobrien#if defined(F_SETFL) && defined(O_NDELAY) 14984260Sobrien if ((e = fcntl(fd, F_GETFL, 0)) == -1) 15084260Sobrien return (-1); 1511573Srgrimes 15284260Sobrien if (fcntl(fd, F_SETFL, e & ~O_NDELAY) == -1) 15384260Sobrien return (-1); 15484260Sobrien else 15584260Sobrien e = 1; 15684260Sobrien#endif /* F_SETFL && O_NDELAY */ 1571573Srgrimes 15884260Sobrien#ifdef FIONBIO 15984260Sobrien { 16084260Sobrien int zero = 0; 1611573Srgrimes 16284260Sobrien if (ioctl(fd, FIONBIO, (ioctl_t) & zero) == -1) 16384260Sobrien return (-1); 16484260Sobrien else 16584260Sobrien e = 1; 16684260Sobrien } 16784260Sobrien#endif /* FIONBIO */ 16884260Sobrien 1691573Srgrimes#endif /* TRY_AGAIN */ 17084260Sobrien return (e ? 0 : -1); 1711573Srgrimes 17284260Sobrien case EINTR: 173238173Spfg return (0); 1741573Srgrimes 17584260Sobrien default: 17684260Sobrien return (-1); 17784260Sobrien } 1781573Srgrimes} 1791573Srgrimes 1801573Srgrimes 1811573Srgrimes/* read_preread(): 1821573Srgrimes * Try to read the stuff in the input queue; 1831573Srgrimes */ 1841573Srgrimesprivate int 18584260Sobrienread_preread(EditLine *el) 1861573Srgrimes{ 18784260Sobrien int chrs = 0; 1881573Srgrimes 18984260Sobrien if (el->el_tty.t_mode == ED_IO) 19084260Sobrien return (0); 1911573Srgrimes 1921573Srgrimes#ifdef FIONREAD 19384260Sobrien (void) ioctl(el->el_infd, FIONREAD, (ioctl_t) & chrs); 19484260Sobrien if (chrs > 0) { 19584260Sobrien char buf[EL_BUFSIZ]; 1961573Srgrimes 19784260Sobrien chrs = read(el->el_infd, buf, 19884260Sobrien (size_t) MIN(chrs, EL_BUFSIZ - 1)); 19984260Sobrien if (chrs > 0) { 20084260Sobrien buf[chrs] = '\0'; 201148834Sstefanf el_push(el, buf); 20284260Sobrien } 2031573Srgrimes } 20484260Sobrien#endif /* FIONREAD */ 2051573Srgrimes 20684260Sobrien return (chrs > 0); 2071573Srgrimes} 2081573Srgrimes 2091573Srgrimes 2101573Srgrimes/* el_push(): 2111573Srgrimes * Push a macro 2121573Srgrimes */ 2131573Srgrimespublic void 214220370Sobrienel_push(EditLine *el, const char *str) 2151573Srgrimes{ 21684260Sobrien c_macro_t *ma = &el->el_chared.c_macro; 2171573Srgrimes 21884260Sobrien if (str != NULL && ma->level + 1 < EL_MAXMACRO) { 21984260Sobrien ma->level++; 220148834Sstefanf if ((ma->macro[ma->level] = el_strdup(str)) != NULL) 221148834Sstefanf return; 222148834Sstefanf ma->level--; 22384260Sobrien } 224148834Sstefanf term_beep(el); 225237448Spfg term__flush(el); 2261573Srgrimes} 2271573Srgrimes 2281573Srgrimes 2291573Srgrimes/* read_getcmd(): 2301573Srgrimes * Return next command from the input stream. 2311573Srgrimes */ 2321573Srgrimesprivate int 23384260Sobrienread_getcmd(EditLine *el, el_action_t *cmdnum, char *ch) 2341573Srgrimes{ 235148834Sstefanf el_action_t cmd; 23684260Sobrien int num; 2371573Srgrimes 238238378Spfg el->el_errno = 0; 239148834Sstefanf do { 240238378Spfg if ((num = el_getc(el, ch)) != 1) { /* if EOF or error */ 241238378Spfg el->el_errno = num == 0 ? 0 : errno; 24284260Sobrien return (num); 243238378Spfg } 2441573Srgrimes 2451573Srgrimes#ifdef KANJI 24684260Sobrien if ((*ch & 0200)) { 24784260Sobrien el->el_state.metanext = 0; 24884260Sobrien cmd = CcViMap[' ']; 24984260Sobrien break; 25084260Sobrien } else 2511573Srgrimes#endif /* KANJI */ 2521573Srgrimes 25384260Sobrien if (el->el_state.metanext) { 25484260Sobrien el->el_state.metanext = 0; 25584260Sobrien *ch |= 0200; 25684260Sobrien } 25784260Sobrien cmd = el->el_map.current[(unsigned char) *ch]; 25884260Sobrien if (cmd == ED_SEQUENCE_LEAD_IN) { 25984260Sobrien key_value_t val; 26084260Sobrien switch (key_get(el, ch, &val)) { 26184260Sobrien case XK_CMD: 26284260Sobrien cmd = val.cmd; 26384260Sobrien break; 26484260Sobrien case XK_STR: 26584260Sobrien el_push(el, val.str); 26684260Sobrien break; 2671573Srgrimes#ifdef notyet 26884260Sobrien case XK_EXE: 26984260Sobrien /* XXX: In the future to run a user function */ 27084260Sobrien RunCommand(val.str); 27184260Sobrien break; 2721573Srgrimes#endif 27384260Sobrien default: 27484260Sobrien EL_ABORT((el->el_errfile, "Bad XK_ type \n")); 27584260Sobrien break; 27684260Sobrien } 27784260Sobrien } 27884260Sobrien if (el->el_map.alt == NULL) 27984260Sobrien el->el_map.current = el->el_map.key; 280148834Sstefanf } while (cmd == ED_SEQUENCE_LEAD_IN); 28184260Sobrien *cmdnum = cmd; 28284260Sobrien return (OKCMD); 2831573Srgrimes} 2841573Srgrimes 2851573Srgrimes 28684260Sobrien/* read_char(): 28784260Sobrien * Read a character from the tty. 28884260Sobrien */ 28984260Sobrienprivate int 29084260Sobrienread_char(EditLine *el, char *cp) 29184260Sobrien{ 292237448Spfg ssize_t num_read; 29384260Sobrien int tried = 0; 29484260Sobrien 295238378Spfg again: 296238378Spfg el->el_signal->sig_no = 0; 297238378Spfg while ((num_read = read(el->el_infd, cp, 1)) == -1) { 298238378Spfg if (el->el_signal->sig_no == SIGCONT) { 299238378Spfg sig_set(el); 300238378Spfg el_set(el, EL_REFRESH); 301238378Spfg goto again; 302238378Spfg } 30384260Sobrien if (!tried && read__fixio(el->el_infd, errno) == 0) 30484260Sobrien tried = 1; 30584260Sobrien else { 30684260Sobrien *cp = '\0'; 30784260Sobrien return (-1); 30884260Sobrien } 309238378Spfg } 310237448Spfg return (int)num_read; 31184260Sobrien} 31284260Sobrien 313167464Sstefanf/* read_pop(): 314167464Sstefanf * Pop a macro from the stack 315167464Sstefanf */ 316167464Sstefanfprivate void 317167464Sstefanfread_pop(c_macro_t *ma) 318167464Sstefanf{ 319167464Sstefanf int i; 32084260Sobrien 321167464Sstefanf el_free(ma->macro[0]); 322237448Spfg for (i = 0; i < ma->level; i++) 323237448Spfg ma->macro[i] = ma->macro[i + 1]; 324237448Spfg ma->level--; 325167464Sstefanf ma->offset = 0; 326167464Sstefanf} 327167464Sstefanf 3281573Srgrimes/* el_getc(): 3291573Srgrimes * Read a character 3301573Srgrimes */ 3311573Srgrimespublic int 33284260Sobrienel_getc(EditLine *el, char *cp) 3331573Srgrimes{ 33484260Sobrien int num_read; 33584260Sobrien c_macro_t *ma = &el->el_chared.c_macro; 3361573Srgrimes 337237448Spfg term__flush(el); 33884260Sobrien for (;;) { 33984260Sobrien if (ma->level < 0) { 34084260Sobrien if (!read_preread(el)) 34184260Sobrien break; 34284260Sobrien } 343167464Sstefanf 34484260Sobrien if (ma->level < 0) 34584260Sobrien break; 3461573Srgrimes 347167464Sstefanf if (ma->macro[0][ma->offset] == '\0') { 348167464Sstefanf read_pop(ma); 34984260Sobrien continue; 35084260Sobrien } 351167464Sstefanf 352167464Sstefanf *cp = ma->macro[0][ma->offset++] & 0377; 353167464Sstefanf 354167464Sstefanf if (ma->macro[0][ma->offset] == '\0') { 355148834Sstefanf /* Needed for QuoteMode On */ 356167464Sstefanf read_pop(ma); 35784260Sobrien } 358167464Sstefanf 35984260Sobrien return (1); 3601573Srgrimes } 3618870Srgrimes 3621573Srgrimes#ifdef DEBUG_READ 36384260Sobrien (void) fprintf(el->el_errfile, "Turning raw mode on\n"); 3641573Srgrimes#endif /* DEBUG_READ */ 36584260Sobrien if (tty_rawmode(el) < 0)/* make sure the tty is set up correctly */ 36684260Sobrien return (0); 3671573Srgrimes 3681573Srgrimes#ifdef DEBUG_READ 36984260Sobrien (void) fprintf(el->el_errfile, "Reading a character\n"); 3701573Srgrimes#endif /* DEBUG_READ */ 371148834Sstefanf num_read = (*el->el_read.read_char)(el, cp); 3721573Srgrimes#ifdef DEBUG_READ 37384260Sobrien (void) fprintf(el->el_errfile, "Got it %c\n", *cp); 3741573Srgrimes#endif /* DEBUG_READ */ 37584260Sobrien return (num_read); 3761573Srgrimes} 3771573Srgrimes 378148834Sstefanfprotected void 379148834Sstefanfread_prepare(EditLine *el) 380148834Sstefanf{ 381148834Sstefanf if (el->el_flags & HANDLE_SIGNALS) 382148834Sstefanf sig_set(el); 383148834Sstefanf if (el->el_flags & NO_TTY) 384148834Sstefanf return; 385148834Sstefanf if ((el->el_flags & (UNBUFFERED|EDIT_DISABLED)) == UNBUFFERED) 386148834Sstefanf tty_rawmode(el); 3871573Srgrimes 388148834Sstefanf /* This is relatively cheap, and things go terribly wrong if 389148834Sstefanf we have the wrong size. */ 390148834Sstefanf el_resize(el); 391148834Sstefanf re_clear_display(el); /* reset the display stuff */ 392148834Sstefanf ch_reset(el, 0); 393148834Sstefanf re_refresh(el); /* print the prompt */ 394148834Sstefanf 395148834Sstefanf if (el->el_flags & UNBUFFERED) 396237448Spfg term__flush(el); 397148834Sstefanf} 398148834Sstefanf 399148834Sstefanfprotected void 400148834Sstefanfread_finish(EditLine *el) 401148834Sstefanf{ 402148834Sstefanf if ((el->el_flags & UNBUFFERED) == 0) 403148834Sstefanf (void) tty_cookedmode(el); 404148834Sstefanf if (el->el_flags & HANDLE_SIGNALS) 405148834Sstefanf sig_clr(el); 406148834Sstefanf} 407148834Sstefanf 4081573Srgrimespublic const char * 40984260Sobrienel_gets(EditLine *el, int *nread) 4101573Srgrimes{ 41184260Sobrien int retval; 41284260Sobrien el_action_t cmdnum = 0; 41384260Sobrien int num; /* how many chars we have read at NL */ 41484260Sobrien char ch; 415148834Sstefanf int crlf = 0; 416238378Spfg int nrb; 41784260Sobrien#ifdef FIONREAD 41884260Sobrien c_macro_t *ma = &el->el_chared.c_macro; 41984260Sobrien#endif /* FIONREAD */ 4201573Srgrimes 421238378Spfg if (nread == NULL) 422238378Spfg nread = &nrb; 423237448Spfg *nread = 0; 424237448Spfg 42584260Sobrien if (el->el_flags & NO_TTY) { 42684260Sobrien char *cp = el->el_line.buffer; 42784260Sobrien size_t idx; 4281573Srgrimes 429240982Skevlo while ((num = (*el->el_read.read_char)(el, cp)) == 1) { 43084260Sobrien /* make sure there is space for next character */ 43184260Sobrien if (cp + 1 >= el->el_line.limit) { 43284260Sobrien idx = (cp - el->el_line.buffer); 43384260Sobrien if (!ch_enlargebufs(el, 2)) 43484260Sobrien break; 43584260Sobrien cp = &el->el_line.buffer[idx]; 43684260Sobrien } 43784260Sobrien cp++; 438148834Sstefanf if (el->el_flags & UNBUFFERED) 439148834Sstefanf break; 44084260Sobrien if (cp[-1] == '\r' || cp[-1] == '\n') 44184260Sobrien break; 44284260Sobrien } 443238378Spfg if (num == -1) 444238378Spfg el->el_errno = errno; 4451573Srgrimes 44684260Sobrien el->el_line.cursor = el->el_line.lastchar = cp; 44784260Sobrien *cp = '\0'; 448238378Spfg *nread = (int)(el->el_line.cursor - el->el_line.buffer); 449238378Spfg goto done; 4501573Srgrimes } 45184260Sobrien 452148834Sstefanf 45384260Sobrien#ifdef FIONREAD 45484260Sobrien if (el->el_tty.t_mode == EX_IO && ma->level < 0) { 45584260Sobrien long chrs = 0; 45684260Sobrien 45784260Sobrien (void) ioctl(el->el_infd, FIONREAD, (ioctl_t) & chrs); 45884260Sobrien if (chrs == 0) { 45984260Sobrien if (tty_rawmode(el) < 0) { 460238378Spfg errno = 0; 461238378Spfg *nread = 0; 46284260Sobrien return (NULL); 46384260Sobrien } 46484260Sobrien } 46584260Sobrien } 4661573Srgrimes#endif /* FIONREAD */ 4671573Srgrimes 468148834Sstefanf if ((el->el_flags & UNBUFFERED) == 0) 469148834Sstefanf read_prepare(el); 4701573Srgrimes 47184260Sobrien if (el->el_flags & EDIT_DISABLED) { 472148834Sstefanf char *cp; 47384260Sobrien size_t idx; 474238378Spfg 475148834Sstefanf if ((el->el_flags & UNBUFFERED) == 0) 476148834Sstefanf cp = el->el_line.buffer; 477148834Sstefanf else 478148834Sstefanf cp = el->el_line.lastchar; 47984260Sobrien 480237448Spfg term__flush(el); 48184260Sobrien 482240982Skevlo while ((num = (*el->el_read.read_char)(el, cp)) == 1) { 48384260Sobrien /* make sure there is space next character */ 48484260Sobrien if (cp + 1 >= el->el_line.limit) { 48584260Sobrien idx = (cp - el->el_line.buffer); 48684260Sobrien if (!ch_enlargebufs(el, 2)) 48784260Sobrien break; 48884260Sobrien cp = &el->el_line.buffer[idx]; 48984260Sobrien } 49084260Sobrien cp++; 491148834Sstefanf crlf = cp[-1] == '\r' || cp[-1] == '\n'; 492148834Sstefanf if (el->el_flags & UNBUFFERED) 49384260Sobrien break; 494148834Sstefanf if (crlf) 495148834Sstefanf break; 49684260Sobrien } 49784260Sobrien 498238378Spfg if (num == -1) { 499238378Spfg el->el_errno = errno; 500238378Spfg } 501238378Spfg 50284260Sobrien el->el_line.cursor = el->el_line.lastchar = cp; 50384260Sobrien *cp = '\0'; 504238378Spfg goto done; 50584260Sobrien } 506148834Sstefanf 50784260Sobrien for (num = OKCMD; num == OKCMD;) { /* while still editing this 50884260Sobrien * line */ 5091573Srgrimes#ifdef DEBUG_EDIT 51084260Sobrien read_debug(el); 5111573Srgrimes#endif /* DEBUG_EDIT */ 51284260Sobrien /* if EOF or error */ 51384260Sobrien if ((num = read_getcmd(el, &cmdnum, &ch)) != OKCMD) { 5141573Srgrimes#ifdef DEBUG_READ 51584260Sobrien (void) fprintf(el->el_errfile, 51684260Sobrien "Returning from el_gets %d\n", num); 5171573Srgrimes#endif /* DEBUG_READ */ 51884260Sobrien break; 51984260Sobrien } 520277931Semaste if ((size_t)cmdnum >= el->el_map.nfunc) { /* BUG CHECK command */ 5211573Srgrimes#ifdef DEBUG_EDIT 52284260Sobrien (void) fprintf(el->el_errfile, 52384260Sobrien "ERROR: illegal command from key 0%o\r\n", ch); 5241573Srgrimes#endif /* DEBUG_EDIT */ 52584260Sobrien continue; /* try again */ 52684260Sobrien } 52784260Sobrien /* now do the real command */ 5281573Srgrimes#ifdef DEBUG_READ 52984260Sobrien { 53084260Sobrien el_bindings_t *b; 53184260Sobrien for (b = el->el_map.help; b->name; b++) 53284260Sobrien if (b->func == cmdnum) 53384260Sobrien break; 53484260Sobrien if (b->name) 53584260Sobrien (void) fprintf(el->el_errfile, 53684260Sobrien "Executing %s\n", b->name); 53784260Sobrien else 53884260Sobrien (void) fprintf(el->el_errfile, 53984260Sobrien "Error command = %d\n", cmdnum); 54084260Sobrien } 5411573Srgrimes#endif /* DEBUG_READ */ 542148834Sstefanf /* vi redo needs these way down the levels... */ 543148834Sstefanf el->el_state.thiscmd = cmdnum; 544148834Sstefanf el->el_state.thisch = ch; 545148834Sstefanf if (el->el_map.type == MAP_VI && 546148834Sstefanf el->el_map.current == el->el_map.key && 547148834Sstefanf el->el_chared.c_redo.pos < el->el_chared.c_redo.lim) { 548148834Sstefanf if (cmdnum == VI_DELETE_PREV_CHAR && 549148834Sstefanf el->el_chared.c_redo.pos != el->el_chared.c_redo.buf 550148834Sstefanf && isprint((unsigned char)el->el_chared.c_redo.pos[-1])) 551148834Sstefanf el->el_chared.c_redo.pos--; 552148834Sstefanf else 553148834Sstefanf *el->el_chared.c_redo.pos++ = ch; 554148834Sstefanf } 55584260Sobrien retval = (*el->el_map.func[cmdnum]) (el, ch); 556148834Sstefanf#ifdef DEBUG_READ 557148834Sstefanf (void) fprintf(el->el_errfile, 558148834Sstefanf "Returned state %d\n", retval ); 559148834Sstefanf#endif /* DEBUG_READ */ 5601573Srgrimes 56184260Sobrien /* save the last command here */ 56284260Sobrien el->el_state.lastcmd = cmdnum; 5631573Srgrimes 56484260Sobrien /* use any return value */ 56584260Sobrien switch (retval) { 56684260Sobrien case CC_CURSOR: 56784260Sobrien re_refresh_cursor(el); 56884260Sobrien break; 5691573Srgrimes 57084260Sobrien case CC_REDISPLAY: 57184260Sobrien re_clear_lines(el); 57284260Sobrien re_clear_display(el); 57384260Sobrien /* FALLTHROUGH */ 57426926Smsmith 57584260Sobrien case CC_REFRESH: 57684260Sobrien re_refresh(el); 57784260Sobrien break; 5781573Srgrimes 57984260Sobrien case CC_REFRESH_BEEP: 58084260Sobrien re_refresh(el); 58184260Sobrien term_beep(el); 58284260Sobrien break; 5831573Srgrimes 58484260Sobrien case CC_NORM: /* normal char */ 58584260Sobrien break; 5861573Srgrimes 58784260Sobrien case CC_ARGHACK: /* Suggested by Rich Salz */ 58884260Sobrien /* <rsalz@pineapple.bbn.com> */ 589148834Sstefanf continue; /* keep going... */ 5901573Srgrimes 59184260Sobrien case CC_EOF: /* end of file typed */ 592148834Sstefanf if ((el->el_flags & UNBUFFERED) == 0) 593148834Sstefanf num = 0; 594148834Sstefanf else if (num == -1) { 595148834Sstefanf *el->el_line.lastchar++ = CONTROL('d'); 596148834Sstefanf el->el_line.cursor = el->el_line.lastchar; 597148834Sstefanf num = 1; 598148834Sstefanf } 59984260Sobrien break; 6001573Srgrimes 60184260Sobrien case CC_NEWLINE: /* normal end of line */ 602237448Spfg num = (int)(el->el_line.lastchar - el->el_line.buffer); 60384260Sobrien break; 60484260Sobrien 60584260Sobrien case CC_FATAL: /* fatal error, reset to known state */ 6061573Srgrimes#ifdef DEBUG_READ 60784260Sobrien (void) fprintf(el->el_errfile, 60884260Sobrien "*** editor fatal ERROR ***\r\n\n"); 6091573Srgrimes#endif /* DEBUG_READ */ 61084260Sobrien /* put (real) cursor in a known place */ 61184260Sobrien re_clear_display(el); /* reset the display stuff */ 612148834Sstefanf ch_reset(el, 1); /* reset the input pointers */ 61384260Sobrien re_refresh(el); /* print the prompt again */ 61484260Sobrien break; 6151573Srgrimes 61684260Sobrien case CC_ERROR: 61784260Sobrien default: /* functions we don't know about */ 6181573Srgrimes#ifdef DEBUG_READ 61984260Sobrien (void) fprintf(el->el_errfile, 62084260Sobrien "*** editor ERROR ***\r\n\n"); 6211573Srgrimes#endif /* DEBUG_READ */ 62284260Sobrien term_beep(el); 623237448Spfg term__flush(el); 62484260Sobrien break; 62584260Sobrien } 626148834Sstefanf el->el_state.argument = 1; 627148834Sstefanf el->el_state.doingarg = 0; 628148834Sstefanf el->el_chared.c_vcmd.action = NOP; 629148834Sstefanf if (el->el_flags & UNBUFFERED) 630148834Sstefanf break; 6311573Srgrimes } 6321573Srgrimes 633237448Spfg term__flush(el); /* flush any buffered output */ 634148834Sstefanf /* make sure the tty is set up correctly */ 635148834Sstefanf if ((el->el_flags & UNBUFFERED) == 0) { 636148834Sstefanf read_finish(el); 637238378Spfg *nread = num != -1 ? num : 0; 638148834Sstefanf } else { 639238378Spfg *nread = (int)(el->el_line.lastchar - el->el_line.buffer); 640148834Sstefanf } 641238378Spfgdone: 642238378Spfg if (*nread == 0) { 643238378Spfg if (num == -1) { 644238378Spfg *nread = -1; 645238378Spfg errno = el->el_errno; 646238378Spfg } 647238378Spfg return NULL; 648238378Spfg } else 649238378Spfg return el->el_line.buffer; 6501573Srgrimes} 651