diff options
-rw-r--r-- | bin/sh/expand.c | 5 | ||||
-rw-r--r-- | bin/sh/parser.c | 28 | ||||
-rw-r--r-- | bin/sh/parser.h | 1 |
3 files changed, 25 insertions, 9 deletions
diff --git a/bin/sh/expand.c b/bin/sh/expand.c index 7fd2ba5..f26a999 100644 --- a/bin/sh/expand.c +++ b/bin/sh/expand.c @@ -763,6 +763,11 @@ record: goto record; break; + case VSERROR: + c = p - var - 1; + error("${%.*s%s}: Bad substitution", c, var, + (c > 0 && *p != CTLENDVAR) ? "..." : ""); + default: abort(); } 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; diff --git a/bin/sh/parser.h b/bin/sh/parser.h index b0bd99e..6b5687d 100644 --- a/bin/sh/parser.h +++ b/bin/sh/parser.h @@ -60,6 +60,7 @@ #define VSTRIMRIGHT 0x8 /* ${var%pattern} */ #define VSTRIMRIGHTMAX 0x9 /* ${var%%pattern} */ #define VSLENGTH 0xa /* ${#var} */ +#define VSERROR 0xb /* Syntax error, issue when expanded */ /* |