fix most of the ambiguous ${[prefix] var [op [word]]} corner cases

prodded by izabera and carstenh; resolution is:
• you can’t trim a vector in mksh, still (consider ${@:-1})
• future POSIX will require non-empty “word” for most “op”s
• dissolve in order of standard → extension
• dissolve to prefer “op” over “prefix” where still necessary, mostly
This commit is contained in:
tg
2016-06-25 23:55:00 +00:00
parent 1563b70658
commit 262ae5a436
3 changed files with 98 additions and 3663 deletions

45
lex.c
View File

@@ -23,7 +23,7 @@
#include "sh.h"
__RCSID("$MirOS: src/bin/mksh/lex.c,v 1.224 2016/05/05 22:45:58 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/lex.c,v 1.225 2016/06/25 23:55:00 tg Exp $");
/*
* states while lexing word
@@ -1574,14 +1574,29 @@ get_brace_var(XString *wsp, char *wp)
c = getsc();
/* State machine to figure out where the variable part ends. */
switch (state) {
case PS_SAW_BANG:
if (ctype(c, C_VAR1))
goto out;
case PS_SAW_HASH:
if (ctype(c, C_VAR1)) {
char c2;
if (0)
/* FALLTHROUGH */
c2 = getsc();
ungetsc(c2);
if (c2 != /*{*/ '}') {
ungetsc(c);
goto out;
}
}
goto ps_common;
case PS_SAW_BANG:
switch (c) {
case '@':
case '#':
case '-':
case '?':
goto out;
}
goto ps_common;
case PS_INITIAL:
switch (c) {
switch (c) {
case '%':
state = PS_SAW_PERCENT;
goto next;
@@ -1594,24 +1609,12 @@ get_brace_var(XString *wsp, char *wp)
}
/* FALLTHROUGH */
case PS_SAW_PERCENT:
case PS_SAW_HASH:
ps_common:
if (ksh_isalphx(c))
state = PS_IDENT;
else if (ksh_isdigit(c))
state = PS_NUMBER;
else if (c == '#') {
if (state == PS_SAW_HASH) {
char c2;
c2 = getsc();
ungetsc(c2);
if (c2 != /*{*/ '}') {
ungetsc(c);
goto out;
}
}
state = PS_VAR1;
} else if (ctype(c, C_VAR1))
else if (ctype(c, C_VAR1))
state = PS_VAR1;
else
goto out;