112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/* $NetBSD: read.c,v 1.70 2013/05/27 23:55:55 christos Exp $ */ 212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/*- 412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * Copyright (c) 1992, 1993 512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * The Regents of the University of California. All rights reserved. 612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * 712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * This code is derived from software contributed to Berkeley by 812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * Christos Zoulas of Cornell University. 912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * 1012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * Redistribution and use in source and binary forms, with or without 1112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * modification, are permitted provided that the following conditions 1212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * are met: 1312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * 1. Redistributions of source code must retain the above copyright 1412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * notice, this list of conditions and the following disclaimer. 1512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * 2. Redistributions in binary form must reproduce the above copyright 1612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * notice, this list of conditions and the following disclaimer in the 1712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * documentation and/or other materials provided with the distribution. 1812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * 3. Neither the name of the University nor the names of its contributors 1912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * may be used to endorse or promote products derived from this software 2012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * without specific prior written permission. 2112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * 2212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 3012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * SUCH DAMAGE. 3312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */ 3412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 3512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#include "config.h" 3612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#if !defined(lint) && !defined(SCCSID) 3712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#if 0 3812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialastatic char sccsid[] = "@(#)read.c 8.1 (Berkeley) 6/4/93"; 3912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#else 4012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala__RCSID("$NetBSD: read.c,v 1.70 2013/05/27 23:55:55 christos Exp $"); 4112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#endif 4212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#endif /* not lint && not SCCSID */ 4312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 4412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/* 4512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * read.c: Clean this junk up! This is horrible code. 4612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * Terminal read functions 4712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */ 4812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#include <errno.h> 4912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#include <fcntl.h> 5012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#include <unistd.h> 5112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#include <stdlib.h> 5212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#include <limits.h> 5312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#include "el.h" 5412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 5512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#define OKCMD -1 /* must be -1! */ 5612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 5712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprivate int read__fixio(int, int); 5812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprivate int read_preread(EditLine *); 5912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprivate int read_char(EditLine *, Char *); 6012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprivate int read_getcmd(EditLine *, el_action_t *, Char *); 6112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprivate void read_pop(c_macro_t *); 6212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 6312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/* read_init(): 6412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * Initialize the read stuff 6512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */ 6612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprotected int 6712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaread_init(EditLine *el) 6812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala{ 6912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala /* builtin read_char */ 7012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala el->el_read.read_char = read_char; 7112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala return 0; 7212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala} 7312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 7412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 7512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/* el_read_setfn(): 7612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * Set the read char function to the one provided. 7712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * If it is set to EL_BUILTIN_GETCFN, then reset to the builtin one. 7812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */ 7912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprotected int 8012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialael_read_setfn(EditLine *el, el_rfunc_t rc) 8112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala{ 8212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala el->el_read.read_char = (rc == EL_BUILTIN_GETCFN) ? read_char : rc; 8312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala return 0; 8412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala} 8512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 8612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 8712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/* el_read_getfn(): 8812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * return the current read char function, or EL_BUILTIN_GETCFN 8912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * if it is the default one 9012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */ 9112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprotected el_rfunc_t 9212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialael_read_getfn(EditLine *el) 9312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala{ 9412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala return el->el_read.read_char == read_char ? 9512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala EL_BUILTIN_GETCFN : el->el_read.read_char; 9612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala} 9712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 9812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 9912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#ifndef MIN 10012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#define MIN(A,B) ((A) < (B) ? (A) : (B)) 10112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#endif 10212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 10312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#ifdef DEBUG_EDIT 10412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprivate void 10512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaread_debug(EditLine *el) 10612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala{ 10712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 10812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if (el->el_line.cursor > el->el_line.lastchar) 10912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala (void) fprintf(el->el_errfile, "cursor > lastchar\r\n"); 11012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if (el->el_line.cursor < el->el_line.buffer) 11112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala (void) fprintf(el->el_errfile, "cursor < buffer\r\n"); 11212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if (el->el_line.cursor > el->el_line.limit) 11312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala (void) fprintf(el->el_errfile, "cursor > limit\r\n"); 11412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if (el->el_line.lastchar > el->el_line.limit) 11512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala (void) fprintf(el->el_errfile, "lastchar > limit\r\n"); 11612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if (el->el_line.limit != &el->el_line.buffer[EL_BUFSIZ - 2]) 11712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala (void) fprintf(el->el_errfile, "limit != &buffer[EL_BUFSIZ-2]\r\n"); 11812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala} 11912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#endif /* DEBUG_EDIT */ 12012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 12112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 12212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/* read__fixio(): 12312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * Try to recover from a read error 12412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */ 12512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/* ARGSUSED */ 12612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprivate int 12712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaread__fixio(int fd __attribute__((__unused__)), int e) 12812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala{ 12912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 13012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala switch (e) { 13112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala case -1: /* Make sure that the code is reachable */ 13212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 13312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#ifdef EWOULDBLOCK 13412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala case EWOULDBLOCK: 13512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#ifndef TRY_AGAIN 13612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#define TRY_AGAIN 13712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#endif 13812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#endif /* EWOULDBLOCK */ 13912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 14012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#if defined(POSIX) && defined(EAGAIN) 14112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN 14212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala case EAGAIN: 14312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#ifndef TRY_AGAIN 14412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#define TRY_AGAIN 14512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#endif 14612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#endif /* EWOULDBLOCK && EWOULDBLOCK != EAGAIN */ 14712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#endif /* POSIX && EAGAIN */ 14812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 14912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala e = 0; 15012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#ifdef TRY_AGAIN 15112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#if defined(F_SETFL) && defined(O_NDELAY) 15212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if ((e = fcntl(fd, F_GETFL, 0)) == -1) 15312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala return -1; 15412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 15512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if (fcntl(fd, F_SETFL, e & ~O_NDELAY) == -1) 15612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala return -1; 15712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala else 15812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala e = 1; 15912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#endif /* F_SETFL && O_NDELAY */ 16012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 16112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#ifdef FIONBIO 16212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { 16312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala int zero = 0; 16412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 16512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if (ioctl(fd, FIONBIO, &zero) == -1) 16612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala return -1; 16712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala else 16812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala e = 1; 16912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala } 17012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#endif /* FIONBIO */ 17112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 17212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#endif /* TRY_AGAIN */ 17312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala return e ? 0 : -1; 17412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 17512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala case EINTR: 17612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala return 0; 17712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 17812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala default: 17912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala return -1; 18012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala } 18112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala} 18212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 18312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 18412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/* read_preread(): 18512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * Try to read the stuff in the input queue; 18612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */ 18712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprivate int 18812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaread_preread(EditLine *el) 18912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala{ 19012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala int chrs = 0; 19112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 19212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if (el->el_tty.t_mode == ED_IO) 19312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala return 0; 19412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 19512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#ifndef WIDECHAR 19612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/* FIONREAD attempts to buffer up multiple bytes, and to make that work 19712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * properly with partial wide/UTF-8 characters would need some careful work. */ 19812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#ifdef FIONREAD 19912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala (void) ioctl(el->el_infd, FIONREAD, &chrs); 20012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if (chrs > 0) { 20112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala char buf[EL_BUFSIZ]; 20212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 20312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala chrs = read(el->el_infd, buf, 20412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala (size_t) MIN(chrs, EL_BUFSIZ - 1)); 20512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if (chrs > 0) { 20612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala buf[chrs] = '\0'; 20712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala el_push(el, buf); 20812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala } 20912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala } 21012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#endif /* FIONREAD */ 21112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#endif 21212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala return chrs > 0; 21312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala} 21412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 21512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 21612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/* el_push(): 21712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * Push a macro 21812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */ 21912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialapublic void 22012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd FialaFUN(el,push)(EditLine *el, const Char *str) 22112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala{ 22212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala c_macro_t *ma = &el->el_chared.c_macro; 22312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 22412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if (str != NULL && ma->level + 1 < EL_MAXMACRO) { 22512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala ma->level++; 22612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if ((ma->macro[ma->level] = Strdup(str)) != NULL) 22712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala return; 22812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala ma->level--; 22912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala } 23012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala terminal_beep(el); 23112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala terminal__flush(el); 23212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala} 23312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 23412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 23512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/* read_getcmd(): 23612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * Get next command from the input stream, return OKCMD on success. 23712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * Character values > 255 are not looked up in the map, but inserted. 23812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */ 23912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprivate int 24012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaread_getcmd(EditLine *el, el_action_t *cmdnum, Char *ch) 24112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala{ 24212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala el_action_t cmd; 24312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala int num; 24412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 24512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala el->el_errno = 0; 24612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala do { 24712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if ((num = FUN(el,getc)(el, ch)) != 1) {/* if EOF or error */ 24812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala el->el_errno = num == 0 ? 0 : errno; 24912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala return 0; /* not OKCMD */ 25012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala } 25112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 25212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#ifdef KANJI 25312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if ((*ch & 0200)) { 25412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala el->el_state.metanext = 0; 25512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala cmd = CcViMap[' ']; 25612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala break; 25712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala } else 25812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#endif /* KANJI */ 25912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 26012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if (el->el_state.metanext) { 26112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala el->el_state.metanext = 0; 26212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *ch |= 0200; 26312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala } 26412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#ifdef WIDECHAR 26512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if (*ch >= N_KEYS) 26612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala cmd = ED_INSERT; 26712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala else 26812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#endif 26912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala cmd = el->el_map.current[(unsigned char) *ch]; 27012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if (cmd == ED_SEQUENCE_LEAD_IN) { 27112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala keymacro_value_t val; 27212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala switch (keymacro_get(el, ch, &val)) { 27312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala case XK_CMD: 27412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala cmd = val.cmd; 27512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala break; 27612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala case XK_STR: 27712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala FUN(el,push)(el, val.str); 27812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala break; 27912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#ifdef notyet 28012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala case XK_EXE: 28112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala /* XXX: In the future to run a user function */ 28212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala RunCommand(val.str); 28312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala break; 28412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#endif 28512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala default: 28612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala EL_ABORT((el->el_errfile, "Bad XK_ type \n")); 28712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala break; 28812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala } 28912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala } 29012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if (el->el_map.alt == NULL) 29112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala el->el_map.current = el->el_map.key; 29212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala } while (cmd == ED_SEQUENCE_LEAD_IN); 29312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *cmdnum = cmd; 29412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala return OKCMD; 29512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala} 29612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 29712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#ifdef WIDECHAR 29812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/* utf8_islead(): 29912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * Test whether a byte is a leading byte of a UTF-8 sequence. 30012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */ 30112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprivate int 30212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialautf8_islead(int c) 30312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala{ 30412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala return c < 0x80 || /* single byte char */ 30512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala (c >= 0xc2 && c <= 0xf4); /* start of multibyte sequence */ 30612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala} 30712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#endif 30812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 30912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/* read_char(): 31012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * Read a character from the tty. 31112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */ 31212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprivate int 31312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaread_char(EditLine *el, Char *cp) 31412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala{ 31512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala ssize_t num_read; 31612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala int tried = 0; 31712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala char cbuf[MB_LEN_MAX]; 31812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala size_t cbp = 0; 31912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala int bytes = 0; 32012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 32112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala again: 32212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala el->el_signal->sig_no = 0; 32312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala while ((num_read = read(el->el_infd, cbuf + cbp, (size_t)1)) == -1) { 32412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala int e = errno; 32512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala switch (el->el_signal->sig_no) { 32612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala case SIGCONT: 32712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala FUN(el,set)(el, EL_REFRESH); 32812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala /*FALLTHROUGH*/ 32912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala case SIGWINCH: 33012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala sig_set(el); 33112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala goto again; 33212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala default: 33312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala break; 33412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala } 33512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if (!tried && read__fixio(el->el_infd, e) == 0) 33612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala tried = 1; 33712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala else { 33812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala errno = e; 33912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *cp = '\0'; 34012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala return -1; 34112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala } 34212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala } 34312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 34412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala /* Test for EOF */ 34512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if (num_read == 0) { 34612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala errno = 0; 34712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *cp = '\0'; 34812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala return 0; 34912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala } 35012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 35112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#ifdef WIDECHAR 35212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if (el->el_flags & CHARSET_IS_UTF8) { 35312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if (!utf8_islead((unsigned char)cbuf[0])) 35412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala goto again; /* discard the byte we read and try again */ 35512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala ++cbp; 35612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if ((bytes = ct_mbtowc(cp, cbuf, cbp)) == -1) { 35712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala ct_mbtowc_reset; 35812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if (cbp >= MB_LEN_MAX) { /* "shouldn't happen" */ 35912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala errno = EILSEQ; 36012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *cp = '\0'; 36112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala return -1; 36212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala } 36312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala goto again; 36412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala } 36512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala } else if (isascii((unsigned char)cbuf[0]) || 36612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala /* we don't support other multibyte charsets */ 36712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala ++cbp != 1 || 36812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala /* Try non-ASCII characters in a 8-bit character set */ 36912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala (bytes = ct_mbtowc(cp, cbuf, cbp)) != 1) 37012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#endif 37112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *cp = (unsigned char)cbuf[0]; 37212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 37312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if ((el->el_flags & IGNORE_EXTCHARS) && bytes > 1) { 37412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala cbp = 0; /* skip this character */ 37512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala goto again; 37612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala } 37712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 37812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala return (int)num_read; 37912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala} 38012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 38112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/* read_pop(): 38212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * Pop a macro from the stack 38312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */ 38412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprivate void 38512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaread_pop(c_macro_t *ma) 38612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala{ 38712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala int i; 38812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 38912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala el_free(ma->macro[0]); 39012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala for (i = 0; i < ma->level; i++) 39112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala ma->macro[i] = ma->macro[i + 1]; 39212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala ma->level--; 39312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala ma->offset = 0; 39412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala} 39512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 39612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/* el_getc(): 39712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * Read a character 39812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */ 39912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialapublic int 40012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd FialaFUN(el,getc)(EditLine *el, Char *cp) 40112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala{ 40212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala int num_read; 40312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala c_macro_t *ma = &el->el_chared.c_macro; 40412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 40512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala terminal__flush(el); 40612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala for (;;) { 40712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if (ma->level < 0) { 40812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if (!read_preread(el)) 40912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala break; 41012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala } 41112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 41212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if (ma->level < 0) 41312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala break; 41412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 41512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if (ma->macro[0][ma->offset] == '\0') { 41612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala read_pop(ma); 41712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala continue; 41812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala } 41912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 42012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *cp = ma->macro[0][ma->offset++]; 42112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 42212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if (ma->macro[0][ma->offset] == '\0') { 42312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala /* Needed for QuoteMode On */ 42412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala read_pop(ma); 42512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala } 42612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 42712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala return 1; 42812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala } 42912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 43012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#ifdef DEBUG_READ 43112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala (void) fprintf(el->el_errfile, "Turning raw mode on\n"); 43212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#endif /* DEBUG_READ */ 43312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if (tty_rawmode(el) < 0)/* make sure the tty is set up correctly */ 43412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala return 0; 43512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 43612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#ifdef DEBUG_READ 43712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala (void) fprintf(el->el_errfile, "Reading a character\n"); 43812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#endif /* DEBUG_READ */ 43912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala num_read = (*el->el_read.read_char)(el, cp); 44012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if (num_read < 0) 44112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala el->el_errno = errno; 44212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#ifdef WIDECHAR 44312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if (el->el_flags & NARROW_READ) 44412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *cp = *(char *)(void *)cp; 44512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#endif 44612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#ifdef DEBUG_READ 44712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala (void) fprintf(el->el_errfile, "Got it %c\n", *cp); 44812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#endif /* DEBUG_READ */ 44912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala return num_read; 45012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala} 45112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 45212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprotected void 45312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaread_prepare(EditLine *el) 45412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala{ 45512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if (el->el_flags & HANDLE_SIGNALS) 45612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala sig_set(el); 45712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if (el->el_flags & NO_TTY) 45812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala return; 45912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if ((el->el_flags & (UNBUFFERED|EDIT_DISABLED)) == UNBUFFERED) 46012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala tty_rawmode(el); 46112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 46212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala /* This is relatively cheap, and things go terribly wrong if 46312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala we have the wrong size. */ 46412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala el_resize(el); 46512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala re_clear_display(el); /* reset the display stuff */ 46612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala ch_reset(el, 0); 46712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala re_refresh(el); /* print the prompt */ 46812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 46912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if (el->el_flags & UNBUFFERED) 47012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala terminal__flush(el); 47112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala} 47212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 47312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprotected void 47412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaread_finish(EditLine *el) 47512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala{ 47612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if ((el->el_flags & UNBUFFERED) == 0) 47712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala (void) tty_cookedmode(el); 47812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if (el->el_flags & HANDLE_SIGNALS) 47912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala sig_clr(el); 48012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala} 48112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 48212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialapublic const Char * 48312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd FialaFUN(el,gets)(EditLine *el, int *nread) 48412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala{ 48512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala int retval; 48612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala el_action_t cmdnum = 0; 48712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala int num; /* how many chars we have read at NL */ 48812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala Char ch, *cp; 48912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala int crlf = 0; 49012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala int nrb; 49112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#ifdef FIONREAD 49212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala c_macro_t *ma = &el->el_chared.c_macro; 49312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#endif /* FIONREAD */ 49412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 49512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if (nread == NULL) 49612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala nread = &nrb; 49712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *nread = 0; 49812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 49912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if (el->el_flags & NO_TTY) { 50012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala size_t idx; 50112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 50212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala cp = el->el_line.buffer; 50312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala while ((num = (*el->el_read.read_char)(el, cp)) == 1) { 50412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala /* make sure there is space for next character */ 50512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if (cp + 1 >= el->el_line.limit) { 50612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala idx = (size_t)(cp - el->el_line.buffer); 50712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if (!ch_enlargebufs(el, (size_t)2)) 50812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala break; 50912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala cp = &el->el_line.buffer[idx]; 51012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala } 51112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala cp++; 51212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if (el->el_flags & UNBUFFERED) 51312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala break; 51412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if (cp[-1] == '\r' || cp[-1] == '\n') 51512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala break; 51612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala } 51712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if (num == -1) { 51812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if (errno == EINTR) 51912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala cp = el->el_line.buffer; 52012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala el->el_errno = errno; 52112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala } 52212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 52312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala goto noedit; 52412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala } 52512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 52612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 52712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#ifdef FIONREAD 52812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if (el->el_tty.t_mode == EX_IO && ma->level < 0) { 52912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala long chrs = 0; 53012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 53112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala (void) ioctl(el->el_infd, FIONREAD, &chrs); 53212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if (chrs == 0) { 53312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if (tty_rawmode(el) < 0) { 53412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala errno = 0; 53512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *nread = 0; 53612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala return NULL; 53712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala } 53812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala } 53912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala } 54012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#endif /* FIONREAD */ 54112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 54212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if ((el->el_flags & UNBUFFERED) == 0) 54312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala read_prepare(el); 54412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 54512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if (el->el_flags & EDIT_DISABLED) { 54612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala size_t idx; 54712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 54812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if ((el->el_flags & UNBUFFERED) == 0) 54912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala cp = el->el_line.buffer; 55012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala else 55112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala cp = el->el_line.lastchar; 55212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 55312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala terminal__flush(el); 55412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 55512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala while ((num = (*el->el_read.read_char)(el, cp)) == 1) { 55612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala /* make sure there is space next character */ 55712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if (cp + 1 >= el->el_line.limit) { 55812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala idx = (size_t)(cp - el->el_line.buffer); 55912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if (!ch_enlargebufs(el, (size_t)2)) 56012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala break; 56112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala cp = &el->el_line.buffer[idx]; 56212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala } 56312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala cp++; 56412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala crlf = cp[-1] == '\r' || cp[-1] == '\n'; 56512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if (el->el_flags & UNBUFFERED) 56612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala break; 56712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if (crlf) 56812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala break; 56912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala } 57012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 57112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if (num == -1) { 57212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if (errno == EINTR) 57312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala cp = el->el_line.buffer; 57412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala el->el_errno = errno; 57512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala } 57612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 57712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala goto noedit; 57812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala } 57912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 58012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala for (num = OKCMD; num == OKCMD;) { /* while still editing this 58112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * line */ 58212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#ifdef DEBUG_EDIT 58312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala read_debug(el); 58412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#endif /* DEBUG_EDIT */ 58512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala /* if EOF or error */ 58612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if ((num = read_getcmd(el, &cmdnum, &ch)) != OKCMD) { 58712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala num = -1; 58812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#ifdef DEBUG_READ 58912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala (void) fprintf(el->el_errfile, 59012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala "Returning from el_gets %d\n", num); 59112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#endif /* DEBUG_READ */ 59212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala break; 59312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala } 59412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if (el->el_errno == EINTR) { 59512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala el->el_line.buffer[0] = '\0'; 59612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala el->el_line.lastchar = 59712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala el->el_line.cursor = el->el_line.buffer; 59812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala break; 59912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala } 60012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if ((unsigned int)cmdnum >= (unsigned int)el->el_map.nfunc) { /* BUG CHECK command */ 60112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#ifdef DEBUG_EDIT 60212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala (void) fprintf(el->el_errfile, 60312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala "ERROR: illegal command from key 0%o\r\n", ch); 60412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#endif /* DEBUG_EDIT */ 60512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala continue; /* try again */ 60612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala } 60712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala /* now do the real command */ 60812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#ifdef DEBUG_READ 60912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala { 61012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala el_bindings_t *b; 61112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala for (b = el->el_map.help; b->name; b++) 61212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if (b->func == cmdnum) 61312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala break; 61412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if (b->name) 61512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala (void) fprintf(el->el_errfile, 61612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala "Executing %s\n", b->name); 61712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala else 61812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala (void) fprintf(el->el_errfile, 61912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala "Error command = %d\n", cmdnum); 62012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala } 62112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#endif /* DEBUG_READ */ 62212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala /* vi redo needs these way down the levels... */ 62312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala el->el_state.thiscmd = cmdnum; 62412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala el->el_state.thisch = ch; 62512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if (el->el_map.type == MAP_VI && 62612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala el->el_map.current == el->el_map.key && 62712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala el->el_chared.c_redo.pos < el->el_chared.c_redo.lim) { 62812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if (cmdnum == VI_DELETE_PREV_CHAR && 62912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala el->el_chared.c_redo.pos != el->el_chared.c_redo.buf 63012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala && Isprint(el->el_chared.c_redo.pos[-1])) 63112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala el->el_chared.c_redo.pos--; 63212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala else 63312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *el->el_chared.c_redo.pos++ = ch; 63412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala } 63512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala retval = (*el->el_map.func[cmdnum]) (el, ch); 63612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#ifdef DEBUG_READ 63712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala (void) fprintf(el->el_errfile, 63812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala "Returned state %d\n", retval ); 63912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#endif /* DEBUG_READ */ 64012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 64112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala /* save the last command here */ 64212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala el->el_state.lastcmd = cmdnum; 64312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 64412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala /* use any return value */ 64512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala switch (retval) { 64612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala case CC_CURSOR: 64712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala re_refresh_cursor(el); 64812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala break; 64912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 65012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala case CC_REDISPLAY: 65112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala re_clear_lines(el); 65212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala re_clear_display(el); 65312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala /* FALLTHROUGH */ 65412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 65512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala case CC_REFRESH: 65612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala re_refresh(el); 65712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala break; 65812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 65912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala case CC_REFRESH_BEEP: 66012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala re_refresh(el); 66112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala terminal_beep(el); 66212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala break; 66312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 66412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala case CC_NORM: /* normal char */ 66512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala break; 66612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 66712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala case CC_ARGHACK: /* Suggested by Rich Salz */ 66812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala /* <rsalz@pineapple.bbn.com> */ 66912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala continue; /* keep going... */ 67012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 67112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala case CC_EOF: /* end of file typed */ 67212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if ((el->el_flags & UNBUFFERED) == 0) 67312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala num = 0; 67412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala else if (num == -1) { 67512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *el->el_line.lastchar++ = CONTROL('d'); 67612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala el->el_line.cursor = el->el_line.lastchar; 67712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala num = 1; 67812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala } 67912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala break; 68012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 68112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala case CC_NEWLINE: /* normal end of line */ 68212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala num = (int)(el->el_line.lastchar - el->el_line.buffer); 68312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala break; 68412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 68512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala case CC_FATAL: /* fatal error, reset to known state */ 68612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#ifdef DEBUG_READ 68712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala (void) fprintf(el->el_errfile, 68812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala "*** editor fatal ERROR ***\r\n\n"); 68912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#endif /* DEBUG_READ */ 69012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala /* put (real) cursor in a known place */ 69112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala re_clear_display(el); /* reset the display stuff */ 69212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala ch_reset(el, 1); /* reset the input pointers */ 69312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala re_refresh(el); /* print the prompt again */ 69412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala break; 69512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 69612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala case CC_ERROR: 69712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala default: /* functions we don't know about */ 69812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#ifdef DEBUG_READ 69912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala (void) fprintf(el->el_errfile, 70012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala "*** editor ERROR ***\r\n\n"); 70112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#endif /* DEBUG_READ */ 70212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala terminal_beep(el); 70312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala terminal__flush(el); 70412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala break; 70512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala } 70612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala el->el_state.argument = 1; 70712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala el->el_state.doingarg = 0; 70812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala el->el_chared.c_vcmd.action = NOP; 70912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if (el->el_flags & UNBUFFERED) 71012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala break; 71112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala } 71212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala 71312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala terminal__flush(el); /* flush any buffered output */ 71412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala /* make sure the tty is set up correctly */ 71512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if ((el->el_flags & UNBUFFERED) == 0) { 71612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala read_finish(el); 71712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *nread = num != -1 ? num : 0; 71812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala } else { 71912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *nread = (int)(el->el_line.lastchar - el->el_line.buffer); 72012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala } 72112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala goto done; 72212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialanoedit: 72312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala el->el_line.cursor = el->el_line.lastchar = cp; 72412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *cp = '\0'; 72512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *nread = (int)(el->el_line.cursor - el->el_line.buffer); 72612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialadone: 72712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if (*nread == 0) { 72812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala if (num == -1) { 72912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *nread = -1; 73012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala errno = el->el_errno; 73112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala } 73212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala return NULL; 73312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala } else 73412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala return el->el_line.buffer; 73512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala} 736