summaryrefslogtreecommitdiff
path: root/tools/common/toml.h
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2018-03-18 10:48:26 +0800
committerJohn Hodge <tpg@mutabah.net>2018-03-18 10:48:26 +0800
commit5b0450395af81ceba0d0ac27fc73b16f966bd7d3 (patch)
treee3c753b83a562be78cdbd74b8164dab785bf07a6 /tools/common/toml.h
parent363e6fa172f787e970c8abc8f631b6d60d571248 (diff)
downloadmrust-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.h163
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;
+ }
+};