From 7c516f7e28813a1ed66a4fd0a94d8a56b611eeef Mon Sep 17 00:00:00 2001 From: Craig Scott Date: Fri, 31 May 2024 21:20:30 +1000 Subject: file(): TOUCH, TOUCH_NOCREATE and MAKE_DIRECTORY accept empty lists Projects may be generating a list of files or directories to pass as arguments to file(TOUCH), file(TOUCH_NOCREATE), or file(MAKE_DIRECTORY). Those lists might end up being empty, so rather than requiring at least one item, allow an empty list. Fixes: #24897 --- Help/command/file.rst | 8 ++++++++ Source/cmFileCommand.cxx | 25 +++++++++++++++-------- Tests/CMakeTests/FileTest.cmake.in | 4 ++-- Tests/RunCMake/file/LOCK-error-no-path-stderr.txt | 2 +- Tests/RunCMake/file/TOUCH-result.txt | 1 - Tests/RunCMake/file/TOUCH-stderr.txt | 9 -------- Tests/RunCMake/file/TOUCH.cmake | 1 + 7 files changed, 29 insertions(+), 21 deletions(-) delete mode 100644 Tests/RunCMake/file/TOUCH-result.txt delete mode 100644 Tests/RunCMake/file/TOUCH-stderr.txt diff --git a/Help/command/file.rst b/Help/command/file.rst index ef49faa..5b9dfac 100644 --- a/Help/command/file.rst +++ b/Help/command/file.rst @@ -192,6 +192,10 @@ Writing With ``TOUCH`` and ``TOUCH_NOCREATE``, the contents of an existing file will not be modified. + .. versionchanged:: 3.30 + ```` can be an empty list. CMake 3.29 and earlier required + at least one file to be given. + .. signature:: file(GENERATE [...]) @@ -398,6 +402,10 @@ Filesystem Create the given directories and their parents as needed. + .. versionchanged:: 3.30 + ```` can be an empty list. CMake 3.29 and earlier required + at least one directory to be given. + .. signature:: file(REMOVE ...) file(REMOVE_RECURSE ...) diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx index 0369051..77f740b 100644 --- a/Source/cmFileCommand.cxx +++ b/Source/cmFileCommand.cxx @@ -73,6 +73,11 @@ namespace { bool HandleWriteImpl(std::vector const& args, bool append, cmExecutionStatus& status) { + if (args.size() < 2) { + status.SetError(cmStrCat( + args[0], " must be called with at least one additional argument.")); + return false; + } auto i = args.begin(); i++; // Get rid of subcommand @@ -658,8 +663,11 @@ bool HandleStringsCommand(std::vector const& args, bool HandleGlobImpl(std::vector const& args, bool recurse, cmExecutionStatus& status) { - // File commands has at least one argument - assert(args.size() > 1); + if (args.size() < 2) { + status.SetError(cmStrCat( + args[0], " must be called with at least one additional argument.")); + return false; + } auto i = args.begin(); @@ -869,8 +877,8 @@ bool HandleGlobRecurseCommand(std::vector const& args, bool HandleMakeDirectoryCommand(std::vector const& args, cmExecutionStatus& status) { - // File command has at least one argument - assert(args.size() > 1); + // Projects might pass a dynamically generated list of directories, and it + // could be an empty list. We should not assume there is at least one. std::string expr; for (std::string const& arg : @@ -903,8 +911,8 @@ bool HandleMakeDirectoryCommand(std::vector const& args, bool HandleTouchImpl(std::vector const& args, bool create, cmExecutionStatus& status) { - // File command has at least one argument - assert(args.size() > 1); + // Projects might pass a dynamically generated list of files, and it + // could be an empty list. We should not assume there is at least one. for (std::string const& arg : cmMakeRange(args).advance(1)) // Get rid of subcommand @@ -3918,8 +3926,9 @@ bool HandleChmodRecurseCommand(std::vector const& args, bool cmFileCommand(std::vector const& args, cmExecutionStatus& status) { - if (args.size() < 2) { - status.SetError("must be called with at least two arguments."); + if (args.empty()) { + status.SetError( + "given no arguments, but it requires at least a sub-command."); return false; } diff --git a/Tests/CMakeTests/FileTest.cmake.in b/Tests/CMakeTests/FileTest.cmake.in index 71cb3db..7b76700 100644 --- a/Tests/CMakeTests/FileTest.cmake.in +++ b/Tests/CMakeTests/FileTest.cmake.in @@ -13,13 +13,13 @@ set(Copy-NoDest-STDERR "given no DESTINATION") set(Copy-NoFile-RESULT 1) set(Copy-NoFile-STDERR "COPY cannot find.*/does_not_exist\\.txt") set(Glob-NoArg-RESULT 1) -set(Glob-NoArg-STDERR "file must be called with at least two arguments") +set(Glob-NoArg-STDERR "file GLOB must be called with at least one additional argument\\.") set(Make_Directory-NoArg-RESULT 1) set(Make-Directory-NoArg-STDERR "file must be called with at least two arguments") set(MD5-NoFile-RESULT 1) set(MD5-NoFile-STDERR "file MD5 failed to read file") set(MD5-BadArg1-RESULT 1) -set(MD5-BadArg1-STDERR "file must be called with at least two arguments") +set(MD5-BadArg1-STDERR "file MD5 requires a file name and output variable") set(MD5-BadArg2-RESULT 1) set(MD5-BadArg2-STDERR "file MD5 requires a file name and output variable") set(MD5-BadArg4-RESULT 1) diff --git a/Tests/RunCMake/file/LOCK-error-no-path-stderr.txt b/Tests/RunCMake/file/LOCK-error-no-path-stderr.txt index 2247aa6..6d70016 100644 --- a/Tests/RunCMake/file/LOCK-error-no-path-stderr.txt +++ b/Tests/RunCMake/file/LOCK-error-no-path-stderr.txt @@ -1,4 +1,4 @@ CMake Error at LOCK-error-no-path.cmake:[0-9]+ \(file\): - file must be called with at least two arguments. + sub-command LOCK requires at least two arguments\. Call Stack \(most recent call first\): CMakeLists.txt:[0-9]+ \(include\) diff --git a/Tests/RunCMake/file/TOUCH-result.txt b/Tests/RunCMake/file/TOUCH-result.txt deleted file mode 100644 index d00491f..0000000 --- a/Tests/RunCMake/file/TOUCH-result.txt +++ /dev/null @@ -1 +0,0 @@ -1 diff --git a/Tests/RunCMake/file/TOUCH-stderr.txt b/Tests/RunCMake/file/TOUCH-stderr.txt deleted file mode 100644 index 9f31676..0000000 --- a/Tests/RunCMake/file/TOUCH-stderr.txt +++ /dev/null @@ -1,9 +0,0 @@ -^CMake Error at TOUCH\.cmake:[0-9]+ \(file\): - file must be called with at least two arguments\. -Call Stack \(most recent call first\): - CMakeLists\.txt:[0-9]+ \(include\) -+ -CMake Error at TOUCH\.cmake:[0-9]+ \(file\): - file must be called with at least two arguments\. -Call Stack \(most recent call first\): - CMakeLists\.txt:[0-9]+ \(include\) diff --git a/Tests/RunCMake/file/TOUCH.cmake b/Tests/RunCMake/file/TOUCH.cmake index 8931eb5..c92a962 100644 --- a/Tests/RunCMake/file/TOUCH.cmake +++ b/Tests/RunCMake/file/TOUCH.cmake @@ -12,5 +12,6 @@ if(NOT EXISTS "${file}") endif() file(REMOVE "${file}") +# Empty arguments used to be an error, but this is valid since CMake 3.30 file(TOUCH) file(TOUCH_NOCREATE) -- cgit v0.12