diff options
author | Brad King <brad.king@kitware.com> | 2005-05-10 15:00:15 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2005-05-10 15:00:15 (GMT) |
commit | dd9e2b904c33787c193bc07d7f811552dfaa72b2 (patch) | |
tree | 3e7fda4d24b2e736adb4a8706ab25bc1b0d1f970 /Source/cmDependsC.cxx | |
parent | b2f5af917b8345cceda21c63a75ad2ee23c35a6b (diff) | |
download | CMake-dd9e2b904c33787c193bc07d7f811552dfaa72b2.zip CMake-dd9e2b904c33787c193bc07d7f811552dfaa72b2.tar.gz CMake-dd9e2b904c33787c193bc07d7f811552dfaa72b2.tar.bz2 |
BUG: Re-implemented dependency line parsing to deal with quoted paths and escaped spaces.
Diffstat (limited to 'Source/cmDependsC.cxx')
-rw-r--r-- | Source/cmDependsC.cxx | 107 |
1 files changed, 63 insertions, 44 deletions
diff --git a/Source/cmDependsC.cxx b/Source/cmDependsC.cxx index 6a64b6a..6e359a5 100644 --- a/Source/cmDependsC.cxx +++ b/Source/cmDependsC.cxx @@ -18,6 +18,8 @@ #include "cmSystemTools.h" +#include <ctype.h> // isspace + //---------------------------------------------------------------------------- cmDependsC::cmDependsC(const char* dir, const char* targetFile, bool verbose): cmDepends(dir, targetFile, verbose), @@ -181,54 +183,12 @@ bool cmDependsC::CheckDependencies(std::istream& is) std::string dependee; while(cmSystemTools::GetLineFromStream(is, line)) { - // Skip empty lines and comments. - std::string::size_type pos = line.find_first_not_of(" \t\r\n"); - if(pos == std::string::npos || line[pos] == '#') + // Parse the dependency line. + if(!this->ParseDependency(line.c_str(), depender, dependee)) { continue; } - // Strip leading whitespace. - if(pos > 0) - { - line = line.substr(pos); - } - - // Skip lines too short to have a dependency. - if(line.size() < 3) - { - continue; - } - - // Find the colon on the line. Skip the first two characters to - // avoid finding the colon in a drive letter on Windows. Ignore - // the line if a colon cannot be found. - if((pos = line.find(':', 2)) == std::string::npos) - { - continue; - } - - // Split the line into depender and dependee. - depender = line.substr(0, pos); - dependee = line.substr(pos+1); - - // Strip whitespace from the dependee. - if((pos = dependee.find_first_not_of(" \t\r\n")) != std::string::npos && - pos > 0) - { - dependee = dependee.substr(pos); - } - if((pos = dependee.find_last_not_of(" \t\r\n")) != std::string::npos) - { - dependee = dependee.substr(0, pos+1); - } - - // Strip whitespace from the depender. - if((pos = depender.find_last_not_of(" \t\r\n")) != std::string::npos) - { - depender = depender.substr(0, pos+1); - } - // Dependencies must be regenerated if the dependee does not exist // or if the depender exists and is older than the dependee. bool regenerate = false; @@ -319,3 +279,62 @@ void cmDependsC::Scan(std::istream& is, const char* directory) } } } + +//---------------------------------------------------------------------------- +bool cmDependsC::ParseDependency(const char* line, std::string& depender, + std::string& dependee) +{ + // Start with empty names. + depender = ""; + dependee = ""; + + // Get the left-hand-side of the dependency. + const char* c = this->ParseFileName(line, depender); + + // Skip the ':' separator. + for(;c && *c && isspace(*c);++c); + if(!c || !*c || *c != ':') + { + return false; + } + ++c; + + // Get the right-hand-side of the dependency. + return this->ParseFileName(c, dependee)?true:false; +} + +//---------------------------------------------------------------------------- +const char* cmDependsC::ParseFileName(const char* in, std::string& name) +{ + // Skip leading whitespace. + const char* c = in; + for(;c && *c && isspace(*c);++c); + + // If this is an empty line or a comment line return failure. + if(!c || !*c || *c == '#') + { + return 0; + } + + // Parse the possibly quoted file name. + bool quoted = false; + for(;*c && (quoted || + ((*c != ':' || name.size() == 1) && !isspace(*c))); ++c) + { + if(*c == '"') + { + quoted = !quoted; + } + else if(!quoted && *c == '\\' && isspace(*(c+1))) + { + name += *(++c); + } + else + { + name += *c; + } + } + + // Return the ending position. + return c; +} |