#pragma once /* * Copyright (C) 2024 Brett Terpstra * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef BLT_LOGGING_FMT_TOKENIZER_H #define BLT_LOGGING_FMT_TOKENIZER_H #include #include #include #include namespace blt::logging { enum class fmt_token_type : u8 { STRING, NUMBER, SPACE, COLON, DOT, MINUS, PLUS, POUND }; enum class fmt_sign_t : u8 { SPACE, PLUS, MINUS }; enum class fmt_type_t : u8 { BINARY, // 'b' CHAR, // 'c' DECIMAL, // 'd' OCTAL, // 'o' HEX, // 'x' HEX_FLOAT, // 'a' EXPONENT, // 'e' FIXED_POINT, // 'f' GENERAL, // 'g' TYPE, // 't' UNSPECIFIED // default }; struct fmt_spec_t { i64 arg_id = -1; i64 width = -1; i64 precision = -1; fmt_type_t type = fmt_type_t::UNSPECIFIED; fmt_sign_t sign = fmt_sign_t::MINUS; bool leading_zeros = false; bool uppercase = false; bool alternate_form = false; }; struct fmt_token_t { fmt_token_type type; std::string_view value; }; class fmt_tokenizer_t { public: explicit fmt_tokenizer_t() = default; static fmt_token_type get_type(char c); std::optional next(); std::vector tokenize(std::string_view fmt); private: size_t m_pos = 0; std::string_view m_fmt; }; class fmt_parser_t { public: explicit fmt_parser_t() = default; fmt_token_t& peek() { return m_tokens[m_pos]; } [[nodiscard]] bool has_next() const { return m_pos < m_tokens.size(); } [[nodiscard]] fmt_token_t& next() { return m_tokens[m_pos++]; } void consume() { ++m_pos; } const fmt_spec_t& parse(std::string_view fmt); private: void parse_fmt_field(); void parse_arg_id(); void parse_fmt_spec(); void parse_fmt_spec_sign(); void parse_fmt_spec_form(); void parse_fmt_spec_width(); void parse_fmt_spec_precision(); void parse_sign(); void parse_form(); void parse_width(); void parse_precision(); void parse_type(); size_t m_pos = 0; std::vector m_tokens; fmt_tokenizer_t m_tokenizer; fmt_spec_t m_spec; }; } #endif //BLT_LOGGING_FMT_TOKENIZER_H