[llvm] r316419 - Support formatv of TimePoint with strftime-style formats.

Simon Dardis via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 26 02:34:37 PDT 2017


Thanks for this, I’ll take a look.

I have another buildbot reporting the same failure, I’ll see what I can do.

Thanks,
Simon

From: Sam McCall [mailto:sam.mccall at gmail.com]
Sent: 25 October 2017 11:41
To: Simon Dardis; benny.kra at gmail.com; brendan.kirby at imgtec.com
Subject: Re: [llvm] r316419 - Support formatv of TimePoint with strftime-style formats.

Hi Simon, +Brendan who's listed as the buildslave owner.

Sorry about the break!
My concern with reverting is I don't know what the problem is and have a MIPS machine to test on, so it's hard to fix.
And I suspect the issue is with the buildslave's toolchain, which makes it really hard for me to fix.

The code doesn't look platform-specific, Ben suggests the most likely culprit is a bad std::chrono implementation.
The buildbot is running gcc 4.7 which isn't supported anymore<https://llvm.org/docs/GettingStarted.html#software> for building llvm - a more recent gcc may work?
https://stackoverflow.com/questions/17405997/c-chrono-duration-cast-to-milliseconds-results-in-seconds/17408315 also seems like a possible explanation.

We can disable the test for this bot (I think?) but maybe better to do that once we have a clearer idea what's wrong.

On Wed, Oct 25, 2017 at 11:12 AM, Simon Dardis <Simon.Dardis at mips.com<mailto:Simon.Dardis at mips.com>> wrote:
Resending as I mis-spelt the list name.

Hi Sam,

This change appears to have broken llvm-mips-linux, would you be able to take a look?

http://lab.llvm.org:8011/builders/llvm-mips-linux/builds/2658

Thanks,
Simon

-----Original Message-----
From: llvm-commits [mailto:llvm-commits-bounces at lists.llvm.org<mailto:llvm-commits-bounces at lists.llvm.org>] On Behalf Of Sam McCall via llvm-commits
Sent: 24 October 2017 09:30
To: llvm-commits at lists.llvm.org<mailto:llvm-commits at lists.llvm.org>
Subject: [llvm] r316419 - Support formatv of TimePoint with strftime-style formats.

Author: sammccall
Date: Tue Oct 24 01:30:19 2017
New Revision: 316419

URL: http://llvm.org/viewvc/llvm-project?rev=316419&view=rev
Log:
Support formatv of TimePoint with strftime-style formats.

Summary:
Support formatv of TimePoint with strftime-style formats.

Extensions for millis/micros/nanos are added.
Inital use case is HH:MM:SS.MMM timestamps in clangd logs.

Reviewers: bkramer, ilya-biryukov

Subscribers: labath, llvm-commits

Differential Revision: https://reviews.llvm.org/D38992

Modified:
    llvm/trunk/include/llvm/Support/Chrono.h
    llvm/trunk/lib/Support/Chrono.cpp
    llvm/trunk/unittests/Support/Chrono.cpp

Modified: llvm/trunk/include/llvm/Support/Chrono.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/Chrono.h?rev=316419&r1=316418&r2=316419&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Support/Chrono.h (original)
+++ llvm/trunk/include/llvm/Support/Chrono.h Tue Oct 24 01:30:19 2017
@@ -51,6 +51,20 @@ toTimePoint(std::time_t T) {

 raw_ostream &operator<<(raw_ostream &OS, sys::TimePoint<> TP);

+/// Format provider for TimePoint<>
+///
+/// The options string is a strftime format string, with extensions:
+///   - %L is millis: 000-999
+///   - %f is micros: 000000-999999
+///   - %N is nanos: 000000000 - 999999999
+///
+/// If no options are given, the default format is "%Y-%m-%d %H:%M:%S.%N".
+template <>
+struct format_provider<sys::TimePoint<>> {
+  static void format(const sys::TimePoint<> &TP, llvm::raw_ostream &OS,
+                     StringRef Style);
+};
+
 /// Implementation of format_provider<T> for duration types.
 ///
 /// The options string of a duration  type has the grammar:

Modified: llvm/trunk/lib/Support/Chrono.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Chrono.cpp?rev=316419&r1=316418&r2=316419&view=diff
==============================================================================
--- llvm/trunk/lib/Support/Chrono.cpp (original)
+++ llvm/trunk/lib/Support/Chrono.cpp Tue Oct 24 01:30:19 2017
@@ -51,4 +51,44 @@ raw_ostream &operator<<(raw_ostream &OS,
                                .count()));  }

+void format_provider<TimePoint<>>::format(const TimePoint<> &T, raw_ostream &OS,
+                                          StringRef Style) {
+  using namespace std::chrono;
+  TimePoint<seconds> Truncated = time_point_cast<seconds>(T);
+  auto Fractional = T - Truncated;
+  struct tm LT = getStructTM(Truncated);
+  // Handle extensions first. strftime mangles unknown %x on some platforms.
+  if (Style.empty()) Style = "%Y-%m-%d %H:%M:%S.%N";
+  std::string Format;
+  raw_string_ostream FStream(Format);
+  for (unsigned I = 0; I < Style.size(); ++I) {
+    if (Style[I] == '%' && Style.size() > I + 1) switch (Style[I + 1]) {
+        case 'L':  // Milliseconds, from Ruby.
+          FStream << llvm::format(
+              "%.3lu", duration_cast<milliseconds>(Fractional).count());
+          ++I;
+          continue;
+        case 'f':  // Microseconds, from Python.
+          FStream << llvm::format(
+              "%.6lu", duration_cast<microseconds>(Fractional).count());
+          ++I;
+          continue;
+        case 'N':  // Nanoseconds, from date(1).
+          FStream << llvm::format(
+              "%.6lu", duration_cast<nanoseconds>(Fractional).count());
+          ++I;
+          continue;
+        case '%':  // Consume %%, so %%f parses as (%%)f not %(%f)
+          FStream << "%%";
+          ++I;
+          continue;
+      }
+    FStream << Style[I];
+  }
+  FStream.flush();
+  char Buffer[256];  // Should be enough for anywhen.
+  size_t Len = strftime(Buffer, sizeof(Buffer), Format.c_str(), &LT);
+  OS << (Len ? Buffer : "BAD-DATE-FORMAT"); }
+
 } // namespace llvm

Modified: llvm/trunk/unittests/Support/Chrono.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Support/Chrono.cpp?rev=316419&r1=316418&r2=316419&view=diff
==============================================================================
--- llvm/trunk/unittests/Support/Chrono.cpp (original)
+++ llvm/trunk/unittests/Support/Chrono.cpp Tue Oct 24 01:30:19 2017
@@ -31,33 +31,35 @@ TEST(Chrono, TimeTConversion) {
   EXPECT_EQ(TP, toTimePoint(toTimeT(TP)));  }

-TEST(Chrono, StringConversion) {
+TEST(Chrono, TimePointFormat) {
+  using namespace std::chrono;
+  struct tm TM {};
+  TM.tm_year = 106;
+  TM.tm_mon = 0;
+  TM.tm_mday = 2;
+  TM.tm_hour = 15;
+  TM.tm_min = 4;
+  TM.tm_sec = 5;
+  TM.tm_isdst = -1;
+  TimePoint<> T =
+      system_clock::from_time_t(mktime(&TM)) + nanoseconds(123456789);
+
+  // operator<< uses the format YYYY-MM-DD HH:MM:SS.NNNNNNNNN
   std::string S;
   raw_string_ostream OS(S);
-  OS << system_clock::now();
-
-  // Do a basic sanity check on the output.
-  // The format we expect is YYYY-MM-DD HH:MM:SS.MMMUUUNNN
-  StringRef Date, Time;
-  std::tie(Date, Time) = StringRef(OS.str()).split(' ');
-
-  SmallVector<StringRef, 3> Components;
-  Date.split(Components, '-');
-  ASSERT_EQ(3u, Components.size());
-  EXPECT_EQ(4u, Components[0].size());
-  EXPECT_EQ(2u, Components[1].size());
-  EXPECT_EQ(2u, Components[2].size());
-
-  StringRef Sec, Nano;
-  std::tie(Sec, Nano) = Time.split('.');
+  OS << T;
+  EXPECT_EQ("2006-01-02 15:04:05.123456789", OS.str());

-  Components.clear();
-  Sec.split(Components, ':');
-  ASSERT_EQ(3u, Components.size());
-  EXPECT_EQ(2u, Components[0].size());
-  EXPECT_EQ(2u, Components[1].size());
-  EXPECT_EQ(2u, Components[2].size());
-  EXPECT_EQ(9u, Nano.size());
+  // formatv default style matches operator<<.
+  EXPECT_EQ("2006-01-02 15:04:05.123456789", formatv("{0}", T).str());
+ // formatv supports strftime-style format strings.
+  EXPECT_EQ("15:04:05", formatv("{0:%H:%M:%S}", T).str());  // formatv
+ supports our strftime extensions for sub-second precision.
+  EXPECT_EQ("123", formatv("{0:%L}", T).str());  EXPECT_EQ("123456",
+ formatv("{0:%f}", T).str());  EXPECT_EQ("123456789", formatv("{0:%N}",
+ T).str());  // our extensions don't interfere with %% escaping.
+  EXPECT_EQ("%foo", formatv("{0:%%foo}", T).str());
 }

 // Test that toTimePoint and toTimeT can be called with a arguments with varying


_______________________________________________
llvm-commits mailing list
llvm-commits at lists.llvm.org<mailto:llvm-commits at lists.llvm.org>
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20171026/fa1ddb76/attachment.html>


More information about the llvm-commits mailing list