diff options
author | Johnny Jazeix <jazeix@gmail.com> | 2020-10-13 21:48:12 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2020-10-14 16:08:07 (GMT) |
commit | f7a5f283188c1e51b0fb549f0a78afaf1d570383 (patch) | |
tree | c5fade762b9cada9b7fd9cf964528c43ccd45c80 /Source | |
parent | 90b39a52090e6ba52424b441d5827b2b6e11ff56 (diff) | |
download | CMake-f7a5f283188c1e51b0fb549f0a78afaf1d570383.zip CMake-f7a5f283188c1e51b0fb549f0a78afaf1d570383.tar.gz CMake-f7a5f283188c1e51b0fb549f0a78afaf1d570383.tar.bz2 |
cmake: Fix '-E cat' command for binary files on Windows
Reset `std::cout` to write in binary mode with no encoding conversions.
Co-Author: Brad King <brad.king@kitware.com>
Fixes: #21295
Diffstat (limited to 'Source')
-rw-r--r-- | Source/cmakemain.cxx | 13 | ||||
-rw-r--r-- | Source/cmcmd.cxx | 14 | ||||
-rw-r--r-- | Source/cmcmd.h | 6 |
3 files changed, 26 insertions, 7 deletions
diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx index eb44329..7e589c0 100644 --- a/Source/cmakemain.cxx +++ b/Source/cmakemain.cxx @@ -9,8 +9,10 @@ #include <cstring> #include <iostream> #include <string> +#include <utility> #include <vector> +#include <cm/memory> #include <cmext/algorithm> #include <cm3p/uv.h> @@ -107,13 +109,14 @@ const char* cmDocumentationOptions[][2] = { #endif -int do_command(int ac, char const* const* av) +int do_command(int ac, char const* const* av, + std::unique_ptr<cmConsoleBuf> consoleBuf) { std::vector<std::string> args; args.reserve(ac - 1); args.emplace_back(av[0]); cm::append(args, av + 2, av + ac); - return cmcmd::ExecuteCMakeCommand(args); + return cmcmd::ExecuteCMakeCommand(args, std::move(consoleBuf)); } cmMakefile* cmakemainGetMakefile(cmake* cm) @@ -687,8 +690,8 @@ int main(int ac, char const* const* av) cmSystemTools::EnsureStdPipes(); // Replace streambuf so we can output Unicode to console - cmConsoleBuf consoleBuf; - consoleBuf.SetUTF8Pipes(); + auto consoleBuf = cm::make_unique<cmConsoleBuf>(); + consoleBuf->SetUTF8Pipes(); cmsys::Encoding::CommandLineArguments args = cmsys::Encoding::CommandLineArguments::Main(ac, av); @@ -708,7 +711,7 @@ int main(int ac, char const* const* av) return do_open(ac, av); } if (strcmp(av[1], "-E") == 0) { - return do_command(ac, av); + return do_command(ac, av, std::move(consoleBuf)); } } int ret = do_cmake(ac, av); diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx index 150fefd..a1fafcb 100644 --- a/Source/cmcmd.cxx +++ b/Source/cmcmd.cxx @@ -48,6 +48,12 @@ #include <sstream> #include <utility> +#ifdef _WIN32 +# include <fcntl.h> // for _O_BINARY +# include <io.h> // for _setmode +# include <stdio.h> // for std{out,err} and fileno +#endif + #include <cm/string_view> #include "cmsys/Directory.hxx" @@ -178,6 +184,9 @@ static bool cmTarFilesFrom(std::string const& file, static void cmCatFile(const std::string& fileToAppend) { +#ifdef _WIN32 + _setmode(fileno(stdout), _O_BINARY); +#endif cmsys::ifstream source(fileToAppend.c_str(), (std::ios::binary | std::ios::in)); std::cout << source.rdbuf(); @@ -497,7 +506,8 @@ int cmcmd::HandleCoCompileCommands(std::vector<std::string> const& args) return ret; } -int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args) +int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args, + std::unique_ptr<cmConsoleBuf> consoleBuf) { // IF YOU ADD A NEW COMMAND, DOCUMENT IT ABOVE and in cmakemain.cxx if (args.size() > 1) { @@ -951,6 +961,8 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args) cmSystemTools::Error(arg + ": no such file or directory (ignoring)"); return_value = 1; } else { + // Destroy console buffers to drop cout/cerr encoding transform. + consoleBuf.reset(); cmCatFile(arg); } } diff --git a/Source/cmcmd.h b/Source/cmcmd.h index 5b6c813..ffadd5a 100644 --- a/Source/cmcmd.h +++ b/Source/cmcmd.h @@ -5,11 +5,14 @@ #include "cmConfigure.h" // IWYU pragma: keep +#include <memory> #include <string> #include <vector> #include "cmCryptoHash.h" +class cmConsoleBuf; + class cmcmd { public: @@ -17,7 +20,8 @@ public: * Execute commands during the build process. Supports options such * as echo, remove file etc. */ - static int ExecuteCMakeCommand(std::vector<std::string> const&); + static int ExecuteCMakeCommand(std::vector<std::string> const&, + std::unique_ptr<cmConsoleBuf> consoleBuf); protected: static int HandleCoCompileCommands(std::vector<std::string> const& args); |