diff options
author | John Hodge <tpg@mutabah.net> | 2018-03-18 10:48:26 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2018-03-18 10:48:26 +0800 |
commit | 5b0450395af81ceba0d0ac27fc73b16f966bd7d3 (patch) | |
tree | e3c753b83a562be78cdbd74b8164dab785bf07a6 /tools/common/toml.h | |
parent | 363e6fa172f787e970c8abc8f631b6d60d571248 (diff) | |
download | mrust-5b0450395af81ceba0d0ac27fc73b16f966bd7d3.tar.gz |
All - Move toml parser and path header to a common library, start on custom target specs.
Diffstat (limited to 'tools/common/toml.h')
-rw-r--r-- | tools/common/toml.h | 163 |
1 files changed, 163 insertions, 0 deletions
diff --git a/tools/common/toml.h b/tools/common/toml.h new file mode 100644 index 00000000..e57c28ae --- /dev/null +++ b/tools/common/toml.h @@ -0,0 +1,163 @@ +#pragma once + +#include <fstream> +#include <vector> +#include <string> +#include <unordered_map> + +class TomlFileIter; +struct TomlKeyValue; + +class TomlFile +{ + /// Input file stream + ::std::ifstream m_if; + + /// Name of the current `[]` block + ::std::vector<::std::string> m_current_block; + + /// Path suffix of the current composite (none if empty) + ::std::vector<::std::string> m_current_composite; + + /// Index of the next array field (if zero, not parsing an array) + unsigned int m_next_array_index; + + /// Next indexes if top-level defined arrays (e.g. `[[foo]]`) + ::std::unordered_map<::std::string,unsigned> m_array_counts; + +public: + TomlFile(const ::std::string& filename); + + TomlFileIter begin(); + TomlFileIter end(); + + TomlKeyValue get_next_value(); +}; + +struct TomlValue +{ + enum class Type + { + Boolean, + String, + Integer, + List, + }; + struct TypeError: + public ::std::exception + { + Type have; + Type exp; + + TypeError(Type h, Type e): + have(h), + exp(e) + { + } + + const char* what() const noexcept override { + return "toml type error"; + } + }; + + Type m_type; + uint64_t m_int_value; + ::std::string m_str_value; + ::std::vector<TomlValue> m_sub_values; + + TomlValue(): + m_type(Type::String) + { + } + TomlValue(::std::string s): + m_type( Type::String ), + m_str_value(::std::move(s)) + { + } + TomlValue(int64_t v): + m_type(Type::Integer), + m_int_value(v) + { + } + TomlValue(bool v) : + m_type(Type::Boolean), + m_int_value(v ? 1 : 0) + { + } + + const ::std::string& as_string() const { + if( m_type != Type::String ) { + throw TypeError { m_type, Type::String }; + } + return m_str_value; + } + bool as_bool() const { + if(m_type != Type::Boolean) { + throw TypeError { m_type, Type::Boolean }; + } + return m_int_value != 0; + } + uint64_t as_int() const { + if(m_type != Type::Integer) { + throw TypeError { m_type, Type::Integer }; + } + return m_int_value; + } + const ::std::vector<TomlValue>& as_list() const { + if(m_type != Type::List) { + throw TypeError { m_type, Type::List }; + } + return m_sub_values; + } + + friend ::std::ostream& operator<<(::std::ostream& os, const TomlValue& x) { + switch(x.m_type) + { + case Type::Boolean: os << (x.m_int_value != 0 ? "true" : "false"); break; + case Type::Integer: os << x.m_int_value; break; + case Type::List: + os << "["; + for(auto& e : x.m_sub_values) + os << e << ","; + os << "]"; + break; + case Type::String: + os << "\"" << x.m_str_value << "\""; + break; + } + return os; + } +}; + +struct TomlKeyValue +{ + ::std::vector<::std::string> path; + TomlValue value; +}; + +class TomlFileIter +{ + friend class TomlFile; + TomlFile& m_reader; + TomlKeyValue m_cur_value; + + TomlFileIter(TomlFile& tf): + m_reader(tf) + { + + } + +public: + TomlKeyValue operator*() const + { + return m_cur_value; + } + void operator++() + { + m_cur_value = m_reader.get_next_value(); + } + bool operator!=(const TomlFileIter& x) const + { + return m_cur_value.path != x.m_cur_value.path; + } +}; |