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,82 +841,72 @@ 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;
} }
else // Break the string at non-escaped semicolons not nested in [].
int squareNesting = 0;
for(const char* c = arg.c_str(); *c; ++c)
{ {
std::string::size_type start = 0; switch(*c)
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)
{ {
endpos = arg.find(';', start); case '\\':
if(endpos == std::string::npos)
{ {
endpos = arg.size(); // We only want to allow escaping of semicolons. Other
} // escapes should not be processed here.
else ++c;
{ if(*c == ';')
// skip right over escaped ; ( \; )
while((endpos != std::string::npos)
&& (endpos > 0)
&& ((arg)[endpos-1] == '\\') )
{ {
endpos = arg.find(';', endpos+1); newarg += ';';
}
if(endpos == std::string::npos)
{
endpos = arg.size();
}
}
std::string::size_type len = endpos - start;
if (len > 0)
{
// check for a closing ] after the start position
if(arg.find('[', start) == std::string::npos)
{
// if there is no [ in the string then keep it
newarg = arg.substr(start, len);
} }
else else
{ {
int opencount = 0; newarg += '\\';
int closecount = 0; if(*c)
for(std::string::size_type j = start; j < endpos; ++j)
{ {
if(arg.at(j) == '[') newarg += *c;
{
++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 } break;
std::string::size_type pos = newarg.find("\\;"); case '[':
while (pos != std::string::npos) {
++squareNesting;
newarg += '[';
} break;
case ']':
{
--squareNesting;
newarg += ']';
} break;
case ';':
{
// Break the string here if we are not nested inside square
// brackets.
if(squareNesting == 0)
{ {
newarg.erase(pos, 1); if(newarg.length())
pos = newarg.find("\\;"); {
// Add an argument if the string is not empty.
newargs.push_back(newarg);
newarg = "";
}
} }
newargs.push_back(newarg); else
} {
start = endpos+1; 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);
}
} }
bool cmSystemTools::SimpleGlob(const std::string& glob, bool cmSystemTools::SimpleGlob(const std::string& glob,