summaryrefslogtreecommitdiff
path: root/read.c
diff options
context:
space:
mode:
Diffstat (limited to 'read.c')
-rw-r--r--read.c177
1 files changed, 116 insertions, 61 deletions
diff --git a/read.c b/read.c
index 0103fb335979..610aac28194a 100644
--- a/read.c
+++ b/read.c
@@ -1,4 +1,4 @@
-/* $NetBSD: read.c,v 1.20 2001/09/27 19:29:50 christos Exp $ */
+/* $NetBSD: read.c,v 1.39 2005/08/02 12:11:14 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -15,11 +15,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
@@ -36,12 +32,12 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
+#include "config.h"
#if !defined(lint) && !defined(SCCSID)
#if 0
static char sccsid[] = "@(#)read.c 8.1 (Berkeley) 6/4/93";
#else
-__RCSID("$NetBSD: read.c,v 1.20 2001/09/27 19:29:50 christos Exp $");
+__RCSID("$NetBSD: read.c,v 1.39 2005/08/02 12:11:14 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
@@ -49,8 +45,8 @@ __RCSID("$NetBSD: read.c,v 1.20 2001/09/27 19:29:50 christos Exp $");
* read.c: Clean this junk up! This is horrible code.
* Terminal read functions
*/
-#include "sys.h"
#include <errno.h>
+#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include "el.h"
@@ -98,6 +94,10 @@ el_read_getfn(EditLine *el)
}
+#ifndef MIN
+#define MIN(A,B) ((A) < (B) ? (A) : (B))
+#endif
+
#ifdef DEBUG_EDIT
private void
read_debug(EditLine *el)
@@ -122,7 +122,7 @@ read_debug(EditLine *el)
*/
/* ARGSUSED */
private int
-read__fixio(int fd, int e)
+read__fixio(int fd __attribute__((__unused__)), int e)
{
switch (e) {
@@ -187,10 +187,6 @@ read_preread(EditLine *el)
{
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);
@@ -203,8 +199,7 @@ read_preread(EditLine *el)
(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);
+ el_push(el, buf);
}
}
#endif /* FIONREAD */
@@ -217,18 +212,18 @@ read_preread(EditLine *el)
* Push a macro
*/
public void
-el_push(EditLine *el, const char *str)
+el_push(EditLine *el, char *str)
{
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();
+ if ((ma->macro[ma->level] = el_strdup(str)) != NULL)
+ return;
+ ma->level--;
}
+ term_beep(el);
+ term__flush();
}
@@ -238,10 +233,10 @@ el_push(EditLine *el, const char *str)
private int
read_getcmd(EditLine *el, el_action_t *cmdnum, char *ch)
{
- el_action_t cmd = ED_UNASSIGNED;
+ el_action_t cmd;
int num;
- while (cmd == ED_UNASSIGNED || cmd == ED_SEQUENCE_LEAD_IN) {
+ do {
if ((num = el_getc(el, ch)) != 1) /* if EOF or error */
return (num);
@@ -280,7 +275,7 @@ read_getcmd(EditLine *el, el_action_t *cmdnum, char *ch)
}
if (el->el_map.alt == NULL)
el->el_map.current = el->el_map.key;
- }
+ } while (cmd == ED_SEQUENCE_LEAD_IN);
*cmdnum = cmd;
return (OKCMD);
}
@@ -325,14 +320,16 @@ el_getc(EditLine *el, char *cp)
if (ma->level < 0)
break;
- if (*ma->macro[ma->level] == 0) {
- ma->level--;
+ if (ma->macro[ma->level][ma->offset] == '\0') {
+ el_free(ma->macro[ma->level--]);
+ ma->offset = 0;
continue;
}
- *cp = *ma->macro[ma->level]++ & 0377;
- if (*ma->macro[ma->level] == 0) { /* Needed for QuoteMode
- * On */
- ma->level--;
+ *cp = ma->macro[ma->level][ma->offset++] & 0377;
+ if (ma->macro[ma->level][ma->offset] == '\0') {
+ /* Needed for QuoteMode On */
+ el_free(ma->macro[ma->level--]);
+ ma->offset = 0;
}
return (1);
}
@@ -353,6 +350,35 @@ el_getc(EditLine *el, char *cp)
return (num_read);
}
+protected void
+read_prepare(EditLine *el)
+{
+ if (el->el_flags & HANDLE_SIGNALS)
+ sig_set(el);
+ if (el->el_flags & NO_TTY)
+ return;
+ if ((el->el_flags & (UNBUFFERED|EDIT_DISABLED)) == UNBUFFERED)
+ tty_rawmode(el);
+
+ /* This is relatively cheap, and things go terribly wrong if
+ we have the wrong size. */
+ el_resize(el);
+ re_clear_display(el); /* reset the display stuff */
+ ch_reset(el, 0);
+ re_refresh(el); /* print the prompt */
+
+ if (el->el_flags & UNBUFFERED)
+ term__flush();
+}
+
+protected void
+read_finish(EditLine *el)
+{
+ if ((el->el_flags & UNBUFFERED) == 0)
+ (void) tty_cookedmode(el);
+ if (el->el_flags & HANDLE_SIGNALS)
+ sig_clr(el);
+}
public const char *
el_gets(EditLine *el, int *nread)
@@ -361,13 +387,11 @@ el_gets(EditLine *el, int *nread)
el_action_t cmdnum = 0;
int num; /* how many chars we have read at NL */
char ch;
+ int crlf = 0;
#ifdef FIONREAD
c_macro_t *ma = &el->el_chared.c_macro;
#endif /* FIONREAD */
- if (el->el_flags & HANDLE_SIGNALS)
- sig_set(el);
-
if (el->el_flags & NO_TTY) {
char *cp = el->el_line.buffer;
size_t idx;
@@ -381,6 +405,8 @@ el_gets(EditLine *el, int *nread)
cp = &el->el_line.buffer[idx];
}
cp++;
+ if (el->el_flags & UNBUFFERED)
+ break;
if (cp[-1] == '\r' || cp[-1] == '\n')
break;
}
@@ -391,8 +417,7 @@ el_gets(EditLine *el, int *nread)
*nread = el->el_line.cursor - el->el_line.buffer;
return (el->el_line.buffer);
}
- re_clear_display(el); /* reset the display stuff */
- ch_reset(el);
+
#ifdef FIONREAD
if (el->el_tty.t_mode == EX_IO && ma->level < 0) {
@@ -409,11 +434,16 @@ el_gets(EditLine *el, int *nread)
}
#endif /* FIONREAD */
- re_refresh(el); /* print the prompt */
+ if ((el->el_flags & UNBUFFERED) == 0)
+ read_prepare(el);
if (el->el_flags & EDIT_DISABLED) {
- char *cp = el->el_line.buffer;
+ char *cp;
size_t idx;
+ if ((el->el_flags & UNBUFFERED) == 0)
+ cp = el->el_line.buffer;
+ else
+ cp = el->el_line.lastchar;
term__flush();
@@ -425,8 +455,13 @@ el_gets(EditLine *el, int *nread)
break;
cp = &el->el_line.buffer[idx];
}
+ if (*cp == 4) /* ought to be stty eof */
+ break;
cp++;
- if (cp[-1] == '\r' || cp[-1] == '\n')
+ crlf = cp[-1] == '\r' || cp[-1] == '\n';
+ if (el->el_flags & UNBUFFERED)
+ break;
+ if (crlf)
break;
}
@@ -436,6 +471,7 @@ el_gets(EditLine *el, int *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
@@ -449,7 +485,7 @@ el_gets(EditLine *el, int *nread)
#endif /* DEBUG_READ */
break;
}
- if ((int) cmdnum >= el->el_map.nfunc) { /* BUG CHECK command */
+ if ((unsigned 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);
@@ -471,7 +507,24 @@ el_gets(EditLine *el, int *nread)
"Error command = %d\n", cmdnum);
}
#endif /* DEBUG_READ */
+ /* vi redo needs these way down the levels... */
+ el->el_state.thiscmd = cmdnum;
+ el->el_state.thisch = ch;
+ if (el->el_map.type == MAP_VI &&
+ el->el_map.current == el->el_map.key &&
+ el->el_chared.c_redo.pos < el->el_chared.c_redo.lim) {
+ if (cmdnum == VI_DELETE_PREV_CHAR &&
+ el->el_chared.c_redo.pos != el->el_chared.c_redo.buf
+ && isprint((unsigned char)el->el_chared.c_redo.pos[-1]))
+ el->el_chared.c_redo.pos--;
+ else
+ *el->el_chared.c_redo.pos++ = ch;
+ }
retval = (*el->el_map.func[cmdnum]) (el, ch);
+#ifdef DEBUG_READ
+ (void) fprintf(el->el_errfile,
+ "Returned state %d\n", retval );
+#endif /* DEBUG_READ */
/* save the last command here */
el->el_state.lastcmd = cmdnum;
@@ -479,8 +532,6 @@ el_gets(EditLine *el, int *nread)
/* use any return value */
switch (retval) {
case CC_CURSOR:
- el->el_state.argument = 1;
- el->el_state.doingarg = 0;
re_refresh_cursor(el);
break;
@@ -490,29 +541,29 @@ el_gets(EditLine *el, int *nread)
/* 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... */
+ continue; /* keep going... */
case CC_EOF: /* end of file typed */
- num = 0;
+ if ((el->el_flags & UNBUFFERED) == 0)
+ num = 0;
+ else if (num == -1) {
+ *el->el_line.lastchar++ = CONTROL('d');
+ el->el_line.cursor = el->el_line.lastchar;
+ num = 1;
+ }
break;
case CC_NEWLINE: /* normal end of line */
@@ -526,10 +577,8 @@ el_gets(EditLine *el, int *nread)
#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 */
+ ch_reset(el, 1); /* 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:
@@ -538,20 +587,26 @@ el_gets(EditLine *el, int *nread)
(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;
+ el->el_chared.c_vcmd.action = NOP;
+ if (el->el_flags & UNBUFFERED)
+ break;
}
- /* make sure the tty is set up correctly */
- (void) tty_cookedmode(el);
term__flush(); /* flush any buffered output */
- if (el->el_flags & HANDLE_SIGNALS)
- sig_clr(el);
- if (nread)
- *nread = num;
+ /* make sure the tty is set up correctly */
+ if ((el->el_flags & UNBUFFERED) == 0) {
+ read_finish(el);
+ if (nread)
+ *nread = num;
+ } else {
+ if (nread)
+ *nread = el->el_line.lastchar - el->el_line.buffer;
+ }
return (num ? el->el_line.buffer : NULL);
}