diff options
author | stefanf <stefanf@FreeBSD.org> | 2006-11-05 18:36:05 +0000 |
---|---|---|
committer | stefanf <stefanf@FreeBSD.org> | 2006-11-05 18:36:05 +0000 |
commit | d02f26394e8614923870babd1d3518dde707c61a (patch) | |
tree | 03b401ffcd1d70294e77fc5bb3a1d899575f0939 /bin/sh/parser.c | |
parent | db8b5b89e2af712352769edf1c4350214fe10657 (diff) | |
download | FreeBSD-src-d02f26394e8614923870babd1d3518dde707c61a.zip FreeBSD-src-d02f26394e8614923870babd1d3518dde707c61a.tar.gz |
When parsing an invalid parameter expansion (eg. ${} or ${foo@bar}) do not
issue a syntax error immediately but save the information that it is erroneous
for later when the parameter expansion is actually done. This means eg. "false
&& ${}" will not generate an error which seems to be required by POSIX.
Include the invalid parameter expansion in the error message (sometimes
abbreviated with ... because recovering it would require a lot of code).
PR: 105078
Submitted by: emaste
Diffstat (limited to 'bin/sh/parser.c')
-rw-r--r-- | bin/sh/parser.c | 28 |
1 files changed, 19 insertions, 9 deletions
diff --git a/bin/sh/parser.c b/bin/sh/parser.c index 26504c1..fb9abc9 100644 --- a/bin/sh/parser.c +++ b/bin/sh/parser.c @@ -1228,12 +1228,17 @@ parsesub: { c = pgetc(); } } else { - if (! is_special(c)) -badsub: synerror("Bad substitution"); - USTPUTC(c, out); - c = pgetc(); + if (! is_special(c)) { + subtype = VSERROR; + if (c == '}') + pungetc(); + else + USTPUTC(c, out); + } else { + USTPUTC(c, out); + c = pgetc(); + } } - STPUTC('=', out); flags = 0; if (subtype == 0) { switch (c) { @@ -1243,9 +1248,13 @@ badsub: synerror("Bad substitution"); /*FALLTHROUGH*/ default: p = strchr(types, c); - if (p == NULL) - goto badsub; - subtype = p - types + VSNORMAL; + if (p == NULL) { + if (flags == VSNUL) + STPUTC(':', out); + STPUTC(c, out); + subtype = VSERROR; + } else + subtype = p - types + VSNORMAL; break; case '%': case '#': @@ -1261,9 +1270,10 @@ badsub: synerror("Bad substitution"); break; } } - } else { + } else if (subtype != VSERROR) { pungetc(); } + STPUTC('=', out); if (subtype != VSLENGTH && (dblquote || arinest)) flags |= VSQUOTE; *(stackblock() + typeloc) = subtype | flags; |