commit: fe33dbf67b94df102603fdcf26d4d95d317e43a8
parent: 189dc1e3a6f3b21d602c8e62b755755dad98b82c
author: Brian Callahan <bcallah@openbsd.org>
date: Fri, 30 Oct 2020 20:42:25 -0400
This is oksh-6.8
6 files changed, 147 insertions(+), 81 deletions(-)
diff --git a/CVS/Entries b/CVS/Entries
@@ -1,7 +1,6 @@
/config.h/1.19/Tue Jan 16 02:21:56 2018//
/c_test.c/1.27/Result of merge//
/edit.c/1.69/Result of merge//
-/eval.c/1.65/Result of merge//
/exec.c/1.74/Result of merge//
/main.c/1.98/Result of merge//
/tty.c/1.18/Result of merge+Tue Jul 23 23:36:05 2019//
@@ -11,36 +10,37 @@
/var.c/1.71/Result of merge//
/emacs.c/1.87/Result of merge//
/sh.h/1.76/Result of merge//
-/CONTRIBUTORS/1.11/Sat Jul 25 01:41:12 2020//
-/LEGAL/1.2/Sat Jul 25 01:41:12 2020//
-/Makefile/1.39/Sat Jul 25 01:41:20 2020//
-/NOTES/1.16/Sat Jul 25 01:41:12 2020//
-/PROJECTS/1.9/Sat Jul 25 01:41:12 2020//
-/README/1.16/Sat Jul 25 01:41:20 2020//
-/alloc.c/1.19/Sat Jul 25 01:41:12 2020//
-/c_ksh.c/1.62/Sat Jul 25 01:41:12 2020//
-/c_sh.c/1.64/Sat Jul 25 01:41:12 2020//
-/c_test.h/1.4/Sat Jul 25 01:41:12 2020//
-/c_ulimit.c/1.29/Sat Jul 25 01:41:12 2020//
-/edit.h/1.12/Sat Jul 25 01:41:12 2020//
-/expand.h/1.15/Sat Jul 25 01:41:12 2020//
-/expr.c/1.34/Sat Jul 25 01:41:12 2020//
-/jobs.c/1.62/Sat Jul 25 01:41:12 2020//
-/ksh.1/1.209/Sat Jul 25 01:41:12 2020//
-/lex.c/1.78/Sat Jul 25 01:41:12 2020//
-/lex.h/1.21/Sat Jul 25 01:41:12 2020//
-/mail.c/1.27/Sat Jul 25 01:41:12 2020//
-/misc.c/1.75/Result of merge//
-/path.c/1.23/Sat Jul 25 01:41:12 2020//
-/sh.1/1.152/Sat Jul 25 01:41:12 2020//
-/shf.c/1.34/Sat Jul 25 01:41:12 2020//
-/shf.h/1.8/Sat Jul 25 01:41:12 2020//
-/syn.c/1.39/Sat Jul 25 01:41:12 2020//
-/table.c/1.25/Sat Jul 25 01:41:12 2020//
-/table.h/1.15/Sat Jul 25 01:41:12 2020//
-/tree.c/1.34/Sat Jul 25 01:41:12 2020//
-/tree.h/1.12/Sat Jul 25 01:41:12 2020//
-/tty.h/1.6/Sat Jul 25 01:41:12 2020//
-/version.c/1.12/Sat Jul 25 01:41:12 2020//
-/vi.c/1.56/Sat Jul 25 01:41:12 2020//
+/CONTRIBUTORS/1.11/Sat Oct 31 00:41:26 2020//
+/LEGAL/1.2/Sat Oct 31 00:41:26 2020//
+/Makefile/1.39/Sat Oct 31 00:41:34 2020//
+/NOTES/1.16/Sat Oct 31 00:41:26 2020//
+/PROJECTS/1.9/Sat Oct 31 00:41:26 2020//
+/README/1.16/Sat Oct 31 00:41:34 2020//
+/alloc.c/1.19/Sat Oct 31 00:41:26 2020//
+/c_ksh.c/1.62/Sat Oct 31 00:41:26 2020//
+/c_sh.c/1.64/Sat Oct 31 00:41:26 2020//
+/c_test.h/1.4/Sat Oct 31 00:41:26 2020//
+/c_ulimit.c/1.29/Sat Oct 31 00:41:26 2020//
+/edit.h/1.12/Sat Oct 31 00:41:26 2020//
+/eval.c/1.66/Result of merge//
+/expand.h/1.15/Sat Oct 31 00:41:26 2020//
+/expr.c/1.34/Sat Oct 31 00:41:26 2020//
+/jobs.c/1.62/Sat Oct 31 00:41:26 2020//
+/ksh.1/1.210/Sat Oct 31 00:41:35 2020//
+/lex.c/1.78/Sat Oct 31 00:41:26 2020//
+/lex.h/1.21/Sat Oct 31 00:41:26 2020//
+/mail.c/1.27/Sat Oct 31 00:41:26 2020//
+/misc.c/1.76/Result of merge//
+/path.c/1.23/Sat Oct 31 00:41:26 2020//
+/sh.1/1.152/Sat Oct 31 00:41:26 2020//
+/shf.c/1.34/Sat Oct 31 00:41:26 2020//
+/shf.h/1.8/Sat Oct 31 00:41:26 2020//
+/syn.c/1.39/Sat Oct 31 00:41:26 2020//
+/table.c/1.25/Sat Oct 31 00:41:26 2020//
+/table.h/1.15/Sat Oct 31 00:41:26 2020//
+/tree.c/1.34/Sat Oct 31 00:41:26 2020//
+/tree.h/1.12/Sat Oct 31 00:41:26 2020//
+/tty.h/1.6/Sat Oct 31 00:41:26 2020//
+/version.c/1.12/Sat Oct 31 00:41:26 2020//
+/vi.c/1.57/Sat Oct 31 00:41:35 2020//
D
diff --git a/CVS/Entries.Log b/CVS/Entries.Log
@@ -0,0 +1,2 @@
+A D/tests////
+R D/tests////
diff --git a/README.md b/README.md
@@ -112,5 +112,5 @@ for details.
Get a tarball
-------------
-See releases tab. The latest release is oksh-6.7.1, which matches the ksh(1)
-from OpenBSD 6.8-beta as of 2020-09-12.
+See releases tab. The latest release is oksh-6.8, which matches the ksh(1)
+from OpenBSD 6.8.
diff --git a/eval.c b/eval.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: eval.c,v 1.65 2019/06/28 13:34:59 deraadt Exp $ */
+/* $OpenBSD: eval.c,v 1.66 2020/09/13 15:39:09 tb Exp $ */
/*
* Expansion - quoting, separation, substitution, globbing
@@ -47,6 +47,8 @@ typedef struct Expand {
#define IFS_WORD 0 /* word has chars (or quotes) */
#define IFS_WS 1 /* have seen IFS white-space */
#define IFS_NWS 2 /* have seen IFS non-white-space */
+#define IFS_IWS 3 /* beginning of word, ignore IFS white-space */
+#define IFS_QUOTE 4 /* beg.w/quote, becomes IFS_WORD unless "$@" */
static int varsub(Expand *, char *, char *, int *, int *);
static int comsub(Expand *, char *);
@@ -217,7 +219,17 @@ expand(char *cp, /* input word */
c = *sp++;
break;
case OQUOTE:
- word = IFS_WORD;
+ switch (word) {
+ case IFS_QUOTE:
+ /* """something */
+ word = IFS_WORD;
+ break;
+ case IFS_WORD:
+ break;
+ default:
+ word = IFS_QUOTE;
+ break;
+ }
tilde_ok = 0;
quote = 1;
continue;
@@ -297,6 +309,8 @@ expand(char *cp, /* input word */
if (f&DOBLANK)
doblank++;
tilde_ok = 0;
+ if (word == IFS_QUOTE && type != XNULLSUB)
+ word = IFS_WORD;
if (type == XBASE) { /* expand? */
if (!st->next) {
SubType *newst;
@@ -358,6 +372,11 @@ expand(char *cp, /* input word */
f |= DOTEMP_;
/* FALLTHROUGH */
default:
+ /* '-' '+' '?' */
+ if (quote)
+ word = IFS_WORD;
+ else if (dp == Xstring(ds, dp))
+ word = IFS_IWS;
/* Enable tilde expansion */
tilde_ok = 1;
f |= DOTILDE;
@@ -387,10 +406,17 @@ expand(char *cp, /* input word */
*/
x.str = trimsub(str_val(st->var),
dp, st->stype);
- if (x.str[0] != '\0' || st->quote)
+ if (x.str[0] != '\0') {
+ word = IFS_IWS;
type = XSUB;
- else
+ } else if (quote) {
+ word = IFS_WORD;
+ type = XSUB;
+ } else {
+ if (dp == Xstring(ds, dp))
+ word = IFS_IWS;
type = XNULLSUB;
+ }
if (f&DOBLANK)
doblank++;
st = st->prev;
@@ -422,6 +448,10 @@ expand(char *cp, /* input word */
if (f&DOBLANK)
doblank++;
st = st->prev;
+ if (quote || !*x.str)
+ word = IFS_WORD;
+ else
+ word = IFS_IWS;
continue;
case '?':
{
@@ -463,12 +493,8 @@ expand(char *cp, /* input word */
type = XBASE;
if (f&DOBLANK) {
doblank--;
- /* not really correct: x=; "$x$@" should
- * generate a null argument and
- * set A; "${@:+}" shouldn't.
- */
- if (dp == Xstring(ds, dp))
- word = IFS_WS;
+ if (dp == Xstring(ds, dp) && word != IFS_WORD)
+ word = IFS_IWS;
}
continue;
@@ -503,7 +529,12 @@ expand(char *cp, /* input word */
if (c == 0) {
if (quote && !x.split)
continue;
+ if (!quote && word == IFS_WS)
+ continue;
+ /* this is so we don't terminate */
c = ' ';
+ /* now force-emit a word */
+ goto emit_word;
}
if (quote && x.split) {
/* terminate word for "$@" */
@@ -554,15 +585,15 @@ expand(char *cp, /* input word */
* -----------------------------------
* IFS_WORD w/WS w/NWS w
* IFS_WS -/WS w/NWS -
- * IFS_NWS -/NWS w/NWS w
+ * IFS_NWS -/NWS w/NWS -
+ * IFS_IWS -/WS w/NWS -
* (w means generate a word)
- * Note that IFS_NWS/0 generates a word (at&t ksh
- * doesn't do this, but POSIX does).
*/
- if (word == IFS_WORD ||
- (!ctype(c, C_IFSWS) && c && word == IFS_NWS)) {
- char *p;
-
+ if ((word == IFS_WORD) || (word == IFS_QUOTE) || (c &&
+ (word == IFS_IWS || word == IFS_NWS) &&
+ !ctype(c, C_IFSWS))) {
+ char *p;
+ emit_word:
*dp++ = '\0';
p = Xclose(ds, dp);
if (fdo & DOBRACE_)
diff --git a/ksh.1 b/ksh.1
@@ -1,8 +1,8 @@
-.\" $OpenBSD: ksh.1,v 1.209 2020/07/07 10:33:58 jca Exp $
+.\" $OpenBSD: ksh.1,v 1.210 2020/09/20 14:40:45 millert Exp $
.\"
.\" Public Domain
.\"
-.Dd $Mdocdate: July 7 2020 $
+.Dd $Mdocdate: September 20 2020 $
.Dt KSH 1
.Os
.Sh NAME
@@ -5053,6 +5053,13 @@ Erases previous character.
.It ^J | ^M
End of line.
The current line is read, parsed, and executed by the shell.
+.It ^L
+Clear the screen (if possible) and redraw the current line.
+See the
+.Em clear-screen
+command in
+.Sx Emacs editing mode
+for more information.
.It ^V
Literal next.
The next character typed is not treated specially (can be used
@@ -5510,7 +5517,9 @@ Miscellaneous vi commands
.Bl -tag -width Ds
.It ^J and ^M
The current line is read, parsed, and executed by the shell.
-.It ^L and ^R
+.It ^L
+Clear the screen (if possible) and redraw the current line.
+.It ^R
Redraw the current line.
.It Xo
.Oo Ar n Oc Ns \&.
diff --git a/vi.c b/vi.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vi.c,v 1.56 2018/03/15 16:51:29 anton Exp $ */
+/* $OpenBSD: vi.c,v 1.57 2020/09/20 14:40:45 millert Exp $ */
/*
* vi command editing
@@ -14,12 +14,14 @@
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
+#ifndef SMALL
+# include <term.h>
+# include <curses.h>
+#endif
#include "sh.h"
#include "edit.h"
-#define CTRL(c) (c & 0x1f)
-
struct edstate {
char *cbuf; /* main buffer to build the command line */
int cbufsize; /* number of bytes allocated for cbuf */
@@ -52,8 +54,9 @@ static int Backword(int);
static int Endword(int);
static int grabhist(int, int);
static int grabsearch(int, int, int, char *);
+static void do_clear_screen(void);
static void redraw_line(int);
-static void refresh(int);
+static void refresh_line(int);
static int outofwin(void);
static void rewindow(void);
static int newcol(int, int);
@@ -271,9 +274,9 @@ vi_hook(int ch)
case 0:
if (state == VLIT) {
es->cursor--;
- refresh(0);
+ refresh_line(0);
} else
- refresh(insert != 0);
+ refresh_line(insert != 0);
break;
case 1:
return 1;
@@ -298,7 +301,7 @@ vi_hook(int ch)
return -1;
} else if (putbuf("?", 1, 0) != 0)
return -1;
- refresh(0);
+ refresh_line(0);
}
}
}
@@ -310,7 +313,7 @@ vi_hook(int ch)
vi_error();
} else
es->cbuf[es->cursor++] = ch;
- refresh(1);
+ refresh_line(1);
state = VNORMAL;
break;
@@ -375,7 +378,7 @@ vi_hook(int ch)
if (!srchpat[0]) {
vi_error();
state = VNORMAL;
- refresh(0);
+ refresh_line(0);
return 0;
}
} else {
@@ -392,17 +395,17 @@ vi_hook(int ch)
} while (srchlen > 0 &&
isu8cont(locpat[srchlen]));
es->cursor = es->linelen;
- refresh(0);
+ refresh_line(0);
return 0;
}
restore_cbuf();
state = VNORMAL;
- refresh(0);
+ refresh_line(0);
} else if (ch == edchars.kill) {
srchlen = 0;
es->linelen = 1;
es->cursor = 1;
- refresh(0);
+ refresh_line(0);
return 0;
} else if (ch == edchars.werase) {
struct edstate new_es, *save_es;
@@ -421,7 +424,7 @@ vi_hook(int ch)
es->linelen -= char_len((unsigned char)locpat[i]);
srchlen = n;
es->cursor = es->linelen;
- refresh(0);
+ refresh_line(0);
return 0;
} else {
if (srchlen == SRCHLEN - 1)
@@ -446,7 +449,7 @@ vi_hook(int ch)
es->cbuf[es->linelen++] = ch;
}
es->cursor = es->linelen;
- refresh(0);
+ refresh_line(0);
}
return 0;
}
@@ -459,15 +462,15 @@ vi_hook(int ch)
switch (vi_cmd(argc1, curcmd)) {
case -1:
vi_error();
- refresh(0);
+ refresh_line(0);
break;
case 0:
if (insert != 0)
inslen = 0;
- refresh(insert != 0);
+ refresh_line(insert != 0);
break;
case 1:
- refresh(0);
+ refresh_line(0);
return 1;
case 2:
/* back from a 'v' command - don't redraw the screen */
@@ -482,7 +485,7 @@ vi_hook(int ch)
switch (vi_cmd(lastac, lastcmd)) {
case -1:
vi_error();
- refresh(0);
+ refresh_line(0);
break;
case 0:
if (insert != 0) {
@@ -495,10 +498,10 @@ vi_hook(int ch)
vi_error();
}
}
- refresh(0);
+ refresh_line(0);
break;
case 1:
- refresh(0);
+ refresh_line(0);
return 1;
case 2:
/* back from a 'v' command - can't happen */
@@ -651,6 +654,10 @@ vi_insert(int ch)
print_expansions(es);
break;
+ case CTRL('l'):
+ do_clear_screen();
+ break;
+
case CTRL('i'):
if (Flag(FVITABCOMPLETE)) {
complete_word(0, 0);
@@ -708,6 +715,9 @@ vi_cmd(int argcnt, const char *cmd)
switch (*cmd) {
case CTRL('l'):
+ do_clear_screen();
+ break;
+
case CTRL('r'):
redraw_line(1);
break;
@@ -1028,7 +1038,7 @@ vi_cmd(int argcnt, const char *cmd)
c1, srchpat)) < 0) {
if (c3) {
restore_cbuf();
- refresh(0);
+ refresh_line(0);
}
return -1;
} else {
@@ -1717,10 +1727,24 @@ grabsearch(int save, int start, int fwd, char *pat)
}
static void
-redraw_line(int newline)
+do_clear_screen(void)
+{
+ int neednl = 1;
+
+#ifndef SMALL
+ if (cur_term != NULL && clear_screen != NULL) {
+ if (tputs(clear_screen, 1, x_putc) != ERR)
+ neednl = 0;
+ }
+#endif
+ redraw_line(neednl);
+}
+
+static void
+redraw_line(int neednl)
{
(void) memset(wbuf[win], ' ', wbuf_len);
- if (newline) {
+ if (neednl) {
x_putc('\r');
x_putc('\n');
}
@@ -1730,7 +1754,7 @@ redraw_line(int newline)
}
static void
-refresh(int leftside)
+refresh_line(int leftside)
{
if (outofwin())
rewindow();
@@ -2033,7 +2057,7 @@ expand_word(int command)
modified = 1; hnum = hlast;
insert = INSERT;
lastac = 0;
- refresh(0);
+ refresh_line(0);
return rval;
}
@@ -2137,7 +2161,7 @@ complete_word(int command, int count)
modified = 1; hnum = hlast;
insert = INSERT;
lastac = 0; /* prevent this from being redone... */
- refresh(0);
+ refresh_line(0);
return rval;
}