This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "CMake".

The branch, next has been updated
       via  ba189140f63bfd9166356ff608f1c281b9c0a394 (commit)
       via  4a99b1b57809fcf5eb4da235a858e9bee9c3abe5 (commit)
      from  06168be1c3824a0850bb76e0f397aa74a7f8a763 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=ba189140f63bfd9166356ff608f1c281b9c0a394
commit ba189140f63bfd9166356ff608f1c281b9c0a394
Merge: 06168be 4a99b1b
Author:     Nils Gladitz <nilsglad...@gmail.com>
AuthorDate: Wed Feb 17 11:03:45 2016 -0500
Commit:     CMake Topic Stage <kwro...@kitware.com>
CommitDate: Wed Feb 17 11:03:45 2016 -0500

    Merge topic 'unix-timestamps' into next
    
    4a99b1b5 CMake: Extend TIMESTAMP sub-commands with new unix time format 
specifier


https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=4a99b1b57809fcf5eb4da235a858e9bee9c3abe5
commit 4a99b1b57809fcf5eb4da235a858e9bee9c3abe5
Author:     Jose-Luis Blanco-Claraco <joseluisblan...@gmail.com>
AuthorDate: Tue Feb 16 21:48:56 2016 +0100
Commit:     Nils Gladitz <nilsglad...@gmail.com>
CommitDate: Wed Feb 17 17:00:08 2016 +0100

    CMake: Extend TIMESTAMP sub-commands with new unix time format specifier
    
    The new %s format specifier is substituted by file()/string()
    TIMESTAMP sub-commands with the number of seconds since
    unix-epoch (1 January 1970 00:00:00 UTC).
    
    Co-Authored-By: Nils Gladitz <nilsglad...@gmail.com>

diff --git a/Help/command/string.rst b/Help/command/string.rst
index 0361c74..3f4050e 100644
--- a/Help/command/string.rst
+++ b/Help/command/string.rst
@@ -277,6 +277,7 @@ specifiers:
    %j        The day of the current year (001-366).
    %m        The month of the current year (01-12).
    %M        The minute of the current hour (00-59).
+   %s        Seconds since midnight (UTC) 1-Jan-1970 (UNIX time).
    %S        The second of the current minute.
              60 represents a leap second. (00-60)
    %U        The week number of the current year (00-53).
diff --git a/Help/release/dev/unix-timestamps.rst 
b/Help/release/dev/unix-timestamps.rst
new file mode 100644
index 0000000..cdb0e5b
--- /dev/null
+++ b/Help/release/dev/unix-timestamps.rst
@@ -0,0 +1,6 @@
+unix-timestamps
+---------------
+
+* The :command:`string(TIMESTAMP)` and :command:`file(TIMESTAMP)`
+  commands gained support for the ``%s`` placeholder.  This is
+  the number of seconds since the UNIX Epoch.
diff --git a/Source/cmTimestamp.cxx b/Source/cmTimestamp.cxx
index 6fd6ab7..2cb3a15 100644
--- a/Source/cmTimestamp.cxx
+++ b/Source/cmTimestamp.cxx
@@ -12,9 +12,11 @@
 #include "cmTimestamp.h"
 
 #include <cstring>
+#include <cstdlib>
 
 #include <sys/types.h>
 #include <sys/stat.h>
+#include <sstream>
 
 //----------------------------------------------------------------------------
 std::string cmTimestamp::CurrentTime(
@@ -44,7 +46,7 @@ std::string cmTimestamp::FileModificationTime(const char* 
path,
 
 //----------------------------------------------------------------------------
 std::string cmTimestamp::CreateTimestampFromTimeT(time_t timeT,
-    std::string formatString, bool utcFlag)
+  std::string formatString, bool utcFlag) const
 {
   if(formatString.empty())
     {
@@ -79,12 +81,12 @@ std::string cmTimestamp::CreateTimestampFromTimeT(time_t 
timeT,
   for(std::string::size_type i = 0; i < formatString.size(); ++i)
     {
     char c1 = formatString[i];
-    char c2 = (i+1 < formatString.size()) ?
-      formatString[i+1] : static_cast<char>(0);
+    char c2 = (i + 1 < formatString.size()) ?
+      formatString[i + 1] : static_cast<char>(0);
 
     if(c1 == '%' && c2 != 0)
       {
-      result += AddTimestampComponent(c2, timeStruct);
+      result += AddTimestampComponent(c2, timeStruct, timeT);
       ++i;
       }
     else
@@ -97,8 +99,42 @@ std::string cmTimestamp::CreateTimestampFromTimeT(time_t 
timeT,
 }
 
 //----------------------------------------------------------------------------
+time_t cmTimestamp::CreateUtcTimeTFromTm(struct tm &tm) const
+{
+#if defined(_MSC_VER) && _MSC_VER >= 1400
+  return _mkgmtime(&tm);
+#else
+  // From Linux timegm() manpage.
+
+  const char * tz = cmSystemTools::GetEnv("TZ");
+
+  if (tz)
+    {
+    tz = strdup(tz);
+    }
+
+  // The standard says that "TZ=" or "TZ=[UNRECOGNIZED_TZ]" means UTC.
+  // It seems that "TZ=" does NOT work, at least under Windows
+  // with neither MSVC nor MinGW, so let's use explicit "TZ=UTC"
+
+  cmSystemTools::PutEnv(std::string("TZ=UTC"));
+
+  tzset();
+
+  time_t result = mktime(&tm);
+
+  cmSystemTools::PutEnv(std::string("TZ=") +
+    std::string(tz ? tz : ""));
+
+  tzset();
+
+  return result;
+#endif
+}
+
+//----------------------------------------------------------------------------
 std::string cmTimestamp::AddTimestampComponent(
-  char flag, struct tm& timeStruct)
+  char flag, struct tm& timeStruct, const time_t timeT) const
 {
   std::string formatString = "%";
   formatString += flag;
@@ -117,6 +153,26 @@ std::string cmTimestamp::AddTimestampComponent(
     case 'y':
     case 'Y':
       break;
+    case 's': // Seconds since UNIX epoch (midnight 1-jan-1970)
+      {
+      // Build a time_t for UNIX epoch and substract from the input "timeT":
+      struct tm tmUnixEpoch;
+      memset(&tmUnixEpoch, 0, sizeof(tmUnixEpoch));
+      tmUnixEpoch.tm_mday = 1;
+      tmUnixEpoch.tm_year = 1970-1900;
+
+      const time_t unixEpoch = this->CreateUtcTimeTFromTm(tmUnixEpoch);
+      if (unixEpoch == -1)
+        {
+        cmSystemTools::Error("Error generating UNIX epoch in "
+          "STRING(TIMESTAMP ...). Please, file a bug report aginst CMake");
+        return std::string();
+        }
+
+      std::stringstream ss;
+      ss << static_cast<long int>(difftime(timeT, unixEpoch));
+      return ss.str();
+      }
     default:
       {
       return formatString;
diff --git a/Source/cmTimestamp.h b/Source/cmTimestamp.h
index 24c1869..7c4b216 100644
--- a/Source/cmTimestamp.h
+++ b/Source/cmTimestamp.h
@@ -16,7 +16,7 @@
 #include <time.h>
 
 /** \class cmTimestamp
- * \brief Utility class to generate sting representation of a timestamp
+ * \brief Utility class to generate string representation of a timestamp
  *
  */
 class cmTimestamp
@@ -30,10 +30,13 @@ public:
     const std::string& formatString, bool utcFlag);
 
 private:
-  std::string CreateTimestampFromTimeT(time_t timeT,
-      std::string formatString, bool utcFlag);
+  time_t CreateUtcTimeTFromTm(struct tm& timeStruct) const;
 
-  std::string AddTimestampComponent(char flag, struct tm& timeStruct);
+  std::string CreateTimestampFromTimeT(
+    time_t timeT, std::string formatString, bool utcFlag) const;
+
+  std::string AddTimestampComponent(
+    char flag, struct tm& timeStruct, time_t timeT) const;
 };
 
 
diff --git a/Tests/CMakeTests/String-TIMESTAMP-UnixTime.cmake 
b/Tests/CMakeTests/String-TIMESTAMP-UnixTime.cmake
new file mode 100644
index 0000000..a93e7f5
--- /dev/null
+++ b/Tests/CMakeTests/String-TIMESTAMP-UnixTime.cmake
@@ -0,0 +1,22 @@
+string(TIMESTAMP timestamp "[%Y-%m-%d %H:%M:%S] %s" UTC)
+
+string(TIMESTAMP unix_time "%s")
+
+string(TIMESTAMP year "%Y" UTC)
+string(TIMESTAMP days "%j" UTC)
+
+# Doing proper date calculations here to verify unix timestamps
+# could be error prone.
+# At the very least use some safe lower and upper bounds to
+# see if we are somewhere in the right region.
+
+math(EXPR years_since_epoch "${year} - 1970")
+math(EXPR lower_bound "((${years_since_epoch} * 365) + ${days}) * 86400")
+math(EXPR upper_bound "((${years_since_epoch} * 366) + ${days}) * 86400")
+
+
+if(unix_time GREATER lower_bound AND unix_time LESS upper_bound)
+  message("~${unix_time}~")
+else()
+  message(FATAL_ERROR "${timestamp} unix time not in expected range 
[${lower_bound}, ${upper_bound}]")
+endif()
diff --git a/Tests/CMakeTests/StringTest.cmake.in 
b/Tests/CMakeTests/StringTest.cmake.in
index 92e70c3..aba35fe 100644
--- a/Tests/CMakeTests/StringTest.cmake.in
+++ b/Tests/CMakeTests/StringTest.cmake.in
@@ -36,6 +36,8 @@ set(TIMESTAMP-IncompleteSpecifier-RESULT 0)
 set(TIMESTAMP-IncompleteSpecifier-STDERR "~foobar%~")
 set(TIMESTAMP-AllSpecifiers-RESULT 0)
 set(TIMESTAMP-AllSpecifiers-STDERR "~[0-9]+(;[0-9]+)*~")
+set(TIMESTAMP-UnixTime-RESULT 0)
+set(TIMESTAMP-UnixTime-STDERR "~[1-9][0-9]+~")
 
 include("@CMAKE_CURRENT_SOURCE_DIR@/CheckCMakeTest.cmake")
 check_cmake_test(String
@@ -58,6 +60,7 @@ check_cmake_test(String
   TIMESTAMP-UnknownSpecifier
   TIMESTAMP-IncompleteSpecifier
   TIMESTAMP-AllSpecifiers
+  TIMESTAMP-UnixTime
   )
 
 # Execute each test listed in StringTestScript.cmake:
@@ -68,9 +71,12 @@ set(number_of_tests_expected 70)
 include("@CMAKE_CURRENT_SOURCE_DIR@/ExecuteScriptTests.cmake")
 execute_all_script_tests(${scriptname} number_of_tests_executed)
 
+string(TIMESTAMP timestamp "[%Y-%m-%d %H:%M:%S] UTC %s" UTC)
+
 # And verify that number_of_tests_executed is at least as many as we know
 # about as of this writing...
 #
+message(STATUS "timestamp='${timestamp}'")
 message(STATUS "scriptname='${scriptname}'")
 message(STATUS "number_of_tests_executed='${number_of_tests_executed}'")
 message(STATUS "number_of_tests_expected='${number_of_tests_expected}'")

-----------------------------------------------------------------------

Summary of changes:


hooks/post-receive
-- 
CMake
_______________________________________________
Cmake-commits mailing list
Cmake-commits@cmake.org
http://public.kitware.com/mailman/listinfo/cmake-commits

Reply via email to