1
0
Эх сурвалжийг харах

cmake -E *sum: Add ability to read from stdin

Kyle Edwards 1 сар өмнө
parent
commit
394ab1fcfb

+ 18 - 0
Help/manual/cmake.1.rst

@@ -1312,6 +1312,9 @@ Available commands are:
      351abe79cd3800b38cdfb25d45015a15  file1.txt
      351abe79cd3800b38cdfb25d45015a15  file1.txt
      052f86c15bbde68af55c7f7b340ab639  file2.txt
      052f86c15bbde68af55c7f7b340ab639  file2.txt
 
 
+  .. versionchanged:: 4.3
+    Passing ``-`` reads from standard input.
+
 .. option:: sha1sum <file>...
 .. option:: sha1sum <file>...
 
 
   .. versionadded:: 3.10
   .. versionadded:: 3.10
@@ -1321,6 +1324,9 @@ Available commands are:
      4bb7932a29e6f73c97bb9272f2bdc393122f86e0  file1.txt
      4bb7932a29e6f73c97bb9272f2bdc393122f86e0  file1.txt
      1df4c8f318665f9a5f2ed38f55adadb7ef9f559c  file2.txt
      1df4c8f318665f9a5f2ed38f55adadb7ef9f559c  file2.txt
 
 
+  .. versionchanged:: 4.3
+    Passing ``-`` reads from standard input.
+
 .. option:: sha224sum <file>...
 .. option:: sha224sum <file>...
 
 
   .. versionadded:: 3.10
   .. versionadded:: 3.10
@@ -1330,6 +1336,9 @@ Available commands are:
      b9b9346bc8437bbda630b0b7ddfc5ea9ca157546dbbf4c613192f930  file1.txt
      b9b9346bc8437bbda630b0b7ddfc5ea9ca157546dbbf4c613192f930  file1.txt
      6dfbe55f4d2edc5fe5c9197bca51ceaaf824e48eba0cc453088aee24  file2.txt
      6dfbe55f4d2edc5fe5c9197bca51ceaaf824e48eba0cc453088aee24  file2.txt
 
 
+  .. versionchanged:: 4.3
+    Passing ``-`` reads from standard input.
+
 .. option:: sha256sum <file>...
 .. option:: sha256sum <file>...
 
 
   .. versionadded:: 3.10
   .. versionadded:: 3.10
@@ -1339,6 +1348,9 @@ Available commands are:
      76713b23615d31680afeb0e9efe94d47d3d4229191198bb46d7485f9cb191acc  file1.txt
      76713b23615d31680afeb0e9efe94d47d3d4229191198bb46d7485f9cb191acc  file1.txt
      15b682ead6c12dedb1baf91231e1e89cfc7974b3787c1e2e01b986bffadae0ea  file2.txt
      15b682ead6c12dedb1baf91231e1e89cfc7974b3787c1e2e01b986bffadae0ea  file2.txt
 
 
+  .. versionchanged:: 4.3
+    Passing ``-`` reads from standard input.
+
 .. option:: sha384sum <file>...
 .. option:: sha384sum <file>...
 
 
   .. versionadded:: 3.10
   .. versionadded:: 3.10
@@ -1348,6 +1360,9 @@ Available commands are:
      acc049fedc091a22f5f2ce39a43b9057fd93c910e9afd76a6411a28a8f2b8a12c73d7129e292f94fc0329c309df49434  file1.txt
      acc049fedc091a22f5f2ce39a43b9057fd93c910e9afd76a6411a28a8f2b8a12c73d7129e292f94fc0329c309df49434  file1.txt
      668ddeb108710d271ee21c0f3acbd6a7517e2b78f9181c6a2ff3b8943af92b0195dcb7cce48aa3e17893173c0a39e23d  file2.txt
      668ddeb108710d271ee21c0f3acbd6a7517e2b78f9181c6a2ff3b8943af92b0195dcb7cce48aa3e17893173c0a39e23d  file2.txt
 
 
+  .. versionchanged:: 4.3
+    Passing ``-`` reads from standard input.
+
 .. option:: sha512sum <file>...
 .. option:: sha512sum <file>...
 
 
   .. versionadded:: 3.10
   .. versionadded:: 3.10
@@ -1357,6 +1372,9 @@ Available commands are:
      2a78d7a6c5328cfb1467c63beac8ff21794213901eaadafd48e7800289afbc08e5fb3e86aa31116c945ee3d7bf2a6194489ec6101051083d1108defc8e1dba89  file1.txt
      2a78d7a6c5328cfb1467c63beac8ff21794213901eaadafd48e7800289afbc08e5fb3e86aa31116c945ee3d7bf2a6194489ec6101051083d1108defc8e1dba89  file1.txt
      7a0b54896fe5e70cca6dd643ad6f672614b189bf26f8153061c4d219474b05dad08c4e729af9f4b009f1a1a280cb625454bf587c690f4617c27e3aebdf3b7a2d  file2.txt
      7a0b54896fe5e70cca6dd643ad6f672614b189bf26f8153061c4d219474b05dad08c4e729af9f4b009f1a1a280cb625454bf587c690f4617c27e3aebdf3b7a2d  file2.txt
 
 
+  .. versionchanged:: 4.3
+    Passing ``-`` reads from standard input.
+
 .. option:: remove [-f] <file>...
 .. option:: remove [-f] <file>...
 
 
   .. deprecated:: 3.17
   .. deprecated:: 3.17

+ 6 - 0
Help/release/dev/E_sum-stdin.rst

@@ -0,0 +1,6 @@
+E_sum-stdin
+-----------
+
+* The :manual:`cmake(1)` ``-E`` commands ``md5sum``, ``sha1sum``,
+  ``sha224sum``, ``sha256sum``, ``sha384sum``, and ``sha512sum`` now have the
+  ability to read from standard input by passing ``-``.

+ 17 - 7
Source/cmCryptoHash.cxx

@@ -153,10 +153,9 @@ std::vector<unsigned char> cmCryptoHash::ByteHashString(cm::string_view input)
   return this->Finalize();
   return this->Finalize();
 }
 }
 
 
-std::vector<unsigned char> cmCryptoHash::ByteHashFile(std::string const& file)
+std::vector<unsigned char> cmCryptoHash::ByteHashStream(std::istream& sin)
 {
 {
-  cmsys::ifstream fin(file.c_str(), std::ios::in | std::ios::binary);
-  if (fin) {
+  if (sin) {
     this->Initialize();
     this->Initialize();
     {
     {
       // Should be efficient enough on most system:
       // Should be efficient enough on most system:
@@ -169,14 +168,14 @@ std::vector<unsigned char> cmCryptoHash::ByteHashFile(std::string const& file)
       // incorrect to not check the error condition on the fin.read()
       // incorrect to not check the error condition on the fin.read()
       // before using the data, but the fin.gcount() will be zero if an
       // before using the data, but the fin.gcount() will be zero if an
       // error occurred.  Therefore, the loop should be safe everywhere.
       // error occurred.  Therefore, the loop should be safe everywhere.
-      while (fin) {
-        fin.read(buffer_c, sizeof(buffer));
-        if (int gcount = static_cast<int>(fin.gcount())) {
+      while (sin) {
+        sin.read(buffer_c, sizeof(buffer));
+        if (int gcount = static_cast<int>(sin.gcount())) {
           this->Append(buffer_uc, gcount);
           this->Append(buffer_uc, gcount);
         }
         }
       }
       }
     }
     }
-    if (fin.eof()) {
+    if (sin.eof()) {
       // Success
       // Success
       return this->Finalize();
       return this->Finalize();
     }
     }
@@ -187,11 +186,22 @@ std::vector<unsigned char> cmCryptoHash::ByteHashFile(std::string const& file)
   return std::vector<unsigned char>();
   return std::vector<unsigned char>();
 }
 }
 
 
+std::vector<unsigned char> cmCryptoHash::ByteHashFile(std::string const& file)
+{
+  cmsys::ifstream fin(file.c_str(), std::ios::in | std::ios::binary);
+  return this->ByteHashStream(fin);
+}
+
 std::string cmCryptoHash::HashString(cm::string_view input)
 std::string cmCryptoHash::HashString(cm::string_view input)
 {
 {
   return ByteHashToString(this->ByteHashString(input));
   return ByteHashToString(this->ByteHashString(input));
 }
 }
 
 
+std::string cmCryptoHash::HashStream(std::istream& sin)
+{
+  return ByteHashToString(this->ByteHashStream(sin));
+}
+
 std::string cmCryptoHash::HashFile(std::string const& file)
 std::string cmCryptoHash::HashFile(std::string const& file)
 {
 {
   return ByteHashToString(this->ByteHashFile(file));
   return ByteHashToString(this->ByteHashFile(file));

+ 13 - 0
Source/cmCryptoHash.h

@@ -5,6 +5,7 @@
 #include "cmConfigure.h" // IWYU pragma: keep
 #include "cmConfigure.h" // IWYU pragma: keep
 
 
 #include <cstddef>
 #include <cstddef>
+#include <iostream>
 #include <memory>
 #include <memory>
 #include <string>
 #include <string>
 #include <vector>
 #include <vector>
@@ -58,6 +59,12 @@ public:
   /// @return Binary hash vector
   /// @return Binary hash vector
   std::vector<unsigned char> ByteHashString(cm::string_view input);
   std::vector<unsigned char> ByteHashString(cm::string_view input);
 
 
+  /// @brief Calculates a binary hash from stream content
+  /// @see ByteHashString()
+  /// @return Non empty binary hash vector if the stream was read successfully.
+  ///         An empty vector otherwise.
+  std::vector<unsigned char> ByteHashStream(std::istream& sin);
+
   /// @brief Calculates a binary hash from file content
   /// @brief Calculates a binary hash from file content
   /// @see ByteHashString()
   /// @see ByteHashString()
   /// @return Non empty binary hash vector if the file was read successfully.
   /// @return Non empty binary hash vector if the file was read successfully.
@@ -68,6 +75,12 @@ public:
   /// @return Sequence of hex characters pairs for each byte of the binary hash
   /// @return Sequence of hex characters pairs for each byte of the binary hash
   std::string HashString(cm::string_view input);
   std::string HashString(cm::string_view input);
 
 
+  /// @brief Calculates a hash string from stream content
+  /// @see HashString()
+  /// @return Non empty hash string if the stream was read successfully.
+  ///         An empty string otherwise.
+  std::string HashStream(std::istream& sin);
+
   /// @brief Calculates a hash string from file content
   /// @brief Calculates a hash string from file content
   /// @see HashString()
   /// @see HashString()
   /// @return Non empty hash string if the file was read successfully.
   /// @return Non empty hash string if the file was read successfully.

+ 15 - 2
Source/cmcmd.cxx

@@ -1920,8 +1920,21 @@ int cmcmd::HashSumFile(std::vector<std::string> const& args,
   int retval = 0;
   int retval = 0;
 
 
   for (auto const& filename : cmMakeRange(args).advance(2)) {
   for (auto const& filename : cmMakeRange(args).advance(2)) {
-    // Cannot compute sum of a directory
-    if (cmSystemTools::FileIsDirectory(filename)) {
+    if (filename == "-") {
+#ifdef _WIN32
+      _setmode(fileno(stdin), _O_BINARY);
+#endif
+      cmCryptoHash hasher(algo);
+      std::string value = hasher.HashStream(std::cin);
+      if (value.empty()) {
+        // To mimic "md5sum/shasum" behavior in a shell:
+        std::cerr << filename << ": No such file or directory\n";
+        retval++;
+      } else {
+        std::cout << value << "  " << filename << '\n';
+      }
+    } else if (cmSystemTools::FileIsDirectory(filename)) {
+      // Cannot compute sum of a directory
       std::cerr << "Error: " << filename << " is a directory\n";
       std::cerr << "Error: " << filename << " is a directory\n";
       retval++;
       retval++;
     } else {
     } else {

+ 1 - 0
Tests/RunCMake/CommandLine/E_md5sum-stdin-stdout.txt

@@ -0,0 +1 @@
+275876e34cf609db118f3d84b799a790  -

+ 1 - 0
Tests/RunCMake/CommandLine/E_sha1sum-stdin-stdout.txt

@@ -0,0 +1 @@
+829c3804401b0727f70f73d4415e162400cbe57b  -

+ 1 - 0
Tests/RunCMake/CommandLine/E_sha224sum-stdin-stdout.txt

@@ -0,0 +1 @@
+37d32c6dbabed711cb1d4620b64090fef0ef63ab16a4a51d668259e6  -

+ 1 - 0
Tests/RunCMake/CommandLine/E_sha256sum-stdin-stdout.txt

@@ -0,0 +1 @@
+b5a2c96250612366ea272ffac6d9744aaf4b45aacd96aa7cfcb931ee3b558259  -

+ 1 - 0
Tests/RunCMake/CommandLine/E_sha384sum-stdin-stdout.txt

@@ -0,0 +1 @@
+43c1835ceba2e29596f05e3859d4fe2b6d124a181ed670f68e914bd3ed251b02b4be609608a13f23ec3d98da6c4eb8cd  -

+ 1 - 0
Tests/RunCMake/CommandLine/E_sha512sum-stdin-stdout.txt

@@ -0,0 +1 @@
+1692526aab84461a8aebcefddcba2b33fb5897ab180c53e8b345ae125484d0aaa35baf60487050be21ed8909a48eace93851bf139087ce1f7a87d97b6120a651  -

+ 9 - 0
Tests/RunCMake/CommandLine/RunCMakeTest.cmake

@@ -904,6 +904,15 @@ run_cmake_command(E_sha224sum ${CMAKE_COMMAND} -E sha224sum ../dummy)
 run_cmake_command(E_sha256sum ${CMAKE_COMMAND} -E sha256sum ../dummy)
 run_cmake_command(E_sha256sum ${CMAKE_COMMAND} -E sha256sum ../dummy)
 run_cmake_command(E_sha384sum ${CMAKE_COMMAND} -E sha384sum ../dummy)
 run_cmake_command(E_sha384sum ${CMAKE_COMMAND} -E sha384sum ../dummy)
 run_cmake_command(E_sha512sum ${CMAKE_COMMAND} -E sha512sum ../dummy)
 run_cmake_command(E_sha512sum ${CMAKE_COMMAND} -E sha512sum ../dummy)
+block()
+  set(RunCMake-stdin-file ${RunCMake_BINARY_DIR}/dummy)
+  run_cmake_command(E_md5sum-stdin ${CMAKE_COMMAND} -E md5sum -)
+  run_cmake_command(E_sha1sum-stdin ${CMAKE_COMMAND} -E sha1sum -)
+  run_cmake_command(E_sha224sum-stdin ${CMAKE_COMMAND} -E sha224sum -)
+  run_cmake_command(E_sha256sum-stdin ${CMAKE_COMMAND} -E sha256sum -)
+  run_cmake_command(E_sha384sum-stdin ${CMAKE_COMMAND} -E sha384sum -)
+  run_cmake_command(E_sha512sum-stdin ${CMAKE_COMMAND} -E sha512sum -)
+endblock()
 file(REMOVE "${RunCMake_BINARY_DIR}/dummy")
 file(REMOVE "${RunCMake_BINARY_DIR}/dummy")
 
 
 set(RunCMake_DEFAULT_stderr ".")
 set(RunCMake_DEFAULT_stderr ".")

+ 3 - 1
Tests/RunCMake/RunCMake.cmake

@@ -96,8 +96,10 @@ function(run_cmake test)
   else()
   else()
     set(maybe_timeout "")
     set(maybe_timeout "")
   endif()
   endif()
-  if(RunCMake-stdin-file AND EXISTS ${top_src}/${RunCMake-stdin-file})
+  if(RunCMake-stdin-file AND NOT IS_ABSOLUTE "${RunCMake-stdin-file}" AND EXISTS ${top_src}/${RunCMake-stdin-file})
     set(maybe_input_file INPUT_FILE ${top_src}/${RunCMake-stdin-file})
     set(maybe_input_file INPUT_FILE ${top_src}/${RunCMake-stdin-file})
+  elseif(RunCMake-stdin-file AND IS_ABSOLUTE "${RunCMake-stdin-file}" AND EXISTS "${RunCMake-stdin-file}")
+    set(maybe_input_file INPUT_FILE ${RunCMake-stdin-file})
   elseif(EXISTS ${top_src}/${test}-stdin.txt)
   elseif(EXISTS ${top_src}/${test}-stdin.txt)
     set(maybe_input_file INPUT_FILE ${top_src}/${test}-stdin.txt)
     set(maybe_input_file INPUT_FILE ${top_src}/${test}-stdin.txt)
   else()
   else()