[llvm] r316419 - Support formatv of TimePoint with strftime-style formats.
Simon Dardis via llvm-commits
llvm-commits at lists.llvm.org
Wed Oct 25 02:12:47 PDT 2017
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] On Behalf Of Sam McCall via llvm-commits
Sent: 24 October 2017 09:30
To: 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(), <);
+ 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
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list