sh: Fix some parameter expansion variants ${#...}.

These already worked: $# ${#} ${##} ${#-} ${#?}
These now work as well: ${#+word} ${#-word} ${##word} ${#%word}

There is an ambiguity in the standard with ${#?}: it could be the length of
$? or it could be $# giving an error in the (impossible) case that it is not
set. We continue to use the former interpretation as it seems more useful.
This commit is contained in:
Jilles Tjoelker 2011-03-13 20:02:39 +00:00
parent fb7db28c25
commit 35c641ed21
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=219623
3 changed files with 51 additions and 19 deletions

View File

@ -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) {

View File

@ -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'

View File

@ -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'