Line data Source code
1 : //===- Support/Chrono.cpp - Utilities for Timing Manipulation ---*- C++ -*-===//
2 : //
3 : // The LLVM Compiler Infrastructure
4 : //
5 : // This file is distributed under the University of Illinois Open Source
6 : // License. See LICENSE.TXT for details.
7 : //
8 : //===----------------------------------------------------------------------===//
9 :
10 : #include "llvm/Support/Chrono.h"
11 : #include "llvm/Config/llvm-config.h"
12 : #include "llvm/Support/Format.h"
13 : #include "llvm/Support/raw_ostream.h"
14 :
15 : namespace llvm {
16 :
17 : using namespace sys;
18 :
19 : const char llvm::detail::unit<std::ratio<3600>>::value[] = "h";
20 : const char llvm::detail::unit<std::ratio<60>>::value[] = "m";
21 : const char llvm::detail::unit<std::ratio<1>>::value[] = "s";
22 : const char llvm::detail::unit<std::milli>::value[] = "ms";
23 : const char llvm::detail::unit<std::micro>::value[] = "us";
24 : const char llvm::detail::unit<std::nano>::value[] = "ns";
25 :
26 : static inline struct tm getStructTM(TimePoint<> TP) {
27 : struct tm Storage;
28 957 : std::time_t OurTime = toTimeT(TP);
29 :
30 : #if defined(LLVM_ON_UNIX)
31 957 : struct tm *LT = ::localtime_r(&OurTime, &Storage);
32 : assert(LT);
33 : (void)LT;
34 : #endif
35 : #if defined(_WIN32)
36 : int Error = ::localtime_s(&Storage, &OurTime);
37 : assert(!Error);
38 : (void)Error;
39 : #endif
40 :
41 : return Storage;
42 : }
43 :
44 236 : raw_ostream &operator<<(raw_ostream &OS, TimePoint<> TP) {
45 : struct tm LT = getStructTM(TP);
46 : char Buffer[sizeof("YYYY-MM-DD HH:MM:SS")];
47 236 : strftime(Buffer, sizeof(Buffer), "%Y-%m-%d %H:%M:%S", <);
48 236 : return OS << Buffer << '.'
49 236 : << format("%.9lu",
50 : long((TP.time_since_epoch() % std::chrono::seconds(1))
51 236 : .count()));
52 : }
53 :
54 721 : void format_provider<TimePoint<>>::format(const TimePoint<> &T, raw_ostream &OS,
55 : StringRef Style) {
56 : using namespace std::chrono;
57 : TimePoint<seconds> Truncated = time_point_cast<seconds>(T);
58 : auto Fractional = T - Truncated;
59 : struct tm LT = getStructTM(Truncated);
60 : // Handle extensions first. strftime mangles unknown %x on some platforms.
61 721 : if (Style.empty()) Style = "%Y-%m-%d %H:%M:%S.%N";
62 : std::string Format;
63 721 : raw_string_ostream FStream(Format);
64 8019 : for (unsigned I = 0; I < Style.size(); ++I) {
65 7298 : if (Style[I] == '%' && Style.size() > I + 1) switch (Style[I + 1]) {
66 : case 'L': // Milliseconds, from Ruby.
67 687 : FStream << llvm::format(
68 687 : "%.3lu", (long)duration_cast<milliseconds>(Fractional).count());
69 : ++I;
70 687 : continue;
71 : case 'f': // Microseconds, from Python.
72 1 : FStream << llvm::format(
73 1 : "%.6lu", (long)duration_cast<microseconds>(Fractional).count());
74 : ++I;
75 1 : continue;
76 : case 'N': // Nanoseconds, from date(1).
77 4 : FStream << llvm::format(
78 4 : "%.6lu", (long)duration_cast<nanoseconds>(Fractional).count());
79 : ++I;
80 4 : continue;
81 1 : case '%': // Consume %%, so %%f parses as (%%)f not %(%f)
82 1 : FStream << "%%";
83 : ++I;
84 1 : continue;
85 : }
86 : FStream << Style[I];
87 : }
88 : FStream.flush();
89 : char Buffer[256]; // Should be enough for anywhen.
90 721 : size_t Len = strftime(Buffer, sizeof(Buffer), Format.c_str(), <);
91 721 : OS << (Len ? Buffer : "BAD-DATE-FORMAT");
92 721 : }
93 :
94 : } // namespace llvm
|