Fix regression introduced by mixing the recursive parser and support

for ;| and ;& in TCASE: ;;-less last casepart produced ";\0" in the
SREREAD string which obviously cased reparsing to fail

test from http://www.in-ulm.de/~mascheck/various/cmd-subst/
This commit is contained in:
tg 2011-11-22 18:01:41 +00:00
parent d7079f3f0e
commit dd014625e1
3 changed files with 36 additions and 18 deletions

32
check.t
View File

@ -1,4 +1,4 @@
# $MirOS: src/bin/mksh/check.t,v 1.492 2011/11/19 21:22:00 tg Exp $ # $MirOS: src/bin/mksh/check.t,v 1.493 2011/11/22 18:01:37 tg Exp $
# $OpenBSD: bksl-nl.t,v 1.2 2001/01/28 23:04:56 niklas 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: 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 $ # $OpenBSD: read.t,v 1.3 2003/03/10 03:48:16 david Exp $
@ -25,7 +25,7 @@
# http://www.research.att.com/~gsf/public/ifs.sh # http://www.research.att.com/~gsf/public/ifs.sh
expected-stdout: expected-stdout:
@(#)MIRBSD KSH R40 2011/11/19 @(#)MIRBSD KSH R40 2011/11/21
description: description:
Check version of shell. Check version of shell.
stdin: stdin:
@ -7834,7 +7834,9 @@ stdin:
print -- "$x\n" >/etc/motd print -- "$x\n" >/etc/motd
fi fi
#wdarrassign #wdarrassign
a+=b; c+=(d e) case x in
x) a+=b; c+=(d e)
esac
#0 #0
EOD EOD
expected-stdout: expected-stdout:
@ -8401,23 +8403,33 @@ expected-stdout:
)" = @(?) ]] && rm -f /etc/motd ; if [[ ! -s /etc/motd ]] ; then install -c -o root -g wheel -m 664 /dev/null /etc/motd ; print -- "$x\n" >/etc/motd ; fi ) | tr u x ) )" = @(?) ]] && rm -f /etc/motd ; if [[ ! -s /etc/motd ]] ; then install -c -o root -g wheel -m 664 /dev/null /etc/motd ; print -- "$x\n" >/etc/motd ; fi ) | tr u x )
} }
inline_wdarrassign() { inline_wdarrassign() {
a+=b; c+=(d e) case x in
x) a+=b; c+=(d e)
esac
} }
inline_wdarrassign() { inline_wdarrassign() {
a+=b case x in
set -A c+ -- d e (x)
a+=b
set -A c+ -- d e
;;
esac
} }
function comsub_wdarrassign { x=$( function comsub_wdarrassign { x=$(
a+=b; c+=(d e) case x in
x) a+=b; c+=(d e)
esac
); } ); }
function comsub_wdarrassign { function comsub_wdarrassign {
x=$(a+=b ; set -A c+ -- d e ) x=$(case x in (x) a+=b ; set -A c+ -- d e ;; esac )
} }
function reread_wdarrassign { x=$(( function reread_wdarrassign { x=$((
a+=b; c+=(d e) case x in
x) a+=b; c+=(d e)
esac
)|tr u x); } )|tr u x); }
function reread_wdarrassign { function reread_wdarrassign {
x=$(( a+=b ; set -A c+ -- d e ) | tr u x ) x=$(( case x in (x) a+=b ; set -A c+ -- d e ;; esac ) | tr u x )
} }
--- ---
name: test-stnze-1 name: test-stnze-1

4
sh.h
View File

@ -151,9 +151,9 @@
#endif #endif
#ifdef EXTERN #ifdef EXTERN
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.503 2011/11/19 21:22:02 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/sh.h,v 1.504 2011/11/22 18:01:40 tg Exp $");
#endif #endif
#define MKSH_VERSION "R40 2011/11/19" #define MKSH_VERSION "R40 2011/11/21"
#ifndef MKSH_INCLUDES_ONLY #ifndef MKSH_INCLUDES_ONLY

18
syn.c
View File

@ -22,7 +22,7 @@
#include "sh.h" #include "sh.h"
__RCSID("$MirOS: src/bin/mksh/syn.c,v 1.70 2011/11/11 22:14:19 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/syn.c,v 1.71 2011/11/22 18:01:41 tg Exp $");
extern short subshell_nesting_level; extern short subshell_nesting_level;
extern void yyskiputf8bom(void); extern void yyskiputf8bom(void);
@ -609,17 +609,23 @@ casepart(int endtok)
musthave(')', 0); musthave(')', 0);
t->left = c_list(true); t->left = c_list(true);
/* Note: POSIX requires the ;; */
/* initialise to default for ;; or omitted */
t->u.charflag = ';';
/* SUSv4 requires the ;; except in the last casepart */
if ((tpeek(CONTIN|KEYWORD|ALIAS)) != endtok) if ((tpeek(CONTIN|KEYWORD|ALIAS)) != endtok)
switch (symbol) { switch (symbol) {
default: default:
syntaxerr(NULL); syntaxerr(NULL);
case BREAK:
case BRKEV: case BRKEV:
t->u.charflag = '|';
if (0)
/* FALLTHROUGH */
case BRKFT: case BRKFT:
t->u.charflag = t->u.charflag = '&';
(symbol == BRKEV) ? '|' : /* FALLTHROUGH */
(symbol == BRKFT) ? '&' : ';'; case BREAK:
/* initialised above, but we need to eat the token */
ACCEPT; ACCEPT;
} }
return (t); return (t);