summaryrefslogtreecommitdiffstats
path: root/Source/cmFileCommand.cxx
diff options
context:
space:
mode:
authorBen Boeckel <ben.boeckel@kitware.com>2021-03-04 16:50:10 (GMT)
committerBen Boeckel <ben.boeckel@kitware.com>2021-03-10 15:43:18 (GMT)
commit088444211e942a3587f4af5ef76c3654f2562364 (patch)
treefa5bd94beead2050d900e7c2341dc27899b2733e /Source/cmFileCommand.cxx
parent100016e9cb31aad7b642a9733409c7294cd6652f (diff)
downloadCMake-088444211e942a3587f4af5ef76c3654f2562364.zip
CMake-088444211e942a3587f4af5ef76c3654f2562364.tar.gz
CMake-088444211e942a3587f4af5ef76c3654f2562364.tar.bz2
file: add `COPY_FILE` subcommand
The `file(COPY)` subcommand is overloaded and busy for such a simple operation. Instead, make a simpler subcommand with error handling support.
Diffstat (limited to 'Source/cmFileCommand.cxx')
-rw-r--r--Source/cmFileCommand.cxx92
1 files changed, 92 insertions, 0 deletions
diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx
index 065b845..1c73d0d 100644
--- a/Source/cmFileCommand.cxx
+++ b/Source/cmFileCommand.cxx
@@ -1379,6 +1379,97 @@ bool HandleRename(std::vector<std::string> const& args,
return false;
}
+bool HandleCopyFile(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
+{
+ if (args.size() < 3) {
+ status.SetError("COPY_FILE must be called with at least two additional "
+ "arguments");
+ return false;
+ }
+
+ // Compute full path for old and new names.
+ std::string oldname = args[1];
+ if (!cmsys::SystemTools::FileIsFullPath(oldname)) {
+ oldname =
+ cmStrCat(status.GetMakefile().GetCurrentSourceDirectory(), '/', args[1]);
+ }
+ std::string newname = args[2];
+ if (!cmsys::SystemTools::FileIsFullPath(newname)) {
+ newname =
+ cmStrCat(status.GetMakefile().GetCurrentSourceDirectory(), '/', args[2]);
+ }
+
+ struct Arguments
+ {
+ bool OnlyIfDifferent = false;
+ std::string Result;
+ };
+
+ static auto const parser =
+ cmArgumentParser<Arguments>{}
+ .Bind("ONLY_IF_DIFFERENT"_s, &Arguments::OnlyIfDifferent)
+ .Bind("RESULT"_s, &Arguments::Result);
+
+ std::vector<std::string> unconsumedArgs;
+ Arguments const arguments =
+ parser.Parse(cmMakeRange(args).advance(3), &unconsumedArgs);
+ if (!unconsumedArgs.empty()) {
+ status.SetError("COPY_FILE unknown argument:\n " +
+ unconsumedArgs.front());
+ return false;
+ }
+
+ bool result = true;
+ if (cmsys::SystemTools::FileIsDirectory(oldname)) {
+ if (!arguments.Result.empty()) {
+ status.GetMakefile().AddDefinition(arguments.Result,
+ "cannot copy a directory");
+ } else {
+ status.SetError(
+ cmStrCat("COPY_FILE cannot copy a directory\n ", oldname));
+ result = false;
+ }
+ return result;
+ }
+ if (cmsys::SystemTools::FileIsDirectory(newname)) {
+ if (!arguments.Result.empty()) {
+ status.GetMakefile().AddDefinition(arguments.Result,
+ "cannot copy to a directory");
+ } else {
+ status.SetError(
+ cmStrCat("COPY_FILE cannot copy to a directory\n ", newname));
+ result = false;
+ }
+ return result;
+ }
+
+ cmSystemTools::CopyWhen when;
+ if (arguments.OnlyIfDifferent) {
+ when = cmSystemTools::CopyWhen::OnlyIfDifferent;
+ } else {
+ when = cmSystemTools::CopyWhen::Always;
+ }
+
+ std::string err;
+ if (cmSystemTools::CopySingleFile(oldname, newname, when, &err) ==
+ cmSystemTools::CopyResult::Success) {
+ if (!arguments.Result.empty()) {
+ status.GetMakefile().AddDefinition(arguments.Result, "0");
+ }
+ } else {
+ if (!arguments.Result.empty()) {
+ status.GetMakefile().AddDefinition(arguments.Result, err);
+ } else {
+ status.SetError(cmStrCat("COPY_FILE failed to copy\n ", oldname,
+ "\nto\n ", newname, "\nbecause: ", err, "\n"));
+ result = false;
+ }
+ }
+
+ return result;
+}
+
bool HandleRemoveImpl(std::vector<std::string> const& args, bool recurse,
cmExecutionStatus& status)
{
@@ -3609,6 +3700,7 @@ bool cmFileCommand(std::vector<std::string> const& args,
{ "GLOB_RECURSE"_s, HandleGlobRecurseCommand },
{ "MAKE_DIRECTORY"_s, HandleMakeDirectoryCommand },
{ "RENAME"_s, HandleRename },
+ { "COPY_FILE"_s, HandleCopyFile },
{ "REMOVE"_s, HandleRemove },
{ "REMOVE_RECURSE"_s, HandleRemoveRecurse },
{ "COPY"_s, HandleCopyCommand },