mirror of
git://git.code.sf.net/p/cdesktopenv/code
synced 2025-02-15 04:32:24 +00:00
Improve fix for parentheses in param expansions (re: 5ed9ffd6
)
The fix was incomplete: expansions using '?' (${var?w(ord}, ${var:?wo)rd}) still did not tolerate parentheses in the word as regular characters. It was also possible to simplify the fix by making use of the ST_BRACE (sh_lexstate7[]) state table. See data/lexstates.c and include/lexstates.h. src/cmd/ksh93/sh/lex.c: sh_lex(): case S_MOD1: - The previous fix tested for modifier operator characters : - + = as part of the S_MOD2 case, though they are defined as S_MOD1 in the ST_BRACE state table. It only worked because of the fallthrough. And it turns out the S_MOD1 case already had a similar fix, though incomplete. The new fix effectively cancelled the old one out as any S_MOD1 character eventually led to 'continue'. So it can be simplified by removing most of that code, without causing any change in behaviour. Only the mode change to the ST_QUOTE state table followed by 'continue' is necessary. This also fixes it for the '?' operator as that is also defined as S_MOD1 in the ST_BRACE state table. src/cmd/ksh93/sh/macro.c: - When skipping a ${...} expansion using sh_lexskip(), use the ST_QUOTE state table if the character c is an S_MOD1 modifier operator character. This makes it consistent with the S_MOD1 handling in sh_lex(). src/cmd/ksh93/tests/variables.sh: - Update regression tests to include ? and :? operators.
This commit is contained in:
parent
ab5dedded7
commit
9f2066f146
3 changed files with 15 additions and 24 deletions
|
@ -998,31 +998,13 @@ int sh_lex(Lex_t* lp)
|
||||||
mode = ST_NESTED;
|
mode = ST_NESTED;
|
||||||
continue;
|
continue;
|
||||||
case S_MOD1:
|
case S_MOD1:
|
||||||
if(oldmode(lp)==ST_QUOTE || oldmode(lp)==ST_NONE)
|
|
||||||
{
|
|
||||||
/* allow ' inside "${...}" */
|
|
||||||
if(c==':' && fcgetc(n)>0)
|
|
||||||
{
|
|
||||||
n = state[n];
|
|
||||||
fcseek(-LEN);
|
|
||||||
}
|
|
||||||
if(n==S_MOD1)
|
|
||||||
{
|
|
||||||
mode = ST_QUOTE;
|
mode = ST_QUOTE;
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
}
|
|
||||||
/* FALL THRU */
|
|
||||||
case S_MOD2:
|
case S_MOD2:
|
||||||
#if SHOPT_KIA
|
#if SHOPT_KIA
|
||||||
if(lp->kiafile)
|
if(lp->kiafile)
|
||||||
refvar(lp,1);
|
refvar(lp,1);
|
||||||
#endif /* SHOPT_KIA */
|
#endif /* SHOPT_KIA */
|
||||||
if(c == ':' || c == '-' || c == '+' || c == '=')
|
|
||||||
{
|
|
||||||
mode = ST_QUOTE;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if(c!=':' && fcgetc(n)>0)
|
if(c!=':' && fcgetc(n)>0)
|
||||||
{
|
{
|
||||||
if(n!=c)
|
if(n!=c)
|
||||||
|
|
|
@ -1628,8 +1628,7 @@ retry1:
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int state = (!newops && mp->quote || c=='-' || c=='+' || c=='=') ? ST_QUOTE : ST_NESTED;
|
sh_lexskip(lp, RBRACE, 0, sh_lexstates[ST_BRACE][c]==S_MOD1 ? ST_QUOTE : ST_NESTED);
|
||||||
sh_lexskip(lp, RBRACE, 0, state);
|
|
||||||
stkseek(stkp,offset);
|
stkseek(stkp,offset);
|
||||||
}
|
}
|
||||||
argp=stkptr(stkp,offset);
|
argp=stkptr(stkp,offset);
|
||||||
|
|
|
@ -1044,7 +1044,7 @@ wait
|
||||||
[[ $$ == ${.sh.pid} ]] || err_exit "\${.sh.pid} and \$$ differ in the parent shell (expected $$, got ${.sh.pid})"
|
[[ $$ == ${.sh.pid} ]] || err_exit "\${.sh.pid} and \$$ differ in the parent shell (expected $$, got ${.sh.pid})"
|
||||||
|
|
||||||
# ======
|
# ======
|
||||||
# Parentheses after the '-', '+', and '=' expansion operators were causing syntax errors.
|
# Parentheses after the '-', '+', '=', and '?' expansion operators were causing syntax errors.
|
||||||
# Check both the unset variable case and the set variable case for each set of symbols.
|
# Check both the unset variable case and the set variable case for each set of symbols.
|
||||||
|
|
||||||
unset -v foo
|
unset -v foo
|
||||||
|
@ -1058,7 +1058,7 @@ do for word in '(word)' 'w(or)d' '(wor)d' 'w(ord)' 'w(ord' 'wor)d'
|
||||||
done
|
done
|
||||||
|
|
||||||
foo=some_value
|
foo=some_value
|
||||||
for op in - :- = :=
|
for op in - :- = := \? :\?
|
||||||
do for word in '(word)' 'w(or)d' '(wor)d' 'w(ord)' 'w(ord' 'wor)d'
|
do for word in '(word)' 'w(or)d' '(wor)d' 'w(ord)' 'w(ord' 'wor)d'
|
||||||
do exp=$(set +x; eval "echo \${foo${op}${word}}" 2>&1)
|
do exp=$(set +x; eval "echo \${foo${op}${word}}" 2>&1)
|
||||||
if [[ $exp != "$foo" ]]
|
if [[ $exp != "$foo" ]]
|
||||||
|
@ -1077,5 +1077,15 @@ do for word in '(word)' 'w(or)d' '(wor)d' 'w(ord)' 'w(ord' 'wor)d'
|
||||||
done
|
done
|
||||||
done
|
done
|
||||||
|
|
||||||
|
unset -v foo
|
||||||
|
for op in \? :\?
|
||||||
|
do for word in '(word)' 'w(or)d' '(wor)d' 'w(ord)' 'w(ord' 'wor)d'
|
||||||
|
do exp=$(set +x; eval "echo \${foo${op}${word}}" 2>&1)
|
||||||
|
if [[ $exp != *": foo: $word" ]]
|
||||||
|
then err_exit "\${foo${op}${word}} when foo is not set: expected *\": foo: $word\", got \"$exp\""
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
done
|
||||||
|
|
||||||
# ======
|
# ======
|
||||||
exit $((Errors<125?Errors:125))
|
exit $((Errors<125?Errors:125))
|
||||||
|
|
Loading…
Reference in a new issue