Commit 3ff33234 authored by tqcq's avatar tqcq
Browse files

feat add toml

parent 93129ae2
Loading
Loading
Loading
Loading

3party/toml11/toml.hpp

0 → 100644
+38 −0
Original line number Diff line number Diff line
/*
 * The MIT License (MIT)
 *
 * Copyright (c) 2017 Toru Niina
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#ifndef TOML_FOR_MODERN_CPP
#define TOML_FOR_MODERN_CPP

#define TOML11_VERSION_MAJOR 3
#define TOML11_VERSION_MINOR 8
#define TOML11_VERSION_PATCH 1

#include "toml/parser.hpp"
#include "toml/literal.hpp"
#include "toml/serializer.hpp"
#include "toml/get.hpp"
#include "toml/macros.hpp"

#endif// TOML_FOR_MODERN_CPP
+109 −0
Original line number Diff line number Diff line
#ifndef TOML11_COLOR_HPP
#define TOML11_COLOR_HPP
#include <cstdint>
#include <ostream>

#ifdef TOML11_COLORIZE_ERROR_MESSAGE
#define TOML11_ERROR_MESSAGE_COLORIZED true
#else
#define TOML11_ERROR_MESSAGE_COLORIZED false
#endif

namespace toml
{

// put ANSI escape sequence to ostream
namespace color_ansi
{
namespace detail
{

inline int colorize_index()
{
    static const int index = std::ios_base::xalloc();
    return index;
}

// Control color mode globally
class color_mode
{
  public:
    inline void enable()
    {
        should_color_ = true;
    }
    inline void disable()
    {
        should_color_ = false;
    }

    inline bool should_color() const
    {
        return should_color_;
    }

    static color_mode& status()
    {
        static color_mode status_;
        return status_;
    }

  private:
    bool should_color_ = false;
};

} // detail

inline std::ostream& colorize(std::ostream& os)
{
    // by default, it is zero.
    os.iword(detail::colorize_index()) = 1;
    return os;
}
inline std::ostream& nocolorize(std::ostream& os)
{
    os.iword(detail::colorize_index()) = 0;
    return os;
}
inline std::ostream& reset  (std::ostream& os)
{if(os.iword(detail::colorize_index()) == 1) {os << "\033[00m";} return os;}
inline std::ostream& bold   (std::ostream& os)
{if(os.iword(detail::colorize_index()) == 1) {os << "\033[01m";} return os;}
inline std::ostream& grey   (std::ostream& os)
{if(os.iword(detail::colorize_index()) == 1) {os << "\033[30m";} return os;}
inline std::ostream& red    (std::ostream& os)
{if(os.iword(detail::colorize_index()) == 1) {os << "\033[31m";} return os;}
inline std::ostream& green  (std::ostream& os)
{if(os.iword(detail::colorize_index()) == 1) {os << "\033[32m";} return os;}
inline std::ostream& yellow (std::ostream& os)
{if(os.iword(detail::colorize_index()) == 1) {os << "\033[33m";} return os;}
inline std::ostream& blue   (std::ostream& os)
{if(os.iword(detail::colorize_index()) == 1) {os << "\033[34m";} return os;}
inline std::ostream& magenta(std::ostream& os)
{if(os.iword(detail::colorize_index()) == 1) {os << "\033[35m";} return os;}
inline std::ostream& cyan   (std::ostream& os)
{if(os.iword(detail::colorize_index()) == 1) {os << "\033[36m";} return os;}
inline std::ostream& white  (std::ostream& os)
{if(os.iword(detail::colorize_index()) == 1) {os << "\033[37m";} return os;}

inline void enable()
{
    return detail::color_mode::status().enable();
}
inline void disable()
{
    return detail::color_mode::status().disable();
}

inline bool should_color()
{
    return detail::color_mode::status().should_color();
}

} // color_ansi

// ANSI escape sequence is the only and default colorization method currently
namespace color = color_ansi;

} // toml
#endif// TOML11_COLOR_HPP
+306 −0
Original line number Diff line number Diff line
//     Copyright Toru Niina 2017.
// Distributed under the MIT License.
#ifndef TOML11_COMBINATOR_HPP
#define TOML11_COMBINATOR_HPP
#include <cassert>
#include <cctype>
#include <cstdio>

#include <array>
#include <iomanip>
#include <iterator>
#include <limits>
#include <type_traits>

#include "region.hpp"
#include "result.hpp"
#include "traits.hpp"
#include "utility.hpp"

// they scans characters and returns region if it matches to the condition.
// when they fail, it does not change the location.
// in lexer.hpp, these are used.

namespace toml
{
namespace detail
{

// to output character as an error message.
inline std::string show_char(const char c)
{
    // It suppresses an error that occurs only in Debug mode of MSVC++ on Windows.
    // I'm not completely sure but they check the value of char to be in the
    // range [0, 256) and some of the COMPLETELY VALID utf-8 character sometimes
    // has negative value (if char has sign). So here it re-interprets c as
    // unsigned char through pointer. In general, converting pointer to a
    // pointer that has different type cause UB, but `(signed|unsigned)?char`
    // are one of the exceptions. Converting pointer only to char and std::byte
    // (c++17) are valid.
    if(std::isgraph(*reinterpret_cast<unsigned char const*>(std::addressof(c))))
    {
        return std::string(1, c);
    }
    else
    {
        std::array<char, 5> buf;
        buf.fill('\0');
        const auto r = std::snprintf(
                buf.data(), buf.size(), "0x%02x", static_cast<int>(c) & 0xFF);
        (void) r; // Unused variable warning
        assert(r == static_cast<int>(buf.size()) - 1);
        return std::string(buf.data());
    }
}

template<char C>
struct character
{
    static constexpr char target = C;

    static result<region, none_t>
    invoke(location& loc)
    {
        if(loc.iter() == loc.end()) {return none();}
        const auto first = loc.iter();

        const char c = *(loc.iter());
        if(c != target)
        {
            return none();
        }
        loc.advance(); // update location

        return ok(region(loc, first, loc.iter()));
    }
};
template<char C>
constexpr char character<C>::target;

// closed interval [Low, Up]. both Low and Up are included.
template<char Low, char Up>
struct in_range
{
    // assuming ascii part of UTF-8...
    static_assert(Low <= Up, "lower bound should be less than upper bound.");

    static constexpr char upper = Up;
    static constexpr char lower = Low;

    static result<region, none_t>
    invoke(location& loc)
    {
        if(loc.iter() == loc.end()) {return none();}
        const auto first = loc.iter();

        const char c = *(loc.iter());
        if(c < lower || upper < c)
        {
            return none();
        }

        loc.advance();
        return ok(region(loc, first, loc.iter()));
    }
};
template<char L, char U> constexpr char in_range<L, U>::upper;
template<char L, char U> constexpr char in_range<L, U>::lower;

// keep iterator if `Combinator` matches. otherwise, increment `iter` by 1 char.
// for detecting invalid characters, like control sequences in toml string.
template<typename Combinator>
struct exclude
{
    static result<region, none_t>
    invoke(location& loc)
    {
        if(loc.iter() == loc.end()) {return none();}
        auto first = loc.iter();

        auto rslt = Combinator::invoke(loc);
        if(rslt.is_ok())
        {
            loc.reset(first);
            return none();
        }
        loc.reset(std::next(first)); // XXX maybe loc.advance() is okay but...
        return ok(region(loc, first, loc.iter()));
    }
};

// increment `iter`, if matches. otherwise, just return empty string.
template<typename Combinator>
struct maybe
{
    static result<region, none_t>
    invoke(location& loc)
    {
        const auto rslt = Combinator::invoke(loc);
        if(rslt.is_ok())
        {
            return rslt;
        }
        return ok(region(loc));
    }
};

template<typename ... Ts>
struct sequence;

template<typename Head, typename ... Tail>
struct sequence<Head, Tail...>
{
    static result<region, none_t>
    invoke(location& loc)
    {
        const auto first = loc.iter();
        auto rslt = Head::invoke(loc);
        if(rslt.is_err())
        {
            loc.reset(first);
            return none();
        }
        return sequence<Tail...>::invoke(loc, std::move(rslt.unwrap()), first);
    }

    // called from the above function only, recursively.
    template<typename Iterator>
    static result<region, none_t>
    invoke(location& loc, region reg, Iterator first)
    {
        const auto rslt = Head::invoke(loc);
        if(rslt.is_err())
        {
            loc.reset(first);
            return none();
        }
        reg += rslt.unwrap(); // concat regions
        return sequence<Tail...>::invoke(loc, std::move(reg), first);
    }
};

template<typename Head>
struct sequence<Head>
{
    // would be called from sequence<T ...>::invoke only.
    template<typename Iterator>
    static result<region, none_t>
    invoke(location& loc, region reg, Iterator first)
    {
        const auto rslt = Head::invoke(loc);
        if(rslt.is_err())
        {
            loc.reset(first);
            return none();
        }
        reg += rslt.unwrap(); // concat regions
        return ok(reg);
    }
};

template<typename ... Ts>
struct either;

template<typename Head, typename ... Tail>
struct either<Head, Tail...>
{
    static result<region, none_t>
    invoke(location& loc)
    {
        const auto rslt = Head::invoke(loc);
        if(rslt.is_ok()) {return rslt;}
        return either<Tail...>::invoke(loc);
    }
};
template<typename Head>
struct either<Head>
{
    static result<region, none_t>
    invoke(location& loc)
    {
        return Head::invoke(loc);
    }
};

template<typename T, typename N>
struct repeat;

template<std::size_t N> struct exactly{};
template<std::size_t N> struct at_least{};
struct unlimited{};

template<typename T, std::size_t N>
struct repeat<T, exactly<N>>
{
    static result<region, none_t>
    invoke(location& loc)
    {
        region retval(loc);
        const auto first = loc.iter();
        for(std::size_t i=0; i<N; ++i)
        {
            auto rslt = T::invoke(loc);
            if(rslt.is_err())
            {
                loc.reset(first);
                return none();
            }
            retval += rslt.unwrap();
        }
        return ok(std::move(retval));
    }
};

template<typename T, std::size_t N>
struct repeat<T, at_least<N>>
{
    static result<region, none_t>
    invoke(location& loc)
    {
        region retval(loc);

        const auto first = loc.iter();
        for(std::size_t i=0; i<N; ++i)
        {
            auto rslt = T::invoke(loc);
            if(rslt.is_err())
            {
                loc.reset(first);
                return none();
            }
            retval += rslt.unwrap();
        }
        while(true)
        {
            auto rslt = T::invoke(loc);
            if(rslt.is_err())
            {
                return ok(std::move(retval));
            }
            retval += rslt.unwrap();
        }
    }
};

template<typename T>
struct repeat<T, unlimited>
{
    static result<region, none_t>
    invoke(location& loc)
    {
        region retval(loc);
        while(true)
        {
            auto rslt = T::invoke(loc);
            if(rslt.is_err())
            {
                return ok(std::move(retval));
            }
            retval += rslt.unwrap();
        }
    }
};

} // detail
} // toml
#endif// TOML11_COMBINATOR_HPP
+484 −0

File added.

Preview size limit exceeded, changes collapsed.

+631 −0

File added.

Preview size limit exceeded, changes collapsed.

Loading