parse_fmt_string now returning struct containing actual format parameters
This commit is contained in:
parent
f1952186e0
commit
7226241097
@ -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 <typename result_t>
|
template <typename result_t>
|
||||||
struct parse_result {
|
struct parse_result_t {
|
||||||
bool valid = false;
|
bool is_valid = false;
|
||||||
unsigned new_index = 0;
|
unsigned new_index = 0;
|
||||||
unsigned length = 0;
|
unsigned length = 0;
|
||||||
result_t result;
|
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
|
// clang-format off
|
||||||
@ -73,7 +80,7 @@ constexpr bool is_digit(ConstString<N> s, unsigned i) {
|
|||||||
|
|
||||||
|
|
||||||
template <std::size_t N>
|
template <std::size_t N>
|
||||||
constexpr parse_result<int> parse_number(ConstString<N> s, unsigned i) {
|
constexpr parse_result_t<int> parse_number(ConstString<N> s, unsigned i) {
|
||||||
int number = 0;
|
int number = 0;
|
||||||
|
|
||||||
while ((i < s.size()) && is_digit(s, i)) {
|
while ((i < s.size()) && is_digit(s, i)) {
|
||||||
@ -86,7 +93,7 @@ constexpr parse_result<int> parse_number(ConstString<N> s, unsigned i) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <std::size_t N>
|
template <std::size_t N>
|
||||||
constexpr parse_result<FormatType> parse_type(ConstString<N> s, unsigned i) {
|
constexpr parse_result_t<FormatType> parse_type(ConstString<N> s, unsigned i) {
|
||||||
if (s[i] == 's') { // string
|
if (s[i] == 's') { // string
|
||||||
++i;
|
++i;
|
||||||
return {true, i, 1, FormatType::s};
|
return {true, i, 1, FormatType::s};
|
||||||
@ -143,40 +150,48 @@ constexpr parse_result<FormatType> parse_type(ConstString<N> s, unsigned i) {
|
|||||||
return {true, i, 1, FormatType::p};
|
return {true, i, 1, FormatType::p};
|
||||||
}
|
}
|
||||||
|
|
||||||
return {false, i, 0, FormatType::a};
|
return {false, i, 0, FormatType::s};
|
||||||
}
|
}
|
||||||
|
|
||||||
template <std::size_t N>
|
template <std::size_t N>
|
||||||
constexpr std::pair<unsigned, int> parse_fmt_string(ConstString<N> s,
|
constexpr parse_result_t<fmt_string_result_t> parse_fmt_string(ConstString<N> s,
|
||||||
unsigned i) {
|
unsigned i) {
|
||||||
int result_extra_len = 0;
|
|
||||||
|
|
||||||
if (s[i] == '0')
|
fmt_string_result_t result;
|
||||||
|
|
||||||
|
unsigned result_extra_len = 0;
|
||||||
|
|
||||||
|
if (s[i] == '0') {
|
||||||
++i;
|
++i;
|
||||||
|
result.has_zero_padding = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (is_digit(s, i)) {
|
if (is_digit(s, i)) {
|
||||||
auto [is_valid, new_i, len, number] = parse_number(s, i);
|
auto [is_valid, new_i, len, number] = parse_number(s, i);
|
||||||
if (!is_valid) return {i, -1};
|
if (!is_valid)
|
||||||
|
return {false, i, 0, result};
|
||||||
i = new_i;
|
i = new_i;
|
||||||
result_extra_len += number;
|
result.length = number;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s[i] == '.') {
|
if (s[i] == '.') {
|
||||||
++i;
|
++i;
|
||||||
auto [is_valid, new_i, len, number] = parse_number(s, i);
|
auto [is_valid, new_i, len, number] = parse_number(s, i);
|
||||||
if (!is_valid) return {i, -1};
|
if (!is_valid)
|
||||||
|
return {false, i, 0, result};
|
||||||
i = new_i;
|
i = new_i;
|
||||||
result_extra_len += len;
|
result.precision = number;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s[i] != '}') {
|
if (s[i] != '}') {
|
||||||
auto [is_valid, new_i, len, type] = parse_type(s, i);
|
auto [is_valid, new_i, len, type] = parse_type(s, i);
|
||||||
if (is_valid) return {i, -1};
|
if (!is_valid)
|
||||||
|
return {false, i, 0, result};
|
||||||
i = new_i;
|
i = new_i;
|
||||||
// result_extra_len += len;
|
result.type = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
return {i, result_extra_len};
|
return {true, i, result_extra_len, result};
|
||||||
}
|
}
|
||||||
|
|
||||||
template <std::size_t N>
|
template <std::size_t N>
|
||||||
@ -189,10 +204,11 @@ constexpr std::pair<unsigned, int> parse_braces(ConstString<N> s, unsigned i) {
|
|||||||
} else if (s[i] == ':') {
|
} else if (s[i] == ':') {
|
||||||
++i;
|
++i;
|
||||||
|
|
||||||
auto [new_i, extra_len] = parse_fmt_string(s, i);
|
auto [is_valid, new_i, len, format_node] = parse_fmt_string(s, i);
|
||||||
if (extra_len < 0) return {i, -1};
|
if (!is_valid)
|
||||||
|
return {i, -1};
|
||||||
i = new_i;
|
i = new_i;
|
||||||
result_extra_len += extra_len;
|
result_extra_len += len;
|
||||||
|
|
||||||
if (s[i] == '}') {
|
if (s[i] == '}') {
|
||||||
++i;
|
++i;
|
||||||
@ -212,7 +228,8 @@ 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) return -1;
|
if (extra_len < 0)
|
||||||
|
return -1;
|
||||||
i = new_i;
|
i = new_i;
|
||||||
result_extra_len += extra_len;
|
result_extra_len += extra_len;
|
||||||
|
|
||||||
|
|||||||
18
src/main.cpp
18
src/main.cpp
@ -13,10 +13,22 @@ private:
|
|||||||
|
|
||||||
|
|
||||||
int main() {
|
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<int>(result.result.type) << std::endl;
|
||||||
|
|
||||||
Logger logger(uart);
|
|
||||||
logger.log<"Test:{:88}">(1, 2, 3);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue
Block a user