diff --git a/inc/parsing.h b/inc/parsing.h index 061d936..1029091 100644 --- a/inc/parsing.h +++ b/inc/parsing.h @@ -15,15 +15,22 @@ namespace detail { */ +enum class FormatType { s, c, b, B, d, o, x, X, a, A, e, E, f, F, g, G, p }; + template -struct parse_result { - bool valid = false; +struct parse_result_t { + bool is_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 }; +struct fmt_string_result_t { + bool has_zero_padding = false; + int length = 6; + int precision = 2; + FormatType type = FormatType::s; +}; // clang-format off @@ -73,7 +80,7 @@ constexpr bool is_digit(ConstString s, unsigned i) { template -constexpr parse_result parse_number(ConstString s, unsigned i) { +constexpr parse_result_t parse_number(ConstString s, unsigned i) { int number = 0; while ((i < s.size()) && is_digit(s, i)) { @@ -86,7 +93,7 @@ constexpr parse_result parse_number(ConstString s, unsigned i) { } template -constexpr parse_result parse_type(ConstString s, unsigned i) { +constexpr parse_result_t parse_type(ConstString s, unsigned i) { if (s[i] == 's') { // string ++i; return {true, i, 1, FormatType::s}; @@ -99,9 +106,9 @@ constexpr parse_result parse_type(ConstString s, unsigned i) { } else if (s[i] == 'B') { ++i; return {true, i, 1, FormatType::B}; -// } else if (s[i] == 'c') { -// ++i; -// return {true, i, 1, FormatType::c}; + // } else if (s[i] == 'c') { + // ++i; + // return {true, i, 1, FormatType::c}; } else if (s[i] == 'd') { ++i; return {true, i, 1, FormatType::d}; @@ -143,40 +150,48 @@ constexpr parse_result parse_type(ConstString s, unsigned i) { return {true, i, 1, FormatType::p}; } - return {false, i, 0, FormatType::a}; + return {false, i, 0, FormatType::s}; } template -constexpr std::pair parse_fmt_string(ConstString s, - unsigned i) { - int result_extra_len = 0; +constexpr parse_result_t parse_fmt_string(ConstString s, + unsigned i) { - if (s[i] == '0') + fmt_string_result_t result; + + unsigned result_extra_len = 0; + + if (s[i] == '0') { ++i; + result.has_zero_padding = true; + } if (is_digit(s, i)) { auto [is_valid, new_i, len, number] = parse_number(s, i); - if (!is_valid) return {i, -1}; - i = new_i; - result_extra_len += number; + if (!is_valid) + return {false, i, 0, result}; + i = new_i; + result.length = number; } if (s[i] == '.') { ++i; auto [is_valid, new_i, len, number] = parse_number(s, i); - if (!is_valid) return {i, -1}; - i = new_i; - result_extra_len += len; + if (!is_valid) + return {false, i, 0, result}; + i = new_i; + result.precision = number; } if (s[i] != '}') { auto [is_valid, new_i, len, type] = parse_type(s, i); - if (is_valid) return {i, -1}; - i = new_i; -// result_extra_len += len; + if (!is_valid) + return {false, i, 0, result}; + i = new_i; + result.type = type; } - return {i, result_extra_len}; + return {true, i, result_extra_len, result}; } template @@ -189,10 +204,11 @@ constexpr std::pair parse_braces(ConstString s, unsigned i) { } else if (s[i] == ':') { ++i; - auto [new_i, extra_len] = parse_fmt_string(s, i); - if (extra_len < 0) return {i, -1}; + auto [is_valid, new_i, len, format_node] = parse_fmt_string(s, i); + if (!is_valid) + return {i, -1}; i = new_i; - result_extra_len += extra_len; + result_extra_len += len; if (s[i] == '}') { ++i; @@ -212,7 +228,8 @@ constexpr int get_output_len(ConstString s) { ++i; auto [new_i, extra_len] = parse_braces(s, i); - if (extra_len < 0) return -1; + if (extra_len < 0) + return -1; i = new_i; result_extra_len += extra_len; diff --git a/src/main.cpp b/src/main.cpp index ce3d14b..7dfdc2a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -13,10 +13,22 @@ private: int main() { - Uart uart; + //Uart uart; + +// Logger logger(uart); +// logger.log<"Test:{:8.2}">(1, 2, 3); + + 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(result.result.type) << std::endl; - Logger logger(uart); - logger.log<"Test:{:88}">(1, 2, 3); return 0; } \ No newline at end of file