]> git.ipfire.org Git - thirdparty/ccache.git/commitdiff
refactor: Extract timestamp format to util::format_iso8601_timestamp
authorJoel Rosdahl <joel@rosdahl.net>
Sun, 30 Mar 2025 08:46:48 +0000 (10:46 +0200)
committerJoel Rosdahl <joel@rosdahl.net>
Sun, 30 Mar 2025 09:05:05 +0000 (11:05 +0200)
cmake/config.h.in
src/ccache/util/logging.cpp
src/ccache/util/string.cpp
src/ccache/util/string.hpp
src/ccache/util/time.cpp
src/ccache/util/time.hpp
unittest/test_util_string.cpp

index f39a18fc1b42dd095336da037ad751b741a5aae8..5e6387ed37d5870856e52f4961f04cba714b9d5d 100644 (file)
@@ -94,7 +94,7 @@
 #cmakedefine HAVE_SYS_MMAN_H
 
 // Define if you have the <sys/sendfile.h> header file.
-#cmakedefine HAVE_SYS_SENDFILE_H 
+#cmakedefine HAVE_SYS_SENDFILE_H
 
 // Define if you have the <sys/utime.h> header file.
 #cmakedefine HAVE_SYS_UTIME_H
 // Define if you have the "getpwuid" function.
 #cmakedefine HAVE_GETPWUID
 
+// Define if you have the "gmtime_r" function.
+#cmakedefine HAVE_GMTIME_R
+
 // Define if you have the "localtime_r" function.
 #cmakedefine HAVE_LOCALTIME_R
 
index 304440275e3187bdd53f614f5cac338d5ecfdb0e..9cbaf7811fb12e621a07e05310b5671dec6eb6d9 100644 (file)
@@ -1,5 +1,5 @@
 // Copyright (C) 2002 Andrew Tridgell
-// Copyright (C) 2009-2024 Joel Rosdahl and other contributors
+// Copyright (C) 2009-2025 Joel Rosdahl and other contributors
 //
 // See doc/AUTHORS.adoc for a complete list of contributors.
 //
@@ -23,6 +23,7 @@
 #include <ccache/util/filesystem.hpp>
 #include <ccache/util/format.hpp>
 #include <ccache/util/logging.hpp>
+#include <ccache/util/string.hpp>
 #include <ccache/util/time.hpp>
 
 #include <string>
@@ -81,21 +82,11 @@ do_log(std::string_view message, bool bulk)
   static char prefix[200];
 
   if (!bulk || prefix[0] == '\0') {
-    char timestamp[100];
-    auto now = util::TimePoint::now();
-    auto tm = util::localtime(now);
-    if (tm) {
-      strftime(timestamp, sizeof(timestamp), "%Y-%m-%dT%H:%M:%S", &*tm);
-    } else {
-      snprintf(timestamp,
-               sizeof(timestamp),
-               "%llu",
-               static_cast<long long unsigned int>(now.sec()));
-    }
+    const auto now = util::TimePoint::now();
     snprintf(prefix,
              sizeof(prefix),
              "[%s.%06u %-5d] ",
-             timestamp,
+             util::format_iso8601_timestamp(now).c_str(),
              static_cast<unsigned int>(now.nsec_decimal_part() / 1000),
              static_cast<int>(getpid()));
   }
index 54874ffb662857509865ae485ee177d93569fac7..b19d3aaef428d942d2a30ba4b670c25391be5362 100644 (file)
@@ -21,6 +21,7 @@
 #include <ccache/util/assertions.hpp>
 #include <ccache/util/filesystem.hpp>
 #include <ccache/util/format.hpp>
+#include <ccache/util/time.hpp>
 
 #include <algorithm>
 #include <cctype>
@@ -185,6 +186,23 @@ format_human_readable_size(uint64_t size, SizeUnitPrefixType prefix_type)
   }
 }
 
+std::string
+format_iso8601_timestamp(const TimePoint& time, TimeZone time_zone)
+{
+  char timestamp[100];
+  const auto tm =
+    (time_zone == TimeZone::local ? util::localtime : util::gmtime)(time);
+  if (tm) {
+    strftime(timestamp, sizeof(timestamp), "%Y-%m-%dT%H:%M:%S", &*tm);
+  } else {
+    snprintf(timestamp,
+             sizeof(timestamp),
+             "%llu",
+             static_cast<long long unsigned int>(time.sec()));
+  }
+  return timestamp;
+}
+
 tl::expected<double, std::string>
 parse_double(const std::string& value)
 {
index f78ee085113cf2b595498e736d16ce669af5a9a4..219b1c347a108520cca9809c6fc8ac0f81adffba 100644 (file)
@@ -19,6 +19,7 @@
 #pragma once
 
 #include <ccache/util/conversion.hpp>
+#include <ccache/util/timepoint.hpp>
 #include <ccache/util/tokenizer.hpp>
 
 #include <nonstd/span.hpp>
@@ -40,6 +41,7 @@ namespace util {
 // --- Interface ---
 
 enum class SizeUnitPrefixType { binary, decimal };
+enum class TimeZone { local, utc };
 
 // Return true if `suffix` is a suffix of `string`.
 bool ends_with(std::string_view string, std::string_view suffix);
@@ -81,6 +83,10 @@ std::string format_human_readable_diff(int64_t diff,
 std::string format_human_readable_size(uint64_t size,
                                        SizeUnitPrefixType prefix_type);
 
+// Format `time` as a human-readable ISO8601 timestamp string.
+std::string format_iso8601_timestamp(const TimePoint& time,
+                                     TimeZone time_zone = TimeZone::local);
+
 // Join stringified elements of `container` delimited by `delimiter` into a
 // string. There must exist an `std::string to_string(T::value_type)` function.
 template<typename T>
index e0ab7eebc97df4703ac8a9bf377b49c1c00f5191..268687347a82dd9f6d2646c1a5e617d59e4b68ac 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2023 Joel Rosdahl and other contributors
+// Copyright (C) 2023-2025 Joel Rosdahl and other contributors
 //
 // See doc/AUTHORS.adoc for a complete list of contributors.
 //
 
 namespace util {
 
+std::optional<tm>
+gmtime(std::optional<TimePoint> time)
+{
+  time_t timestamp = time ? time->sec() : TimePoint::now().sec();
+#ifdef HAVE_GMTIME_R
+  struct tm result;
+  if (gmtime_r(&timestamp, &result)) {
+    return result;
+  }
+#else
+  struct tm* result = ::gmtime(&timestamp);
+  if (result) {
+    return *result;
+  }
+#endif
+  return std::nullopt;
+}
+
 std::optional<tm>
 localtime(std::optional<TimePoint> time)
 {
index 938b691af011513000215fdaf85b8b5825fde412..635faad3d0afc079e850798ae0ee4c590fe0a270 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Joel Rosdahl and other contributors
+// Copyright (C) 2023-2025 Joel Rosdahl and other contributors
 //
 // See doc/AUTHORS.adoc for a complete list of contributors.
 //
 
 namespace util {
 
+// Thread-safe version of `gmtime(3)`. If `time` is not specified the current
+// time of day is used.
+std::optional<tm> gmtime(std::optional<TimePoint> time = {});
+
 // Thread-safe version of `localtime(3)`. If `time` is not specified the current
 // time of day is used.
 std::optional<tm> localtime(std::optional<TimePoint> time = {});
index 25fbb8b855f5e7b1e5e6963b18f8ef1c81d2294c..6d98f83d80bd6883af51ddc6c67ddf3d85319677 100644 (file)
@@ -274,6 +274,17 @@ TEST_CASE("util::format_human_readable_size")
   }
 }
 
+TEST_CASE("util::format_iso8601_timestamp")
+{
+  using util::TimePoint;
+  using util::TimeZone;
+
+  CHECK(util::format_iso8601_timestamp(TimePoint(0), TimeZone::utc)
+        == "1970-01-01T00:00:00");
+  CHECK(util::format_iso8601_timestamp(TimePoint(1234567890), TimeZone::utc)
+        == "2009-02-13T23:31:30");
+}
+
 TEST_CASE("util::join")
 {
   {