Refactored parse_num and parse_type to return type parse_result
This commit is contained in:
parent
83332cc295
commit
f1952186e0
11
inc/Logger.h
11
inc/Logger.h
@ -35,14 +35,11 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <detail::ConstString msg, typename... args_t>
|
template <detail::ConstString msg, typename... args_t>
|
||||||
void log(args_t...) {
|
void log(args_t... args) {
|
||||||
constexpr int len = get_output_len(msg);
|
const auto formatted_msg = format<msg>(args...);
|
||||||
static_assert(len > 0, "Syntax error in log string");
|
|
||||||
|
|
||||||
std::cout << "Computed Length: " << len << std::endl;
|
for (const auto& c : formatted_msg) {
|
||||||
|
m_output_policy.write(c);
|
||||||
for (unsigned i = 0; i < msg.size(); ++i) {
|
|
||||||
m_output_policy.write(msg[i]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
119
inc/parsing.h
119
inc/parsing.h
@ -8,6 +8,24 @@
|
|||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* Parse format string
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
template <typename result_t>
|
||||||
|
struct parse_result {
|
||||||
|
bool valid = false;
|
||||||
|
unsigned new_index = 0;
|
||||||
|
unsigned length = 0;
|
||||||
|
result_t result;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class FormatType { s, c, b, B, d, o, x, X, a, A, e, E, f, F, g, G, p };
|
||||||
|
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -45,74 +63,87 @@ constexpr bool is_digit(ConstString<N> s, unsigned i) {
|
|||||||
return (s[i] > 47) && (s[i] < 58);
|
return (s[i] > 47) && (s[i] < 58);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* Functions to convert X to char array
|
||||||
|
* and ConstString to X
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
template <std::size_t N>
|
template <std::size_t N>
|
||||||
constexpr std::pair<unsigned, int> parse_number(ConstString<N> s, unsigned i) {
|
constexpr parse_result<int> parse_number(ConstString<N> s, unsigned i) {
|
||||||
|
int number = 0;
|
||||||
|
|
||||||
while ((i < s.size()) && is_digit(s, i)) {
|
while ((i < s.size()) && is_digit(s, i)) {
|
||||||
|
number = number * 10;
|
||||||
|
number += (s[i] - 48);
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
|
|
||||||
return {i, 0};
|
return {true, i, 0, number};
|
||||||
}
|
}
|
||||||
|
|
||||||
template <std::size_t N>
|
template <std::size_t N>
|
||||||
constexpr std::pair<unsigned, int> parse_type(ConstString<N> s, unsigned i) {
|
constexpr parse_result<FormatType> parse_type(ConstString<N> s, unsigned i) {
|
||||||
if (s[i] == 's') { // string
|
if (s[i] == 's') { // string
|
||||||
++i;
|
++i;
|
||||||
return {i, 0};
|
return {true, i, 1, FormatType::s};
|
||||||
} else if (s[i] == 'c') { // char
|
} else if (s[i] == 'c') { // char
|
||||||
++i;
|
++i;
|
||||||
return {i, 0};
|
return {true, i, 1, FormatType::c};
|
||||||
} else if (s[i] == 'b') { // int
|
} else if (s[i] == 'b') { // int
|
||||||
++i;
|
++i;
|
||||||
return {i, 0};
|
return {true, i, 1, FormatType::b};
|
||||||
} else if (s[i] == 'B') {
|
} else if (s[i] == 'B') {
|
||||||
++i;
|
++i;
|
||||||
return {i, 0};
|
return {true, i, 1, FormatType::B};
|
||||||
} else if (s[i] == 'c') {
|
// } else if (s[i] == 'c') {
|
||||||
++i;
|
// ++i;
|
||||||
return {i, 0};
|
// return {true, i, 1, FormatType::c};
|
||||||
} else if (s[i] == 'd') {
|
} else if (s[i] == 'd') {
|
||||||
++i;
|
++i;
|
||||||
return {i, 0};
|
return {true, i, 1, FormatType::d};
|
||||||
} else if (s[i] == '0') {
|
} else if (s[i] == 'o') {
|
||||||
++i;
|
++i;
|
||||||
return {i, 0};
|
return {true, i, 1, FormatType::o};
|
||||||
} else if (s[i] == 'x') {
|
} else if (s[i] == 'x') {
|
||||||
++i;
|
++i;
|
||||||
return {i, 0};
|
return {true, i, 1, FormatType::x};
|
||||||
} else if (s[i] == 'X') {
|
} else if (s[i] == 'X') {
|
||||||
++i;
|
++i;
|
||||||
return {i, 0};
|
return {true, i, 1, FormatType::X};
|
||||||
} else if (s[i] == 'a') { // float
|
} else if (s[i] == 'a') { // float
|
||||||
++i;
|
++i;
|
||||||
return {i, 0};
|
return {true, i, 1, FormatType::a};
|
||||||
} else if (s[i] == 'A') {
|
} else if (s[i] == 'A') {
|
||||||
++i;
|
++i;
|
||||||
return {i, 0};
|
return {true, i, 1, FormatType::A};
|
||||||
} else if (s[i] == 'e') {
|
} else if (s[i] == 'e') {
|
||||||
++i;
|
++i;
|
||||||
return {i, 0};
|
return {true, i, 1, FormatType::e};
|
||||||
} else if (s[i] == 'E') {
|
} else if (s[i] == 'E') {
|
||||||
++i;
|
++i;
|
||||||
return {i, 0};
|
return {true, i, 1, FormatType::E};
|
||||||
} else if (s[i] == 'f') {
|
} else if (s[i] == 'f') {
|
||||||
++i;
|
++i;
|
||||||
return {i, 0};
|
return {true, i, 1, FormatType::f};
|
||||||
} else if (s[i] == 'F') {
|
} else if (s[i] == 'F') {
|
||||||
++i;
|
++i;
|
||||||
return {i, 0};
|
return {true, i, 1, FormatType::F};
|
||||||
} else if (s[i] == 'g') {
|
} else if (s[i] == 'g') {
|
||||||
++i;
|
++i;
|
||||||
return {i, 0};
|
return {true, i, 1, FormatType::g};
|
||||||
} else if (s[i] == 'G') {
|
} else if (s[i] == 'G') {
|
||||||
++i;
|
++i;
|
||||||
return {i, 0};
|
return {true, i, 1, FormatType::G};
|
||||||
} else if (s[i] == 'p') { // pointer
|
} else if (s[i] == 'p') { // pointer
|
||||||
++i;
|
++i;
|
||||||
return {i, 0};
|
return {true, i, 1, FormatType::p};
|
||||||
}
|
}
|
||||||
|
|
||||||
return {i, -1};
|
return {false, i, 0, FormatType::a};
|
||||||
}
|
}
|
||||||
|
|
||||||
template <std::size_t N>
|
template <std::size_t N>
|
||||||
@ -124,28 +155,25 @@ constexpr std::pair<unsigned, int> parse_fmt_string(ConstString<N> s,
|
|||||||
++i;
|
++i;
|
||||||
|
|
||||||
if (is_digit(s, i)) {
|
if (is_digit(s, i)) {
|
||||||
auto [new_i, extra_len] = parse_number(s, i);
|
auto [is_valid, new_i, len, number] = parse_number(s, i);
|
||||||
if (extra_len < 0)
|
if (!is_valid) return {i, -1};
|
||||||
return {i, -1};
|
|
||||||
i = new_i;
|
i = new_i;
|
||||||
result_extra_len += extra_len;
|
result_extra_len += number;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s[i] == '.') {
|
if (s[i] == '.') {
|
||||||
++i;
|
++i;
|
||||||
auto [new_i, extra_len] = parse_number(s, i);
|
auto [is_valid, new_i, len, number] = parse_number(s, i);
|
||||||
if (extra_len < 0)
|
if (!is_valid) return {i, -1};
|
||||||
return {i, -1};
|
|
||||||
i = new_i;
|
i = new_i;
|
||||||
result_extra_len += extra_len;
|
result_extra_len += len;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s[i] != '}') {
|
if (s[i] != '}') {
|
||||||
auto [new_i, extra_len] = parse_type(s, i);
|
auto [is_valid, new_i, len, type] = parse_type(s, i);
|
||||||
if (extra_len < 0)
|
if (is_valid) return {i, -1};
|
||||||
return {i, -1};
|
|
||||||
i = new_i;
|
i = new_i;
|
||||||
result_extra_len += extra_len;
|
// result_extra_len += len;
|
||||||
}
|
}
|
||||||
|
|
||||||
return {i, result_extra_len};
|
return {i, result_extra_len};
|
||||||
@ -162,8 +190,7 @@ constexpr std::pair<unsigned, int> parse_braces(ConstString<N> s, unsigned i) {
|
|||||||
++i;
|
++i;
|
||||||
|
|
||||||
auto [new_i, extra_len] = parse_fmt_string(s, i);
|
auto [new_i, extra_len] = parse_fmt_string(s, i);
|
||||||
if (extra_len < 0)
|
if (extra_len < 0) return {i, -1};
|
||||||
return {i, -1};
|
|
||||||
i = new_i;
|
i = new_i;
|
||||||
result_extra_len += extra_len;
|
result_extra_len += extra_len;
|
||||||
|
|
||||||
@ -185,8 +212,7 @@ constexpr int get_output_len(ConstString<N> s) {
|
|||||||
++i;
|
++i;
|
||||||
|
|
||||||
auto [new_i, extra_len] = parse_braces(s, i);
|
auto [new_i, extra_len] = parse_braces(s, i);
|
||||||
if (extra_len < 0)
|
if (extra_len < 0) return -1;
|
||||||
return -1;
|
|
||||||
i = new_i;
|
i = new_i;
|
||||||
result_extra_len += extra_len;
|
result_extra_len += extra_len;
|
||||||
|
|
||||||
@ -202,4 +228,15 @@ constexpr int get_output_len(ConstString<N> s) {
|
|||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
|
|
||||||
|
template <detail::ConstString s, typename... args_t>
|
||||||
|
const std::array<char, detail::get_output_len(s)> format(args_t...) {
|
||||||
|
constexpr int len = get_output_len(s);
|
||||||
|
static_assert(len > 0, "Syntax error in log string");
|
||||||
|
|
||||||
|
std::cout << "Computed Length: " << len << std::endl;
|
||||||
|
|
||||||
|
return {0};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif // LOGGER_PARSING_H
|
#endif // LOGGER_PARSING_H
|
||||||
|
|||||||
@ -5,6 +5,14 @@
|
|||||||
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:
|
||||||
|
|||||||
@ -16,7 +16,7 @@ int main() {
|
|||||||
Uart uart;
|
Uart uart;
|
||||||
|
|
||||||
Logger logger(uart);
|
Logger logger(uart);
|
||||||
logger.log<"Test format string: {:08.4f} {}">(1, 2, 3);
|
logger.log<"Test:{:88}">(1, 2, 3);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue
Block a user