Browse Source

Merge topic 'file-size'

12b471e828 file: add SIZE option

Acked-by: Kitware Robot <[email protected]>
Merge-request: !2639
Brad King 7 years ago
parent
commit
5daf7d92f8

+ 11 - 0
Help/command/file.rst

@@ -25,6 +25,7 @@ Synopsis
     file({`REMOVE`_ | `REMOVE_RECURSE`_ } [<files>...])
     file(`MAKE_DIRECTORY`_ [<dir>...])
     file({`COPY`_ | `INSTALL`_} <file>... DESTINATION <dir> [...])
+    file(`SIZE`_ <filename> <out-var>)
 
   `Path Conversion`_
     file(`RELATIVE_PATH`_ <out-var> <directory> <file>)
@@ -333,6 +334,16 @@ and ``NO_SOURCE_PERMISSIONS`` is default.
 Installation scripts generated by the :command:`install` command
 use this signature (with some undocumented options for internal use).
 
+.. _SIZE:
+
+.. code-block:: cmake
+
+  file(SIZE <filename> <variable>)
+
+Determine the file size of the ``<filename>`` and put the result in
+``<variable>`` variable. Requires that ``<filename>`` is a valid path
+pointing to a file and is readable.
+
 Path Conversion
 ^^^^^^^^^^^^^^^
 

+ 5 - 0
Help/release/dev/file-size.rst

@@ -0,0 +1,5 @@
+file-size
+---------
+
+* The :command:`file` command gained a ``SIZE`` mode to get the size
+  of a file on disk.

+ 32 - 0
Source/cmFileCommand.cxx

@@ -177,6 +177,9 @@ bool cmFileCommand::InitialPass(std::vector<std::string> const& args,
   if (subCommand == "LOCK") {
     return this->HandleLockCommand(args);
   }
+  if (subCommand == "SIZE") {
+    return this->HandleSizeCommand(args);
+  }
 
   std::string e = "does not recognize sub-command " + subCommand;
   this->SetError(e);
@@ -3606,3 +3609,32 @@ bool cmFileCommand::HandleTimestampCommand(
 
   return true;
 }
+
+bool cmFileCommand::HandleSizeCommand(std::vector<std::string> const& args)
+{
+  if (args.size() != 3) {
+    std::ostringstream e;
+    e << args[0] << " requires a file name and output variable";
+    this->SetError(e.str());
+    return false;
+  }
+
+  unsigned int argsIndex = 1;
+
+  const std::string& filename = args[argsIndex++];
+
+  const std::string& outputVariable = args[argsIndex++];
+
+  if (!cmSystemTools::FileExists(filename, true)) {
+    std::ostringstream e;
+    e << "SIZE requested of path that is not readable " << filename;
+    this->SetError(e.str());
+    return false;
+  }
+
+  this->Makefile->AddDefinition(
+    outputVariable,
+    std::to_string(cmSystemTools::FileLength(filename)).c_str());
+
+  return true;
+}

+ 1 - 0
Source/cmFileCommand.h

@@ -59,6 +59,7 @@ protected:
   bool HandleTimestampCommand(std::vector<std::string> const& args);
   bool HandleGenerateCommand(std::vector<std::string> const& args);
   bool HandleLockCommand(std::vector<std::string> const& args);
+  bool HandleSizeCommand(std::vector<std::string> const& args);
 
 private:
   void AddEvaluationFile(const std::string& inputName,

+ 2 - 0
Tests/RunCMake/file/RunCMakeTest.cmake

@@ -36,6 +36,8 @@ run_cmake(READ_ELF)
 run_cmake(GLOB)
 run_cmake(GLOB_RECURSE)
 run_cmake(GLOB_RECURSE-noexp-FOLLOW_SYMLINKS)
+run_cmake(SIZE)
+run_cmake(SIZE-error-does-not-exist)
 
 # tests are valid both for GLOB and GLOB_RECURSE
 run_cmake(GLOB-sort-dedup)

+ 1 - 0
Tests/RunCMake/file/SIZE-error-does-not-exist-result.txt

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

+ 5 - 0
Tests/RunCMake/file/SIZE-error-does-not-exist-stderr.txt

@@ -0,0 +1,5 @@
+^CMake Error at SIZE-error-does-not-exist.cmake:[0-9]+ \(file\):
+  file SIZE requested of path that is not readable
+  /a/file/that/does-not-exist
+Call Stack \(most recent call first\):
+  CMakeLists.txt:[0-9]+ \(include\)

+ 3 - 0
Tests/RunCMake/file/SIZE-error-does-not-exist.cmake

@@ -0,0 +1,3 @@
+set(file "/a/file/that/does-not-exist")
+
+file(SIZE "${file}" CALCULATED_SIZE)

+ 9 - 0
Tests/RunCMake/file/SIZE.cmake

@@ -0,0 +1,9 @@
+set(file "${CMAKE_CURRENT_BINARY_DIR}/a-test-file")
+
+file(WRITE "${file}" "test")
+
+file(SIZE "${file}" CALCULATED_SIZE)
+
+if (NOT CALCULATED_SIZE EQUAL 4)
+  message(FATAL_ERROR "Unexpected file size")
+endif()