syntax(sh): Improve the recognition of bracket expressions
- Define a general non-"contained" "shBracketExpr" group,
and replace with it the "contained" bracket variant of
"shOperator", adjusting the patterns for the competing
conditional commands "[" and "[[".
- Accommodate some unbalanced brackets (e.g. "[!][!]").
- Make the leading "!" (or "^") stand out in NON-matching
bracket expressions.
- Support literal newlines in parametric patterns (along
with pathname globbings and "case" patterns).
- Also match bracket expressions in:
* parametric patterns (e.g. "${1#[ab]_}");
* pathname globbings (e.g. "[ab]*.txt");
* arguments for the "[[", "echo", and "print" commands.
- Recognise collating symbols (e.g. "[.a.]") and equivalence
classes (e.g. "[=a=]").
- Recognise end patterns for a pattern substitution form of
parameter expansion and match bracket expressions in such
patterns (e.g. "${1/%[.!]/;}").
fixes #15799
closes: #15941
References:
https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/V1_chap09.html#tag_09_03_05
https://pubs.opengroup.org/onlinepubs/9799919799/utilities/V3_chap02.html#tag_19_14
https://git.savannah.gnu.org/gitweb/?p=bash.git;a=blob_plain;f=doc/bash.html;hb=37b7e91d64ad10b1a1815d12128c9475636df670
http://www.mirbsd.org/htman/i386/man1/mksh.htm
Signed-off-by: Aliaksei Budavei <0x000c70@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
committed by
Christian Brabandt
parent
6de7191c31
commit
48fa3198b7
@ -20,8 +20,3 @@ Variable="${VariableB:=${VariableC:={Var3:=${Var4:-eng}}}}"
|
||||
# This is OK
|
||||
: ${VariableB:-${VariableC:-eng}}
|
||||
: "${VariableB:-${VariableC:-eng}}"
|
||||
|
||||
# First line is OK except its missing a closing "}",
|
||||
# so second line should have some error highlighting
|
||||
Variable=${VariableB:=${VariableC:={Var3:=${Var4:-eng}}}
|
||||
Variable=${VariableB:-${VariableC:-{Var3:=eng}}
|
||||
|
||||
206
runtime/syntax/testdir/input/sh_12.sh
Normal file
206
runtime/syntax/testdir/input/sh_12.sh
Normal file
@ -0,0 +1,206 @@
|
||||
#!/bin/bash
|
||||
# VIM_TEST_SETUP highlight link shArrayValue Identifier
|
||||
# VIM_TEST_SETUP highlight link shBracketExprDelim Structure
|
||||
# VIM_TEST_SETUP highlight link shCharClass Todo
|
||||
# VIM_TEST_SETUP highlight link shRange CursorLine
|
||||
|
||||
|
||||
|
||||
|
||||
[[ ( "$1" == ?(-)+([0-9]) && "$1" =~ ^-?[[:digit:]]+$ &&
|
||||
'^?(-)+([[:digit:]])$' == "$2" && ! "^-?[0-9]+$" =~ "$2" ) ]] || :
|
||||
|
||||
[ \( "$1" != "?(-)+([0-9])" -a "$1" != '?(-)+([[:digit:]])' \) ] &&
|
||||
[ \( "?(-)+([[:digit:]])" != "$2" -a '?(-)+([0-9])' != "$2" \) ] || :
|
||||
|
||||
# Match "\[0\]\[0\]", "{0}{0}", etc.
|
||||
: [[{][0-9]*[]}][[{][[:digit:]]*[]}]
|
||||
: [\
|
||||
[{][0-9]*[]}][[{][[:digit:]]*[]}]
|
||||
: [[\
|
||||
{][0-9]*[]}][[{][[:digit:]]*[]}]
|
||||
: [[{\
|
||||
][0-9]*[]}][[{][[:digit:]]*[]}]
|
||||
: [[{]\
|
||||
[0-9]*[]}][[{][[:digit:]]*[]}]
|
||||
: [[{][\
|
||||
0-9]*[]}][[{][[:digit:]]*[]}]
|
||||
: [[{][0-9\
|
||||
]*[]}][[{][[:digit:]]*[]}]
|
||||
: [[{][0-9]\
|
||||
*[]}][[{][[:digit:]]*[]}]
|
||||
: [[{][0-9]*\
|
||||
[]}][[{][[:digit:]]*[]}]
|
||||
: [[{][0-9]*[]\
|
||||
}][[{][[:digit:]]*[]}]
|
||||
: [[{][0-9]*[]}\
|
||||
][[{][[:digit:]]*[]}]
|
||||
: [[{][0-9]*[]}]\
|
||||
[[{][[:digit:]]*[]}]
|
||||
: [[{][0-9]*[]}][\
|
||||
[{][[:digit:]]*[]}]
|
||||
: [[{][0-9]*[]}][[\
|
||||
{][[:digit:]]*[]}]
|
||||
: [[{][0-9]*[]}][[{\
|
||||
][[:digit:]]*[]}]
|
||||
: [[{][0-9]*[]}][[{]\
|
||||
[[:digit:]]*[]}]
|
||||
: [[{][0-9]*[]}][[{][\
|
||||
[:digit:]]*[]}]
|
||||
: [[{][0-9]*[]}][[{][[:digit:]\
|
||||
]*[]}]
|
||||
: [[{][0-9]*[]}][[{][[:digit:]]\
|
||||
*[]}]
|
||||
: [[{][0-9]*[]}][[{][[:digit:]]*\
|
||||
[]}]
|
||||
: [[{][0-9]*[]}][[{][[:digit:]]*[]\
|
||||
}]
|
||||
: [[{][0-9]*[]}][[{][[:digit:]]*[]}\
|
||||
]
|
||||
: [[{][0-9]*[]}][[{][[:digit:]]*[[.].]}]
|
||||
: [[{][0-9]*[]}][[{][[:digit:]]*[\
|
||||
[.].]}]
|
||||
: [[{][0-9]*[]}][[{][[:digit:]]*[[.].]\
|
||||
}]
|
||||
: [[{][0-9]*[]}][[{][[:digit:]]*[[.].]}\
|
||||
]
|
||||
|
||||
# Match "\[0\]\[0\]", "{0}{0}", etc.
|
||||
case "$1" in
|
||||
[[{][0-9]*[]}][[{][[:digit:]]*[]}]*) : [0-9]; : [!0-9]; : [^0-9];;
|
||||
[\
|
||||
[{][0-9]*[]}][[{][[:digit:]]*[]}]*) : [0123]; : [!0123]; : [^0123];;
|
||||
[[\
|
||||
{][0-9]*[]}][[{][[:digit:]]*[]}]*) : [1[.0.]]; : [![.0.]]; : [^[.0.]^];;
|
||||
[[{\
|
||||
][0-9]*[]}][[{][[:digit:]]*[]}]*) : [1[=0=]]; : [![=0=]!]; : [^[=0=]];;
|
||||
[[{]\
|
||||
[0-9]*[]}][[{][[:digit:]]*[]}]*) ;;
|
||||
[[{][\
|
||||
0-9]*[]}][[{][[:digit:]]*[]}]*) ;;
|
||||
[[{][0-9\
|
||||
]*[]}][[{][[:digit:]]*[]}]*) : ?[[:foo:]]?; : [![:foo:]]?; : ?[^[:foo:]];;
|
||||
[[{][0-9]\
|
||||
*[]}][[{][[:digit:]]*[]}]*) : [[:digit:]]; : [![:digit:]]; : [^[:digit:]];;
|
||||
[[{][0-9]*\
|
||||
[]}][[{][[:digit:]]*[]}]*) : "${1^[[:lower:]]}"; : "${1^^[a-z]}";;
|
||||
[[{][0-9]*[]\
|
||||
}][[{][[:digit:]]*[]}]*) : "${1,[[:upper:]]}"; : "${1,,[A-Z]}";;
|
||||
[[{][0-9]*[]}\
|
||||
][[{][[:digit:]]*[]}]*) ;;
|
||||
[[{][0-9]*[]}]\
|
||||
[[{][[:digit:]]*[]}]*) ;;
|
||||
[[{][0-9]*[]}][\
|
||||
[{][[:digit:]]*[]}]*) : "${1#[[:digit:]]}"; : "${1##[0-9]}";;
|
||||
[[{][0-9]*[]}][[\
|
||||
{][[:digit:]]*[]}]*) : "${1%[[:digit:]]}"; : "${1%%[0-9]}";;
|
||||
[[{][0-9]*[]}][[{\
|
||||
][[:digit:]]*[]}]*) : "${1/[][:digit:][]/[0-9]}"; : "${1//[]0-9[]/[0-9]}";;
|
||||
[[{][0-9]*[]}][[{]\
|
||||
[[:digit:]]*[]}]*) : "${1/#[][:digit:][]/[0-9]}"; : "${1/%[]0-9[]/[0-9]}";;
|
||||
[[{][0-9]*[]}][[{][\
|
||||
[:digit:]]*[]}]*) ;;
|
||||
[[{][0-9]*[]}][[{][[:digit:]\
|
||||
]*[]}]*) ;;
|
||||
[[{][0-9]*[]}][[{][[:digit:]]\
|
||||
*[]}]*) : "${1#*[[.[.][.].]]}"; : "${1%[[.].][.[.]]*}"; : "${1#*" "[][]}";;
|
||||
[[{][0-9]*[]}][[{][[:digit:]]*\
|
||||
[]}]*) : "${1#*[[=[=][=]=]]}"; : "${1%[[=]=][=[=]]*}"; : "${1#*\ [!][]}";;
|
||||
[[{][0-9]*[]}][[{][[:digit:]]*[]\
|
||||
}]*) : "${1#*[!]]}"; : "${1#*[^]]}"; : "${1%[![]*}"; : "${1%[^[]*}";;
|
||||
[[{][0-9]*[]}][[{][[:digit:]]*[]}\
|
||||
]*) : "${1#*[!\]]}"; : "${1#*[^\]]}"; : "${1%[!\[]*}"; : "${1%[^\[]*}";;
|
||||
[[{][0-9]*[]}][[{][[:digit:]]*[]}]\
|
||||
*) ;;
|
||||
[[{][0-9]*[]}][[{][[:digit:]]*[[.].]}]\
|
||||
*) ;;
|
||||
[[{][0-9]*[]}][[{][[:digit:]]*[\
|
||||
[.].]}]*) ;;
|
||||
[[{][0-9]*[]}][[{][[:digit:]]*[[.].]\
|
||||
}]*) ;;
|
||||
[[{][0-9]*[]}][[{][[:digit:]]*[[.].]}\
|
||||
]*) ;;
|
||||
[!][:digit:][:xdigit:]\ [^[:lower:]![:upper:]]*) ;;
|
||||
[^][:digit:]0-9a-fA-F\ [![:lower:]^[:upper:]]*) ;;
|
||||
[!!] | [!![] | [!]!] | [!^] | [!^[] | [!]^]) ;;
|
||||
[^!] | [^![] | [^]!] | [^^] | [^^[] | [^]^]) ;;
|
||||
esac
|
||||
|
||||
# Match "\[0\]\[0\]", "{0}{0}", etc.
|
||||
: "${1#*[[{][0-9]*[]}][[{][[:digit:]]*[]}]}"
|
||||
: "${1#*\
|
||||
[[{][0-9]*[]}][[{][[:digit:]]*[]}]}"
|
||||
: "${1#*[\
|
||||
[{][0-9]*[]}][[{][[:digit:]]*[]}]}"
|
||||
: "${1#*[[\
|
||||
{][0-9]*[]}][[{][[:digit:]]*[]}]}"
|
||||
: "${1#*[[{\
|
||||
][0-9]*[]}][[{][[:digit:]]*[]}]}"
|
||||
: "${1#*[[{]\
|
||||
[0-9]*[]}][[{][[:digit:]]*[]}]}"
|
||||
: "${1#*[[{][\
|
||||
0-9]*[]}][[{][[:digit:]]*[]}]}"
|
||||
: "${1#*[[{][0-9\
|
||||
]*[]}][[{][[:digit:]]*[]}]}"
|
||||
: "${1#*[[{][0-9]\
|
||||
*[]}][[{][[:digit:]]*[]}]}"
|
||||
: "${1#*[[{][0-9]*\
|
||||
[]}][[{][[:digit:]]*[]}]}"
|
||||
: "${1#*[[{][0-9]*[]\
|
||||
}][[{][[:digit:]]*[]}]}"
|
||||
: "${1#*[[{][0-9]*[]}\
|
||||
][[{][[:digit:]]*[]}]}"
|
||||
: "${1#*[[{][0-9]*[]}]\
|
||||
[[{][[:digit:]]*[]}]}"
|
||||
: "${1#*[[{][0-9]*[]}][\
|
||||
[{][[:digit:]]*[]}]}"
|
||||
: "${1#*[[{][0-9]*[]}][[\
|
||||
{][[:digit:]]*[]}]}"
|
||||
: "${1#*[[{][0-9]*[]}][[{\
|
||||
][[:digit:]]*[]}]}"
|
||||
: "${1#*[[{][0-9]*[]}][[{]\
|
||||
[[:digit:]]*[]}]}"
|
||||
: "${1#*[[{][0-9]*[]}][[{][\
|
||||
[:digit:]]*[]}]}"
|
||||
: "${1#*[[{][0-9]*[]}][[{][[:digit:]\
|
||||
]*[]}]}"
|
||||
: "${1#*[[{][0-9]*[]}][[{][[:digit:]]\
|
||||
*[]}]}"
|
||||
: "${1#*[[{][0-9]*[]}][[{][[:digit:]]*\
|
||||
[]}]}"
|
||||
: "${1#*[[{][0-9]*[]}][[{][[:digit:]]*[]\
|
||||
}]}"
|
||||
: "${1#*[[{][0-9]*[]}][[{][[:digit:]]*[]}\
|
||||
]}"
|
||||
: "${1#*[[{][0-9]*[]}][[{][[:digit:]]*[]}]\
|
||||
}"
|
||||
: "${1#*[[{][0-9]*[]}][[{][[:digit:]]*[[.].]}]}"
|
||||
: "${1#*[[{][0-9]*[]}][[{][[:digit:]]*[\
|
||||
[.].]}]}"
|
||||
: "${1#*[[{][0-9]*[]}][[{][[:digit:]]*[[.].]\
|
||||
}]}"
|
||||
: "${1#*[[{][0-9]*[]}][[{][[:digit:]]*[[.].]}]\
|
||||
}"
|
||||
|
||||
: *[x[=[=][=]=]]; : [x[=]=][=[=]]*; : *[x[.[.][.].]]; : [x[.].][.[.]]*
|
||||
: *[[=[=]x[=]=]]; : [[=]=]x[=[=]]*; : *[[.[.]x[.].]]; : [[.].]x[.[.]]*
|
||||
: *[[=[=][=]=]x]; : [[=]=][=[=]x]*; : *[[.[.][.].]x]; : [[.].][.[.]x]*
|
||||
: [!]]; : [^]]; : [![]; : [^[]; : [!\]]; : [^\]]; : [!\[]; : [^\[]
|
||||
: [$'\x5b']; : [$'\x5d']; : []]; : [[]; : [\]]; : [\[]
|
||||
: [$'\x20'[]; : [" "[]; : [' '[]; : [\ []; : [\ \[]; : "${1#[ ]}"
|
||||
: [[$'\x20']; : [[" "]; : [[' ']; : [[\ ]; : [\[\ ]; : "${1#[ ]}"
|
||||
: [^$'\x20'[]; : [!" "[]; : [^' '[]; : [!\ []; : "${1#[^ ]}"
|
||||
: [![$'\x20']; : [^[" "]; : [![' ']; : [^[\ ]; : "${1#[! ]}"
|
||||
|
||||
nl='
|
||||
'
|
||||
echo "${1#${1%%[!"${nl}"]*}}"; echo "${1#${1%%[!'${nl}']*}}"
|
||||
echo "${1#${1%%[!\"${nl}]*}}"; echo "${1#${1%%[!\'${nl}]*}}"
|
||||
echo "${1#${1%%[!${nl}\"]*}}"; echo "${1#${1%%[!${nl}\']*}}"
|
||||
|
||||
bins=(); bins=(0 1); eval bins+=({0..1})
|
||||
bins[0]=0; bins[1]=1; eval bins+=(\${bins[{1..0}]}); unset bins[3] bins[2]
|
||||
bins=([8#0]=$((2#100)) [$((8#1))]=$((2#10)) [3]=${bins[2#1]} ${bins[0]})
|
||||
(echo sum[$((bins[16#3] + bins[8#2] + bins[2#1] + bins[0]))])
|
||||
eval unset bins[{0..$((${#bins[*]} - 1))}]
|
||||
:
|
||||
Reference in New Issue
Block a user