BUG: Reimplemented ExpandListArguments to properly handle escaped backslashes that occur right before semicolons. This is important for lists of paths ending in backslashes on windows.

This commit is contained in:
Brad King 2003-12-08 18:05:29 -05:00
parent 06092a31fd
commit ec78910bac
1 changed files with 51 additions and 61 deletions

View File

@ -841,81 +841,71 @@ void cmSystemTools::ExpandListArgument(const std::string& arg,
if(arg.find(';') == std::string::npos)
{
newargs.push_back(arg);
return;
}
// Break the string at non-escaped semicolons not nested in [].
int squareNesting = 0;
for(const char* c = arg.c_str(); *c; ++c)
{
switch(*c)
{
case '\\':
{
// We only want to allow escaping of semicolons. Other
// escapes should not be processed here.
++c;
if(*c == ';')
{
newarg += ';';
}
else
{
std::string::size_type start = 0;
std::string::size_type endpos = 0;
const std::string::size_type size = arg.size();
// break up ; separated sections of the string into separate strings
while(endpos != size)
newarg += '\\';
if(*c)
{
endpos = arg.find(';', start);
if(endpos == std::string::npos)
{
endpos = arg.size();
}
else
{
// skip right over escaped ; ( \; )
while((endpos != std::string::npos)
&& (endpos > 0)
&& ((arg)[endpos-1] == '\\') )
{
endpos = arg.find(';', endpos+1);
}
if(endpos == std::string::npos)
{
endpos = arg.size();
newarg += *c;
}
}
std::string::size_type len = endpos - start;
if (len > 0)
} break;
case '[':
{
// check for a closing ] after the start position
if(arg.find('[', start) == std::string::npos)
++squareNesting;
newarg += '[';
} break;
case ']':
{
// if there is no [ in the string then keep it
newarg = arg.substr(start, len);
}
else
--squareNesting;
newarg += ']';
} break;
case ';':
{
int opencount = 0;
int closecount = 0;
for(std::string::size_type j = start; j < endpos; ++j)
// Break the string here if we are not nested inside square
// brackets.
if(squareNesting == 0)
{
if(arg.at(j) == '[')
if(newarg.length())
{
++opencount;
}
else if (arg.at(j) == ']')
{
++closecount;
}
}
if(opencount != closecount)
{
// skip this one
endpos = arg.find(';', endpos+1);
if(endpos == std::string::npos)
{
endpos = arg.size();
}
len = endpos - start;
}
newarg = arg.substr(start, len);
}
// unescape semicolons
std::string::size_type pos = newarg.find("\\;");
while (pos != std::string::npos)
{
newarg.erase(pos, 1);
pos = newarg.find("\\;");
}
// Add an argument if the string is not empty.
newargs.push_back(newarg);
newarg = "";
}
start = endpos+1;
}
else
{
newarg += ';';
}
} break;
default:
{
// Just append this character.
newarg += *c;
} break;
}
}
if(newarg.length())
{
// Add the last argument if the string is not empty.
newargs.push_back(newarg);
}
}