Browse Source

Util: Add ability to print log messages

master
Riyyi 2 years ago
parent
commit
f58113e257
  1. 2
      src/util/format/builder.cpp
  2. 109
      src/util/format/log.cpp
  3. 97
      src/util/format/log.h
  4. 6
      test/unit/testutilformat.cpp

2
src/util/format/builder.cpp

@ -36,7 +36,6 @@ void Builder::putF32(float number, size_t precision) const
<< number
<< std::defaultfloat << std::setprecision(6);
std::string string = stream.str();
string = string.substr(0, string.find_first_of('0', string.find('.')));
m_builder << string;
}
@ -50,7 +49,6 @@ void Builder::putF64(double number, size_t precision) const
<< number
<< std::defaultfloat << std::setprecision(6);
std::string string = stream.str();
string = string.substr(0, string.find_first_of('0', string.find('.')));
m_builder << string;
}

109
src/util/format/log.cpp

@ -0,0 +1,109 @@
/*
* Copyright (C) 2022 Riyyi
*
* SPDX-License-Identifier: MIT
*/
#include <cstdio> // FILE
#include <string>
#include "util/format/color.h"
#include "util/format/log.h"
namespace Util::Format {
std::string formatTimeElapsed()
{
return format("{:.3}s ", s_timer.elapsedNanoseconds() / 1000000000.0);
}
std::string formatType(Type type)
{
std::string output;
formatTo(output, "[");
switch (type) {
case Type::Trace:
formatTo(output, "trace");
break;
case Type::Debug:
formatTo(output, fg(TerminalColor::Magenta), "debug");
break;
case Type::Success:
formatTo(output, fg(TerminalColor::Green), "success");
break;
case Type::Info:
formatTo(output, fg(TerminalColor::Blue), "info");
break;
case Type::Warn:
formatTo(output, Emphasis::Bold | fg(TerminalColor::Yellow), "warn");
break;
case Type::Error:
formatTo(output, Emphasis::Bold | fg(TerminalColor::Red), "error");
break;
case Type::Critical:
formatTo(output, Emphasis::Bold | fg(TerminalColor::White) | bg(TerminalColor::Red), "critical");
break;
default:
break;
};
formatTo(output, "] ");
return output;
}
// -----------------------------------------
LogOperatorStyle::LogOperatorStyle(FILE* file, Type type)
: m_file(file)
, m_type(type)
, m_stream()
, m_builder(m_stream)
{
m_stream << formatTimeElapsed();
m_stream << formatType(type);
}
LogOperatorStyle::~LogOperatorStyle()
{
m_stream.write("\n", 1);
std::string string = m_stream.str();
fputs(string.c_str(), m_file);
}
LogOperatorStyle trace()
{
return LogOperatorStyle(stdout, Type::Trace);
}
LogOperatorStyle debug()
{
return LogOperatorStyle(stdout, Type::Debug);
}
LogOperatorStyle success()
{
return LogOperatorStyle(stdout, Type::Success);
}
LogOperatorStyle info()
{
return LogOperatorStyle(stdout, Type::Info);
}
LogOperatorStyle warn()
{
return LogOperatorStyle(stderr, Type::Warn);
}
LogOperatorStyle error()
{
return LogOperatorStyle(stderr, Type::Error);
}
LogOperatorStyle critical()
{
return LogOperatorStyle(stderr, Type::Critical);
}
} // namespace Util::Format

97
src/util/format/log.h

@ -0,0 +1,97 @@
/*
* Copyright (C) 2022 Riyyi
*
* SPDX-License-Identifier: MIT
*/
#pragma once
#include <cstdio> // FILE, stderr, stdout
#include <string>
#include <string_view>
#include "util/format/format.h"
#include "util/format/print.h"
#include "util/timer.h"
namespace Util::Format {
static Util::Timer s_timer;
enum class Type : uint8_t {
Trace, // White
Debug, // Purple
Success, // Green
Info, // Blue
Warn, // Bold yellow
Error, // Bold red
Critical, // Bold on red
};
std::string formatTimeElapsed();
std::string formatType(Type type);
#define LOG_FUNCTION(name, file, type) \
template<size_t N, typename... Parameters> \
void name(const char(&format)[N], const Parameters&... parameters) \
{ \
print(file, "{}", formatTimeElapsed()); \
print(file, "{}", formatType(type)); \
VariadicParameters variadicParameters { parameters... }; \
print(file, format, variadicParameters); \
print(file, "\n"); \
}
LOG_FUNCTION(trace, stdout, Type::Trace);
LOG_FUNCTION(debug, stdout, Type::Debug);
LOG_FUNCTION(success, stdout, Type::Success);
LOG_FUNCTION(info, stdout, Type::Info);
LOG_FUNCTION(warn, stderr, Type::Warn);
LOG_FUNCTION(error, stderr, Type::Error);
LOG_FUNCTION(critical, stderr, Type::Critical);
// -----------------------------------------
class LogOperatorStyle {
public:
LogOperatorStyle(FILE* file, Type type);
virtual ~LogOperatorStyle();
Builder& builder() { return m_builder; }
private:
FILE* m_file;
Type m_type;
std::stringstream m_stream;
Builder m_builder;
};
template<typename T>
const LogOperatorStyle& operator<<(const LogOperatorStyle& logOperatorStyle, const T& value)
{
_format(const_cast<LogOperatorStyle&>(logOperatorStyle).builder(), value);
return logOperatorStyle;
}
LogOperatorStyle trace();
LogOperatorStyle debug();
LogOperatorStyle success();
LogOperatorStyle info();
LogOperatorStyle warn();
LogOperatorStyle error();
LogOperatorStyle critical();
} // namespace Util::Format
namespace Util {
using Util::Format::critical;
using Util::Format::debug;
using Util::Format::error;
using Util::Format::info;
using Util::Format::success;
using Util::Format::trace;
using Util::Format::warn;
} // namespace Util

6
test/unit/testutilformat.cpp

@ -85,7 +85,7 @@ TEST_CASE(FormatNumbers)
float f32R = 245789.70000;
result = Util::format("{}", f32R);
EXPECT_EQ(result, "245789.7");
EXPECT_EQ(result, "245789.703125");
float f32 = 45645.3233;
result = Util::format("{}", f32);
@ -93,11 +93,11 @@ TEST_CASE(FormatNumbers)
double f64 = 87522.300000000;
result = Util::format("{}", f64);
EXPECT_EQ(result, "87522.3");
EXPECT_EQ(result, "87522.300000");
double pi = 3.14159265359;
result = Util::format("{:.15}", pi);
EXPECT_EQ(result, "3.14159265359");
EXPECT_EQ(result, "3.141592653590000");
}
TEST_CASE(FormatContainers)

Loading…
Cancel
Save