-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlog.h
136 lines (101 loc) · 2.85 KB
/
log.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
// log.h - logging header
#pragma once
#include <unistd.h>
#include <syslog.h>
#include <cstring>
#include <string>
#include <string_view>
/*
Look below. The functions you want are probably:
logOut() - lot to stdout
logErr() - log to stderr
logSys() - log to syslog
*/
namespace zezax::sensorrd {
// lengths
inline size_t length(char) { return 1; }
inline size_t length(const std::string &x) { return x.size(); }
inline size_t length(std::string_view x) { return x.size(); }
inline size_t length(const char *x) { return strlen(x); }
inline size_t length(double x) { return snprintf(nullptr, 0, "%g", x); }
template <class T> size_t logTen(T x) { size_t rv = 0;
do { x /= 10; ++rv; } while (x);
return rv;
}
inline size_t length(unsigned x) { return logTen(x); }
inline size_t length(unsigned long x) { return logTen(x); }
inline size_t length(int x) {
return (x < 0 ? 1 + logTen((unsigned) -x) : logTen((unsigned) x));
}
inline size_t length(long x) {
return (x < 0 ? 1 + logTen((unsigned long) -x) : logTen((unsigned long) x));
}
// appends
template <class T> void append(std::string &s, const T &x) { s += x; }
template <> void append<int>(std::string &s, const int &x) {
char buf[32];
snprintf(buf, sizeof(buf), "%d", x);
s += buf;
}
template <> void append<unsigned>(std::string &s, const unsigned &x) {
char buf[32];
snprintf(buf, sizeof(buf), "%u", x);
s += buf;
}
template <> void append<long>(std::string &s, const long &x) {
char buf[64];
snprintf(buf, sizeof(buf), "%ld", x);
s += buf;
}
template <> void append<unsigned long>(std::string &s, const unsigned long &x) {
char buf[64];
snprintf(buf, sizeof(buf), "%lu", x);
s += buf;
}
template <> void append<float>(std::string &s, const float &x) {
char buf[64];
snprintf(buf, sizeof(buf), "%g", x);
s += buf;
}
template <> void append<double>(std::string &s, const double &x) {
char buf[64];
snprintf(buf, sizeof(buf), "%g", x);
s += buf;
}
// variadic templates
inline void concat(std::string &) {}
template <class T, class ...Args>
void concat(std::string &s, T x, Args... args) {
append(s, x);
concat(s, args...);
}
inline size_t measure() { return 0; }
template <class T, class ...Args>
size_t measure(T x, Args... args) {
return length(x) + measure(args...);
}
// main entrypoints
template <class ...Args>
void logOut(Args... args) {
std::string s;
s.reserve(measure(args...) + 1);
concat(s, args...);
s += '\n';
write(STDOUT_FILENO, s.data(), s.size());
}
template <class ...Args>
void logErr(Args... args) {
std::string s;
s.reserve(measure(args...) + 1);
concat(s, args...);
s += '\n';
write(STDERR_FILENO, s.data(), s.size());
}
template <class ...Args>
void logSys(int priority, Args... args) {
std::string s;
s.reserve(measure(args...));
concat(s, args...);
syslog(priority, "%s", s.c_str());
}
} // namespace zezax::sensorrd