diff options
author | Brad King <brad.king@kitware.com> | 2003-12-08 23:05:29 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2003-12-08 23:05:29 (GMT) |
commit | ec78910bacbb909c07a194ad7c00299dfd990314 (patch) | |
tree | 29c48a026bd743d33a7c464e569ad7e900e52730 /Source/cmSystemTools.cxx | |
parent | 06092a31fd73d2752d1697b32fc93fb3b25c6920 (diff) | |
download | CMake-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.
Diffstat (limited to 'Source/cmSystemTools.cxx')
-rw-r--r-- | Source/cmSystemTools.cxx | 108 |
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, |