diff --git a/Help/manual/cmake.1.rst b/Help/manual/cmake.1.rst index 5223acb5f1..15ae6ea467 100644 --- a/Help/manual/cmake.1.rst +++ b/Help/manual/cmake.1.rst @@ -891,6 +891,10 @@ Available commands are: ``-`` will result in an error. Use ``--`` to indicate the end of options, in case a file starts with ``-``. + .. versionadded:: 3.29 + + ``cat`` can now print the standard input by passing the ``-`` argument. + .. program:: cmake-E .. option:: chdir [...] diff --git a/Help/release/dev/cmake-E-cat-stdin.rst b/Help/release/dev/cmake-E-cat-stdin.rst new file mode 100644 index 0000000000..43a8aedea9 --- /dev/null +++ b/Help/release/dev/cmake-E-cat-stdin.rst @@ -0,0 +1,5 @@ +cmake-E-cat-stdin +----------------- + +* :manual:`cmake(1)` :option:`-E cat ` can now print the standard + input by passing the ``-`` argument. diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx index 43a945f2ed..93b008694e 100644 --- a/Source/cmcmd.cxx +++ b/Source/cmcmd.cxx @@ -203,11 +203,16 @@ bool cmTarFilesFrom(std::string const& file, std::vector& files) void cmCatFile(const std::string& fileToAppend) { #ifdef _WIN32 + _setmode(fileno(stdin), _O_BINARY); _setmode(fileno(stdout), _O_BINARY); #endif - cmsys::ifstream source(fileToAppend.c_str(), - (std::ios::binary | std::ios::in)); - std::cout << source.rdbuf(); + std::streambuf* buf = std::cin.rdbuf(); + cmsys::ifstream source; + if (fileToAppend != "-") { + source.open(fileToAppend.c_str(), (std::ios::binary | std::ios::in)); + buf = source.rdbuf(); + } + std::cout << buf; } bool cmRemoveDirectory(const std::string& dir, bool recursive = true) @@ -1147,7 +1152,12 @@ int cmcmd::ExecuteCMakeCommand(std::vector const& args, int return_value = 0; bool doing_options = true; for (auto const& arg : cmMakeRange(args).advance(2)) { - if (doing_options && cmHasLiteralPrefix(arg, "-")) { + if (arg == "-") { + doing_options = false; + // Destroy console buffers to drop cout/cerr encoding transform. + consoleBuf.reset(); + cmCatFile(arg); + } else if (doing_options && cmHasLiteralPrefix(arg, "-")) { if (arg == "--") { doing_options = false; } else { diff --git a/Tests/RunCMake/CommandLine/E_cat-stdin-stdout.txt b/Tests/RunCMake/CommandLine/E_cat-stdin-stdout.txt new file mode 100644 index 0000000000..8210d59ac0 --- /dev/null +++ b/Tests/RunCMake/CommandLine/E_cat-stdin-stdout.txt @@ -0,0 +1 @@ +^Hello world$ diff --git a/Tests/RunCMake/CommandLine/E_cat-stdin.cmake b/Tests/RunCMake/CommandLine/E_cat-stdin.cmake new file mode 100644 index 0000000000..e83e6194d3 --- /dev/null +++ b/Tests/RunCMake/CommandLine/E_cat-stdin.cmake @@ -0,0 +1,10 @@ +file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/ell.txt" "ell") +file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/rld.txt" "rld") +execute_process( + COMMAND ${CMAKE_COMMAND} -E echo_append "H" + COMMAND ${CMAKE_COMMAND} -E cat - + ) +execute_process( + COMMAND ${CMAKE_COMMAND} -E echo_append "o wo" + COMMAND ${CMAKE_COMMAND} -E cat "${CMAKE_CURRENT_BINARY_DIR}/ell.txt" - "${CMAKE_CURRENT_BINARY_DIR}/rld.txt" + ) diff --git a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake index 52be1bbd8a..6d4e0e2087 100644 --- a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake +++ b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake @@ -782,6 +782,8 @@ run_cmake_command(E_cat-without-double-dash ${CMAKE_COMMAND} -E cat "-file-start unset(RunCMake_TEST_COMMAND_WORKING_DIRECTORY) unset(out) +run_cmake_command(E_cat-stdin ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/E_cat-stdin.cmake) + # Unset environment variables that are used for testing cmake -E unset(ENV{TEST_ENV}) unset(ENV{TEST_ENV_EXPECTED})