diff --git a/bin/sh/parser.c b/bin/sh/parser.c index f883dff2f2f7..075c04d6e488 100644 --- a/bin/sh/parser.c +++ b/bin/sh/parser.c @@ -1447,6 +1447,7 @@ parsesub: { int bracketed_name = 0; /* used to handle ${[0-9]*} variables */ int linno; int length; + int c1; c = pgetc(); if (c != '(' && c != '{' && (is_eof(c) || !is_name(c)) && @@ -1473,15 +1474,9 @@ parsesub: { if (c == '{') { bracketed_name = 1; c = pgetc(); - if (c == '#') { - if ((c = pgetc()) == '}') - c = '#'; - else - subtype = VSLENGTH; - } - else - subtype = 0; + subtype = 0; } +varname: if (!is_eof(c) && is_name(c)) { length = 0; do { @@ -1511,19 +1506,35 @@ parsesub: { STPUTC(c, out); c = pgetc(); } - } else { - if (! is_special(c)) { - subtype = VSERROR; - if (c == '}') - pungetc(); - else if (c == '\n' || c == PEOF) - synerror("Unexpected end of line in substitution"); - else - USTPUTC(c, out); - } else { - USTPUTC(c, out); + } else if (is_special(c)) { + c1 = c; + c = pgetc(); + if (subtype == 0 && c1 == '#') { + subtype = VSLENGTH; + if (strchr(types, c) == NULL && c != ':' && + c != '#' && c != '%') + goto varname; + c1 = c; c = pgetc(); + if (c1 != '}' && c == '}') { + pungetc(); + c = c1; + goto varname; + } + pungetc(); + c = c1; + c1 = '#'; + subtype = 0; } + USTPUTC(c1, out); + } else { + subtype = VSERROR; + if (c == '}') + pungetc(); + else if (c == '\n' || c == PEOF) + synerror("Unexpected end of line in substitution"); + else + USTPUTC(c, out); } if (subtype == 0) { switch (c) { diff --git a/tools/regression/bin/sh/expansion/plus-minus8.0 b/tools/regression/bin/sh/expansion/plus-minus8.0 new file mode 100644 index 000000000000..beba009b0660 --- /dev/null +++ b/tools/regression/bin/sh/expansion/plus-minus8.0 @@ -0,0 +1,5 @@ +# $FreeBSD$ + +set -- 1 2 3 4 5 6 7 8 9 10 11 12 13 +[ "${#+hi}" = hi ] || echo '${#+hi} wrong' +[ "${#-hi}" = 13 ] || echo '${#-hi} wrong' diff --git a/tools/regression/bin/sh/expansion/trim7.0 b/tools/regression/bin/sh/expansion/trim7.0 new file mode 100644 index 000000000000..352bdea920bf --- /dev/null +++ b/tools/regression/bin/sh/expansion/trim7.0 @@ -0,0 +1,16 @@ +# $FreeBSD$ + +set -- 1 2 3 4 5 6 7 8 9 10 11 12 13 +[ "${##1}" = 3 ] || echo '${##1} wrong' +[ "${###1}" = 3 ] || echo '${###1} wrong' +[ "${###}" = 13 ] || echo '${###} wrong' +[ "${#%3}" = 1 ] || echo '${#%3} wrong' +[ "${#%%3}" = 1 ] || echo '${#%%3} wrong' +[ "${#%%}" = 13 ] || echo '${#%%} wrong' +set -- +[ "${##0}" = "" ] || echo '${##0} wrong' +[ "${###0}" = "" ] || echo '${###0} wrong' +[ "${###}" = 0 ] || echo '${###} wrong' +[ "${#%0}" = "" ] || echo '${#%0} wrong' +[ "${#%%0}" = "" ] || echo '${#%%0} wrong' +[ "${#%%}" = 0 ] || echo '${#%%} wrong'