diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx index ab8edda6f..1808027c9 100644 --- a/Source/cmFileCommand.cxx +++ b/Source/cmFileCommand.cxx @@ -100,6 +100,10 @@ bool cmFileCommand { return this->HandleMakeDirectoryCommand(args); } + else if ( subCommand == "RENAME" ) + { + return this->HandleRename(args); + } else if ( subCommand == "REMOVE" ) { return this->HandleRemove(args, false); @@ -2174,6 +2178,45 @@ bool cmFileCommand::HandleRelativePathCommand( } +//---------------------------------------------------------------------------- +bool cmFileCommand::HandleRename(std::vector const& args) +{ + if(args.size() != 3) + { + this->SetError("given incorrect number of arguments."); + return false; + } + + // Compute full path for old and new names. + std::string oldname = args[1]; + if(!cmsys::SystemTools::FileIsFullPath(oldname.c_str())) + { + oldname = this->Makefile->GetCurrentDirectory(); + oldname += "/" + args[1]; + } + std::string newname = args[2]; + if(!cmsys::SystemTools::FileIsFullPath(newname.c_str())) + { + newname = this->Makefile->GetCurrentDirectory(); + newname += "/" + args[2]; + } + + if(!cmSystemTools::RenameFile(oldname.c_str(), newname.c_str())) + { + std::string err = cmSystemTools::GetLastSystemError(); + cmOStringStream e; + e << "RENAME failed to rename\n" + << " " << oldname << "\n" + << "to\n" + << " " << newname << "\n" + << "because: " << err << "\n"; + this->SetError(e.str().c_str()); + return false; + } + return true; +} + + //---------------------------------------------------------------------------- bool cmFileCommand::HandleRemove(std::vector const& args, bool recurse) diff --git a/Source/cmFileCommand.h b/Source/cmFileCommand.h index 656ad96e7..925785564 100644 --- a/Source/cmFileCommand.h +++ b/Source/cmFileCommand.h @@ -78,6 +78,7 @@ public: " file(GLOB variable [RELATIVE path] [globbing expressions]...)\n" " file(GLOB_RECURSE variable [RELATIVE path] \n" " [FOLLOW_SYMLINKS] [globbing expressions]...)\n" + " file(RENAME )\n" " file(REMOVE [file1 ...])\n" " file(REMOVE_RECURSE [file1 ...])\n" " file(MAKE_DIRECTORY [directory1 directory2 ...])\n" @@ -133,6 +134,9 @@ public: " /dir/*.py - match all python files in /dir and subdirectories\n" "MAKE_DIRECTORY will create the given directories, also if their parent " "directories don't exist yet\n" + "RENAME moves a file or directory within a filesystem, " + "replacing the destination atomically." + "\n" "REMOVE will remove the given files, also in subdirectories\n" "REMOVE_RECURSE will remove the given files and directories, also " "non-empty directories\n" @@ -159,6 +163,7 @@ public: cmTypeMacro(cmFileCommand, cmCommand); protected: + bool HandleRename(std::vector const& args); bool HandleRemove(std::vector const& args, bool recurse); bool HandleWriteCommand(std::vector const& args, bool append); bool HandleReadCommand(std::vector const& args); diff --git a/Tests/StringFileTest/CMakeLists.txt b/Tests/StringFileTest/CMakeLists.txt index f2789e623..b50d20325 100644 --- a/Tests/StringFileTest/CMakeLists.txt +++ b/Tests/StringFileTest/CMakeLists.txt @@ -184,7 +184,9 @@ SET(infile "${infile+-/out}") # Write include file to a file STRING(REGEX REPLACE "includefile" "${file}" outfile "${infile}") -FILE(WRITE "${CMAKE_CURRENT_BINARY_DIR}/OutputFile.h" "${outfile}") +FILE(WRITE "${CMAKE_CURRENT_BINARY_DIR}/OutputFile.h-tmp" "${outfile}") +FILE(RENAME "${CMAKE_CURRENT_BINARY_DIR}/OutputFile.h-tmp" + "${CMAKE_CURRENT_BINARY_DIR}/OutputFile.h") # Test file glob FILE(GLOB_RECURSE src_files "${CMAKE_CURRENT_SOURCE_DIR}/*")