From: Peter Avalos Date: Sat, 16 Apr 2011 21:17:03 +0000 (-1000) Subject: sh: Fix some parameter expansion variants ${#...}. X-Git-Tag: v2.11.0~32 X-Git-Url: https://gitweb.dragonflybsd.org/dragonfly.git/commitdiff_plain/6ea1c53357054b48026c1fbe6223a0b674921f12 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. Obtained-from: FreeBSD --- diff --git a/bin/sh/parser.c b/bin/sh/parser.c index f0494a3179..74e7cbdc4f 100644 --- a/bin/sh/parser.c +++ b/bin/sh/parser.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)parser.c 8.7 (Berkeley) 5/16/95 - * $FreeBSD: src/bin/sh/parser.c,v 1.105 2011/02/05 15:02:19 jilles Exp $ + * $FreeBSD: src/bin/sh/parser.c,v 1.106 2011/03/13 20:02:39 jilles Exp $ */ #include @@ -1446,6 +1446,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)) && @@ -1472,15 +1473,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 { @@ -1510,19 +1505,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 0000000000..20ebf4bdef --- /dev/null +++ b/tools/regression/bin/sh/expansion/plus-minus8.0 @@ -0,0 +1,5 @@ +# $FreeBSD: src/tools/regression/bin/sh/expansion/plus-minus8.0,v 1.1 2011/03/13 20:02:39 jilles Exp $ + +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 0000000000..274fa43c2f --- /dev/null +++ b/tools/regression/bin/sh/expansion/trim7.0 @@ -0,0 +1,16 @@ +# $FreeBSD: src/tools/regression/bin/sh/expansion/trim7.0,v 1.1 2011/03/13 20:02:39 jilles Exp $ + +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'