// mars::text -- lazily typed tokens for the flat tuning tables. // // A token is the raw bytes of one whitespace-delimited item (or the inside of // a "quoted string"). Nothing is converted at parse time; kind() classifies a // bareword the way the game data reads it (int / float / true|false / word) // and the as_*() accessors convert on demand. Quoted tokens are always // strings, even when they look numeric ("8" stays "8"). #pragma once #include #include #include #include namespace mars::text { enum class ValueKind { Int, // [+-]?digits Float, // [+-]?(d+.d* | .d+ | d+)([eE][+-]?d+)? (and not Int) Bool, // true / false, any case Bareword, // any other unquoted token String // a "quoted" token }; // Classification of an unquoted token. ValueKind classify(std::string_view bareword); bool looks_like_int(std::string_view s); bool looks_like_float(std::string_view s); // Conversions; nullopt when the text does not have the requested shape // (or, for parse_int, does not fit in 64 bits). std::optional parse_int(std::string_view s); std::optional parse_float(std::string_view s); // accepts Int or Float shapes std::optional parse_bool(std::string_view s); struct Token { std::string text; bool quoted = false; ValueKind kind() const { return quoted ? ValueKind::String : classify(text); } std::optional as_int() const { return quoted ? std::nullopt : parse_int(text); } std::optional as_float() const { return quoted ? std::nullopt : parse_float(text); } std::optional as_bool() const { return quoted ? std::nullopt : parse_bool(text); } }; // A colour written as "r g b" or "r g b a" (any numeric components; the data // uses 0-255 ints). a defaults to 1 when absent. `components` is 3 or 4. struct Color { double r = 0, g = 0, b = 0, a = 1; int components = 0; }; std::optional parse_color(std::string_view s); // ASCII helpers shared by the readers (the data is cp1252; high bytes are // never whitespace and never case-folded). inline bool is_space(char c) { return c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '\v' || c == '\f'; } std::string_view strip(std::string_view s); std::string_view lstrip(std::string_view s); std::string fold_case(std::string_view s); // ASCII lower-case copy bool equals_fold(std::string_view a, std::string_view b); // ASCII case-insensitive } // namespace mars::text