Implemented ast_node_T; parse_string now returns an actual AST; Moved functions to new files
This commit is contained in:
parent
92d8f423d8
commit
0d72d35229
@ -1,18 +1,10 @@
|
|||||||
#ifndef LOGGER_UTILITY_H
|
#ifndef LOGGER_CONSTSTRING_H
|
||||||
#define LOGGER_UTILITY_H
|
#define LOGGER_CONSTSTRING_H
|
||||||
|
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
|
|
||||||
constexpr std::size_t const_pow(std::size_t base, int exponent) {
|
|
||||||
if (exponent == 0)
|
|
||||||
return 1;
|
|
||||||
else
|
|
||||||
return base * const_pow(base, exponent -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <std::size_t N>
|
template <std::size_t N>
|
||||||
class ConstString {
|
class ConstString {
|
||||||
public:
|
public:
|
||||||
@ -40,4 +32,4 @@ ConstString(const char (&)[N]) -> ConstString<N>;
|
|||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
|
|
||||||
#endif // LOGGER_UTILITY_H
|
#endif // LOGGER_CONSTSTRING_H
|
||||||
@ -6,8 +6,8 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
|
|
||||||
#include <parsing.h>
|
#include <format.h>
|
||||||
#include <utility.h>
|
#include <ConstString.h>
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
61
inc/format.h
Normal file
61
inc/format.h
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
#ifndef LOGGER_FORMAT_H
|
||||||
|
#define LOGGER_FORMAT_H
|
||||||
|
|
||||||
|
|
||||||
|
#include "parse.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
|
||||||
|
template <ConstString s>
|
||||||
|
constexpr int get_output_len() {
|
||||||
|
constexpr auto parse_result = parse_string<s>();
|
||||||
|
static_assert(parse_result.is_valid, "Syntax error in log string");
|
||||||
|
|
||||||
|
unsigned result = 0;
|
||||||
|
|
||||||
|
for (const auto& ast_node : parse_result.value) {
|
||||||
|
if (ast_node.is_char())
|
||||||
|
++result;
|
||||||
|
else
|
||||||
|
result += ast_node.get_node().length;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, fmt_node_t fmt_node>
|
||||||
|
constexpr bool is_valid_type() {
|
||||||
|
// TODO
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, fmt_node_t fmt_node>
|
||||||
|
constexpr std::array<char, fmt_node.length> format_arg(T arg) {
|
||||||
|
static_assert(is_valid_type<T, fmt_node>(), "Invalid argument type");
|
||||||
|
|
||||||
|
std::array<char, fmt_node.length> result;
|
||||||
|
|
||||||
|
for (auto& c : result)
|
||||||
|
c = 'f';
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
|
||||||
|
template <detail::ConstString s, typename... args_t>
|
||||||
|
std::array<char, detail::get_output_len<s>()> format(args_t... args) {
|
||||||
|
constexpr auto parse_result = detail::parse_string<s>();
|
||||||
|
static_assert(parse_result.is_valid);
|
||||||
|
|
||||||
|
std::array<char, detail::get_output_len<s>()> result;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif // LOGGER_FORMAT_H
|
||||||
@ -1,31 +1,9 @@
|
|||||||
#ifndef LOGGER_PARSING_H
|
#ifndef LOGGER_PARSE_H
|
||||||
#define LOGGER_PARSING_H
|
#define LOGGER_PARSE_H
|
||||||
|
|
||||||
|
|
||||||
#include <utility.h>
|
#include "ConstString.h"
|
||||||
|
#include "parse_types.h"
|
||||||
|
|
||||||
namespace detail {
|
|
||||||
|
|
||||||
|
|
||||||
enum class FormatType { s, c, b, B, d, o, x, X, a, A, e, E, f, F, g, G, p };
|
|
||||||
|
|
||||||
template <typename value_t>
|
|
||||||
struct parse_result_t {
|
|
||||||
bool is_valid = false;
|
|
||||||
unsigned new_index = 0;
|
|
||||||
value_t value;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct fmt_node_t {
|
|
||||||
bool has_zero_padding = false;
|
|
||||||
int length = 6;
|
|
||||||
int precision = 2;
|
|
||||||
FormatType type = FormatType::s;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <std::size_t N>
|
|
||||||
using string_result_t = std::array<fmt_node_t, N>;
|
|
||||||
|
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
@ -60,6 +38,63 @@ using string_result_t = std::array<fmt_node_t, N>;
|
|||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* Functions to determine the size of data structures
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
template <ConstString s>
|
||||||
|
constexpr unsigned count_braces() {
|
||||||
|
unsigned result = 0;
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < s.size(); ++i) {
|
||||||
|
if (s[i] == '{')
|
||||||
|
++result;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <ConstString s>
|
||||||
|
constexpr unsigned strlen_braces() {
|
||||||
|
unsigned result = 0;
|
||||||
|
|
||||||
|
bool brace_open = false;
|
||||||
|
for (unsigned i = 0; i < s.size(); ++i) {
|
||||||
|
if (!brace_open) {
|
||||||
|
if (s[i] == '{') {
|
||||||
|
brace_open = true;
|
||||||
|
++result;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
++result;
|
||||||
|
if (s[i] == '}') {
|
||||||
|
brace_open = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <ConstString s>
|
||||||
|
constexpr int get_ast_len() {
|
||||||
|
return (s.size() - strlen_braces<s>() + count_braces<s>());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* Parsing functions
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
template <std::size_t N>
|
template <std::size_t N>
|
||||||
constexpr bool is_digit(ConstString<N> s, unsigned i) {
|
constexpr bool is_digit(ConstString<N> s, unsigned i) {
|
||||||
return (s[i] > 47) && (s[i] < 58);
|
return (s[i] > 47) && (s[i] < 58);
|
||||||
@ -200,47 +235,14 @@ constexpr parse_result_t<fmt_node_t> parse_braces(unsigned i) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <ConstString s>
|
template <ConstString s>
|
||||||
constexpr unsigned count_braces() {
|
constexpr parse_result_t<string_result_t<get_ast_len<s>()>> parse_string() {
|
||||||
unsigned result = 0;
|
parse_result_t<string_result_t<get_ast_len<s>()>> result;
|
||||||
|
|
||||||
for (unsigned i = 0; i < s.size(); ++i) {
|
|
||||||
if (s[i] == '{')
|
|
||||||
++result;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <ConstString s>
|
|
||||||
constexpr unsigned len_braces() {
|
|
||||||
unsigned result = 0;
|
|
||||||
|
|
||||||
bool brace_open = false;
|
|
||||||
for (unsigned i = 0; i < s.size(); ++i) {
|
|
||||||
if (!brace_open) {
|
|
||||||
if (s[i] == '{') {
|
|
||||||
brace_open = true;
|
|
||||||
++result;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
++result;
|
|
||||||
if (s[i] == '}') {
|
|
||||||
brace_open = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <ConstString s>
|
|
||||||
constexpr parse_result_t<string_result_t<count_braces<s>()>> parse_string() {
|
|
||||||
parse_result_t<string_result_t<count_braces<s>()>> result;
|
|
||||||
result.is_valid = true;
|
result.is_valid = true;
|
||||||
|
|
||||||
unsigned format_node_pos = 0;
|
unsigned ast_position = 0;
|
||||||
|
|
||||||
for (unsigned i = 0; i < s.size(); ++i) {
|
unsigned i = 0;
|
||||||
|
while (i < s.size()) {
|
||||||
if (s[i] == '{') {
|
if (s[i] == '{') {
|
||||||
++i;
|
++i;
|
||||||
|
|
||||||
@ -249,56 +251,22 @@ constexpr parse_result_t<string_result_t<count_braces<s>()>> parse_string() {
|
|||||||
return {false, i, {}};
|
return {false, i, {}};
|
||||||
}
|
}
|
||||||
i = new_i;
|
i = new_i;
|
||||||
result.value[format_node_pos++] = format_node;
|
result.value[ast_position++].set_node(format_node);
|
||||||
|
|
||||||
} else if (s[i] == '}') {
|
} else if (s[i] == '}') {
|
||||||
return {false, i, {}};
|
return {false, i, {}};
|
||||||
|
} else {
|
||||||
|
result.value[ast_position++].set_char(s[i]);
|
||||||
|
++i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <ConstString s>
|
|
||||||
constexpr int get_output_len() {
|
|
||||||
constexpr auto parse_result = parse_string<s>();
|
|
||||||
static_assert(parse_result.is_valid, "Syntax error in log string");
|
|
||||||
|
|
||||||
unsigned result = s.size() - len_braces<s>();
|
|
||||||
|
|
||||||
for (const auto& fmt_node : parse_result.value) {
|
|
||||||
result += fmt_node.length;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
|
|
||||||
template <detail::ConstString s, typename... args_t>
|
|
||||||
std::array<char, detail::get_output_len<s>()> format(args_t...) {
|
|
||||||
std::array<char, detail::get_output_len<s>()> result;
|
|
||||||
|
|
||||||
constexpr auto parse_result = detail::parse_string<s>();
|
#endif // LOGGER_PARSE_H
|
||||||
static_assert(parse_result.is_valid);
|
|
||||||
|
|
||||||
std::cout << "Total computed length: " << result.size() << std::endl;
|
|
||||||
|
|
||||||
for (const auto& format_node : parse_result.value) {
|
|
||||||
std::cout << "\tFormat Node:" << std::endl;
|
|
||||||
std::cout << "\t\thas_zero_padding:\t" << format_node.has_zero_padding
|
|
||||||
<< std::endl;
|
|
||||||
std::cout << "\t\tlength:\t\t\t\t" << format_node.length << std::endl;
|
|
||||||
std::cout << "\t\tprecision:\t\t\t" << format_node.precision
|
|
||||||
<< std::endl;
|
|
||||||
std::cout << "\t\ttype:\t\t\t\t" << static_cast<int>(format_node.type)
|
|
||||||
<< std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endif // LOGGER_PARSING_H
|
|
||||||
61
inc/parse_types.h
Normal file
61
inc/parse_types.h
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
#ifndef LOGGER_PARSE_TYPES_H
|
||||||
|
#define LOGGER_PARSE_TYPES_H
|
||||||
|
|
||||||
|
|
||||||
|
enum class FormatType { s, c, b, B, d, o, x, X, a, A, e, E, f, F, g, G, p };
|
||||||
|
|
||||||
|
|
||||||
|
template <typename value_t>
|
||||||
|
struct parse_result_t {
|
||||||
|
bool is_valid = false;
|
||||||
|
unsigned new_index = 0;
|
||||||
|
value_t value;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct fmt_node_t {
|
||||||
|
bool has_zero_padding = false;
|
||||||
|
int length = 6;
|
||||||
|
int precision = 2;
|
||||||
|
FormatType type = FormatType::s;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class ast_node_t {
|
||||||
|
public:
|
||||||
|
constexpr ast_node_t() {
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr void set_char(char c) {
|
||||||
|
m_c = c;
|
||||||
|
m_is_char = true;
|
||||||
|
}
|
||||||
|
constexpr void set_node(fmt_node_t node) {
|
||||||
|
m_node = node;
|
||||||
|
m_is_char = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr char get_char() const {
|
||||||
|
return m_c;
|
||||||
|
}
|
||||||
|
constexpr fmt_node_t get_node() const {
|
||||||
|
return m_node;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr bool is_char() const {
|
||||||
|
return m_is_char;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool m_is_char = false;
|
||||||
|
|
||||||
|
char m_c = 'c';
|
||||||
|
fmt_node_t m_node;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template <std::size_t N>
|
||||||
|
using string_result_t = std::array<ast_node_t, N>;
|
||||||
|
|
||||||
|
|
||||||
|
#endif //LOGGER_PARSE_TYPES_H
|
||||||
23
src/main.cpp
23
src/main.cpp
@ -8,36 +8,13 @@ public:
|
|||||||
void write(char c) {
|
void write(char c) {
|
||||||
std::cout << c;
|
std::cout << c;
|
||||||
}
|
}
|
||||||
private:
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
/* Uart uart;
|
|
||||||
|
|
||||||
Logger logger(uart);
|
|
||||||
logger.log<"Test:{}">(1, 2, 3);
|
|
||||||
|
|
||||||
std::cout << std::endl;
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
constexpr detail::ConstString s{"Test: {:16.8f} {:03.5} {:08.2}"};
|
constexpr detail::ConstString s{"Test: {:16.8f} {:03.5} {:08.2}"};
|
||||||
|
|
||||||
const auto formatted = format<s>(3.4, "abc", 8.98754);
|
const auto formatted = format<s>(3.4, "abc", 8.98754);
|
||||||
|
|
||||||
/*
|
|
||||||
constexpr detail::ConstString s = "{:8.14c}";
|
|
||||||
|
|
||||||
constexpr auto result = detail::parse_fmt_string<s>(2);
|
|
||||||
|
|
||||||
std::cout << "Is valid: " << result.is_valid << std::endl << std::endl;
|
|
||||||
|
|
||||||
std::cout << "\tresult.has_zero_padding: " << result.result.has_zero_padding << std::endl;
|
|
||||||
std::cout << "\tresult.length: " << result.result.length << std::endl;
|
|
||||||
std::cout << "\tresult.precision: " << result.result.precision << std::endl;
|
|
||||||
std::cout << "\tresult.type: " << static_cast<int>(result.result.type) << std::endl;
|
|
||||||
*/
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue
Block a user