summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKyle Edwards <kyle.edwards@kitware.com>2020-04-16 15:35:45 (GMT)
committerKitware Robot <kwrobot@kitware.com>2020-04-16 15:35:55 (GMT)
commit5f20e854122e19ed867ea3edf32d41cf6e8f3be0 (patch)
tree119cbfbbdcba694dd57c556b1d628fbdb73b8f89
parent7e8df1bb24dcde30d1baafb23f6ab26352e67763 (diff)
parenta625f30785130586a7d2a59c13a7526eab8b3086 (diff)
downloadCMake-5f20e854122e19ed867ea3edf32d41cf6e8f3be0.zip
CMake-5f20e854122e19ed867ea3edf32d41cf6e8f3be0.tar.gz
CMake-5f20e854122e19ed867ea3edf32d41cf6e8f3be0.tar.bz2
Merge topic 'cat_cmd_20557'
a625f30785 cmake -E: add cat command. Acked-by: Kitware Robot <kwrobot@kitware.com> Merge-request: !4600
-rw-r--r--Help/manual/cmake.1.rst3
-rw-r--r--Help/release/dev/command-line-cat.rst5
-rw-r--r--Source/cmcmd.cxx35
-rw-r--r--Tests/RunCMake/CommandLine/E_cat_directory-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_cat_directory-stderr.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_cat_good_cat-stdout.txt3
-rw-r--r--Tests/RunCMake/CommandLine/E_cat_non_existing_file-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_cat_non_existing_file-stderr.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_cat_non_readable_file-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_cat_non_readable_file-stderr.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_cat_option_not_handled-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_cat_option_not_handled-stderr.txt1
-rw-r--r--Tests/RunCMake/CommandLine/RunCMakeTest.cmake38
13 files changed, 92 insertions, 0 deletions
diff --git a/Help/manual/cmake.1.rst b/Help/manual/cmake.1.rst
index 9a43499..e3e965c 100644
--- a/Help/manual/cmake.1.rst
+++ b/Help/manual/cmake.1.rst
@@ -554,6 +554,9 @@ Available commands are:
``serverMode``
``true`` if cmake supports server-mode and ``false`` otherwise.
+``cat <files>...``
+ Concatenate files and print on the standard output.
+
``chdir <dir> <cmd> [<arg>...]``
Change the current working directory and run a command.
diff --git a/Help/release/dev/command-line-cat.rst b/Help/release/dev/command-line-cat.rst
new file mode 100644
index 0000000..acde835
--- /dev/null
+++ b/Help/release/dev/command-line-cat.rst
@@ -0,0 +1,5 @@
+Command-Line
+------------
+* :manual:`cmake(1)` gained a ``cat`` command line
+ option that can be used to concatenate files and print them
+ on standard output.
diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx
index 49d04a6..67a5d92 100644
--- a/Source/cmcmd.cxx
+++ b/Source/cmcmd.cxx
@@ -90,6 +90,7 @@ void CMakeCommandUsage(const char* program)
<< "Available commands: \n"
<< " capabilities - Report capabilities built into cmake "
"in JSON format\n"
+ << " cat <files>... - concat the files and print them to the standard output\n"
<< " chdir dir cmd [args...] - run command in a given directory\n"
<< " compare_files [--ignore-eol] file1 file2\n"
<< " - check if file1 is same as file2\n"
@@ -180,6 +181,13 @@ static bool cmTarFilesFrom(std::string const& file,
return true;
}
+static void cmCatFile(const std::string& fileToAppend)
+{
+ cmsys::ifstream source(fileToAppend.c_str(),
+ (std::ios::binary | std::ios::in));
+ std::cout << source.rdbuf();
+}
+
static bool cmRemoveDirectory(const std::string& dir, bool recursive = true)
{
if (cmSystemTools::FileIsSymlink(dir)) {
@@ -927,6 +935,33 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args)
return HashSumFile(args, cmCryptoHash::AlgoSHA512);
}
+ // Command to concat files into one
+ if (args[1] == "cat" && args.size() >= 3) {
+ int return_value = 0;
+ for (auto const& arg : cmMakeRange(args).advance(2)) {
+ if (cmHasLiteralPrefix(arg, "-")) {
+ if (arg != "--") {
+ cmSystemTools::Error(arg + ": option not handled");
+ return_value = 1;
+ }
+ } else if (!cmSystemTools::TestFileAccess(arg,
+ cmsys::TEST_FILE_READ) &&
+ cmSystemTools::TestFileAccess(arg, cmsys::TEST_FILE_OK)) {
+ cmSystemTools::Error(arg + ": permission denied (ignoring)");
+ return_value = 1;
+ } else if (cmSystemTools::FileIsDirectory(arg)) {
+ cmSystemTools::Error(arg + ": is a directory (ignoring)");
+ return_value = 1;
+ } else if (!cmSystemTools::FileExists(arg)) {
+ cmSystemTools::Error(arg + ": no such file or directory (ignoring)");
+ return_value = 1;
+ } else {
+ cmCatFile(arg);
+ }
+ }
+ return return_value;
+ }
+
// Command to change directory and run a program.
if (args[1] == "chdir" && args.size() >= 4) {
std::string const& directory = args[2];
diff --git a/Tests/RunCMake/CommandLine/E_cat_directory-result.txt b/Tests/RunCMake/CommandLine/E_cat_directory-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_cat_directory-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/E_cat_directory-stderr.txt b/Tests/RunCMake/CommandLine/E_cat_directory-stderr.txt
new file mode 100644
index 0000000..c4d0d48
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_cat_directory-stderr.txt
@@ -0,0 +1 @@
+^CMake Error: .* is a directory
diff --git a/Tests/RunCMake/CommandLine/E_cat_good_cat-stdout.txt b/Tests/RunCMake/CommandLine/E_cat_good_cat-stdout.txt
new file mode 100644
index 0000000..aae90e6
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_cat_good_cat-stdout.txt
@@ -0,0 +1,3 @@
+first file to append
+second file to append
+àéùç - 한국어
diff --git a/Tests/RunCMake/CommandLine/E_cat_non_existing_file-result.txt b/Tests/RunCMake/CommandLine/E_cat_non_existing_file-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_cat_non_existing_file-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/E_cat_non_existing_file-stderr.txt b/Tests/RunCMake/CommandLine/E_cat_non_existing_file-stderr.txt
new file mode 100644
index 0000000..0d8fc4b
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_cat_non_existing_file-stderr.txt
@@ -0,0 +1 @@
+^CMake Error: .*: no such file or directory \(ignoring\)
diff --git a/Tests/RunCMake/CommandLine/E_cat_non_readable_file-result.txt b/Tests/RunCMake/CommandLine/E_cat_non_readable_file-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_cat_non_readable_file-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/E_cat_non_readable_file-stderr.txt b/Tests/RunCMake/CommandLine/E_cat_non_readable_file-stderr.txt
new file mode 100644
index 0000000..97ec822
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_cat_non_readable_file-stderr.txt
@@ -0,0 +1 @@
+^CMake Error: .*: permission denied \(ignoring\)
diff --git a/Tests/RunCMake/CommandLine/E_cat_option_not_handled-result.txt b/Tests/RunCMake/CommandLine/E_cat_option_not_handled-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_cat_option_not_handled-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/E_cat_option_not_handled-stderr.txt b/Tests/RunCMake/CommandLine/E_cat_option_not_handled-stderr.txt
new file mode 100644
index 0000000..92f7acf
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_cat_option_not_handled-stderr.txt
@@ -0,0 +1 @@
+^CMake Error: -f: option not handled
diff --git a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
index 839aec0..0f806bc 100644
--- a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
@@ -459,6 +459,44 @@ if(NOT WIN32 AND NOT CYGWIN)
endif()
unset(out)
+# cat tests
+set(out ${RunCMake_BINARY_DIR}/cat_tests)
+file(REMOVE_RECURSE "${out}")
+file(MAKE_DIRECTORY ${out})
+run_cmake_command(E_cat_non_existing_file
+ ${CMAKE_COMMAND} -E cat ${out}/non-existing-file.txt)
+
+if(UNIX)
+ # test non readable file only if not root
+ execute_process(
+ COMMAND id -u $ENV{USER}
+ OUTPUT_VARIABLE uid
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+ if(NOT "${uid}" STREQUAL "0")
+ # Create non readable file
+ set(inside_folder "${out}/in")
+ file(MAKE_DIRECTORY ${inside_folder})
+ file(WRITE "${inside_folder}/non_readable_file.txt" "first file to append\n")
+ file(COPY "${inside_folder}/non_readable_file.txt" DESTINATION "${out}" FILE_PERMISSIONS OWNER_WRITE)
+ run_cmake_command(E_cat_non_readable_file
+ ${CMAKE_COMMAND} -E cat "${out}/non_readable_file.txt")
+ endif()
+endif()
+
+run_cmake_command(E_cat_option_not_handled
+ ${CMAKE_COMMAND} -E cat -f)
+
+run_cmake_command(E_cat_directory
+ ${CMAKE_COMMAND} -E cat ${out})
+
+file(WRITE "${out}/first_file.txt" "first file to append\n")
+file(WRITE "${out}/second_file.txt" "second file to append\n")
+file(WRITE "${out}/unicode_file.txt" "àéùç - 한국어") # Korean in Korean
+run_cmake_command(E_cat_good_cat
+ ${CMAKE_COMMAND} -E cat "${out}/first_file.txt" "${out}/second_file.txt" "${out}/unicode_file.txt")
+unset(out)
+
run_cmake_command(E_env-no-command0 ${CMAKE_COMMAND} -E env)
run_cmake_command(E_env-no-command1 ${CMAKE_COMMAND} -E env TEST_ENV=1)
run_cmake_command(E_env-bad-arg1 ${CMAKE_COMMAND} -E env -bad-arg1)