summaryrefslogtreecommitdiff
path: root/bin/ksh
diff options
context:
space:
mode:
authorJason Downs <downsj@cvs.openbsd.org>1996-10-13 21:32:24 +0000
committerJason Downs <downsj@cvs.openbsd.org>1996-10-13 21:32:24 +0000
commitec3c5af51bfcb51f976b184af54d6b0c12b077f3 (patch)
tree62bbeddd3e75559a71fa45465439dc59493d27b1 /bin/ksh
parent647a0f92a2544a00265b0a8eaff14f417a2dbe0f (diff)
Update to version 5.2.11.
Diffstat (limited to 'bin/ksh')
-rw-r--r--bin/ksh/BUG-REPORTS22
-rw-r--r--bin/ksh/ChangeLog42
-rw-r--r--bin/ksh/IAFA-PACKAGE4
-rw-r--r--bin/ksh/NEWS17
-rw-r--r--bin/ksh/README4
-rw-r--r--bin/ksh/c_sh.c8
-rw-r--r--bin/ksh/lex.c186
-rw-r--r--bin/ksh/lex.h7
-rw-r--r--bin/ksh/syn.c16
-rw-r--r--bin/ksh/tests/alias.t91
-rw-r--r--bin/ksh/tests/bksl-nl.t339
-rw-r--r--bin/ksh/tests/heredoc.t110
-rw-r--r--bin/ksh/tests/version.t2
-rw-r--r--bin/ksh/version.c4
14 files changed, 749 insertions, 103 deletions
diff --git a/bin/ksh/BUG-REPORTS b/bin/ksh/BUG-REPORTS
index d87a0c7276a..7c6cc24c41d 100644
--- a/bin/ksh/BUG-REPORTS
+++ b/bin/ksh/BUG-REPORTS
@@ -1,4 +1,4 @@
-$OpenBSD: BUG-REPORTS,v 1.3 1996/10/01 02:05:23 downsj Exp $
+$OpenBSD: BUG-REPORTS,v 1.4 1996/10/13 21:32:15 downsj Exp $
List of reported problems (problems reported and fixed before 5.0.4 not
included). Unresolved problems (may or may not still exist) marked by *,
@@ -84,6 +84,10 @@ problems believed to be fixed marked by x.
* pdksh 5.2.8, - : extended pattern globing doesn't handle nested parens ().
+* pdksh 5.2.10, - (reported by Simon J. Gerraty): in emacs, <ESC><ESC> applied
+ to a word with a macro does not complete the word (only expands the macro).
+ [see Mail.XXX]
+
--------------------- put fixed problems below this line ---------------------
x pdksh 5.0.3, NetBSD 0.9a (reported by Simon J. Gerraty): pipelines
@@ -1068,3 +1072,19 @@ x pdksh 5.2.9, - (reported by Loris Talpo): long prompts are messed up in
[see Mail.XXX]
[fixed in 5.2.9: lex.c(pprompt) was broken]
+x pdksh 5.2.9, - (reported by Will Renkel): a double backslash followed
+ by a newline in an unquoted here document results in one of the backslashes
+ and the newline being stripped.
+ [see Mail.XXX]
+ [fixed in 5.2.10: fixed backslash-newline processing in lex.c]
+
+x pdksh 5.2.9, - (reported by Han Holl): read x?prompt doesn't work
+ on non-interactive shells when the input is from a tty.
+ [see Mail.XXX]
+ [fixed in 5.2.10: changed test in c_read() from FTALKING to isatty]
+
+x pdksh 5.2.10, - (reported by Dale DePriest): expanding aliases causes
+ extra input.
+ [see Mail.XXX]
+ [fixed in 5.2.11: fixed syn.c(c_list).]
+
diff --git a/bin/ksh/ChangeLog b/bin/ksh/ChangeLog
index e1c250f8e24..23c1442e316 100644
--- a/bin/ksh/ChangeLog
+++ b/bin/ksh/ChangeLog
@@ -1,4 +1,44 @@
-$OpenBSD: ChangeLog,v 1.3 1996/10/01 02:05:26 downsj Exp $
+$OpenBSD: ChangeLog,v 1.4 1996/10/13 21:32:16 downsj Exp $
+
+Tue Oct 8 11:42:36 NDT 1996 Michael Rendell (michael@panda.cs.mun.ca)
+
+ * made pdksh-5.2.11 distribution
+
+Tue Oct 8 11:02:54 NDT 1996 Michael Rendell (michael@panda.cs.mun.ca)
+
+ * syn.c(inalias): new function.
+ * syn.c(c_list): call inalias() instead of testing source->type.
+
+Mon Oct 7 17:00:40 NDT 1996 Michael Rendell (michael@panda.cs.mun.ca)
+
+ * made pdksh-5.2.10 distribution
+
+Mon Oct 7 16:23:53 NDT 1996 Michael Rendell (michael@panda.cs.mun.ca)
+
+ * c_sh.c(c_read): when printing prompt, use isatty, not FTALKING.
+
+Wed Oct 2 12:00:51 NDT 1996 Michael Rendell (michael@panda.cs.mun.ca)
+
+ * lex.c(yylex): redirection stuff: save result of getsc() == '-'
+ and use it for ungetsc().
+
+ * lex.h(struct source): moved ugbuf out of union so it can be used
+ with alias stuff.
+ * lex.c(getsc__) case SALIAS: instead of appending a space, get the
+ next character and stuff it in ugbuf.
+
+ * lex.c(getsc_,getsc__): getsc_() renamed to getsc__().
+ * lex.c(getsc_,getsc): getsc() macro renamed to getsc_().
+ * lex.c(backslash_skip,ignore_backslash_newline): new variables.
+ * lex.c(getsc): new macro that checks backslash_skip.
+ * lex.c(getsc_bn_,getsc_bn): getsc_bn() macro deleted (all calls
+ replaced with getsc()); getsc_bn_ renamed to getsc_bn.
+ * lex.c(ungetsc_,ungetsc): ungetsc() macro deleted; renamed ungetsc_()
+ to ungetsc().
+ * lex.c(yylex,ungetsc,getsc_bn): set and use backslash_skip,
+ ignore_backslash_newline.
+ * lex.c(yylex): removed special cases for backslash-newline sequence,
+ explicitly ignore backslash followed by eof.
Mon Sep 30 17:14:41 NDT 1996 Michael Rendell (michael@panda.cs.mun.ca)
diff --git a/bin/ksh/IAFA-PACKAGE b/bin/ksh/IAFA-PACKAGE
index d93847222ca..4ef2c92384f 100644
--- a/bin/ksh/IAFA-PACKAGE
+++ b/bin/ksh/IAFA-PACKAGE
@@ -1,7 +1,7 @@
-$OpenBSD: IAFA-PACKAGE,v 1.3 1996/10/01 02:05:27 downsj Exp $
+$OpenBSD: IAFA-PACKAGE,v 1.4 1996/10/13 21:32:17 downsj Exp $
Title: pdksh
-Version: 5.2.9
+Version: 5.2.11
Description: A public domain implementation of the Korn shell (ksh88),
a UNIX command line interpreter / scripting language; the few
missing ksh features are being added and the shell is being
diff --git a/bin/ksh/NEWS b/bin/ksh/NEWS
index 8efe211b889..bf29902103e 100644
--- a/bin/ksh/NEWS
+++ b/bin/ksh/NEWS
@@ -1,4 +1,17 @@
-$OpenBSD: NEWS,v 1.3 1996/10/01 02:05:28 downsj Exp $
+$OpenBSD: NEWS,v 1.4 1996/10/13 21:32:17 downsj Exp $
+
+Version 5.2.11
+
+* bug fixes
+ * aliases: expansion was reading an extra character (bug added in 5.2.10).
+
+
+Version 5.2.10
+
+* bug fixes
+ * parsing: handling of backslash-newline fixed (esp. in here documents).
+ * read: prints prompt if non-interactive and input is a tty.
+
Version 5.2.9
@@ -9,7 +22,7 @@ Version 5.2.9
* config: fixed test for broken S_IFIFO.
* config: fixed test for getwd() routine.
* config: better NeXT support (signal list generated correctly, clock_t
- type detected, enable job contorl in rlogin sessions)
+ type detected, enable job control in rlogin sessions)
* parsing: assignments containing brackets ([]) not treated as commands.
* editing: terminal column width determined correctly on startup.
* vi: long prompts truncated (more or less) correctly.
diff --git a/bin/ksh/README b/bin/ksh/README
index 032fadafd55..7e0c9015a89 100644
--- a/bin/ksh/README
+++ b/bin/ksh/README
@@ -1,6 +1,6 @@
-$OpenBSD: README,v 1.3 1996/10/01 02:05:31 downsj Exp $
+$OpenBSD: README,v 1.4 1996/10/13 21:32:18 downsj Exp $
-Last updated September '96 for pdksh-5.2.9.
+Last updated October '96 for pdksh-5.2.11.
(check ftp://ftp.cs.mun.ca:/pub/pdksh/ or
http://www.cs.mun.ca/~michael/pdksh/ for new versions/patches)
diff --git a/bin/ksh/c_sh.c b/bin/ksh/c_sh.c
index 691abee19bf..fe090f09277 100644
--- a/bin/ksh/c_sh.c
+++ b/bin/ksh/c_sh.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: c_sh.c,v 1.2 1996/08/19 20:08:46 downsj Exp $ */
+/* $OpenBSD: c_sh.c,v 1.3 1996/10/13 21:32:18 downsj Exp $ */
/*
* built-in Bourne commands
@@ -288,9 +288,11 @@ c_read(wp)
if ((cp = strchr(*wp, '?')) != NULL) {
*cp = 0;
- if (Flag(FTALKING)) {
- /* at&t says it prints prompt on fd if its open
+ if (isatty(fd)) {
+ /* at&t ksh says it prints prompt on fd if it's open
* for writing and is a tty, but it doesn't do it
+ * (it also doesn't check the interactive flag,
+ * as is indicated in the Kornshell book).
*/
shellf("%s", cp+1);
}
diff --git a/bin/ksh/lex.c b/bin/ksh/lex.c
index 356d164e935..6c11aa00c11 100644
--- a/bin/ksh/lex.c
+++ b/bin/ksh/lex.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: lex.c,v 1.3 1996/10/01 02:05:42 downsj Exp $ */
+/* $OpenBSD: lex.c,v 1.4 1996/10/13 21:32:19 downsj Exp $ */
/*
* lexical analysis and source input
@@ -8,20 +8,22 @@
#include <ctype.h>
static void readhere ARGS((struct ioword *iop));
-static int getsc_ ARGS((void));
+static int getsc__ ARGS((void));
static void getsc_line ARGS((Source *s));
static char *get_brace_var ARGS((XString *wsp, char *wp));
static int arraysub ARGS((char **strp));
-static const char *ungetsc_ ARGS((int c));
-static int getsc_bn_ ARGS((void));
+static const char *ungetsc ARGS((int c));
+static int getsc_bn ARGS((void));
+static void gethere ARGS((void));
-static void gethere ARGS((void));
+static int backslash_skip;
+static int ignore_backslash_newline;
-/* optimized getsc_() */
-#define getsc() ((*source->str != '\0') ? *source->str++ : getsc_())
-#define getsc_bn() (*source->str != '\0' && *source->str != '\\' \
- ? *source->str++ : getsc_bn_())
-#define ungetsc(c) (source->str > source->start ? source->str-- : ungetsc_(c))
+/* optimized getsc_bn() */
+#define getsc() (*source->str != '\0' && *source->str != '\\' \
+ && !backslash_skip ? *source->str++ : getsc_bn())
+/* optimized getsc__() */
+#define getsc_() ((*source->str != '\0') ? *source->str++ : getsc__())
/*
@@ -52,6 +54,9 @@ yylex(cf)
Again:
Xinit(ws, wp, 64, ATEMP);
+ backslash_skip = 0;
+ ignore_backslash_newline = 0;
+
if (cf&ONEWORD)
istate = SWORD;
#ifdef KSH
@@ -65,9 +70,12 @@ yylex(cf)
istate = (cf & HEREDELIM) ? SHEREDELIM : SBASE;
while ((c = getsc()) == ' ' || c == '\t')
;
- if (c == '#')
+ if (c == '#') {
+ ignore_backslash_newline++;
while ((c = getsc()) != '\0' && c != '\n')
;
+ ignore_backslash_newline--;
+ }
ungetsc(c);
}
if (source->flags & SF_ALIAS) { /* trailing ' ' in alias definition */
@@ -139,23 +147,19 @@ yylex(cf)
switch (c) {
case '\\':
c = getsc();
- if (c != '\n') {
#ifdef OS2
- if (isalnum(c)) {
- *wp++ = CHAR, *wp++ = '\\';
- *wp++ = CHAR, *wp++ = c;
- } else
+ if (isalnum(c)) {
+ *wp++ = CHAR, *wp++ = '\\';
+ *wp++ = CHAR, *wp++ = c;
+ } else
#endif
- *wp++ = QCHAR, *wp++ = c;
- } else
- if (wp == Xstring(ws, wp)) {
- Xfree(ws, wp); /* free word */
- goto Again;
- }
+ if (c) /* trailing \ is lost */
+ *wp++ = QCHAR, *wp++ = c;
break;
case '\'':
*++statep = state = SSQUOTE;
*wp++ = OQUOTE;
+ ignore_backslash_newline++;
break;
case '"':
*++statep = state = SDQUOTE;
@@ -171,16 +175,16 @@ yylex(cf)
case '\\':
c = getsc();
switch (c) {
- case '\n':
- break;
case '"': case '\\':
case '$': case '`':
*wp++ = QCHAR, *wp++ = c;
break;
default:
Xcheck(ws, wp);
- *wp++ = CHAR, *wp++ = '\\';
- *wp++ = CHAR, *wp++ = c;
+ if (c) { /* trailing \ is lost */
+ *wp++ = CHAR, *wp++ = '\\';
+ *wp++ = CHAR, *wp++ = c;
+ }
break;
}
break;
@@ -207,10 +211,10 @@ yylex(cf)
* wrap @(...) around the pattern
* (allows easy handling of ${a#b|c})
*/
- c = getsc_bn();
+ c = getsc();
if (c == '#' || c == '%') {
*wp++ = CHAR, *wp++ = c;
- if ((c2 = getsc_bn()) == c)
+ if ((c2 = getsc()) == c)
*wp++ = CHAR, *wp++ = c;
else
ungetsc(c2);
@@ -263,6 +267,7 @@ yylex(cf)
if (c == '\'') {
state = *--statep;
*wp++ = CQUOTE;
+ ignore_backslash_newline--;
} else
*wp++ = QCHAR, *wp++ = c;
break;
@@ -298,6 +303,7 @@ yylex(cf)
break;
case '\'':
csstate = 4;
+ ignore_backslash_newline++;
break;
}
break;
@@ -315,8 +321,10 @@ yylex(cf)
break;
case 4: /* single quotes */
- if (c == '\'')
+ if (c == '\'') {
csstate = 0;
+ ignore_backslash_newline--;
+ }
break;
}
if (nparen == 0) {
@@ -390,8 +398,6 @@ yylex(cf)
state = *--statep;
} else if (c == '\\') {
switch (c = getsc()) {
- case '\n':
- break;
case '\\':
case '$': case '`':
*wp++ = c;
@@ -403,8 +409,10 @@ yylex(cf)
}
/* fall through.. */
default:
- *wp++ = '\\';
- *wp++ = c;
+ if (c) { /* trailing \ is lost */
+ *wp++ = '\\';
+ *wp++ = c;
+ }
break;
}
} else
@@ -447,13 +455,14 @@ yylex(cf)
*/
if (c == '\\') {
c = getsc();
- if (c != '\n') {
+ if (c) { /* trailing \ is lost */
*wp++ = QCHAR;
*wp++ = c;
}
} else if (c == '\'') {
*++statep = state = SSQUOTE;
*wp++ = OQUOTE;
+ ignore_backslash_newline++;
} else if (c == '"') {
state = SHEREDQUOTE;
*wp++ = OQUOTE;
@@ -468,8 +477,19 @@ yylex(cf)
*wp++ = CQUOTE;
state = SHEREDELIM;
} else {
- if (c == '\\' && (c = getsc()) == '\n')
- break;
+ if (c == '\\') {
+ switch (c = getsc()) {
+ case '\\': case '"':
+ case '$': case '`':
+ break;
+ default:
+ if (c) { /* trailing \ lost */
+ *wp++ = CHAR;
+ *wp++ = '\\';
+ }
+ break;
+ }
+ }
*wp++ = CHAR;
*wp++ = c;
}
@@ -540,7 +560,7 @@ Done:
iop->flag = c == c2 ?
(c == '>' ? IOCAT : IOHERE) : IORDWR;
if (iop->flag == IOHERE)
- if (getsc() == '-')
+ if ((c2 = getsc()) == '-')
iop->flag |= IOSKIP;
else
ungetsc(c2);
@@ -653,7 +673,7 @@ readhere(iop)
register int c;
char *volatile eof;
char *eofp;
- int skiptabs, bn;
+ int skiptabs;
int i;
eof = evalstr(iop->delim, 0);
@@ -680,11 +700,13 @@ readhere(iop)
unwind(i);
}
- bn = iop->flag & IOEVAL;
+ if (!(iop->flag & IOEVAL))
+ ignore_backslash_newline++;
+
for (;;) {
eofp = eof;
skiptabs = iop->flag & IOSKIP;
- while ((c = (bn ? getsc_bn() : getsc())) != 0) {
+ while ((c = getsc()) != 0) {
if (skiptabs) {
if (c == '\t')
continue;
@@ -701,7 +723,7 @@ readhere(iop)
break;
ungetsc(c);
shf_write(eof, eofp - eof, shf);
- while ((c = (bn ? getsc_bn() : getsc())) != '\n') {
+ while ((c = getsc()) != '\n') {
if (c == 0)
yyerror("here document `%s' unclosed\n", eof);
shf_putc(c, shf);
@@ -715,6 +737,8 @@ readhere(iop)
/*XXX add similar checks for write errors everywhere */
quitenv();
shf_close(shf);
+ if (!(iop->flag & IOEVAL))
+ ignore_backslash_newline--;
}
void
@@ -771,7 +795,7 @@ pushs(type, areap)
}
static int
-getsc_()
+getsc__()
{
register Source *s = source;
register int c;
@@ -819,21 +843,40 @@ getsc_()
&& isspace(strchr(s->u.tblp->val.s, 0)[-1]))
{
source = s = s->next; /* pop source stack */
+ /* Note that this alias ended with a space,
+ * enabling alias expansion on the following
+ * word.
+ */
s->flags |= SF_ALIAS;
} else {
- /* put a fake space at the end of the alias.
- * This keeps the current alias in the source
- * list so recursive aliases can be detected.
- * The addition of a space after an alias
- * never affects anything (I think).
+ /* At this point, we need to keep the current
+ * alias in the source list so recursive
+ * aliases can be detected and we also need
+ * to return the next character. Do this
+ * by temporarily popping the alias to get
+ * the next character and then put it back
+ * in the source list with the SF_ALIASEND
+ * flag set.
*/
- s->flags |= SF_ALIASEND;
- s->start = s->str = space;
+ source = s->next; /* pop source stack */
+ source->flags |= s->flags & SF_ALIAS;
+ c = getsc__();
+ if (c) {
+ s->flags |= SF_ALIASEND;
+ s->ugbuf[0] = c; s->ugbuf[1] = '\0';
+ s->start = s->str = s->ugbuf;
+ s->next = source;
+ source = s;
+ } else {
+ s = source;
+ /* avoid reading eof twice */
+ s->str = NULL;
+ }
}
continue;
case SREREAD:
- if (s->start != s->u.ugbuf) /* yuck */
+ if (s->start != s->ugbuf) /* yuck */
afree(s->u.freeme, ATEMP);
source = s = s->next;
continue;
@@ -1088,7 +1131,7 @@ get_brace_var(wsp, wp)
state = PS_INITIAL;
while (1) {
- c = getsc_bn();
+ c = getsc();
/* State machine to figure out where the variable part ends. */
switch (state) {
case PS_INITIAL:
@@ -1121,7 +1164,7 @@ get_brace_var(wsp, wp)
*wp++ = *p++;
}
afree(tmp, ATEMP);
- c = getsc();
+ c = getsc(); /* the ] */
}
}
break;
@@ -1163,7 +1206,7 @@ arraysub(strp)
Xinit(ws, wp, 32, ATEMP);
do {
- c = getsc_bn();
+ c = getsc();
Xcheck(ws, wp);
*wp++ = c;
if (c == '[')
@@ -1180,9 +1223,11 @@ arraysub(strp)
/* Unget a char: handles case when we are already at the start of the buffer */
static const char *
-ungetsc_(c)
+ungetsc(c)
int c;
{
+ if (backslash_skip)
+ backslash_skip--;
/* Don't unget eof... */
if (source->str == null && c == '\0')
return source->str;
@@ -1192,29 +1237,40 @@ ungetsc_(c)
Source *s;
s = pushs(SREREAD, source->areap);
- s->u.ugbuf[0] = c; s->u.ugbuf[1] = '\0';
- s->start = s->str = s->u.ugbuf;
+ s->ugbuf[0] = c; s->ugbuf[1] = '\0';
+ s->start = s->str = s->ugbuf;
s->next = source;
source = s;
}
return source->str;
}
+
/* Called to get a char that isn't a \newline sequence. */
static int
-getsc_bn_ ARGS((void))
+getsc_bn ARGS((void))
{
- int c;
+ int c, c2;
+
+ if (ignore_backslash_newline)
+ return getsc_();
+
+ if (backslash_skip == 1) {
+ backslash_skip = 2;
+ return getsc_();
+ }
+
+ backslash_skip = 0;
while (1) {
c = getsc_();
- if (c != '\\')
- return c;
- c = getsc();
- if (c != '\n') {
- ungetsc(c);
- return '\\';
+ if (c == '\\') {
+ if ((c2 = getsc_()) == '\n')
+ /* ignore the \newline; get the next char... */
+ continue;
+ ungetsc(c2);
+ backslash_skip = 1;
}
- /* ignore the \newline; get the next char... */
+ return c;
}
}
diff --git a/bin/ksh/lex.h b/bin/ksh/lex.h
index 8d755ca031d..bca6446d268 100644
--- a/bin/ksh/lex.h
+++ b/bin/ksh/lex.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: lex.h,v 1.2 1996/10/01 02:05:43 downsj Exp $ */
+/* $OpenBSD: lex.h,v 1.3 1996/10/13 21:32:20 downsj Exp $ */
/*
* Source input, lexer and parser
@@ -14,12 +14,13 @@ struct source {
int type; /* input type */
char const *start; /* start of current buffer */
union {
- char ugbuf[2]; /* buffer for ungetsc() (SREREAD) */
char **strv; /* string [] */
struct shf *shf; /* shell file */
- struct tbl *tblp; /* alias */
+ struct tbl *tblp; /* alias (SALIAS) */
char *freeme; /* also for SREREAD */
} u;
+ char ugbuf[2]; /* buffer for ungetsc() (SREREAD) and
+ * alias (SALIAS) */
int line; /* line number */
int errline; /* line the error occured on (0 if not set) */
const char *file; /* input file name */
diff --git a/bin/ksh/syn.c b/bin/ksh/syn.c
index c45d449d993..2d883c4eda8 100644
--- a/bin/ksh/syn.c
+++ b/bin/ksh/syn.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: syn.c,v 1.3 1996/10/01 02:05:50 downsj Exp $ */
+/* $OpenBSD: syn.c,v 1.4 1996/10/13 21:32:20 downsj Exp $ */
/*
* shell parser (C version)
@@ -36,6 +36,7 @@ static void syntaxerr ARGS((const char *what))
static void multiline_push ARGS((struct multiline_state *save, int tok));
static void multiline_pop ARGS((struct multiline_state *saved));
static int assign_command ARGS((char *s));
+static int inalias ARGS((struct source *s));
#ifdef KSH
static int dbtestp_isa ARGS((Test_env *te, Test_meta meta));
static const char *dbtestp_getopnd ARGS((Test_env *te, Test_op op,
@@ -123,7 +124,7 @@ c_list()
t = andor();
if (t != NULL) {
while ((c = token(0)) == ';' || c == '&' || c == COPROC ||
- (c == '\n' && (multiline.on || source->type == SALIAS)))
+ (c == '\n' && (multiline.on || inalias(source))))
{
if (c == '&' || c == COPROC) {
int type = c == '&' ? TASYNC : TCOPROC;
@@ -812,6 +813,17 @@ assign_command(s)
|| (c == 't' && strcmp(s, "typeset") == 0);
}
+/* Check if we are in the middle of reading an alias */
+static int
+inalias(s)
+ struct source *s;
+{
+ for (; s && s->type == SALIAS; s = s->next)
+ if (!(s->flags & SF_ALIASEND))
+ return 1;
+ return 0;
+}
+
#ifdef KSH
/* Order important - indexed by Test_meta values
diff --git a/bin/ksh/tests/alias.t b/bin/ksh/tests/alias.t
new file mode 100644
index 00000000000..0db6a2594cd
--- /dev/null
+++ b/bin/ksh/tests/alias.t
@@ -0,0 +1,91 @@
+name: alias-1
+description:
+ Check that recursion is detected/avoided in aliases.
+stdin:
+ alias fooBar=fooBar
+ fooBar
+ exit 0
+expected-stderr-pattern:
+ /fooBar.*not found.*/
+---
+
+name: alias-2
+description:
+ Check that recursion is detected/avoided in aliases.
+stdin:
+ alias fooBar=barFoo
+ alias barFoo=fooBar
+ fooBar
+ barFoo
+ exit 0
+expected-stderr-pattern:
+ /fooBar.*not found.*\n.*barFoo.*not found/
+---
+
+name: alias-3
+description:
+ Check that recursion is detected/avoided in aliases.
+stdin:
+ alias Echo='echo '
+ alias fooBar=barFoo
+ alias barFoo=fooBar
+ Echo fooBar
+ unalias barFoo
+ Echo fooBar
+expected-stdout:
+ fooBar
+ barFoo
+---
+
+name: alias-4
+description:
+ Check that alias expansion isn't done on keywords (in keyword
+ postitions).
+stdin:
+ alias Echo='echo '
+ alias while=While
+ while false; do echo hi ; done
+ Echo while
+expected-stdout:
+ While
+---
+
+name: alias-5
+description:
+ Check that alias expansion done after alias with trailing space.
+stdin:
+ alias Echo='echo '
+ alias foo='bar stuff '
+ alias bar='Bar1 Bar2 '
+ alias stuff='Stuff'
+ alias blah='Blah'
+ Echo foo blah
+expected-stdout:
+ Bar1 Bar2 Stuff Blah
+---
+
+name: alias-6
+description:
+ Check that alias expansion done after alias with trailing space.
+stdin:
+ alias Echo='echo '
+ alias foo='bar bar'
+ alias bar='Bar '
+ alias blah=Blah
+ Echo foo blah
+expected-stdout:
+ Bar Bar Blah
+---
+
+name: alias-7
+description:
+ Check that alias expansion done after alias with trailing space
+ after a keyword.
+stdin:
+ alias X='case '
+ alias Y=Z
+ X Y in 'Y') echo is y ;; Z) echo is z ; esac
+expected-stdout:
+ is z
+---
+
diff --git a/bin/ksh/tests/bksl-nl.t b/bin/ksh/tests/bksl-nl.t
new file mode 100644
index 00000000000..3fb92ff53b5
--- /dev/null
+++ b/bin/ksh/tests/bksl-nl.t
@@ -0,0 +1,339 @@
+#
+# These tests deal with how \newline is handled in various situations. The
+# first group of tests are places where it shouldn't be collapsed, the next
+# group of tests are places where it should be collapsed.
+#
+name: bksl-nl-ign-1
+description:
+ Check that \newline is not collasped after #
+stdin:
+ echo hi #there \
+ echo folks
+expected-stdout:
+ hi
+ folks
+---
+
+name: bksl-nl-ign-2
+description:
+ Check that \newline is not collasped inside single quotes
+stdin:
+ echo 'hi \
+ there'
+ echo folks
+expected-stdout:
+ hi \
+ there
+ folks
+---
+
+name: bksl-nl-ign-3
+description:
+ Check that \newline is not collasped inside single quotes
+stdin:
+ cat << \EOF
+ hi \
+ there
+ EOF
+expected-stdout:
+ hi \
+ there
+---
+
+name: blsk-nl-ign-4
+description:
+ Check interaction of aliases, single quotes and here-documents
+ with backslash-newline
+ (don't know what posix has to say about this)
+stdin:
+ a=2
+ alias x='echo hi
+ cat << "EOF"
+ foo\
+ bar
+ some'
+ x
+ more\
+ stuff$a
+ EOF
+expected-stdout:
+ hi
+ foo\
+ bar
+ some
+ more\
+ stuff$a
+---
+
+name: blsk-nl-ign-5
+description:
+ Check what happens with backslash at end of input
+ (the old bourne shell trashes them; so do we)
+stdin: !
+ echo `echo foo\\`bar
+ echo hi\
+expected-stdout:
+ foobar
+ hi
+---
+
+
+#
+# Places \newline should be collapsed
+#
+name: bksl-nl-1
+description:
+ Check that \newline is collasped before, in the middle of, and
+ after words
+stdin:
+ \
+ echo hi\
+ There, \
+ folks
+expected-stdout:
+ hiThere, folks
+---
+
+name: bksl-nl-2
+description:
+ Check that \newline is collasped in $ sequences
+ (ksh93 fails this)
+stdin:
+ a=12
+ ab=19
+ echo $\
+ a
+ echo $a\
+ b
+ echo $\
+ {a}
+ echo ${a\
+ b}
+ echo ${ab\
+ }
+expected-stdout:
+ 12
+ 19
+ 12
+ 19
+ 19
+---
+
+name: bksl-nl-3
+description:
+ Check that \newline is collasped in $(..) and `...` sequences
+ (ksh93 fails this)
+stdin:
+ echo $\
+ (echo foobar1)
+ echo $(\
+ echo foobar2)
+ echo $(echo foo\
+ bar3)
+ echo $(echo foobar4\
+ )
+ echo `
+ echo stuff1`
+ echo `echo st\
+ uff2`
+expected-stdout:
+ foobar1
+ foobar2
+ foobar3
+ foobar4
+ stuff1
+ stuff2
+---
+
+name: bksl-nl-4
+description:
+ Check that \newline is collasped in $((..)) sequences
+ (ksh93 fails this)
+stdin:
+ echo $\
+ ((1+2))
+ echo $(\
+ (1+2+3))
+ echo $((\
+ 1+2+3+4))
+ echo $((1+\
+ 2+3+4+5))
+ echo $((1+2+3+4+5+6)\
+ )
+expected-stdout:
+ 3
+ 6
+ 10
+ 15
+ 21
+---
+
+name: bksl-nl-5
+description:
+ Check that \newline is collasped in double quoted strings
+stdin:
+ echo "\
+ hi"
+ echo "foo\
+ bar"
+ echo "folks\
+ "
+expected-stdout:
+ hi
+ foobar
+ folks
+---
+
+name: bksl-nl-6
+description:
+ Check that \newline is collasped in here document delimiters
+ (ksh93 fails second part of this)
+stdin:
+ a=12
+ cat << EO\
+ F
+ a=$a
+ foo\
+ bar
+ EOF
+ cat << E_O_F
+ foo
+ E_O_\
+ F
+ echo done
+expected-stdout:
+ a=12
+ foobar
+ foo
+ done
+---
+
+name: bksl-nl-7
+description:
+ Check that \newline is collasped in double-quoted here-document
+ delimiter.
+stdin:
+ a=12
+ cat << "EO\
+ F"
+ a=$a
+ foo\
+ bar
+ EOF
+ echo done
+expected-stdout:
+ a=$a
+ foo\
+ bar
+ done
+---
+
+name: bksl-nl-8
+description:
+ Check that \newline is collasped in various 2+ character tokens
+ delimiter.
+ (ksh93 fails this)
+stdin:
+ echo hi &\
+ & echo there
+ echo foo |\
+ | echo bar
+ cat <\
+ < EOF
+ stuff
+ EOF
+ cat <\
+ <\
+ - EOF
+ more stuff
+ EOF
+ cat <<\
+ EOF
+ abcdef
+ EOF
+ echo hi >\
+ > /dev/null
+ echo $?
+ i=1
+ case $i in
+ (\
+ x|\
+ 1\
+ ) echo hi;\
+ ;
+ (*) echo oops
+ esac
+expected-stdout:
+ hi
+ there
+ foo
+ stuff
+ more stuff
+ abcdef
+ 0
+ hi
+---
+
+name: blsk-nl-9
+description:
+ Check that \ at the end of an alias is collapsed when followed
+ by a newline
+ (don't know what posix has to say about this)
+stdin:
+ alias x='echo hi\'
+ x
+ echo there
+expected-stdout:
+ hiecho there
+---
+
+name: blsk-nl-10
+description:
+ Check that \newline in a keyword is collapsed
+stdin:
+ i\
+ f true; then\
+ echo pass; el\
+ se echo fail; fi
+expected-stdout:
+ pass
+---
+
+#
+# Places \newline should be collapsed (ksh extensions)
+#
+
+name: blsk-nl-ksh-1
+description:
+ Check that \newline is collapsed in extended globbing
+ (ksh93 fails this)
+stdin:
+ xxx=foo
+ case $xxx in
+ (f*\
+ (\
+ o\
+ )\
+ ) echo ok ;;
+ *) echo bad
+ esac
+expected-stdout:
+ ok
+---
+
+name: blsk-nl-ksh-2
+description:
+ Check that \newline is collapsed in ((...)) expressions
+ (ksh93 fails this)
+stdin:
+ i=1
+ (\
+ (\
+ i=i+2\
+ )\
+ )
+ echo $i
+expected-stdout:
+ 3
+---
+
diff --git a/bin/ksh/tests/heredoc.t b/bin/ksh/tests/heredoc.t
index 27c28302258..21feb925cea 100644
--- a/bin/ksh/tests/heredoc.t
+++ b/bin/ksh/tests/heredoc.t
@@ -20,33 +20,18 @@ stdin:
hi\
there$a
stuff
- EOF
-expected-stdout:
- hi\
- there$a
- stuff
----
-
-name: heredoc-3
-description:
- Check quoted here-documents don't have \newline processing done
- on them.
-stdin:
- cat << 'EOF'
- hi\
- there
EO\
F
EOF
- true
expected-stdout:
hi\
- there
+ there$a
+ stuff
EO\
F
---
-name: heredoc-4
+name: heredoc-3
description:
Check that newline isn't needed after heredoc-delimiter marker.
stdin: !
@@ -59,7 +44,7 @@ expected-stdout:
there
---
-name: heredoc-5
+name: heredoc-4
description:
Check that an error occurs if the heredoc-delimiter is missing.
stdin: !
@@ -70,3 +55,90 @@ expected-exit: e > 0
expected-stderr-pattern: /.*/
---
+name: heredoc-5
+description:
+ Check that backslash quotes a $, ` and \ and kills a \newline
+stdin:
+ a=BAD
+ b=ok
+ cat << EOF
+ h\${a}i
+ h\\${b}i
+ th\`echo not-run\`ere
+ th\\`echo is-run`ere
+ fol\\ks
+ more\\
+ last \
+ line
+ EOF
+expected-stdout:
+ h${a}i
+ h\oki
+ th`echo not-run`ere
+ th\is-runere
+ fol\ks
+ more\
+ last line
+---
+
+name: heredoc-6
+description:
+ Check that \newline in initial here-delim word doesn't imply
+ a quoted here-doc.
+stdin:
+ a=i
+ cat << EO\
+ F
+ h$a
+ there
+ EOF
+expected-stdout:
+ hi
+ there
+---
+
+name: heredoc-7
+description:
+ Check that double quoted $ expressions in here delimiters are
+ not expanded and match the delimiter.
+ POSIX says only quote removal is applied to the delimiter.
+stdin:
+ a=b
+ cat << "E$a"
+ hi
+ h$a
+ hb
+ E$a
+ echo done
+expected-stdout:
+ hi
+ h$a
+ hb
+ done
+---
+
+name: heredoc-8
+description:
+ Check that double quoted escaped $ expressions in here
+ delimiters are not expanded and match the delimiter.
+ POSIX says only quote removal is applied to the delimiter
+ (\ counts as a quote).
+stdin:
+ a=b
+ cat << "E\$a"
+ hi
+ h$a
+ h\$a
+ hb
+ h\b
+ E$a
+ echo done
+expected-stdout:
+ hi
+ h$a
+ h\$a
+ hb
+ h\b
+ done
+---
+
diff --git a/bin/ksh/tests/version.t b/bin/ksh/tests/version.t
index e1b8127fcbc..51abf75f296 100644
--- a/bin/ksh/tests/version.t
+++ b/bin/ksh/tests/version.t
@@ -4,5 +4,5 @@ description:
stdin:
echo $KSH_VERSION
expected-stdout:
- @(#)PD KSH v5.2.9 96/09/30
+ @(#)PD KSH v5.2.11 96/10/08
---
diff --git a/bin/ksh/version.c b/bin/ksh/version.c
index d22e8f1ec29..c676ba774c6 100644
--- a/bin/ksh/version.c
+++ b/bin/ksh/version.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: version.c,v 1.3 1996/10/01 02:05:54 downsj Exp $ */
+/* $OpenBSD: version.c,v 1.4 1996/10/13 21:32:21 downsj Exp $ */
/*
* value of $KSH_VERSION (or $SH_VERSION)
@@ -7,4 +7,4 @@
#include "sh.h"
const char ksh_version [] =
- "@(#)PD KSH v5.2.9 96/09/30";
+ "@(#)PD KSH v5.2.11 96/10/08";