1 #include "log/logger.hpp"
13 std::ostream*& ostream_pointer() {
14 static std::ostream* stream = &std::cout;
18 std::ostream& get_stream() {
19 return *ostream_pointer();
22 std::string make_prefix( level l ) {
23 auto prefix = std::string {};
47 using clock = std::chrono::system_clock;
48 const auto now = clock::to_time_t( clock::now() );
49 // ctime appends a newline, we don't want that here:
50 auto time_str = std::ctime( &now );
51 prefix.append( time_str, time_str + std::strlen( time_str ) - 1 );
56 } // anonymous namespace
60 std::string replace_newlines( const std::string& str, std::size_t length ) {
61 auto returnstring = std::string {};
62 auto it = str.begin();
63 const auto end = str.end();
66 while( ( nl_it = std::find( it, end, '\n' ) ) != end ) {
68 returnstring.append( it, nl_it );
69 returnstring.append( length, ' ' );
73 returnstring.append( it, end );
77 void log( level l, const std::vector<std::string>& args ) {
78 const auto prefix = make_prefix( l );
79 const auto length = prefix.length();
80 get_stream() << prefix;
81 std::transform( args.begin(), args.end(), std::ostream_iterator<std::string> {get_stream()},
82 [length]( const std::string & str ) {
83 return replace_newlines( str, length );
85 get_stream() << '\n' << std::flush;
88 void logf( level l, const std::string& format, std::vector<std::string> args ) {
89 const auto prefix = make_prefix( l );
90 const auto length = prefix.length();
91 const auto fmt = replace_newlines( format, length );
92 std::transform( args.begin(), args.end(), args.begin(),
93 [length]( const std::string & str ) {
94 return replace_newlines( str, length );
98 auto arg_index = std::size_t {0};
99 auto it = fmt.begin();
100 const auto end = fmt.end();
103 auto pos = std::find( it, end, '%' );
104 mesg.append( it, pos );
113 throw std::invalid_argument {"Invalid formatstring (ends on single '%')"};
118 mesg.push_back( '%' );
122 if( arg_index >= args.size() ) {
123 throw std::invalid_argument {"Invalid formatstring (not enough arguments)"};
126 mesg.append( args[arg_index++] );
130 throw std::invalid_argument {"Invalid formatstring (unknown format-character)"};
133 it = std::next( pos );
136 mesg.push_back( '\n' );
137 get_stream() << mesg << std::flush;
142 void set_stream( std::ostream& stream ) {
143 ostream_pointer() = &stream;
146 } // namespace logger