diff --git a/check.t b/check.t index ba27498..8acd588 100644 --- a/check.t +++ b/check.t @@ -1,4 +1,4 @@ -# $MirOS: src/bin/mksh/check.t,v 1.554 2012/08/03 18:45:29 tg Exp $ +# $MirOS: src/bin/mksh/check.t,v 1.555 2012/08/17 18:34:18 tg Exp $ # $OpenBSD: bksl-nl.t,v 1.2 2001/01/28 23:04:56 niklas Exp $ # $OpenBSD: history.t,v 1.5 2001/01/28 23:04:56 niklas Exp $ # $OpenBSD: read.t,v 1.3 2003/03/10 03:48:16 david Exp $ @@ -29,7 +29,7 @@ # http://www.freebsd.org/cgi/cvsweb.cgi/src/tools/regression/bin/test/regress.sh?rev=HEAD expected-stdout: - @(#)MIRBSD KSH R40 2012/08/03 + @(#)MIRBSD KSH R40 2012/08/17 description: Check version of shell. stdin: @@ -38,7 +38,7 @@ name: KSH_VERSION category: shell:legacy-no --- expected-stdout: - @(#)LEGACY KSH R40 2012/08/03 + @(#)LEGACY KSH R40 2012/08/17 description: Check version of legacy shell. stdin: @@ -9505,26 +9505,6 @@ expected-stdout: x=$(( echo $(true >&3 ) $((1+ 2)) ) | tr u x ) } --- -name: funsub-1 -description: - Check that non-subenvironment command substitution works -stdin: - set -e - foo=bar - echo "ob $foo ." - echo "${ - echo "ib $foo :" - foo=baz - echo "ia $foo :" - false - }" . - echo "oa $foo ." -expected-stdout: - ob bar . - ib bar : - ia baz : . - oa baz . ---- name: test-stnze-1 description: Check that the short form [ $x ] works diff --git a/dot.mkshrc b/dot.mkshrc index d850e99..4d61dd5 100644 --- a/dot.mkshrc +++ b/dot.mkshrc @@ -1,5 +1,5 @@ # $Id$ -# $MirOS: src/bin/mksh/dot.mkshrc,v 1.70 2012/07/30 21:37:10 tg Exp $ +# $MirOS: src/bin/mksh/dot.mkshrc,v 1.71 2012/08/17 18:34:20 tg Exp $ #- # Copyright (c) 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2010, # 2011, 2012 @@ -30,7 +30,7 @@ function precmd { (( e )) && print -n "$e|" } -PS1=$'\001\r''${ precmd;}${USER:=$(ulimit -c 0; id -un 2>/dev/null || echo \? +PS1=$'\001\r''$(precmd)${USER:=$(ulimit -c 0; id -un 2>/dev/null || echo \? )}@${HOSTNAME%%.*}:$(local d=${PWD:-?} p=~; [[ $p = ?(*/) ]] || \ d=${d/#$p/~}; local m=${%d} n p=...; (( m > 0 )) || m=${#d} (( m > (n = (COLUMNS/3 < 7 ? 7 : COLUMNS/3)) )) && d=${d:(-n)} || \ diff --git a/eval.c b/eval.c index 34ace2f..68f1246 100644 --- a/eval.c +++ b/eval.c @@ -23,7 +23,7 @@ #include "sh.h" -__RCSID("$MirOS: src/bin/mksh/eval.c,v 1.123 2012/07/30 21:37:11 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/eval.c,v 1.124 2012/08/17 18:34:20 tg Exp $"); /* * string expansion @@ -58,7 +58,7 @@ typedef struct Expand { #define IFS_NWS 2 /* have seen IFS non-white-space */ static int varsub(Expand *, const char *, const char *, int *, int *); -static int comsub(Expand *, const char *, int); +static int comsub(Expand *, const char *); static char *trimsub(char *, char *, int); static void glob(char *, XPtrV *, int); static void globit(XString *, char **, char *, XPtrV *, int); @@ -278,27 +278,18 @@ expand(const char *cp, /* input word */ quote = st->quotew; continue; case COMSUB: - case FUNSUB: tilde_ok = 0; if (f & DONTRUNCOMMAND) { word = IFS_WORD; *dp++ = '$'; - if (c == FUNSUB) { - *dp++ = '{'; - *dp++ = ' '; - } else - *dp++ = '('; + *dp++ = '('; while (*sp != '\0') { Xcheck(ds, dp); *dp++ = *sp++; } - if (c == FUNSUB) { - *dp++ = ';'; - *dp++ = '}'; - } else - *dp++ = ')'; + *dp++ = ')'; } else { - type = comsub(&x, sp, c); + type = comsub(&x, sp); if (type == XCOM && (f&DOBLANK)) doblank++; sp = strnul(sp) + 1; @@ -1282,7 +1273,7 @@ varsub(Expand *xp, const char *sp, const char *word, * Run the command in $(...) and read its output. */ static int -comsub(Expand *xp, const char *cp, int fn) +comsub(Expand *xp, const char *cp) { Source *s, *sold; struct op *t; @@ -1327,14 +1318,11 @@ comsub(Expand *xp, const char *cp, int fn) ksh_dup2(pv[1], 1, false); close(pv[1]); } - execute(t, XXCOM | XPIPEO | - (fn == FUNSUB ? XERROK : XFORK), NULL); + execute(t, XXCOM | XPIPEO | XFORK, NULL); restfd(1, ofd1); - if (fn != FUNSUB) { - startlast(); - /* waitlast() */ - xp->split = true; - } + startlast(); + /* waitlast() */ + xp->split = true; } xp->u.shf = shf; diff --git a/lex.c b/lex.c index b3802a4..3f101ce 100644 --- a/lex.c +++ b/lex.c @@ -23,7 +23,7 @@ #include "sh.h" -__RCSID("$MirOS: src/bin/mksh/lex.c,v 1.166 2012/07/30 21:37:12 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/lex.c,v 1.167 2012/08/17 18:34:21 tg Exp $"); /* * states while lexing word @@ -109,7 +109,7 @@ void yyskiputf8bom(void); static int backslash_skip; static int ignore_backslash_newline; static struct sretrace_info *retrace_info; -int subshell_nesting_type = 0; +uint8_t subshell_nesting_level = 0; /* optimised getsc_bn() */ #define o_getsc() (*source->str != '\0' && *source->str != '\\' && \ @@ -262,11 +262,6 @@ yylex(int cf) while (!((c = getsc()) == 0 || ((state == SBASE || state == SHEREDELIM || state == SHERESTRING) && ctype(c, C_LEX1)))) { - if (state == SBASE && - subshell_nesting_type == /*{*/ '}' && - c == /*{*/ '}') - /* possibly end ${ :;} */ - break; accept_nonword: Xcheck(ws, wp); switch (state) { @@ -400,27 +395,14 @@ yylex(int cf) } else { ungetsc(c); subst_command: - c = COMSUB; - subst_command2: - sp = yyrecursive(c); + sp = yyrecursive(); cz = strlen(sp) + 1; XcheckN(ws, wp, cz); - *wp++ = c; + *wp++ = COMSUB; memcpy(wp, sp, cz); wp += cz; } } else if (c == '{') /*}*/ { - c = getsc(); - if (ctype(c, C_IFSWS)) { - /* - * non-subenvironment - * "command" substitution - */ - c = FUNSUB; - goto subst_command2; - } - ungetsc(c); - *wp++ = OSUBST; *wp++ = '{'; /*}*/ wp = get_brace_var(&ws, wp); @@ -1189,7 +1171,7 @@ readhere(struct ioword *iop) /* end of here document marker, what to do? */ switch (c) { case /*(*/ ')': - if (!subshell_nesting_type) + if (!subshell_nesting_level) /*- * not allowed outside $(...) or (...) * => mismatch diff --git a/mksh.1 b/mksh.1 index c3b0461..0f9353b 100644 --- a/mksh.1 +++ b/mksh.1 @@ -1,4 +1,4 @@ -.\" $MirOS: src/bin/mksh/mksh.1,v 1.292 2012/08/03 18:34:31 tg Exp $ +.\" $MirOS: src/bin/mksh/mksh.1,v 1.293 2012/08/17 18:34:22 tg Exp $ .\" $OpenBSD: ksh.1,v 1.144 2012/07/08 08:13:20 guenther Exp $ .\"- .\" Copyright © 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, @@ -74,7 +74,7 @@ .\" with -mandoc, it might implement .Mx itself, but we want to .\" use our own definition. And .Dd must come *first*, always. .\" -.Dd $Mdocdate: August 3 2012 $ +.Dd $Mdocdate: August 17 2012 $ .\" .\" Check which macro package we use, and do other -mdoc setup. .\" @@ -1146,14 +1146,9 @@ command substitutions take the form .Pf $( Ns Ar command Ns \&) or (deprecated) .Pf \` Ns Ar command Ns \` -or (executed in the current environment) -.Pf ${\ \& Ar command Ns \&;} and strip trailing newlines; and arithmetic substitutions take the form .Pf $(( Ns Ar expression Ns )) . -Parsing the current-environment command substitution requires a space, -tab or newline after the opening brace and that the closing brace be -recognised as a keyword (i.e. is preceded by a newline or semicolon). .Pp If a substitution appears outside of double quotes, the results of the substitution are generally subject to word or field splitting according to @@ -1231,8 +1226,6 @@ A command substitution is replaced by the output generated by the specified command which is run in a subshell. For .Pf $( Ns Ar command Ns \&) -and -.Pf ${\ \& Ar command Ns \&;} substitutions, normal quoting rules are used when .Ar command is parsed; however, for the deprecated diff --git a/sh.h b/sh.h index 26d1d6e..efa9de4 100644 --- a/sh.h +++ b/sh.h @@ -157,9 +157,9 @@ #endif #ifdef EXTERN -__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.577 2012/08/03 18:45:32 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.578 2012/08/17 18:34:24 tg Exp $"); #endif -#define MKSH_VERSION "R40 2012/08/03" +#define MKSH_VERSION "R40 2012/08/17" /* arithmetic types: C implementation */ #if !HAVE_CAN_INTTYPES @@ -1283,7 +1283,6 @@ struct op { #define SPAT 10 /* separate pattern: | */ #define CPAT 11 /* close pattern: ) */ #define ADELIM 12 /* arbitrary delimiter: ${foo:2:3} ${foo/bar/baz} */ -#define FUNSUB 14 /* ${ foo;} substitution (NUL terminated) */ /* * IO redirection @@ -1906,7 +1905,7 @@ ssize_t shf_vfprintf(struct shf *, const char *, va_list) void initkeywords(void); struct op *compile(Source *, bool); bool parse_usec(const char *, struct timeval *); -char *yyrecursive(int); +char *yyrecursive(void); /* tree.c */ void fptreef(struct shf *, int, const char *, ...); char *snptreef(char *, ssize_t, const char *, ...); diff --git a/syn.c b/syn.c index 2a377d0..a14b0bc 100644 --- a/syn.c +++ b/syn.c @@ -23,11 +23,12 @@ #include "sh.h" -__RCSID("$MirOS: src/bin/mksh/syn.c,v 1.79 2012/07/30 21:37:16 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/syn.c,v 1.80 2012/08/17 18:34:25 tg Exp $"); -extern int subshell_nesting_type; extern void yyskiputf8bom(void); +extern uint8_t subshell_nesting_level; + struct nesting_state { int start_token; /* token than began nesting (eg, FOR) */ int start_line; /* line nesting began on */ @@ -363,15 +364,12 @@ get_command(int cf) Leave: break; - case '(': /*)*/ { - int subshell_nesting_type_saved; + case '(': /*)*/ Subshell: - subshell_nesting_type_saved = subshell_nesting_type; - subshell_nesting_type = ')'; + ++subshell_nesting_level; t = nested(TPAREN, '(', ')'); - subshell_nesting_type = subshell_nesting_type_saved; + --subshell_nesting_level; break; - } case '{': /*}*/ t = nested(TBRACE, '{', '}'); @@ -1118,29 +1116,16 @@ parse_usec(const char *s, struct timeval *tv) * a COMSUB recursively using the main shell parser and lexer */ char * -yyrecursive(int subtype) +yyrecursive(void) { struct op *t; char *cp; bool old_reject; - int old_symbol, old_salias, old_nesting_type; + int old_symbol, old_salias; struct ioword **old_herep; - int stok, etok; - - switch (subtype) { - case FUNSUB: - stok = '{'; - etok = '}'; - break; - case COMSUB: - default: - stok = '('; - etok = ')'; - } /* tell the lexer to accept a closing parenthesis as EOD */ - old_nesting_type = subshell_nesting_type; - subshell_nesting_type = etok; + ++subshell_nesting_level; /* push reject state, parse recursively, pop reject state */ old_reject = reject; @@ -1150,7 +1135,7 @@ yyrecursive(int subtype) old_salias = sALIAS; sALIAS = 0; /* we use TPAREN as a helper container here */ - t = nested(TPAREN, stok, etok); + t = nested(TPAREN, '(', ')'); sALIAS = old_salias; herep = old_herep; reject = old_reject; @@ -1160,6 +1145,6 @@ yyrecursive(int subtype) cp = snptreef(NULL, 0, "%T", t->left); tfree(t, ATEMP); - subshell_nesting_type = old_nesting_type; + --subshell_nesting_level; return (cp); } diff --git a/tree.c b/tree.c index d2e20b3..678f530 100644 --- a/tree.c +++ b/tree.c @@ -23,7 +23,7 @@ #include "sh.h" -__RCSID("$MirOS: src/bin/mksh/tree.c,v 1.63 2012/07/30 21:37:17 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/tree.c,v 1.64 2012/08/17 18:34:25 tg Exp $"); #define INDENT 8 @@ -342,10 +342,6 @@ wdvarput(struct shf *shf, const char *wp, int quotelevel, int opmode) shf_putc(c, shf); shf_puts(cs, shf); break; - case FUNSUB: - shf_puts("${ ", shf); - cs = ";}"; - goto pSUB; case EXPRSUB: shf_puts("$((", shf); cs = "))"; @@ -585,7 +581,6 @@ wdscan(const char *wp, int c) wp++; break; case COMSUB: - case FUNSUB: case EXPRSUB: while (*wp++ != 0) ; @@ -825,9 +820,6 @@ dumpwdvar_i(struct shf *shf, const char *wp, int quotelevel) closeandout: shf_putc('>', shf); break; - case FUNSUB: - shf_puts("FUNSUB<", shf); - goto dumpsub; case EXPRSUB: shf_puts("EXPRSUB<", shf); goto dumpsub;