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

View File

@ -841,81 +841,71 @@ void cmSystemTools::ExpandListArgument(const std::string& arg,
if(arg.find(';') == std::string::npos) if(arg.find(';') == std::string::npos)
{ {
newargs.push_back(arg); 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 else
{ {
std::string::size_type start = 0; newarg += '\\';
std::string::size_type endpos = 0; if(*c)
const std::string::size_type size = arg.size();
// break up ; separated sections of the string into separate strings
while(endpos != size)
{ {
endpos = arg.find(';', start); newarg += *c;
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();
} }
} }
std::string::size_type len = endpos - start; } break;
if (len > 0) case '[':
{ {
// check for a closing ] after the start position ++squareNesting;
if(arg.find('[', start) == std::string::npos) newarg += '[';
} break;
case ']':
{ {
// if there is no [ in the string then keep it --squareNesting;
newarg = arg.substr(start, len); newarg += ']';
} } break;
else case ';':
{ {
int opencount = 0; // Break the string here if we are not nested inside square
int closecount = 0; // brackets.
for(std::string::size_type j = start; j < endpos; ++j) if(squareNesting == 0)
{ {
if(arg.at(j) == '[') if(newarg.length())
{ {
++opencount; // Add an argument if the string is not empty.
}
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("\\;");
}
newargs.push_back(newarg); 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);
} }
} }