Browse Source

cmake -E: add cat command.

Concatenate files and print on the standard output.

FIXES: #20557
pull/333/head
Johnny Jazeix 5 years ago
parent
commit
a625f30785
  1. 3
      Help/manual/cmake.1.rst
  2. 5
      Help/release/dev/command-line-cat.rst
  3. 35
      Source/cmcmd.cxx
  4. 1
      Tests/RunCMake/CommandLine/E_cat_directory-result.txt
  5. 1
      Tests/RunCMake/CommandLine/E_cat_directory-stderr.txt
  6. 3
      Tests/RunCMake/CommandLine/E_cat_good_cat-stdout.txt
  7. 1
      Tests/RunCMake/CommandLine/E_cat_non_existing_file-result.txt
  8. 1
      Tests/RunCMake/CommandLine/E_cat_non_existing_file-stderr.txt
  9. 1
      Tests/RunCMake/CommandLine/E_cat_non_readable_file-result.txt
  10. 1
      Tests/RunCMake/CommandLine/E_cat_non_readable_file-stderr.txt
  11. 1
      Tests/RunCMake/CommandLine/E_cat_option_not_handled-result.txt
  12. 1
      Tests/RunCMake/CommandLine/E_cat_option_not_handled-stderr.txt
  13. 38
      Tests/RunCMake/CommandLine/RunCMakeTest.cmake

3
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.

5
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.

35
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];

1
Tests/RunCMake/CommandLine/E_cat_directory-result.txt

@ -0,0 +1 @@
1

1
Tests/RunCMake/CommandLine/E_cat_directory-stderr.txt

@ -0,0 +1 @@
^CMake Error: .* is a directory

3
Tests/RunCMake/CommandLine/E_cat_good_cat-stdout.txt

@ -0,0 +1,3 @@
first file to append
second file to append
àéùç - 한국어

1
Tests/RunCMake/CommandLine/E_cat_non_existing_file-result.txt

@ -0,0 +1 @@
1

1
Tests/RunCMake/CommandLine/E_cat_non_existing_file-stderr.txt

@ -0,0 +1 @@
^CMake Error: .*: no such file or directory \(ignoring\)

1
Tests/RunCMake/CommandLine/E_cat_non_readable_file-result.txt

@ -0,0 +1 @@
1

1
Tests/RunCMake/CommandLine/E_cat_non_readable_file-stderr.txt

@ -0,0 +1 @@
^CMake Error: .*: permission denied \(ignoring\)

1
Tests/RunCMake/CommandLine/E_cat_option_not_handled-result.txt

@ -0,0 +1 @@
1

1
Tests/RunCMake/CommandLine/E_cat_option_not_handled-stderr.txt

@ -0,0 +1 @@
^CMake Error: -f: option not handled

38
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)

Loading…
Cancel
Save