mCRL2
Loading...
Searching...
No Matches
logger.cpp
Go to the documentation of this file.
1// Author(s): Jeroen Keiren
2// Copyright: see the accompanying file COPYING or copy at
3// https://github.com/mCRL2org/mCRL2/blob/master/COPYING
4//
5// Distributed under the Boost Software License, Version 1.0.
6// (See accompanying file LICENSE_1_0.txt or copy at
7// http://www.boost.org/LICENSE_1_0.txt)
8//
10
12#include <cassert>
13
14namespace mcrl2 {
15 namespace log {
16
17 std::string format_time(const time_t* t)
18 {
19 struct tm* r;
20 r = localtime(t);
21
22 char buffer[11];
23 std::size_t res = strftime(buffer, sizeof(buffer), "%H:%M:%S", r);
24 if(res == 0)
25 {
26 std::clog << "Could not write time to buffer" << std::endl;
27 return std::string();
28 }
29 return buffer;
30 }
31
32 std::string formatter::format(const log_level_t level,
33 const time_t timestamp,
34 const std::string& msg,
35 const bool print_time_information)
36 {
37 assert(quiet != level);
38 // Construct the message header, with or without time and debug level info.
39 const bool print_log_level= level >= debug;
40 std::stringstream start_of_line;
41 if (print_time_information || print_log_level)
42 {
43 start_of_line << "[";
44 }
45 if (print_time_information)
46 {
47 start_of_line << format_time(&timestamp);
48 }
49 if (print_time_information && print_log_level)
50 {
51 start_of_line << " ";
52 }
53 if (print_log_level)
54 {
55 start_of_line << log_level_to_string(level);
56 }
57 if (print_time_information || print_log_level)
58 {
59 start_of_line << "] ";
60 }
61 if (print_log_level)
62 {
63 start_of_line << std::string(7 - log_level_to_string(level).size(), ' ');
64 }
65
66 // Check if message is finished. We
67 bool msg_ends_with_newline = false;
68 if (msg.size() > 0)
69 {
70 msg_ends_with_newline = (msg[msg.size()-1] == '\n');
71 }
72
73 std::stringstream result;
74
75 // Determine whether the last line should be overwritten (by inserting a
76 // carriage return).
77 bool overwrite = false;
79 {
80 if (level == status)
81 {
83 {
84 if (msg != "\n")
85 {
86 result << "\r" << start_of_line.str();
87 overwrite = true;
88 }
89 else
90 {
91 result << "\n";
92 }
93 }
94 }
95 else
96 {
97 result << "\n" << start_of_line.str();
98 }
99 }
100 else
102 {
103 result << start_of_line.str();
104 }
105
106 // Copy the message to result, keeping track of the caret position and
107 // inserting message headers at newlines. A trailing newline is ignored.
108 for (std::string::const_iterator it = msg.begin(); it != msg.end(); )
109 {
110 if (*it != '\n')
111 {
112 result << *it++;
113 ++caret_pos();
114 }
115 else
116 {
117 if (++it != msg.end())
118 {
119 result << "\n" << start_of_line.str();
120 caret_pos() = 0;
121 last_caret_pos() = 0;
122 }
123 }
124 }
125
126 // Pad message with spaces when overwriting a previous line
127 if (msg_ends_with_newline && overwrite && caret_pos() < last_caret_pos())
128 {
129 for (std::size_t i = 0; i < last_caret_pos() - caret_pos(); ++i)
130 {
131 result << ' ';
132 }
133 }
134
135 // If this is a finished status message, remember the caret position
136 // so the next line can overwrite properly. If this is a finished message
137 // of another type, restore the trailing newline.
138 if(msg_ends_with_newline)
139 {
140 if (level == status)
141 {
142 last_caret_pos() = caret_pos().load();
143 }
144 else
145 {
146 result << "\n";
147 }
148 caret_pos() = 0;
149 }
150
151 // Store information about this message so next time we can determine
152 // whether we should overwrite the last line or not.
153 last_message_ended_with_newline() = msg_ends_with_newline;
154 if (level == status)
155 {
156 last_message_was_status() = msg != "\n";
157 }
158 else
159 {
160 last_message_was_status() = false;
161 }
162
163 return result.str();
164 }
165
166 } // namespace log
167} // namespace mcrl2
static std::atomic< std::size_t > & caret_pos()
Definition logger.h:292
static std::atomic< bool > & last_message_ended_with_newline()
Records whether the last message that was printed ended with a new line.
Definition logger.h:278
static std::atomic< std::size_t > & last_caret_pos()
Definition logger.h:299
static std::atomic< bool > & last_message_was_status()
Definition logger.h:285
static std::string format(const log_level_t level, const time_t timestamp, const std::string &msg, const bool print_time_information)
Prefix each line in s with some extra information. The things that are added are:
Definition logger.cpp:32
std::string log_level_to_string(const log_level_t level)
Convert log level to string This string is used to prefix messages in the logging output.
Definition logger.h:45
std::string format_time(const time_t *t)
Definition logger.cpp:17
log_level_t
Log levels that are supported.
Definition logger.h:31
A class that takes a linear process specification and checks all tau-summands of that LPS for conflue...
Definition indexed_set.h:72