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
This commit is contained in:
stefanf 2006-11-05 18:36:05 +00:00
parent db8b5b89e2
commit d02f26394e
3 changed files with 25 additions and 9 deletions

View File

@ -763,6 +763,11 @@ record:
goto record; goto record;
break; break;
case VSERROR:
c = p - var - 1;
error("${%.*s%s}: Bad substitution", c, var,
(c > 0 && *p != CTLENDVAR) ? "..." : "");
default: default:
abort(); abort();
} }

View File

@ -1228,12 +1228,17 @@ parsesub: {
c = pgetc(); c = pgetc();
} }
} else { } else {
if (! is_special(c)) if (! is_special(c)) {
badsub: synerror("Bad substitution"); subtype = VSERROR;
USTPUTC(c, out); if (c == '}')
c = pgetc(); pungetc();
else
USTPUTC(c, out);
} else {
USTPUTC(c, out);
c = pgetc();
}
} }
STPUTC('=', out);
flags = 0; flags = 0;
if (subtype == 0) { if (subtype == 0) {
switch (c) { switch (c) {
@ -1243,9 +1248,13 @@ badsub: synerror("Bad substitution");
/*FALLTHROUGH*/ /*FALLTHROUGH*/
default: default:
p = strchr(types, c); p = strchr(types, c);
if (p == NULL) if (p == NULL) {
goto badsub; if (flags == VSNUL)
subtype = p - types + VSNORMAL; STPUTC(':', out);
STPUTC(c, out);
subtype = VSERROR;
} else
subtype = p - types + VSNORMAL;
break; break;
case '%': case '%':
case '#': case '#':
@ -1261,9 +1270,10 @@ badsub: synerror("Bad substitution");
break; break;
} }
} }
} else { } else if (subtype != VSERROR) {
pungetc(); pungetc();
} }
STPUTC('=', out);
if (subtype != VSLENGTH && (dblquote || arinest)) if (subtype != VSLENGTH && (dblquote || arinest))
flags |= VSQUOTE; flags |= VSQUOTE;
*(stackblock() + typeloc) = subtype | flags; *(stackblock() + typeloc) = subtype | flags;

View File

@ -60,6 +60,7 @@
#define VSTRIMRIGHT 0x8 /* ${var%pattern} */ #define VSTRIMRIGHT 0x8 /* ${var%pattern} */
#define VSTRIMRIGHTMAX 0x9 /* ${var%%pattern} */ #define VSTRIMRIGHTMAX 0x9 /* ${var%%pattern} */
#define VSLENGTH 0xa /* ${#var} */ #define VSLENGTH 0xa /* ${#var} */
#define VSERROR 0xb /* Syntax error, issue when expanded */
/* /*