summaryrefslogtreecommitdiff
path: root/tools/minicargo
diff options
context:
space:
mode:
Diffstat (limited to 'tools/minicargo')
-rw-r--r--tools/minicargo/Makefile9
-rw-r--r--tools/minicargo/build.h2
-rw-r--r--tools/minicargo/debug.cpp80
-rw-r--r--tools/minicargo/debug.h68
-rw-r--r--tools/minicargo/helpers.h53
-rw-r--r--tools/minicargo/manifest.h3
-rw-r--r--tools/minicargo/path.cpp194
-rw-r--r--tools/minicargo/path.h181
-rw-r--r--tools/minicargo/toml.cpp414
-rw-r--r--tools/minicargo/toml.h151
10 files changed, 8 insertions, 1147 deletions
diff --git a/tools/minicargo/Makefile b/tools/minicargo/Makefile
index 71e266b0..01010fb5 100644
--- a/tools/minicargo/Makefile
+++ b/tools/minicargo/Makefile
@@ -14,10 +14,10 @@ OBJDIR := .obj/
BIN := ../bin/minicargo$(EXESUF)
OBJS := main.o build.o manifest.o repository.o
-OBJS += toml.o path.o debug.o
LINKFLAGS := -g -lpthread
CXXFLAGS := -Wall -std=c++14 -g -O2
+CXXFLAGS += -I ../common
OBJS := $(OBJS:%=$(OBJDIR)%)
@@ -28,15 +28,18 @@ all: $(BIN)
clean:
rm $(BIN) $(OBJS)
-$(BIN): $(OBJS)
+$(BIN): $(OBJS) ../bin/common_lib.a
@mkdir -p $(dir $@)
@echo [CXX] -o $@
- $V$(CXX) -o $@ $(OBJS) $(LINKFLAGS)
+ $V$(CXX) -o $@ $(OBJS) ../bin/common_lib.a $(LINKFLAGS)
$(OBJDIR)%.o: %.cpp
@mkdir -p $(dir $@)
@echo [CXX] $<
$V$(CXX) -o $@ -c $< $(CXXFLAGS) -MMD -MP -MF $@.dep
+../bin/common_lib.a:
+ make -C ../common
+
-include $(OBJS:%.o=%.o.dep)
diff --git a/tools/minicargo/build.h b/tools/minicargo/build.h
index 0b3e949b..54d03575 100644
--- a/tools/minicargo/build.h
+++ b/tools/minicargo/build.h
@@ -1,7 +1,7 @@
#pragma once
#include "manifest.h"
-#include "path.h"
+#include <path.h>
class StringList;
class StringListKV;
diff --git a/tools/minicargo/debug.cpp b/tools/minicargo/debug.cpp
deleted file mode 100644
index a3fb9956..00000000
--- a/tools/minicargo/debug.cpp
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * MiniCargo - mrustc's minimal clone of cargo
- * - By John Hodge (Mutabah/thePowersGang)
- *
- * debug.cpp
- * - Debugging helpers
- */
-#if defined(__MINGW32__)
-# define DISABLE_MULTITHREAD // Mingw32 doesn't have c++11 threads
-#endif
-#include <set>
-#include <iostream>
-#include "debug.h"
-#include <mutex>
-
-static int giIndentLevel = 0;
-static const char* gsDebugPhase = "";
-static ::std::set<::std::string> gmDisabledDebug;
-#ifndef DISABLE_MULTITHREAD
-static ::std::mutex gDebugLock;
-#endif
-
-void Debug_SetPhase(const char* phase_name)
-{
- gsDebugPhase = phase_name;
-}
-bool Debug_IsEnabled()
-{
- if( gmDisabledDebug.find(gsDebugPhase) != gmDisabledDebug.end() )
- return false;
- return true;
-}
-void Debug_DisablePhase(const char* phase_name)
-{
- gmDisabledDebug.insert( ::std::string(phase_name) );
-}
-void Debug_Print(::std::function<void(::std::ostream& os)> cb)
-{
- if( !Debug_IsEnabled() )
- return ;
-#ifndef DISABLE_MULTITHREAD
- ::std::unique_lock<::std::mutex> _lh { gDebugLock };
-#endif
-
- ::std::cout << gsDebugPhase << "- ";
- for(auto i = giIndentLevel; i --; )
- ::std::cout << " ";
- cb(::std::cout);
- ::std::cout << ::std::endl;
-}
-void Debug_EnterScope(const char* name, dbg_cb_t cb)
-{
- if( !Debug_IsEnabled() )
- return ;
-#ifndef DISABLE_MULTITHREAD
- ::std::unique_lock<::std::mutex> _lh { gDebugLock };
-#endif
-
- ::std::cout << gsDebugPhase << "- ";
- for(auto i = giIndentLevel; i --; )
- ::std::cout << " ";
- ::std::cout << ">>> " << name << "(";
- cb(::std::cout);
- ::std::cout << ")" << ::std::endl;
- giIndentLevel ++;
-}
-void Debug_LeaveScope(const char* name, dbg_cb_t cb)
-{
- if( !Debug_IsEnabled() )
- return ;
-#ifndef DISABLE_MULTITHREAD
- ::std::unique_lock<::std::mutex> _lh { gDebugLock };
-#endif
-
- ::std::cout << gsDebugPhase << "- ";
- giIndentLevel --;
- for(auto i = giIndentLevel; i --; )
- ::std::cout << " ";
- ::std::cout << "<<< " << name << ::std::endl;
-}
diff --git a/tools/minicargo/debug.h b/tools/minicargo/debug.h
deleted file mode 100644
index ace00876..00000000
--- a/tools/minicargo/debug.h
+++ /dev/null
@@ -1,68 +0,0 @@
-#pragma once
-
-#include <functional>
-#include <vector>
-#include <sstream>
-
-typedef ::std::function<void(::std::ostream& os)> dbg_cb_t;
-extern void Debug_SetPhase(const char* phase_name);
-extern void Debug_DisablePhase(const char* phase_name);
-extern bool Debug_IsEnabled();
-extern void Debug_EnterScope(const char* name, dbg_cb_t );
-extern void Debug_LeaveScope(const char* name, dbg_cb_t );
-extern void Debug_Print(dbg_cb_t cb);
-
-#if defined(NOLOG)
-# define DEBUG(fmt) do { } while(0)
-# define TRACE_FUNCTION_F(fmt) do{}while(0)
-#else
-# define DEBUG(fmt) do { Debug_Print([&](auto& os){ os << "DEBUG: " << fmt; }); } while(0)
-# define TRACE_FUNCTION_F(fmt) DebugFunctionScope trace_function_hdr { __FUNCTION__, [&](auto& os){ os << fmt; } }
-#endif
-#define TODO(fmt) do { ::std::cerr << "TODO: " << fmt << ::std::endl; abort(); } while(0)
-
-namespace {
- static inline void format_to_stream(::std::ostream& os) {
- }
- template<typename T, typename... A>
- static inline void format_to_stream(::std::ostream& os, const T& v, const A&... a) {
- os << v;
- format_to_stream(os, a...);
- }
-}
-
-struct DebugFunctionScope {
- const char* m_name;
- DebugFunctionScope(const char* name, dbg_cb_t cb):
- m_name(name)
- {
- Debug_EnterScope(m_name, cb);
- }
- ~DebugFunctionScope()
- {
- Debug_LeaveScope(m_name, [](auto& ){});
- }
-};
-
-template<typename ...T>
-::std::string format(const T&... v)
-{
- ::std::stringstream ss;
- format_to_stream(ss, v...);
- return ss.str();
-}
-
-template<typename T>
-::std::ostream& operator<<(::std::ostream& os, const ::std::vector<T>& v)
-{
- bool first = true;
- for(const auto& e : v)
- {
- if(!first)
- os << ",";
- os << e;
- first = false;
- }
- return os;
-}
-
diff --git a/tools/minicargo/helpers.h b/tools/minicargo/helpers.h
deleted file mode 100644
index 8111483a..00000000
--- a/tools/minicargo/helpers.h
+++ /dev/null
@@ -1,53 +0,0 @@
-#pragma once
-
-#include <string>
-#include <cstring>
-#include <iostream>
-
-namespace helpers {
-
-class string_view
-{
- const char* m_start;
- const size_t m_len;
-public:
- string_view(const char* s, size_t n):
- m_start(s), m_len(n)
- {
- }
-
- bool operator==(const ::std::string& s) const {
- return *this == s.c_str();
- }
- bool operator==(const char* s) const {
- if(::std::strncmp(m_start, s, m_len) != 0)
- return false;
- return s[m_len] == '\0';
- }
-
- char operator[](size_t n) const {
- return m_start[n];
- }
-
- operator ::std::string() const {
- return ::std::string { m_start, m_start + m_len };
- }
- friend ::std::string& operator+=(::std::string& x, const string_view& sv) {
- x.append(sv.m_start, sv.m_start+sv.m_len);
- return x;
- }
- friend ::std::ostream& operator<<(::std::ostream& os, const string_view& sv) {
- os.write(sv.m_start, sv.m_len);
- return os;
- }
-
- const char* begin() const {
- return m_start;
- }
- const char* end() const {
- return m_start+m_len;
- }
-};
-
-
-} // namespace helpers
diff --git a/tools/minicargo/manifest.h b/tools/minicargo/manifest.h
index bbe2c34b..e48e7f2a 100644
--- a/tools/minicargo/manifest.h
+++ b/tools/minicargo/manifest.h
@@ -5,8 +5,7 @@
#include <map>
#include <memory>
#include <functional>
-#include "path.h"
-#include <functional>
+#include <path.h>
class PackageManifest;
class Repository;
diff --git a/tools/minicargo/path.cpp b/tools/minicargo/path.cpp
deleted file mode 100644
index 12e505bb..00000000
--- a/tools/minicargo/path.cpp
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- */
-#include "path.h"
-#if _WIN32
-# include <Windows.h>
-#else
-# include <unistd.h> // getcwd/chdir
-#endif
-
-helpers::path::path(const char* s):
- m_str(s)
-{
- // 1. Normalise path separators to the system specified separator
- for(size_t i = 0; i < m_str.size(); i ++)
- {
- if( m_str[i] == '/' || m_str[i] == '\\' )
- m_str[i] = SEP;
- }
-
- // 2. Remove any trailing separators
- if( !m_str.empty() )
- {
- while(!m_str.empty() && m_str.back() == SEP )
- m_str.pop_back();
- if(m_str.empty())
- {
- m_str.push_back(SEP);
- }
- }
- else
- {
- throw ::std::runtime_error("Empty path being constructed");
- }
-}
-
-helpers::path helpers::path::to_absolute() const
-{
- if(!this->is_valid())
- throw ::std::runtime_error("Calling to_absolute() on an invalid path");
-
- if(this->m_str[0] == SEP)
- return *this;
-
- #if _WIN32
- char cwd[1024];
- GetCurrentDirectoryA(sizeof(cwd), cwd);
- #else
- char cwd[1024];
- if( !getcwd(cwd, sizeof(cwd)) )
- throw ::std::runtime_error("Calling getcwd() failed in path::to_absolute()");
- #endif
- auto rv = path(cwd);
- for(auto comp : *this)
- {
- if(comp == ".")
- ;
- else if( comp == ".." )
- rv.pop_component();
- else
- rv /= comp;
- }
- #if _WIN32
- #else
- #endif
- return rv;
-}
-
-helpers::path helpers::path::normalise() const
-{
- path rv;
- rv.m_str.reserve( m_str.size()+1 );
-
- for(auto comp : *this)
- {
- if( comp == "." ) {
- // Ignore.
- }
- else if( comp == ".." )
- {
- // If the path is empty, OR the last element is a "..", push the element
- if( rv.m_str.empty()
- || (rv.m_str.size() == 3 && rv.m_str[0] == '.' && rv.m_str[1] == '.' && rv.m_str[2] == SEP)
- || (rv.m_str.size() > 4 && *(rv.m_str.end()-4) == SEP && *(rv.m_str.end()-3) == '.' && *(rv.m_str.end()-2) == '.' && *(rv.m_str.end()-1) == SEP )
- )
- {
- // Push
- rv.m_str += comp;
- rv.m_str += SEP;
- }
- else
- {
- rv.m_str.pop_back();
- auto pos = rv.m_str.find_last_of(SEP);
- if(pos == ::std::string::npos)
- {
- rv.m_str.resize(0);
- }
- else if( pos == 0 )
- {
- // Keep.
- }
- else
- {
- rv.m_str.resize(pos+1);
- }
- }
- }
- else
- {
- rv.m_str += comp;
- rv.m_str += SEP;
- }
- }
- rv.m_str.pop_back();
- return rv;
-}
-
-#if 0
-void helpers::path::normalise_in_place()
-{
- size_t insert_point = 0;
-
- for(size_t read_pos = 0; read_pos < m_str.size(); read_pos ++)
- {
- auto pos = m_str.find_first_of(SEP, read_pos);
- if(pos == ::std::string::npos)
- pos = m_str.size();
- auto comp = string_view(m_str.c_str() + read_pos, pos - read_pos);
-
- bool append;
- if(comp == ".")
- {
- // Advance read without touching insert
- append = false;
- }
- else if( comp == ".." )
- {
- // Consume parent (if not a relative component already)
- // Move insertion point back to the previous separator
- auto pos = m_str.find_last_of(SEP, insert_point);
- if(pos == ::std::string::npos)
- {
- // Only one component currently (or empty)
- append = true;
- }
- else if(string_view(m_str.c_str() + pos+1, insert_point - pos-1) == "..")
- {
- // Last component is ".." - keep adding
- append = true;
- }
- else
- {
- insert_point = pos;
- append = false;
- }
- }
- else
- {
- append = true;
- }
-
- if(append)
- {
- if( read_pos != insert_point )
- {
- //assert(read_pos > insert_point);
- while(read_pos < pos)
- {
- m_str[insert_point++] = m_str[read_pos++];
- }
- }
- }
- else
- {
- read_pos = pos;
- }
- }
-}
-#endif
-
-void helpers::path::ComponentsIter::operator++()
-{
- if(end == p.m_str.size())
- {
- pos = end;
- }
- else
- {
- pos = end+1;
- end = p.m_str.find(SEP, pos);
- if(end == ::std::string::npos)
- end = p.m_str.size();
- }
-}
diff --git a/tools/minicargo/path.h b/tools/minicargo/path.h
deleted file mode 100644
index dd97f9be..00000000
--- a/tools/minicargo/path.h
+++ /dev/null
@@ -1,181 +0,0 @@
-#pragma once
-
-#include <string>
-#include <stdexcept>
-#include "helpers.h"
-
-namespace helpers {
-
-/// Path helper class (because I don't want to include boost)
-class path
-{
-#ifdef _WIN32
- static const char SEP = '\\';
-#else
- static const char SEP = '/';
-#endif
-
- ::std::string m_str;
-
-public:
- path()
- {
- }
- path(const ::std::string& s):
- path(s.c_str())
- {
- }
- path(const char* s);
-
- bool is_valid() const {
- return m_str != "";
- }
-
- path& operator/=(const path& p)
- {
- if(!p.is_valid())
- throw ::std::runtime_error("Appending from an invalid path");
-
- return *this /= p.m_str.c_str();
- }
- path& operator/=(const char* o)
- {
- if(!this->is_valid())
- throw ::std::runtime_error("Appending to an invalid path");
- if(o[0] == '/')
- throw ::std::runtime_error("Appending an absolute path to another path");
- this->m_str.push_back(SEP);
- this->m_str.append(o);
- return *this;
- }
- path& operator/=(const string_view& o)
- {
- if(!this->is_valid())
- throw ::std::runtime_error("Appending to an invalid path");
- if(o[0] == '/')
- throw ::std::runtime_error("Appending an absolute path to another path");
- this->m_str.push_back(SEP);
- this->m_str += o;
- return *this;
- }
-
- path operator/(const path& p) const
- {
- auto rv = *this;
- rv /= p;
- return rv;
- }
- /// Append a relative path
- path operator/(const char* o) const
- {
- auto rv = *this;
- rv /= o;
- return rv;
- }
- /// Add an arbitary string to the final component
- path operator+(const char* o) const
- {
- if(!this->is_valid())
- throw ::std::runtime_error("Appending a string to an invalid path");
- if( ::std::strchr(o, SEP) != nullptr )
- throw ::std::runtime_error("Appending a string containing the path separator (with operator+)");
- auto rv = *this;
- rv.m_str.append(o);
- return rv;
- }
-
- bool pop_component()
- {
- if(!this->is_valid())
- throw ::std::runtime_error("Calling pop_component() on an invalid path");
- auto pos = m_str.find_last_of(SEP);
- if(pos == ::std::string::npos || pos == 0)
- {
- return false;
- }
- else
- {
- this->m_str.resize(pos);
- return true;
- }
- }
- path parent() const
- {
- if(!this->is_valid())
- throw ::std::runtime_error("Calling parent() on an invalid path");
- auto pos = m_str.find_last_of(SEP);
- if(pos == ::std::string::npos)
- {
- return *this;
- }
- else
- {
- path rv;
- rv.m_str = m_str.substr(0, pos);
- return rv;
- }
- }
- path to_absolute() const;
- ::std::string basename() const
- {
- if(!this->is_valid())
- throw ::std::runtime_error("Calling basename() on an invalid path");
-
- auto pos = m_str.find_last_of(SEP);
- if(pos == ::std::string::npos)
- {
- return m_str;
- }
- else
- {
- return m_str.substr(pos+1);
- }
- }
-
- const ::std::string& str() const
- {
- return m_str;
- }
- operator ::std::string() const
- {
- return m_str;
- }
-
- class ComponentsIter
- {
- const path& p;
- size_t pos;
- size_t end;
-
- friend class path;
- ComponentsIter(const path& p, size_t i): p(p), pos(i) {
- end = p.m_str.find(SEP, pos);
- if(end == ::std::string::npos)
- end = p.m_str.size();
- }
- public:
- string_view operator*() const {
- return string_view(p.m_str.c_str() + pos, end - pos);
- }
- void operator++();
- bool operator!=(const ComponentsIter& x) const {
- return pos != x.pos;
- }
- };
- ComponentsIter begin() const {
- return ComponentsIter(*this, 0);
- }
- ComponentsIter end() const {
- return ComponentsIter(*this, m_str.size());
- }
-
- path normalise() const;
- //void normalise_in_place();
-
- friend ::std::ostream& operator<<(::std::ostream& os, const path& p)
- {
- return os << p.m_str;
- }
-};
-
-}
diff --git a/tools/minicargo/toml.cpp b/tools/minicargo/toml.cpp
deleted file mode 100644
index 9fad0ec4..00000000
--- a/tools/minicargo/toml.cpp
+++ /dev/null
@@ -1,414 +0,0 @@
-/*
- * A very bad streaming TOML parser
- */
-#define NOLOG
-#include "toml.h"
-#include "debug.h"
-#include <cassert>
-#include <string>
-
-
-struct Token
-{
- enum class Type
- {
- Eof,
- SquareOpen,
- SquareClose,
- BraceOpen,
- BraceClose,
- Assign,
- Newline,
- Comma,
- Dot,
-
- Ident,
- String,
- Integer,
- };
-
- Type m_type;
- ::std::string m_data;
- int64_t m_intval = 0;
-
- Token(Type ty):
- m_type(ty)
- {
- }
- Token(Type ty, ::std::string s):
- m_type(ty),
- m_data(s)
- {
- }
- Token(Type ty, int64_t i):
- m_type(ty),
- m_intval(i)
- {
- }
-
-
- static Token lex_from(::std::ifstream& is);
- static Token lex_from_inner(::std::ifstream& is);
-
- const ::std::string& as_string() const {
- assert(m_type == Type::Ident || m_type == Type::String);
- return m_data;
- }
-
- friend ::std::ostream& operator<<(::std::ostream& os, const Token& x) {
- switch(x.m_type)
- {
- case Type::Eof: os << "Eof"; break;
- case Type::SquareOpen: os << "SquareOpen"; break;
- case Type::SquareClose: os << "SquareClose"; break;
- case Type::BraceOpen: os << "BraceOpen"; break;
- case Type::BraceClose: os << "BraceClose"; break;
- case Type::Assign: os << "Assign"; break;
- case Type::Newline: os << "Newline"; break;
- case Type::Comma: os << "Comma"; break;
- case Type::Dot: os << "Dot"; break;
- case Type::Ident: os << "Ident(" << x.m_data << ")"; break;
- case Type::String: os << "String(" << x.m_data << ")"; break;
- case Type::Integer: os << "Integer(" << x.m_intval << ")"; break;
- }
- return os;
- }
-};
-
-TomlFile::TomlFile(const ::std::string& filename):
- m_if(filename)
-{
- if( !m_if.is_open() ) {
- throw ::std::runtime_error("Unable to open file '" + filename + "'");
- }
-}
-TomlFileIter TomlFile::begin()
-{
- TomlFileIter rv { *this };
- ++rv;
- return rv;
-}
-TomlFileIter TomlFile::end()
-{
- return TomlFileIter { *this };
-}
-
-TomlKeyValue TomlFile::get_next_value()
-{
- auto t = Token::lex_from(m_if);
-
- if(m_current_composite.empty())
- {
- while( t.m_type == Token::Type::Newline )
- t = Token::lex_from(m_if);
-
- // Expect '[', a string, or an identifier
- switch(t.m_type)
- {
- case Token::Type::Eof:
- // Empty return indicates the end of the list
- return TomlKeyValue {};
- case Token::Type::SquareOpen:
- m_current_block.clear();
- do
- {
- t = Token::lex_from(m_if);
- bool is_array = false;
- if(t.m_type == Token::Type::SquareOpen)
- {
- is_array = true;
- t = Token::lex_from(m_if);
- }
- assert(t.m_type == Token::Type::Ident || t.m_type == Token::Type::String);
- m_current_block.push_back(t.as_string());
- if(is_array)
- {
- m_current_block.push_back(::format(m_array_counts[t.as_string()]++));
- t = Token::lex_from(m_if);
- assert(t.m_type == Token::Type::SquareClose);
- }
-
- t = Token::lex_from(m_if);
- } while(t.m_type == Token::Type::Dot);
- if( t.m_type != Token::Type::SquareClose )
- {
- throw ::std::runtime_error(::format("Unexpected token in block header - ", t));
- }
- t = Token::lex_from(m_if);
- if (t.m_type != Token::Type::Newline)
- {
- throw ::std::runtime_error(::format("Unexpected token after block block - ", t));
- }
- DEBUG("Start block " << m_current_block);
- // Recurse!
- return get_next_value();
- default:
- break;
- }
- }
- else
- {
- // Expect a string or an identifier
- if( t.m_type == Token::Type::Eof )
- {
- // EOF isn't allowed here
- throw ::std::runtime_error(::format("Unexpected EOF in composite"));
- }
- }
- switch (t.m_type)
- {
- case Token::Type::String:
- case Token::Type::Ident:
- break;
- default:
- throw ::std::runtime_error(::format("Unexpected token for key - ", t));
- }
- ::std::string key_name = t.as_string();
- t = Token::lex_from(m_if);
-
- if(t.m_type != Token::Type::Assign)
- throw ::std::runtime_error(::format("Unexpected token after key - ", t));
- t = Token::lex_from(m_if);
-
- TomlKeyValue rv;
- switch(t.m_type)
- {
- case Token::Type::String:
- rv.path = m_current_block;
- rv.path.insert(rv.path.end(), m_current_composite.begin(), m_current_composite.end());
- rv.path.push_back(key_name);
-
- rv.value = TomlValue { t.m_data };
- break;
- case Token::Type::SquareOpen:
- rv.path = m_current_block;
- rv.path.insert(rv.path.end(), m_current_composite.begin(), m_current_composite.end());
- rv.path.push_back(key_name);
-
- rv.value.m_type = TomlValue::Type::List;
- while( (t = Token::lex_from(m_if)).m_type != Token::Type::SquareClose )
- {
- while( t.m_type == Token::Type::Newline )
- t = Token::lex_from(m_if);
- if( t.m_type == Token::Type::SquareClose )
- break;
-
- // TODO: Recurse parse a value
- switch(t.m_type)
- {
- case Token::Type::String:
- rv.value.m_sub_values.push_back(TomlValue { t.as_string() });
- break;
- default:
- throw ::std::runtime_error(::format("Unexpected token in array value position - ", t));
- }
-
- t = Token::lex_from(m_if);
- if(t.m_type != Token::Type::Comma)
- break;
- }
- if(t.m_type != Token::Type::SquareClose)
- throw ::std::runtime_error(::format("Unexpected token after array - ", t));
- break;
- case Token::Type::BraceOpen:
- m_current_composite.push_back(key_name);
- DEBUG("Enter composite block " << m_current_block << ", " << m_current_composite);
- // Recurse to restart parse
- return get_next_value();
- case Token::Type::Integer:
- rv.path = m_current_block;
- rv.path.insert(rv.path.end(), m_current_composite.begin(), m_current_composite.end());
- rv.path.push_back(key_name);
- rv.value = TomlValue { t.m_intval };
- return rv;
- case Token::Type::Ident:
- if( t.m_data == "true" )
- {
- rv.path = m_current_block;
- rv.path.insert(rv.path.end(), m_current_composite.begin(), m_current_composite.end());
- rv.path.push_back(key_name);
- rv.value = TomlValue { true };
- }
- else if( t.m_data == "false" )
- {
- rv.path = m_current_block;
- rv.path.insert(rv.path.end(), m_current_composite.begin(), m_current_composite.end());
- rv.path.push_back(key_name);
-
- rv.value = TomlValue { false };
- }
- else
- {
- throw ::std::runtime_error(::format("Unexpected identifier in value position - ", t));
- }
- break;
- default:
- throw ::std::runtime_error(::format("Unexpected token in value position - ", t));
- }
-
- t = Token::lex_from(m_if);
- while (!m_current_composite.empty() && t.m_type == Token::Type::BraceClose)
- {
- DEBUG("Leave composite block " << m_current_block << ", " << m_current_composite);
- m_current_composite.pop_back();
- t = Token::lex_from(m_if);
- }
- if( m_current_composite.empty() )
- {
- // TODO: Allow EOF?
- if(t.m_type != Token::Type::Newline)
- throw ::std::runtime_error(::format("Unexpected token in TOML file after entry - ", t));
- }
- else
- {
- if( t.m_type != Token::Type::Comma )
- throw ::std::runtime_error(::format("Unexpected token in TOML file after composite entry - ", t));
- }
- return rv;
-}
-
-Token Token::lex_from(::std::ifstream& is)
-{
- auto rv = Token::lex_from_inner(is);
- //DEBUG("lex_from: " << rv);
- return rv;
-}
-Token Token::lex_from_inner(::std::ifstream& is)
-{
- int c;
- do
- {
- c = is.get();
- } while( c != EOF && c != '\n' && isspace(c) );
-
- ::std::string str;
- switch(c)
- {
- case EOF: return Token { Type::Eof };
- case '[': return Token { Type::SquareOpen };
- case ']': return Token { Type::SquareClose };
- case '{': return Token { Type::BraceOpen };
- case '}': return Token { Type::BraceClose };
- case ',': return Token { Type::Comma };
- case '.': return Token { Type::Dot };
- case '=': return Token { Type::Assign };
- case '\n': return Token { Type::Newline };
- case '#':
- while(c != '\n')
- {
- c = is.get();
- if(c == EOF)
- return Token { Type::Eof };
- }
- return Token { Type::Newline };
- case '\'':
- c = is.get();
- while (c != '\'')
- {
- if (c == EOF)
- throw ::std::runtime_error("Unexpected EOF in single-quoted string");
- if (c == '\\')
- {
- // TODO: Escaped strings
- throw ::std::runtime_error("TODO: Escaped sequences in strings (single)");
- }
- str += (char)c;
- c = is.get();
- }
- return Token { Type::String, str };
- case '"':
- c = is.get();
- if(c == '"')
- {
- c = is.get();
- if( c != '"' )
- {
- is.putback(c);
- return Token { Type::String, "" };
- }
- else
- {
- // Keep reading until """
- for(;;)
- {
- c = is.get();
- if(c == '"')
- {
- c = is.get();
- if(c == '"')
- {
- c = is.get();
- if(c == '"')
- {
- break;
- }
- str += '"';
- }
- str += '"';
- }
- if( c == EOF )
- throw ::std::runtime_error("Unexpected EOF in triple-quoted string");
- if(c == '\\')
- {
- // TODO: Escaped strings
- throw ::std::runtime_error("TODO: Escaped sequences in strings (triple)");
- }
- str += (char)c;
- }
- }
- }
- else
- {
- while(c != '"')
- {
- if (c == EOF)
- throw ::std::runtime_error("Unexpected EOF in double-quoted string");
- if (c == '\\')
- {
- // TODO: Escaped strings
- c = is.get();
- switch(c)
- {
- case '"': str += '"'; break;
- case 'n': str += '\n'; break;
- default:
- throw ::std::runtime_error("TODO: Escaped sequences in strings");
- }
- c = is.get();
- continue ;
- }
- str += (char)c;
- c = is.get();
- }
- }
- return Token { Type::String, str };
- default:
- if(isalpha(c))
- {
- // Identifier
- while(isalnum(c) || c == '-' || c == '_')
- {
- str += (char)c;
- c = is.get();
- }
- is.putback(c);
- return Token { Type::Ident, str };
- }
- else if( isdigit(c) )
- {
- int64_t val = 0;
- while(isdigit(c))
- {
- val *= 10;
- val += c - '0';
- c = is.get();
- }
- is.putback(c);
- return Token { Type::Integer, val };
- }
- else
- {
- throw ::std::runtime_error(::format("Unexpected chracter '", (char)c, "' in file"));
- }
- }
-}
diff --git a/tools/minicargo/toml.h b/tools/minicargo/toml.h
deleted file mode 100644
index 315cf62f..00000000
--- a/tools/minicargo/toml.h
+++ /dev/null
@@ -1,151 +0,0 @@
-#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;
- }
-
- 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;
- }
-};