summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2003-12-08 23:05:29 (GMT)
committerBrad King <brad.king@kitware.com>2003-12-08 23:05:29 (GMT)
commitec78910bacbb909c07a194ad7c00299dfd990314 (patch)
tree29c48a026bd743d33a7c464e569ad7e900e52730
parent06092a31fd73d2752d1697b32fc93fb3b25c6920 (diff)
downloadCMake-ec78910bacbb909c07a194ad7c00299dfd990314.zip
CMake-ec78910bacbb909c07a194ad7c00299dfd990314.tar.gz
CMake-ec78910bacbb909c07a194ad7c00299dfd990314.tar.bz2
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.
-rw-r--r--Source/cmSystemTools.cxx108
1 files changed, 49 insertions, 59 deletions
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx
index 48ba54e..c878899 100644
--- a/Source/cmSystemTools.cxx
+++ b/Source/cmSystemTools.cxx
@@ -841,82 +841,72 @@ void cmSystemTools::ExpandListArgument(const std::string& arg,
if(arg.find(';') == std::string::npos)
{
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;
- 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)
+ switch(*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();
- }
- }
- std::string::size_type len = endpos - start;
- if (len > 0)
+ case '\\':
{
- // check for a closing ] after the start position
- if(arg.find('[', start) == std::string::npos)
+ // We only want to allow escaping of semicolons. Other
+ // escapes should not be processed here.
+ ++c;
+ if(*c == ';')
{
- // if there is no [ in the string then keep it
- newarg = arg.substr(start, len);
+ newarg += ';';
}
else
{
- int opencount = 0;
- int closecount = 0;
- for(std::string::size_type j = start; j < endpos; ++j)
+ newarg += '\\';
+ if(*c)
{
- if(arg.at(j) == '[')
- {
- ++opencount;
- }
- else if (arg.at(j) == ']')
- {
- ++closecount;
- }
+ newarg += *c;
}
- if(opencount != closecount)
+ }
+ } break;
+ case '[':
+ {
+ ++squareNesting;
+ newarg += '[';
+ } break;
+ case ']':
+ {
+ --squareNesting;
+ newarg += ']';
+ } break;
+ case ';':
+ {
+ // Break the string here if we are not nested inside square
+ // brackets.
+ if(squareNesting == 0)
+ {
+ if(newarg.length())
{
- // skip this one
- endpos = arg.find(';', endpos+1);
- if(endpos == std::string::npos)
- {
- endpos = arg.size();
- }
- len = endpos - start;
+ // Add an argument if the string is not empty.
+ newargs.push_back(newarg);
+ newarg = "";
}
- newarg = arg.substr(start, len);
}
- // unescape semicolons
- std::string::size_type pos = newarg.find("\\;");
- while (pos != std::string::npos)
+ else
{
- newarg.erase(pos, 1);
- pos = newarg.find("\\;");
+ newarg += ';';
}
- newargs.push_back(newarg);
- }
- start = endpos+1;
+ } 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,