Fix the bug reported in #834, but behaves differently
Adds tests and checks for unterminated macros, which are now reported but not expanded.
This commit is contained in:
1 parent
daa54cd4b8
commit
ec3e950642
2 files changed
+39
-9
No files matched your search
@@ -958,13 +958,14 @@ static void trans( MAC_HANDLE *handle, MAC_ENTRY *entry, int level,
|
||||
static void refer ( MAC_HANDLE *handle, MAC_ENTRY *entry, int level,
|
||||
const char **rawval, char **value, char *valend )
|
||||
{
|
||||
const char *r = *rawval;
|
||||
const char *r = *rawval + 1; /* step over '$' */
|
||||
const char *macEnd = (*r++ == '(') ? "=,)" : "=,}";
|
||||
const char close = macEnd[2]; /* Matching ')' or '}' */
|
||||
char *v = *value;
|
||||
char refname[MAC_SIZE + 1] = {'\0'};
|
||||
char *rn = refname;
|
||||
MAC_ENTRY *refentry;
|
||||
const char *defval = NULL;
|
||||
const char *macEnd;
|
||||
const char *errval = NULL;
|
||||
int pop = FALSE;
|
||||
|
||||
@@ -973,14 +974,14 @@ static void refer ( MAC_HANDLE *handle, MAC_ENTRY *entry, int level,
|
||||
printf( "refer-> entry = %p, level = %d, capacity = %u, rawval = %s\n",
|
||||
entry, level, (unsigned int)(valend - *value), *rawval );
|
||||
|
||||
/* step over '$(' or '${' */
|
||||
r++;
|
||||
macEnd = ( *r == '(' ) ? "=,)" : "=,}";
|
||||
r++;
|
||||
|
||||
/* translate name (may contain macro references); truncated
|
||||
quietly if too long but always guaranteed to be null terminated */
|
||||
trans( handle, entry, level + 1, macEnd, &r, &rn, rn + MAC_SIZE );
|
||||
{
|
||||
int flags = handle->flags;
|
||||
handle->flags |= FLAG_SUPPRESS_WARNINGS;
|
||||
trans( handle, entry, level + 1, macEnd, &r, &rn, rn + MAC_SIZE );
|
||||
handle->flags = flags;
|
||||
}
|
||||
refname[MAC_SIZE] = '\0';
|
||||
|
||||
/* Is there a default value? */
|
||||
@@ -1043,6 +1044,21 @@ static void refer ( MAC_HANDLE *handle, MAC_ENTRY *entry, int level,
|
||||
handle->flags = flags;
|
||||
}
|
||||
|
||||
/* If the closing delimiter doesn't match the opener, pass through verbatim */
|
||||
if ( *r != close ) {
|
||||
const char *p;
|
||||
v = *value;
|
||||
for ( p = *rawval; p <= r && v < valend; p++ )
|
||||
*v++ = *p;
|
||||
*v = '\0';
|
||||
entry->error = TRUE;
|
||||
if ( (handle->flags & FLAG_SUPPRESS_WARNINGS) == 0 )
|
||||
errlogPrintf( "macLib: " ANSI_MAGENTA("unterminated")
|
||||
" macro reference in %s %s\n",
|
||||
entry->type, entry->name );
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Now we can look up the translated name */
|
||||
refentry = lookup( handle, refname, FALSE );
|
||||
|
||||
|
||||
@@ -66,13 +66,25 @@ static void ovcheck(void)
|
||||
|
||||
MAIN(macLibTest)
|
||||
{
|
||||
testPlan(93);
|
||||
testPlan(105);
|
||||
|
||||
if (macCreateHandle(&h, NULL))
|
||||
testAbort("macCreateHandle() failed");
|
||||
eltc(0);
|
||||
|
||||
check("FOO", " FOO");
|
||||
check("F(O){O}", " F(O){O}");
|
||||
check("F(O}{O)", " F(O}{O)");
|
||||
|
||||
check("x${FOO)", "!x${FOO)");
|
||||
check("x${FOO=bar)", "!x${FOO=bar)");
|
||||
check("x${FOO,bar)", "!x${FOO,bar)");
|
||||
check("x${FOO ${BAR", "!x${FOO ${BAR");
|
||||
|
||||
check("x$(FOO}", "!x$(FOO}");
|
||||
check("x$(FOO=bar}", "!x$(FOO=bar}");
|
||||
check("x$(FOO,bar}", "!x$(FOO,bar}");
|
||||
check("x$(FOO $(BAR", "!x$(FOO $(BAR");
|
||||
|
||||
check("$(FOO)", "!$(FOO,undefined)");
|
||||
check("${FOO}", "!$(FOO,undefined)");
|
||||
@@ -115,6 +127,8 @@ MAIN(macLibTest)
|
||||
|
||||
check("${=BAR}", " BAR");
|
||||
check("x${=BAR}y", " xBARy");
|
||||
check("x(${=)}y", " x()y");
|
||||
check("x{$(=})y", " x{}y");
|
||||
|
||||
check("${FOO=BAR}", " BAR");
|
||||
check("x${FOO=BAR}y", " xBARy");
|
||||
|
||||
Reference in new issue
Block a user