1 /**
2  * Functions for logging and error checking.
3  */
4 #ifndef BTLLIB_STATUS_HPP
5 #define BTLLIB_STATUS_HPP
6 
7 #include <cstdlib>
8 #include <cstring>
9 #include <ctime>
10 #include <iostream>
11 #include <string>
12 
13 namespace btllib {
14 
15 constexpr const char* PRINT_COLOR_INFO = "\33[32m";
16 constexpr const char* PRINT_COLOR_WARNING = "\33[33m";
17 constexpr const char* PRINT_COLOR_ERROR = "\33[31m";
18 constexpr const char* PRINT_COLOR_END = "\33[0m";
19 
20 inline std::string
21 get_time();
22 
23 /**
24  * Log info level events.
25  *
26  * @param msg Message to print.
27  */
28 inline void
29 log_info(const std::string& msg);
30 
31 /**
32  * Log warning level events.
33  *
34  * @param msg Message to print.
35  */
36 inline void
37 log_warning(const std::string& msg);
38 
39 /**
40  * Log error level events.
41  *
42  * @param msg Message to print.
43  */
44 inline void
45 log_error(const std::string& msg);
46 
47 /**
48  * Conditionally log info level events.
49  *
50  * @param condition If this is true, the message is printed.
51  * @param msg Message to print.
52  */
53 inline void
54 check_info(bool condition, const std::string& msg);
55 
56 /**
57  * Conditionally log warning level events.
58  *
59  * @param condition If this is true, the message is printed.
60  * @param msg Message to print.
61  */
62 inline void
63 check_warning(bool condition, const std::string& msg);
64 
65 /**
66  * Conditionally log error level events. The program exits if the condition is
67  * true.
68  *
69  * @param condition If this is true, the message is printed and the program
70  * exits.
71  * @param msg Message to print.
72  */
73 inline void
74 check_error(bool condition, const std::string& msg);
75 
76 /**
77  * Check whether the stream is good. Program prints an error message and exits
78  * if not.
79  *
80  * @param stream Stream to check goodness of.
81  * @param name Name of the stream, e.g. filepath or stdin
82  */
83 inline void
84 check_stream(const std::ios& stream, const std::string& name);
85 
86 inline std::string
get_time()87 get_time()
88 {
89   time_t now;
90   time(&now);
91   char buf[sizeof("2011-10-08T07:07:09Z")];
92   std::tm tm_result = {};
93   localtime_r(&now, &tm_result);
94   std::strftime(buf, sizeof buf, "%F %T", &tm_result);
95   return std::string(buf);
96 }
97 
98 inline void
log_info(const std::string & msg)99 log_info(const std::string& msg)
100 {
101   std::cerr << ('[' + get_time() + "]" + PRINT_COLOR_INFO + "[INFO] " +
102                 PRINT_COLOR_END + msg + '\n')
103             << std::flush;
104 }
105 
106 inline void
log_warning(const std::string & msg)107 log_warning(const std::string& msg)
108 {
109   std::cerr << ('[' + get_time() + "]" + PRINT_COLOR_WARNING + "[WARNING] " +
110                 PRINT_COLOR_END + msg + '\n')
111             << std::flush;
112 }
113 
114 inline void
log_error(const std::string & msg)115 log_error(const std::string& msg)
116 {
117   std::cerr << ('[' + get_time() + "]" + PRINT_COLOR_ERROR + "[ERROR] " +
118                 PRINT_COLOR_END + msg + '\n')
119             << std::flush;
120 }
121 
122 inline void
check_info(bool condition,const std::string & msg)123 check_info(bool condition, const std::string& msg)
124 {
125   if (condition) {
126     log_info(msg);
127   }
128 }
129 
130 inline void
check_warning(bool condition,const std::string & msg)131 check_warning(bool condition, const std::string& msg)
132 {
133   if (condition) {
134     log_warning(msg);
135   }
136 }
137 
138 inline void
check_error(bool condition,const std::string & msg)139 check_error(bool condition, const std::string& msg)
140 {
141   if (condition) {
142     log_error(msg);
143     std::exit(EXIT_FAILURE);
144   }
145 }
146 
147 inline void
check_stream(const std::ios & stream,const std::string & name)148 check_stream(const std::ios& stream, const std::string& name)
149 {
150   check_error(!stream.good(),
151               "'" + name + "' stream error: " + std::strerror(errno));
152 }
153 
154 } // namespace btllib
155 
156 #endif
157