diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx index c3d596fca..71c3b7450 100644 --- a/Source/cmFileCommand.cxx +++ b/Source/cmFileCommand.cxx @@ -903,14 +903,10 @@ cmFileCommand::HandleDifferentCommand(std::vector const& args) // File installation helper class. struct cmFileInstaller { - // Methods to actually install files. - bool InstallFile(const char* fromFile, const char* toFile); - bool InstallDirectory(const char* source, const char* destination); - // All instances need the file command and makefile using them. cmFileInstaller(cmFileCommand* command): FileCommand(command), Makefile(command->GetMakefile()), - Always(false), DestDirLength(0), MatchlessFiles(true) + Always(false), Optional(false), DestDirLength(0), MatchlessFiles(true) { // Check whether to copy files always or only if they have changed. this->Always = @@ -932,6 +928,7 @@ private: bool Always; cmFileTimeComparison FileTimes; public: + bool Optional; // The length of the destdir setting. int DestDirLength; @@ -964,8 +961,7 @@ public: std::vector MatchRules; // Get the properties from rules matching this input file. - MatchProperties CollectMatchProperties(const char* file, - bool isDirectory) + MatchProperties CollectMatchProperties(const char* file) { // Match rules are case-insensitive on some platforms. #if defined(_WIN32) || defined(__APPLE__) || defined(__CYGWIN__) @@ -986,9 +982,9 @@ public: result.Permissions |= mr->Properties.Permissions; } } - if(!matched && !this->MatchlessFiles && !isDirectory) + if(!matched && !this->MatchlessFiles) { - result.Exclude = true; + result.Exclude = !cmSystemTools::FileIsDirectory(file); } return result; } @@ -1038,8 +1034,61 @@ public: private: bool InstallSymlink(const char* fromFile, const char* toFile); +public: + bool InstallFile(const char* fromFile, const char* toFile, + MatchProperties const& match_properties); + bool InstallDirectory(const char* source, const char* destination, + MatchProperties const& match_properties); + bool Install(const char* fromFile, const char* toFile); }; +//---------------------------------------------------------------------------- +bool cmFileInstaller::Install(const char* fromFile, const char* toFile) +{ + if(!*fromFile) + { + cmOStringStream e; + e << "INSTALL encountered an empty string input file name."; + this->FileCommand->SetError(e.str().c_str()); + return false; + } + + // Collect any properties matching this file name. + MatchProperties match_properties = this->CollectMatchProperties(fromFile); + + // Skip the file if it is excluded. + if(match_properties.Exclude) + { + return true; + } + + if(cmSystemTools::SameFile(fromFile, toFile)) + { + return true; + } + else if(cmSystemTools::FileIsSymlink(fromFile)) + { + return this->InstallSymlink(fromFile, toFile); + } + else if(cmSystemTools::FileIsDirectory(fromFile)) + { + return this->InstallDirectory(fromFile, toFile, match_properties); + } + else if(cmSystemTools::FileExists(fromFile)) + { + return this->InstallFile(fromFile, toFile, match_properties); + } + else if(!this->Optional) + { + // The input file does not exist and installation is not optional. + cmOStringStream e; + e << "INSTALL cannot find file \"" << fromFile << "\" to install."; + this->FileCommand->SetError(e.str().c_str()); + return false; + } + return true; +} + //---------------------------------------------------------------------------- bool cmFileInstaller::InstallSymlink(const char* fromFile, const char* toFile) { @@ -1097,24 +1146,9 @@ bool cmFileInstaller::InstallSymlink(const char* fromFile, const char* toFile) } //---------------------------------------------------------------------------- -bool cmFileInstaller::InstallFile(const char* fromFile, const char* toFile) +bool cmFileInstaller::InstallFile(const char* fromFile, const char* toFile, + MatchProperties const& match_properties) { - // Collect any properties matching this file name. - MatchProperties match_properties = - this->CollectMatchProperties(fromFile, false); - - // Skip the file if it is excluded. - if(match_properties.Exclude) - { - return true; - } - - // Short-circuit for symbolic links. - if(cmSystemTools::FileIsSymlink(fromFile)) - { - return this->InstallSymlink(fromFile, toFile); - } - // Determine whether we will copy the file. bool copy = true; if(!this->Always) @@ -1170,24 +1204,9 @@ bool cmFileInstaller::InstallFile(const char* fromFile, const char* toFile) //---------------------------------------------------------------------------- bool cmFileInstaller::InstallDirectory(const char* source, - const char* destination) + const char* destination, + MatchProperties const& match_properties) { - // Collect any properties matching this directory name. - MatchProperties match_properties = - this->CollectMatchProperties(source, true); - - // Skip the directory if it is excluded. - if(match_properties.Exclude) - { - return true; - } - - // Short-circuit for symbolic links. - if(cmSystemTools::FileIsSymlink(source)) - { - return this->InstallSymlink(source, destination); - } - // Inform the user about this directory installation. std::string message = "Installing: "; message += destination; @@ -1254,26 +1273,12 @@ bool cmFileInstaller::InstallDirectory(const char* source, cmsys_stl::string fromPath = source; fromPath += "/"; fromPath += dir.GetFile(fileNum); - if(cmSystemTools::FileIsDirectory(fromPath.c_str())) + std::string toPath = destination; + toPath += "/"; + toPath += dir.GetFile(fileNum); + if(!this->Install(fromPath.c_str(), toPath.c_str())) { - cmsys_stl::string toDir = destination; - toDir += "/"; - toDir += dir.GetFile(fileNum); - if(!this->InstallDirectory(fromPath.c_str(), toDir.c_str())) - { - return false; - } - } - else - { - // Install this file. - std::string toFile = destination; - toFile += "/"; - toFile += dir.GetFile(fileNum); - if(!this->InstallFile(fromPath.c_str(), toFile.c_str())) - { - return false; - } + return false; } } } @@ -1728,14 +1733,12 @@ bool cmFileCommand::HandleInstallCommand(std::vector const& args) std::vector files; int itype = cmTarget::INSTALL_FILES; - bool optional = false; bool result = this->ParseInstallArgs(args, installer, - itype, rename, destination, files, - optional); + itype, rename, destination, files); if (result == true) { result = this->DoInstall(installer, - itype, rename, destination, files, optional); + itype, rename, destination, files); } return result; } @@ -1746,8 +1749,7 @@ bool cmFileCommand::ParseInstallArgs(std::vector const& args, int& itype, std::string& rename, std::string& destination, - std::vector& files, - bool& optional) + std::vector& files) { std::string stype = "FILES"; enum Doing { DoingNone, DoingFiles, @@ -1795,7 +1797,7 @@ bool cmFileCommand::ParseInstallArgs(std::vector const& args, if ( args[i+1] == "OPTIONAL" ) { i++; - optional = true; + installer.Optional = true; } doing = DoingNone; } @@ -2030,8 +2032,7 @@ bool cmFileCommand::DoInstall( cmFileInstaller& installer, const int itype, const std::string& rename, const std::string& destination, - const std::vector& files, - const bool optional) + const std::vector& files) { typedef std::set::const_iterator iter_type; @@ -2063,36 +2064,18 @@ bool cmFileCommand::DoInstall( cmFileInstaller& installer, fromFile += fromName; } - std::string message; - if(!cmSystemTools::SameFile(fromFile.c_str(), toFile.c_str())) + if(itype == cmTarget::INSTALL_DIRECTORY && fromFile.empty()) { - if(itype == cmTarget::INSTALL_DIRECTORY && - (fromFile.empty() || - cmSystemTools::FileIsDirectory(fromFile.c_str()))) + if(!installer.InstallDirectory(fromFile.c_str(), toFile.c_str(), + cmFileInstaller::MatchProperties())) { - // Try installing this directory. - if(!installer.InstallDirectory(fromFile.c_str(), toFile.c_str())) - { - return false; - } - } - else if(cmSystemTools::FileExists(fromFile.c_str())) - { - // Install this file. - if(!installer.InstallFile(fromFile.c_str(), toFile.c_str())) - { - return false; - } - } - else if(!optional) - { - // The input file does not exist and installation is not optional. - cmOStringStream e; - e << "INSTALL cannot find file \"" << fromFile << "\" to install."; - this->SetError(e.str().c_str()); return false; } } + else if(!installer.Install(fromFile.c_str(), toFile.c_str())) + { + return false; + } } return true; diff --git a/Source/cmFileCommand.h b/Source/cmFileCommand.h index ded7813e6..b75cecd9b 100644 --- a/Source/cmFileCommand.h +++ b/Source/cmFileCommand.h @@ -186,15 +186,13 @@ protected: int& itype, std::string& destination, std::string& rename, - std::vector& files, - bool& optional + std::vector& files ); bool DoInstall(cmFileInstaller& installer, const int itype, const std::string& rename, const std::string& destination, - const std::vector& files, - const bool optional + const std::vector& files ); bool HandleDownloadCommand(std::vector const& args); void GetTargetTypeFromString(const std::string& stype, int& itype) const;