print statements
parent
637b4fa0e6
commit
1e30544cff
|
@ -1,6 +1,6 @@
|
||||||
cmake_minimum_required(VERSION 3.20)
|
cmake_minimum_required(VERSION 3.20)
|
||||||
include(cmake/color.cmake)
|
include(cmake/color.cmake)
|
||||||
set(BLT_VERSION 5.1.8)
|
set(BLT_VERSION 5.1.9)
|
||||||
|
|
||||||
set(BLT_TARGET BLT)
|
set(BLT_TARGET BLT)
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,17 @@ namespace blt::logging
|
||||||
DOT,
|
DOT,
|
||||||
MINUS,
|
MINUS,
|
||||||
PLUS,
|
PLUS,
|
||||||
POUND
|
POUND,
|
||||||
|
LEFT_CHEVRON,
|
||||||
|
RIGHT_CHEVRON,
|
||||||
|
CARET
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class fmt_align_t : u8
|
||||||
|
{
|
||||||
|
LEFT,
|
||||||
|
CENTER,
|
||||||
|
RIGHT
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class fmt_sign_t : u8
|
enum class fmt_sign_t : u8
|
||||||
|
@ -67,7 +77,8 @@ namespace blt::logging
|
||||||
i64 precision = -1;
|
i64 precision = -1;
|
||||||
fmt_type_t type = fmt_type_t::UNSPECIFIED;
|
fmt_type_t type = fmt_type_t::UNSPECIFIED;
|
||||||
fmt_sign_t sign = fmt_sign_t::MINUS;
|
fmt_sign_t sign = fmt_sign_t::MINUS;
|
||||||
bool leading_zeros = false;
|
fmt_align_t alignment = fmt_align_t::RIGHT;
|
||||||
|
std::optional<char> prefix_char;
|
||||||
bool uppercase = false;
|
bool uppercase = false;
|
||||||
bool alternate_form = false;
|
bool alternate_form = false;
|
||||||
};
|
};
|
||||||
|
@ -100,6 +111,11 @@ namespace blt::logging
|
||||||
public:
|
public:
|
||||||
explicit fmt_parser_t() = default;
|
explicit fmt_parser_t() = default;
|
||||||
|
|
||||||
|
fmt_token_t& peek(const size_t offset)
|
||||||
|
{
|
||||||
|
return m_tokens[m_pos + offset];
|
||||||
|
}
|
||||||
|
|
||||||
fmt_token_t& peek()
|
fmt_token_t& peek()
|
||||||
{
|
{
|
||||||
return m_tokens[m_pos];
|
return m_tokens[m_pos];
|
||||||
|
@ -110,6 +126,11 @@ namespace blt::logging
|
||||||
return m_pos < m_tokens.size();
|
return m_pos < m_tokens.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] bool has_next(const size_t offset) const
|
||||||
|
{
|
||||||
|
return (m_pos + offset) < m_tokens.size();
|
||||||
|
}
|
||||||
|
|
||||||
[[nodiscard]] fmt_token_t& next()
|
[[nodiscard]] fmt_token_t& next()
|
||||||
{
|
{
|
||||||
return m_tokens[m_pos++];
|
return m_tokens[m_pos++];
|
||||||
|
@ -120,18 +141,27 @@ namespace blt::logging
|
||||||
++m_pos;
|
++m_pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void consume(const size_t amount)
|
||||||
|
{
|
||||||
|
m_pos += amount;
|
||||||
|
}
|
||||||
|
|
||||||
const fmt_spec_t& parse(std::string_view fmt);
|
const fmt_spec_t& parse(std::string_view fmt);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
static bool is_align_t(fmt_token_type type);
|
||||||
|
|
||||||
void parse_fmt_field();
|
void parse_fmt_field();
|
||||||
void parse_arg_id();
|
void parse_arg_id();
|
||||||
|
|
||||||
void parse_fmt_spec();
|
void parse_fmt_spec();
|
||||||
|
void parse_fmt_spec_align();
|
||||||
void parse_fmt_spec_sign();
|
void parse_fmt_spec_sign();
|
||||||
void parse_fmt_spec_form();
|
void parse_fmt_spec_form();
|
||||||
void parse_fmt_spec_width();
|
void parse_fmt_spec_width();
|
||||||
void parse_fmt_spec_precision();
|
void parse_fmt_spec_precision();
|
||||||
|
|
||||||
|
void parse_align();
|
||||||
void parse_sign();
|
void parse_sign();
|
||||||
void parse_form();
|
void parse_form();
|
||||||
void parse_width();
|
void parse_width();
|
||||||
|
|
|
@ -19,7 +19,6 @@
|
||||||
#ifndef BLT_LOGGING_LOGGING_H
|
#ifndef BLT_LOGGING_LOGGING_H
|
||||||
#define BLT_LOGGING_LOGGING_H
|
#define BLT_LOGGING_LOGGING_H
|
||||||
|
|
||||||
#include <sstream>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
@ -37,7 +36,9 @@ namespace blt::logging
|
||||||
|
|
||||||
struct logger_t
|
struct logger_t
|
||||||
{
|
{
|
||||||
explicit logger_t() = default;
|
explicit logger_t(std::ostream& stream): m_stream(stream)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
template <typename... Args>
|
template <typename... Args>
|
||||||
std::string log(std::string fmt, Args&&... args)
|
std::string log(std::string fmt, Args&&... args)
|
||||||
|
@ -51,7 +52,7 @@ namespace blt::logging
|
||||||
return to_string();
|
return to_string();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string to_string();
|
[[nodiscard]] std::string to_string() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template <typename... Args, size_t... Indexes>
|
template <typename... Args, size_t... Indexes>
|
||||||
|
@ -136,7 +137,7 @@ namespace blt::logging
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
void setup_stream(const fmt_spec_t& spec);
|
void setup_stream(const fmt_spec_t& spec) const;
|
||||||
void process_strings();
|
void process_strings();
|
||||||
static void handle_type(std::ostream& stream, const fmt_spec_t& spec);
|
static void handle_type(std::ostream& stream, const fmt_spec_t& spec);
|
||||||
|
|
||||||
|
@ -148,7 +149,7 @@ namespace blt::logging
|
||||||
std::optional<std::pair<size_t, size_t>> consume_to_next_fmt();
|
std::optional<std::pair<size_t, size_t>> consume_to_next_fmt();
|
||||||
|
|
||||||
std::string m_fmt;
|
std::string m_fmt;
|
||||||
std::stringstream m_stream;
|
std::ostream& m_stream;
|
||||||
fmt_parser_t m_parser;
|
fmt_parser_t m_parser;
|
||||||
// normal sections of string
|
// normal sections of string
|
||||||
std::vector<std::string_view> m_string_sections;
|
std::vector<std::string_view> m_string_sections;
|
||||||
|
@ -159,7 +160,7 @@ namespace blt::logging
|
||||||
size_t m_arg_pos = 0;
|
size_t m_arg_pos = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
void print(const std::string& fmt);
|
void print(const std::string& str);
|
||||||
|
|
||||||
void newline();
|
void newline();
|
||||||
|
|
||||||
|
@ -172,12 +173,26 @@ namespace blt::logging
|
||||||
print(logger.log(std::move(fmt), std::forward<Args>(args)...));
|
print(logger.log(std::move(fmt), std::forward<Args>(args)...));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename... Args>
|
||||||
|
void print(std::ostream& stream, std::string fmt, Args&&... args)
|
||||||
|
{
|
||||||
|
auto& logger = get_global_logger();
|
||||||
|
stream << logger.log(std::move(fmt), std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
template <typename... Args>
|
template <typename... Args>
|
||||||
void println(std::string fmt, Args&&... args)
|
void println(std::string fmt, Args&&... args)
|
||||||
{
|
{
|
||||||
print(std::move(fmt), std::forward<Args>(args)...);
|
print(std::move(fmt), std::forward<Args>(args)...);
|
||||||
newline();
|
newline();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename... Args>
|
||||||
|
void println(std::ostream& stream, std::string fmt, Args&&... args)
|
||||||
|
{
|
||||||
|
print(stream, std::move(fmt), std::forward<Args>(args)...);
|
||||||
|
stream << std::endl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // BLT_LOGGING_LOGGING_H
|
#endif // BLT_LOGGING_LOGGING_H
|
||||||
|
|
|
@ -19,6 +19,8 @@
|
||||||
#ifndef BLT_META_IS_STREAMABLE_H
|
#ifndef BLT_META_IS_STREAMABLE_H
|
||||||
#define BLT_META_IS_STREAMABLE_H
|
#define BLT_META_IS_STREAMABLE_H
|
||||||
|
|
||||||
|
#include <ostream>
|
||||||
|
|
||||||
namespace blt::meta
|
namespace blt::meta
|
||||||
{
|
{
|
||||||
// https://stackoverflow.com/questions/66397071/is-it-possible-to-check-if-overloaded-operator-for-type-or-class-exists
|
// https://stackoverflow.com/questions/66397071/is-it-possible-to-check-if-overloaded-operator-for-type-or-class-exists
|
||||||
|
|
|
@ -49,6 +49,12 @@ namespace blt::logging
|
||||||
return fmt_token_type::SPACE;
|
return fmt_token_type::SPACE;
|
||||||
case '#':
|
case '#':
|
||||||
return fmt_token_type::POUND;
|
return fmt_token_type::POUND;
|
||||||
|
case '<':
|
||||||
|
return fmt_token_type::LEFT_CHEVRON;
|
||||||
|
case '>':
|
||||||
|
return fmt_token_type::RIGHT_CHEVRON;
|
||||||
|
case '^':
|
||||||
|
return fmt_token_type::CARET;
|
||||||
default:
|
default:
|
||||||
return fmt_token_type::STRING;
|
return fmt_token_type::STRING;
|
||||||
}
|
}
|
||||||
|
@ -66,6 +72,9 @@ namespace blt::logging
|
||||||
case fmt_token_type::DOT:
|
case fmt_token_type::DOT:
|
||||||
case fmt_token_type::COLON:
|
case fmt_token_type::COLON:
|
||||||
case fmt_token_type::POUND:
|
case fmt_token_type::POUND:
|
||||||
|
case fmt_token_type::LEFT_CHEVRON:
|
||||||
|
case fmt_token_type::RIGHT_CHEVRON:
|
||||||
|
case fmt_token_type::CARET:
|
||||||
return fmt_token_t{base_type, std::string_view{m_fmt.data() + m_pos++, 1}};
|
return fmt_token_t{base_type, std::string_view{m_fmt.data() + m_pos++, 1}};
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
|
@ -99,6 +108,19 @@ namespace blt::logging
|
||||||
return m_spec;
|
return m_spec;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool fmt_parser_t::is_align_t(const fmt_token_type type)
|
||||||
|
{
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case fmt_token_type::LEFT_CHEVRON:
|
||||||
|
case fmt_token_type::RIGHT_CHEVRON:
|
||||||
|
case fmt_token_type::CARET:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void fmt_parser_t::parse_fmt_field()
|
void fmt_parser_t::parse_fmt_field()
|
||||||
{
|
{
|
||||||
if (!has_next())
|
if (!has_next())
|
||||||
|
@ -119,12 +141,7 @@ namespace blt::logging
|
||||||
case fmt_token_type::COLON:
|
case fmt_token_type::COLON:
|
||||||
parse_fmt_spec();
|
parse_fmt_spec();
|
||||||
break;
|
break;
|
||||||
case fmt_token_type::STRING:
|
default:
|
||||||
case fmt_token_type::SPACE:
|
|
||||||
case fmt_token_type::DOT:
|
|
||||||
case fmt_token_type::MINUS:
|
|
||||||
case fmt_token_type::PLUS:
|
|
||||||
case fmt_token_type::POUND:
|
|
||||||
{
|
{
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << "Expected unknown token '" << static_cast<u8>(type) << "' value '" << value << "' when parsing format field";
|
ss << "Expected unknown token '" << static_cast<u8>(type) << "' value '" << value << "' when parsing format field";
|
||||||
|
@ -155,7 +172,18 @@ namespace blt::logging
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case fmt_token_type::STRING:
|
case fmt_token_type::STRING:
|
||||||
|
if (has_next(1))
|
||||||
|
{
|
||||||
|
const auto [next_type, next_value] = peek(1);
|
||||||
|
if (is_align_t(next_type))
|
||||||
|
parse_fmt_spec_align();
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
|
case fmt_token_type::RIGHT_CHEVRON:
|
||||||
|
case fmt_token_type::LEFT_CHEVRON:
|
||||||
|
case fmt_token_type::CARET:
|
||||||
|
parse_fmt_spec_align();
|
||||||
|
break;
|
||||||
case fmt_token_type::COLON:
|
case fmt_token_type::COLON:
|
||||||
{
|
{
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
|
@ -179,6 +207,42 @@ namespace blt::logging
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void fmt_parser_t::parse_fmt_spec_align()
|
||||||
|
{
|
||||||
|
parse_align();
|
||||||
|
if (!has_next())
|
||||||
|
return;
|
||||||
|
auto [type, value] = peek();
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case fmt_token_type::STRING:
|
||||||
|
return;
|
||||||
|
case fmt_token_type::NUMBER:
|
||||||
|
parse_fmt_spec_width();
|
||||||
|
break;
|
||||||
|
case fmt_token_type::DOT:
|
||||||
|
parse_fmt_spec_precision();
|
||||||
|
break;
|
||||||
|
case fmt_token_type::SPACE:
|
||||||
|
case fmt_token_type::MINUS:
|
||||||
|
case fmt_token_type::PLUS:
|
||||||
|
parse_fmt_spec_sign();
|
||||||
|
break;
|
||||||
|
case fmt_token_type::POUND:
|
||||||
|
parse_fmt_spec_form();
|
||||||
|
break;
|
||||||
|
case fmt_token_type::CARET:
|
||||||
|
case fmt_token_type::COLON:
|
||||||
|
case fmt_token_type::LEFT_CHEVRON:
|
||||||
|
case fmt_token_type::RIGHT_CHEVRON:
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << "(Stage (Begin)) Invalid token type " << static_cast<u8>(type) << " value " << value;
|
||||||
|
throw std::runtime_error(ss.str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// handle start of fmt, with sign
|
// handle start of fmt, with sign
|
||||||
void fmt_parser_t::parse_fmt_spec_sign()
|
void fmt_parser_t::parse_fmt_spec_sign()
|
||||||
{
|
{
|
||||||
|
@ -194,6 +258,9 @@ namespace blt::logging
|
||||||
case fmt_token_type::MINUS:
|
case fmt_token_type::MINUS:
|
||||||
case fmt_token_type::PLUS:
|
case fmt_token_type::PLUS:
|
||||||
case fmt_token_type::COLON:
|
case fmt_token_type::COLON:
|
||||||
|
case fmt_token_type::CARET:
|
||||||
|
case fmt_token_type::LEFT_CHEVRON:
|
||||||
|
case fmt_token_type::RIGHT_CHEVRON:
|
||||||
{
|
{
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << "(Stage (Sign)) Invalid token type " << static_cast<u8>(type) << " value " << value;
|
ss << "(Stage (Sign)) Invalid token type " << static_cast<u8>(type) << " value " << value;
|
||||||
|
@ -226,6 +293,9 @@ namespace blt::logging
|
||||||
case fmt_token_type::MINUS:
|
case fmt_token_type::MINUS:
|
||||||
case fmt_token_type::PLUS:
|
case fmt_token_type::PLUS:
|
||||||
case fmt_token_type::POUND:
|
case fmt_token_type::POUND:
|
||||||
|
case fmt_token_type::CARET:
|
||||||
|
case fmt_token_type::LEFT_CHEVRON:
|
||||||
|
case fmt_token_type::RIGHT_CHEVRON:
|
||||||
{
|
{
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << "(Stage (Form)) Invalid token type " << static_cast<u8>(type) << " value " << value;
|
ss << "(Stage (Form)) Invalid token type " << static_cast<u8>(type) << " value " << value;
|
||||||
|
@ -257,6 +327,9 @@ namespace blt::logging
|
||||||
case fmt_token_type::SPACE:
|
case fmt_token_type::SPACE:
|
||||||
case fmt_token_type::POUND:
|
case fmt_token_type::POUND:
|
||||||
case fmt_token_type::NUMBER:
|
case fmt_token_type::NUMBER:
|
||||||
|
case fmt_token_type::CARET:
|
||||||
|
case fmt_token_type::LEFT_CHEVRON:
|
||||||
|
case fmt_token_type::RIGHT_CHEVRON:
|
||||||
{
|
{
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << "(Stage (Width)) Invalid token type " << static_cast<u8>(type) << " value " << value;
|
ss << "(Stage (Width)) Invalid token type " << static_cast<u8>(type) << " value " << value;
|
||||||
|
@ -275,6 +348,36 @@ namespace blt::logging
|
||||||
parse_precision();
|
parse_precision();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void fmt_parser_t::parse_align()
|
||||||
|
{
|
||||||
|
auto [type, value] = next();
|
||||||
|
fmt_token_type process_type = type;
|
||||||
|
if (type == fmt_token_type::STRING)
|
||||||
|
{
|
||||||
|
auto [next_type, next_value] = next();
|
||||||
|
process_type = next_type;
|
||||||
|
m_spec.prefix_char = value.front();
|
||||||
|
}
|
||||||
|
switch (process_type)
|
||||||
|
{
|
||||||
|
case fmt_token_type::LEFT_CHEVRON:
|
||||||
|
m_spec.alignment = fmt_align_t::LEFT;
|
||||||
|
break;
|
||||||
|
case fmt_token_type::RIGHT_CHEVRON:
|
||||||
|
m_spec.alignment = fmt_align_t::RIGHT;
|
||||||
|
break;
|
||||||
|
case fmt_token_type::CARET:
|
||||||
|
m_spec.alignment = fmt_align_t::CENTER;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << "Invalid align type " << static_cast<u8>(process_type) << " value " << value;
|
||||||
|
throw std::runtime_error(ss.str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void fmt_parser_t::parse_sign()
|
void fmt_parser_t::parse_sign()
|
||||||
{
|
{
|
||||||
auto [_, value] = next();
|
auto [_, value] = next();
|
||||||
|
@ -313,8 +416,8 @@ namespace blt::logging
|
||||||
void fmt_parser_t::parse_width()
|
void fmt_parser_t::parse_width()
|
||||||
{
|
{
|
||||||
auto [_, value] = next();
|
auto [_, value] = next();
|
||||||
if (value.front() == '0')
|
if (value.front() == '0' && !m_spec.prefix_char.has_value())
|
||||||
m_spec.leading_zeros = true;
|
m_spec.prefix_char = '0';
|
||||||
m_spec.width = std::stoll(std::string(value));
|
m_spec.width = std::stoll(std::string(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
*/
|
*/
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
#include <blt/iterator/enumerate.h>
|
#include <blt/iterator/enumerate.h>
|
||||||
#include <blt/logging/logging.h>
|
#include <blt/logging/logging.h>
|
||||||
#include <blt/std/types.h>
|
#include <blt/std/types.h>
|
||||||
|
@ -25,23 +26,33 @@ namespace blt::logging
|
||||||
{
|
{
|
||||||
struct logging_thread_context_t
|
struct logging_thread_context_t
|
||||||
{
|
{
|
||||||
logger_t logger;
|
std::stringstream stream;
|
||||||
|
logger_t logger{stream};
|
||||||
};
|
};
|
||||||
|
|
||||||
std::string logger_t::to_string()
|
std::string logger_t::to_string() const
|
||||||
{
|
{
|
||||||
auto str = m_stream.str();
|
return dynamic_cast<std::stringstream&>(m_stream).str();
|
||||||
m_stream.str("");
|
|
||||||
m_stream.clear();
|
|
||||||
return str;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void logger_t::setup_stream(const fmt_spec_t& spec)
|
void logger_t::setup_stream(const fmt_spec_t& spec) const
|
||||||
{
|
{
|
||||||
if (spec.leading_zeros)
|
if (spec.prefix_char)
|
||||||
m_stream << std::setfill('0');
|
m_stream << std::setfill(*spec.prefix_char);
|
||||||
else
|
else
|
||||||
m_stream << std::setfill(' ');
|
m_stream << std::setfill(' ');
|
||||||
|
switch (spec.alignment)
|
||||||
|
{
|
||||||
|
case fmt_align_t::LEFT:
|
||||||
|
m_stream << std::left;
|
||||||
|
break;
|
||||||
|
case fmt_align_t::CENTER:
|
||||||
|
// TODO?
|
||||||
|
break;
|
||||||
|
case fmt_align_t::RIGHT:
|
||||||
|
m_stream << std::right;
|
||||||
|
break;
|
||||||
|
}
|
||||||
if (spec.width > 0)
|
if (spec.width > 0)
|
||||||
m_stream << std::setw(static_cast<i32>(spec.width));
|
m_stream << std::setw(static_cast<i32>(spec.width));
|
||||||
else
|
else
|
||||||
|
@ -52,6 +63,8 @@ namespace blt::logging
|
||||||
m_stream << std::setprecision(16);
|
m_stream << std::setprecision(16);
|
||||||
if (spec.alternate_form)
|
if (spec.alternate_form)
|
||||||
m_stream << std::showbase;
|
m_stream << std::showbase;
|
||||||
|
else
|
||||||
|
m_stream << std::noshowbase;
|
||||||
if (spec.uppercase)
|
if (spec.uppercase)
|
||||||
m_stream << std::uppercase;
|
m_stream << std::uppercase;
|
||||||
else
|
else
|
||||||
|
@ -129,7 +142,8 @@ namespace blt::logging
|
||||||
m_fmt = std::move(fmt);
|
m_fmt = std::move(fmt);
|
||||||
m_last_fmt_pos = 0;
|
m_last_fmt_pos = 0;
|
||||||
m_arg_pos = 0;
|
m_arg_pos = 0;
|
||||||
m_stream.str("");
|
auto& ss = dynamic_cast<std::stringstream&>(m_stream);
|
||||||
|
ss.str("");
|
||||||
m_stream.clear();
|
m_stream.clear();
|
||||||
m_string_sections.clear();
|
m_string_sections.clear();
|
||||||
m_fmt_specs.clear();
|
m_fmt_specs.clear();
|
||||||
|
@ -171,9 +185,9 @@ namespace blt::logging
|
||||||
return context.logger;
|
return context.logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
void print(const std::string& fmt)
|
void print(const std::string& str)
|
||||||
{
|
{
|
||||||
std::cout << fmt;
|
std::cout << str;
|
||||||
}
|
}
|
||||||
|
|
||||||
void newline()
|
void newline()
|
||||||
|
|
|
@ -15,45 +15,112 @@
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
#include <blt/logging/logging.h>
|
#include <blt/logging/logging.h>
|
||||||
|
#include <blt/std/assert.h>
|
||||||
#include <blt/std/utility.h>
|
#include <blt/std/utility.h>
|
||||||
|
|
||||||
struct some_silly_type_t
|
struct some_silly_type_t
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
|
||||||
|
auto expected_str = std::string(R"(This is a println!
|
||||||
|
This is a println with args '42'
|
||||||
|
This is a println with multiple args '42' '32.342311859130859375' 'Hello World!'
|
||||||
|
This is a 'Well so am I except cooler :3' fmt string with positionals 'I am a string!'
|
||||||
|
This is a println with a sign +4120
|
||||||
|
This is a println with a sign -4120
|
||||||
|
This is a println with a space 4120
|
||||||
|
This is a println with a space -4120
|
||||||
|
This is a println with a minus 4120
|
||||||
|
This is a println with a minus -4120
|
||||||
|
This is a println with a with 4120
|
||||||
|
This is a println with a with leading zeros 0000004120
|
||||||
|
This is a println with a precision 42.2323423490
|
||||||
|
This is a println with hex 109a
|
||||||
|
This is a println with hex with leading 0x109a
|
||||||
|
This is a println with binary 0b00110010000110100101011000000000
|
||||||
|
This is a println with binary with space 0b10110010 00011010 01010110 00000000
|
||||||
|
This is a println with binary with space 10100010 00000000 00000000 00000000
|
||||||
|
This is a println with octal 015015
|
||||||
|
This is a println with hexfloat 0x1.926e978d4fdf4p+8
|
||||||
|
This is a println with exponent 4.4320902431999996e+07
|
||||||
|
This is a println with exponent 9.5324342340423400e+15
|
||||||
|
This is a println with general 953243.49
|
||||||
|
This is a println with general 9.532433240234033e+17
|
||||||
|
This is a println with a char B
|
||||||
|
This is a println with type some_silly_type_t
|
||||||
|
This is a println with boolean true
|
||||||
|
This is a println with boolean as int 0
|
||||||
|
This is a println with boolean as hex 0x1
|
||||||
|
This is a println with boolean as octal 1
|
||||||
|
This is a println with alignment left 64 end value
|
||||||
|
This is a println with alignment right 46 end value
|
||||||
|
This is a println with alignment left (fill) 46******** end value
|
||||||
|
This is a println with alignment right (fill) ********46 end value
|
||||||
|
)");
|
||||||
|
|
||||||
|
std::pair<bool, std::string> compare_strings(const std::string& s1, const std::string& s2)
|
||||||
|
{
|
||||||
|
if (s1.size() != s2.size())
|
||||||
|
return {false, "Strings size do not match '" + std::to_string(s1.size()) + "' vs '" + std::to_string(s2.size()) + "'"};
|
||||||
|
size_t index = 0;
|
||||||
|
for (; index < s1.size(); ++index)
|
||||||
|
{
|
||||||
|
if (s1[index] != s2[index])
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
const auto i1 = std::max(static_cast<blt::i64>(index) - 32, 0l);
|
||||||
|
const auto l1 = std::min(static_cast<blt::i64>(s1.size()) - i1, 65l);
|
||||||
|
ss << "Strings differ at index " << index << "!\n";
|
||||||
|
ss << "'" << s1.substr(i1, l1) << "' vs '" << s2.substr(i1, l1) << "'" << std::endl;
|
||||||
|
return {false, ss.str()};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {true, ""};
|
||||||
|
}
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
blt::logging::println("This is a println!");
|
std::stringstream ss;
|
||||||
blt::logging::println("This is a println with args '{}'", 42);
|
blt::logging::println(ss, "This is a println!");
|
||||||
blt::logging::println("This is a println with multiple args '{}' '{:.100}' '{}'", 42, 32.34231233f, "Hello World!");
|
blt::logging::println(ss, "This is a println with args '{}'", 42);
|
||||||
blt::logging::println("This is a '{1}' fmt string with positionals '{0}'", "I am a string!", "Well so am I except cooler :3");
|
blt::logging::println(ss, "This is a println with multiple args '{}' '{:.100}' '{}'", 42, 32.34231233f, "Hello World!");
|
||||||
blt::logging::println("This is a println with a sign {:+}", 4120);
|
blt::logging::println(ss, "This is a '{1}' fmt string with positionals '{0}'", "I am a string!", "Well so am I except cooler :3");
|
||||||
blt::logging::println("This is a println with a sign {:+}", -4120);
|
blt::logging::println(ss, "This is a println with a sign {:+}", 4120);
|
||||||
blt::logging::println("This is a println with a space {: }", 4120);
|
blt::logging::println(ss, "This is a println with a sign {:+}", -4120);
|
||||||
blt::logging::println("This is a println with a space {: }", -4120);
|
blt::logging::println(ss, "This is a println with a space {: }", 4120);
|
||||||
blt::logging::println("This is a println with a minus {:-}", 4120);
|
blt::logging::println(ss, "This is a println with a space {: }", -4120);
|
||||||
blt::logging::println("This is a println with a minus {:-}", -4120);
|
blt::logging::println(ss, "This is a println with a minus {:-}", 4120);
|
||||||
blt::logging::println("This is a println with a with {:10}", 4120);
|
blt::logging::println(ss, "This is a println with a minus {:-}", -4120);
|
||||||
blt::logging::println("This is a println with a with leading zeros {:010}", 4120);
|
blt::logging::println(ss, "This is a println with a with {:10}", 4120);
|
||||||
blt::logging::println("This is a println with a precision {:.10f}", 42.232342349);
|
blt::logging::println(ss, "This is a println with a with leading zeros {:010}", 4120);
|
||||||
blt::logging::println("This is a println with hex {:.10x}", 4250);
|
blt::logging::println(ss, "This is a println with a precision {:.10f}", 42.232342349);
|
||||||
blt::logging::println("This is a println with hex with leading {:#.10x}", 4250);
|
blt::logging::println(ss, "This is a println with hex {:.10x}", 4250);
|
||||||
blt::logging::println("This is a println with binary {:#b}", 6969420);
|
blt::logging::println(ss, "This is a println with hex with leading {:#.10x}", 4250);
|
||||||
blt::logging::println("This is a println with binary with space {: #b}", 6969421);
|
blt::logging::println(ss, "This is a println with binary {:#b}", 6969420);
|
||||||
blt::logging::println("This is a println with binary with space {: b}", 69);
|
blt::logging::println(ss, "This is a println with binary with space {: #b}", 6969421);
|
||||||
blt::logging::println("This is a println with octal {:#o}", 6669);
|
blt::logging::println(ss, "This is a println with binary with space {: b}", 69);
|
||||||
blt::logging::println("This is a println with hexfloat {:a}", 402.4320);
|
blt::logging::println(ss, "This is a println with octal {:#o}", 6669);
|
||||||
blt::logging::println("This is a println with exponent {:e}", 44320902.4320);
|
blt::logging::println(ss, "This is a println with hexfloat {:a}", 402.4320);
|
||||||
blt::logging::println("This is a println with exponent {:e}", 9532434234042340.0);
|
blt::logging::println(ss, "This is a println with exponent {:e}", 44320902.4320);
|
||||||
blt::logging::println("This is a println with general {:g}", 953243.49);
|
blt::logging::println(ss, "This is a println with exponent {:e}", 9532434234042340.0);
|
||||||
blt::logging::println("This is a println with general {:g}", 953243324023403240.49);
|
blt::logging::println(ss, "This is a println with general {:g}", 953243.49);
|
||||||
blt::logging::println("This is a println with a char {:c}", 66);
|
blt::logging::println(ss, "This is a println with general {:g}", 953243324023403240.49);
|
||||||
blt::logging::println("This is a println with type {:t}", some_silly_type_t{});
|
blt::logging::println(ss, "This is a println with a char {:c}", 66);
|
||||||
blt::logging::println("This is a println with boolean {}", true);
|
blt::logging::println(ss, "This is a println with type {:t}", some_silly_type_t{});
|
||||||
blt::logging::println("This is a println with boolean as int {:d}", false);
|
blt::logging::println(ss, "This is a println with boolean {}", true);
|
||||||
blt::logging::println("This is a println with boolean as hex {:#x}", true);
|
blt::logging::println(ss, "This is a println with boolean as int {:d}", false);
|
||||||
blt::logging::println("This is a println with boolean as octal {:o}", true);
|
blt::logging::println(ss, "This is a println with boolean as hex {:#x}", true);
|
||||||
blt::logging::println("This is a println with boolean as test {:h}", true);
|
blt::logging::println(ss, "This is a println with boolean as octal {:o}", true);
|
||||||
|
blt::logging::println(ss, "This is a println with alignment left {:<10} end value", 64);
|
||||||
|
blt::logging::println(ss, "This is a println with alignment right {:>10} end value", 46);
|
||||||
|
blt::logging::println(ss, "This is a println with alignment left (fill) {:*<10} end value", 46);
|
||||||
|
blt::logging::println(ss, "This is a println with alignment right (fill) {:*>10} end value", 46);
|
||||||
|
blt::logging::print(ss.str());
|
||||||
|
auto [passed, error_msg] = compare_strings(expected_str, ss.str());
|
||||||
|
BLT_ASSERT_MSG(passed && "Logger logged string doesn't match precomputed expected string!", error_msg.c_str());
|
||||||
|
|
||||||
// blt::logging::println("This is println {}\twith a std::endl in the middle of it");
|
// blt::logging::println("This is println {}\twith a std::endl in the middle of it");
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue