mirror of
https://github.com/ToruNiina/toml11.git
synced 2025-12-16 03:08:52 +08:00
Merge origin/add-src-loc-to-exception #87
This commit is contained in:
@@ -2,6 +2,7 @@
|
|||||||
// Distributed under the MIT License.
|
// Distributed under the MIT License.
|
||||||
#ifndef TOML11_EXCEPTION_HPP
|
#ifndef TOML11_EXCEPTION_HPP
|
||||||
#define TOML11_EXCEPTION_HPP
|
#define TOML11_EXCEPTION_HPP
|
||||||
|
#include "source_location.hpp"
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
@@ -18,32 +19,41 @@ struct exception : public std::exception
|
|||||||
struct syntax_error : public toml::exception
|
struct syntax_error : public toml::exception
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit syntax_error(const std::string& what_arg) : what_(what_arg){}
|
explicit syntax_error(const std::string& what_arg, const source_location& loc)
|
||||||
explicit syntax_error(const char* what_arg) : what_(what_arg){}
|
: what_(what_arg), loc_(loc)
|
||||||
|
{}
|
||||||
virtual ~syntax_error() noexcept override = default;
|
virtual ~syntax_error() noexcept override = default;
|
||||||
virtual const char* what() const noexcept override {return what_.c_str();}
|
virtual const char* what() const noexcept override {return what_.c_str();}
|
||||||
|
|
||||||
|
source_location const& location() const noexcept {return loc_;}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::string what_;
|
std::string what_;
|
||||||
|
source_location loc_;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct type_error : public toml::exception
|
struct type_error : public toml::exception
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit type_error(const std::string& what_arg) : what_(what_arg){}
|
explicit type_error(const std::string& what_arg, const source_location& loc)
|
||||||
explicit type_error(const char* what_arg) : what_(what_arg){}
|
: what_(what_arg), loc_(loc)
|
||||||
|
{}
|
||||||
virtual ~type_error() noexcept override = default;
|
virtual ~type_error() noexcept override = default;
|
||||||
virtual const char* what() const noexcept override {return what_.c_str();}
|
virtual const char* what() const noexcept override {return what_.c_str();}
|
||||||
|
|
||||||
|
source_location const& location() const noexcept {return loc_;}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::string what_;
|
std::string what_;
|
||||||
|
source_location loc_;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct internal_error : public toml::exception
|
struct internal_error : public toml::exception
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit internal_error(const std::string& what_arg) : what_(what_arg){}
|
explicit internal_error(const std::string& what_arg)
|
||||||
explicit internal_error(const char* what_arg) : what_(what_arg){}
|
: what_(what_arg)
|
||||||
|
{}
|
||||||
virtual ~internal_error() noexcept override = default;
|
virtual ~internal_error() noexcept override = default;
|
||||||
virtual const char* what() const noexcept override {return what_.c_str();}
|
virtual const char* what() const noexcept override {return what_.c_str();}
|
||||||
protected:
|
protected:
|
||||||
|
|||||||
@@ -190,7 +190,7 @@ get(const basic_value<C, M, V>& v)
|
|||||||
"bad_cast to std::chrono::system_clock::time_point", {
|
"bad_cast to std::chrono::system_clock::time_point", {
|
||||||
{std::addressof(detail::get_region(v)),
|
{std::addressof(detail::get_region(v)),
|
||||||
concat_to_string("the actual type is ", v.type())}
|
concat_to_string("the actual type is ", v.type())}
|
||||||
}));
|
}), v.location());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,7 +76,8 @@ inline ::toml::value operator"" _toml(const char* str, std::size_t len)
|
|||||||
}
|
}
|
||||||
else // none of them.
|
else // none of them.
|
||||||
{
|
{
|
||||||
throw ::toml::syntax_error(data.unwrap_err());
|
throw ::toml::syntax_error(data.unwrap_err(),
|
||||||
|
source_location(std::addressof(loc)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -278,7 +278,7 @@ std::string read_utf8_codepoint(const region<Container>& reg,
|
|||||||
"toml::read_utf8_codepoint: codepoints in the range "
|
"toml::read_utf8_codepoint: codepoints in the range "
|
||||||
"[0xD800, 0xDFFF] are not valid UTF-8.", {{
|
"[0xD800, 0xDFFF] are not valid UTF-8.", {{
|
||||||
std::addressof(loc), "not a valid UTF-8 codepoint"
|
std::addressof(loc), "not a valid UTF-8 codepoint"
|
||||||
}}));
|
}}), source_location(std::addressof(loc)));
|
||||||
}
|
}
|
||||||
assert(codepoint < 0xD800 || 0xDFFF < codepoint);
|
assert(codepoint < 0xD800 || 0xDFFF < codepoint);
|
||||||
// 1110yyyy 10yxxxxx 10xxxxxx
|
// 1110yyyy 10yxxxxx 10xxxxxx
|
||||||
@@ -298,7 +298,8 @@ std::string read_utf8_codepoint(const region<Container>& reg,
|
|||||||
{
|
{
|
||||||
throw syntax_error(format_underline("[error] toml::read_utf8_codepoint:"
|
throw syntax_error(format_underline("[error] toml::read_utf8_codepoint:"
|
||||||
" input codepoint is too large.",
|
" input codepoint is too large.",
|
||||||
{{std::addressof(loc), "should be in [0x00..0x10FFFF]"}}));
|
{{std::addressof(loc), "should be in [0x00..0x10FFFF]"}}),
|
||||||
|
source_location(std::addressof(loc)));
|
||||||
}
|
}
|
||||||
return character;
|
return character;
|
||||||
}
|
}
|
||||||
@@ -929,7 +930,7 @@ parse_array(location<Container>& loc)
|
|||||||
std::addressof(get_region(val.unwrap())),
|
std::addressof(get_region(val.unwrap())),
|
||||||
"value has different type, " + stringize(val.unwrap().type())
|
"value has different type, " + stringize(val.unwrap().type())
|
||||||
}
|
}
|
||||||
}));
|
}), source_location(std::addressof(loc)));
|
||||||
}
|
}
|
||||||
retval.push_back(std::move(val.unwrap()));
|
retval.push_back(std::move(val.unwrap()));
|
||||||
}
|
}
|
||||||
@@ -942,7 +943,7 @@ parse_array(location<Container>& loc)
|
|||||||
"value having invalid format appeared in an array", {
|
"value having invalid format appeared in an array", {
|
||||||
{std::addressof(array_start_loc), "array starts here"},
|
{std::addressof(array_start_loc), "array starts here"},
|
||||||
{std::addressof(loc), "it is not a valid value."}
|
{std::addressof(loc), "it is not a valid value."}
|
||||||
}));
|
}), source_location(std::addressof(loc)));
|
||||||
}
|
}
|
||||||
|
|
||||||
using lex_array_separator = sequence<maybe<lex_ws>, character<','>>;
|
using lex_array_separator = sequence<maybe<lex_ws>, character<','>>;
|
||||||
@@ -965,14 +966,15 @@ parse_array(location<Container>& loc)
|
|||||||
" missing array separator `,` after a value", {
|
" missing array separator `,` after a value", {
|
||||||
{std::addressof(array_start_loc), "array starts here"},
|
{std::addressof(array_start_loc), "array starts here"},
|
||||||
{std::addressof(loc), "should be `,`"}
|
{std::addressof(loc), "should be `,`"}
|
||||||
}));
|
}), source_location(std::addressof(loc)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
loc.reset(first);
|
loc.reset(first);
|
||||||
throw syntax_error(format_underline("[error] toml::parse_array: "
|
throw syntax_error(format_underline("[error] toml::parse_array: "
|
||||||
"array did not closed by `]`",
|
"array did not closed by `]`",
|
||||||
{{std::addressof(loc), "should be closed"}}));
|
{{std::addressof(loc), "should be closed"}}),
|
||||||
|
source_location(std::addressof(loc)));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Value, typename Container>
|
template<typename Value, typename Container>
|
||||||
@@ -1175,7 +1177,7 @@ insert_nested_key(typename Value::table_type& root, const Value& v,
|
|||||||
"table already defined"},
|
"table already defined"},
|
||||||
{std::addressof(get_region(v)),
|
{std::addressof(get_region(v)),
|
||||||
"this conflicts with the previous table"}
|
"this conflicts with the previous table"}
|
||||||
}));
|
}), v.location());
|
||||||
}
|
}
|
||||||
else if(!(tab->at(k).is_array()))
|
else if(!(tab->at(k).is_array()))
|
||||||
{
|
{
|
||||||
@@ -1188,7 +1190,7 @@ insert_nested_key(typename Value::table_type& root, const Value& v,
|
|||||||
" value already exists")},
|
" value already exists")},
|
||||||
{std::addressof(get_region(v)),
|
{std::addressof(get_region(v)),
|
||||||
"while inserting this array-of-tables"}
|
"while inserting this array-of-tables"}
|
||||||
}));
|
}), v.location());
|
||||||
}
|
}
|
||||||
// the above if-else-if checks tab->at(k) is an array
|
// the above if-else-if checks tab->at(k) is an array
|
||||||
auto& a = tab->at(k).as_array();
|
auto& a = tab->at(k).as_array();
|
||||||
@@ -1203,7 +1205,7 @@ insert_nested_key(typename Value::table_type& root, const Value& v,
|
|||||||
" value already exists")},
|
" value already exists")},
|
||||||
{std::addressof(get_region(v)),
|
{std::addressof(get_region(v)),
|
||||||
"while inserting this array-of-tables"}
|
"while inserting this array-of-tables"}
|
||||||
}));
|
}), v.location());
|
||||||
}
|
}
|
||||||
// avoid conflicting array of table like the following.
|
// avoid conflicting array of table like the following.
|
||||||
// ```toml
|
// ```toml
|
||||||
@@ -1231,7 +1233,7 @@ insert_nested_key(typename Value::table_type& root, const Value& v,
|
|||||||
" value has static size")},
|
" value has static size")},
|
||||||
{std::addressof(get_region(v)),
|
{std::addressof(get_region(v)),
|
||||||
"appending it to the statically sized array"}
|
"appending it to the statically sized array"}
|
||||||
}));
|
}), v.location());
|
||||||
}
|
}
|
||||||
a.push_back(v);
|
a.push_back(v);
|
||||||
return ok(true);
|
return ok(true);
|
||||||
@@ -1259,7 +1261,7 @@ insert_nested_key(typename Value::table_type& root, const Value& v,
|
|||||||
"table already exists here"},
|
"table already exists here"},
|
||||||
{std::addressof(get_region(v)),
|
{std::addressof(get_region(v)),
|
||||||
"table defined twice"}
|
"table defined twice"}
|
||||||
}));
|
}), v.location());
|
||||||
}
|
}
|
||||||
// to allow the following toml file.
|
// to allow the following toml file.
|
||||||
// [a.b.c]
|
// [a.b.c]
|
||||||
@@ -1286,7 +1288,7 @@ insert_nested_key(typename Value::table_type& root, const Value& v,
|
|||||||
"array of tables defined here"},
|
"array of tables defined here"},
|
||||||
{std::addressof(get_region(v)),
|
{std::addressof(get_region(v)),
|
||||||
"table conflicts with the previous array of table"}
|
"table conflicts with the previous array of table"}
|
||||||
}));
|
}), v.location());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -1297,7 +1299,7 @@ insert_nested_key(typename Value::table_type& root, const Value& v,
|
|||||||
"value already exists here"},
|
"value already exists here"},
|
||||||
{std::addressof(get_region(v)),
|
{std::addressof(get_region(v)),
|
||||||
"value defined twice"}
|
"value defined twice"}
|
||||||
}));
|
}), v.location());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tab->insert(std::make_pair(k, v));
|
tab->insert(std::make_pair(k, v));
|
||||||
@@ -1333,7 +1335,7 @@ insert_nested_key(typename Value::table_type& root, const Value& v,
|
|||||||
{std::addressof(get_region(a.back())),
|
{std::addressof(get_region(a.back())),
|
||||||
concat_to_string("actual type is ", a.back().type())},
|
concat_to_string("actual type is ", a.back().type())},
|
||||||
{std::addressof(get_region(v)), "inserting this"}
|
{std::addressof(get_region(v)), "inserting this"}
|
||||||
}));
|
}), v.location());
|
||||||
}
|
}
|
||||||
tab = std::addressof(a.back().as_table());
|
tab = std::addressof(a.back().as_table());
|
||||||
}
|
}
|
||||||
@@ -1346,7 +1348,7 @@ insert_nested_key(typename Value::table_type& root, const Value& v,
|
|||||||
{std::addressof(get_region(tab->at(k))),
|
{std::addressof(get_region(tab->at(k))),
|
||||||
concat_to_string("actual type is ", tab->at(k).type())},
|
concat_to_string("actual type is ", tab->at(k).type())},
|
||||||
{std::addressof(get_region(v)), "inserting this"}
|
{std::addressof(get_region(v)), "inserting this"}
|
||||||
}));
|
}), v.location());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1412,20 +1414,23 @@ parse_inline_table(location<Container>& loc)
|
|||||||
{
|
{
|
||||||
throw syntax_error(format_underline("[error] "
|
throw syntax_error(format_underline("[error] "
|
||||||
"toml::parse_inline_table: missing curly brace `}`",
|
"toml::parse_inline_table: missing curly brace `}`",
|
||||||
{{std::addressof(loc), "should be `}`"}}));
|
{{std::addressof(loc), "should be `}`"}}),
|
||||||
|
source_location(std::addressof(loc)));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
throw syntax_error(format_underline("[error] "
|
throw syntax_error(format_underline("[error] "
|
||||||
"toml::parse_inline_table: missing table separator `,` ",
|
"toml::parse_inline_table: missing table separator `,` ",
|
||||||
{{std::addressof(loc), "should be `,`"}}));
|
{{std::addressof(loc), "should be `,`"}}),
|
||||||
|
source_location(std::addressof(loc)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
loc.reset(first);
|
loc.reset(first);
|
||||||
throw syntax_error(format_underline("[error] toml::parse_inline_table: "
|
throw syntax_error(format_underline("[error] toml::parse_inline_table: "
|
||||||
"inline table did not closed by `}`",
|
"inline table did not closed by `}`",
|
||||||
{{std::addressof(loc), "should be closed"}}));
|
{{std::addressof(loc), "should be closed"}}),
|
||||||
|
source_location(std::addressof(loc)));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Container>
|
template<typename Container>
|
||||||
@@ -1668,7 +1673,8 @@ parse_table_key(location<Container>& loc)
|
|||||||
{
|
{
|
||||||
throw syntax_error(format_underline("[error] "
|
throw syntax_error(format_underline("[error] "
|
||||||
"toml::parse_table_key: newline required after [table.key]",
|
"toml::parse_table_key: newline required after [table.key]",
|
||||||
{{std::addressof(loc), "expected newline"}}));
|
{{std::addressof(loc), "expected newline"}}),
|
||||||
|
source_location(std::addressof(loc)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ok(std::make_pair(keys.unwrap().first, token.unwrap()));
|
return ok(std::make_pair(keys.unwrap().first, token.unwrap()));
|
||||||
@@ -1722,7 +1728,8 @@ parse_array_table_key(location<Container>& loc)
|
|||||||
{
|
{
|
||||||
throw syntax_error(format_underline("[error] toml::"
|
throw syntax_error(format_underline("[error] toml::"
|
||||||
"parse_array_table_key: newline required after [[table.key]]",
|
"parse_array_table_key: newline required after [[table.key]]",
|
||||||
{{std::addressof(loc), "expected newline"}}));
|
{{std::addressof(loc), "expected newline"}}),
|
||||||
|
source_location(std::addressof(loc)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ok(std::make_pair(keys.unwrap().first, token.unwrap()));
|
return ok(std::make_pair(keys.unwrap().first, token.unwrap()));
|
||||||
@@ -1976,7 +1983,7 @@ parse(std::istream& is, const std::string& fname = "unknown file")
|
|||||||
const auto data = detail::parse_toml_file<value_type>(loc);
|
const auto data = detail::parse_toml_file<value_type>(loc);
|
||||||
if(!data)
|
if(!data)
|
||||||
{
|
{
|
||||||
throw syntax_error(data.unwrap_err());
|
throw syntax_error(data.unwrap_err(), source_location(std::addressof(loc)));
|
||||||
}
|
}
|
||||||
return data.unwrap();
|
return data.unwrap();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
// Distributed under the MIT License.
|
// Distributed under the MIT License.
|
||||||
#ifndef TOML11_REGION_HPP
|
#ifndef TOML11_REGION_HPP
|
||||||
#define TOML11_REGION_HPP
|
#define TOML11_REGION_HPP
|
||||||
#include "exception.hpp"
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
@@ -231,11 +230,10 @@ struct region final : public region_base
|
|||||||
|
|
||||||
region& operator+=(const region& other)
|
region& operator+=(const region& other)
|
||||||
{
|
{
|
||||||
if(this->begin() != other.begin() || this->end() != other.end() ||
|
// different regions cannot be concatenated
|
||||||
this->last_ != other.first_)
|
assert(this->begin() == other.begin() && this->end() == other.end() &&
|
||||||
{
|
this->last_ == other.first_);
|
||||||
throw internal_error("invalid region concatenation");
|
|
||||||
}
|
|
||||||
this->last_ = other.last_;
|
this->last_ = other.last_;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,7 +48,11 @@ struct source_location
|
|||||||
{
|
{
|
||||||
if(reg)
|
if(reg)
|
||||||
{
|
{
|
||||||
line_num_ = static_cast<std::uint_least32_t>(std::stoul(reg->line_num()));
|
if(reg->line_num() != detail::region_base().line_num())
|
||||||
|
{
|
||||||
|
line_num_ = static_cast<std::uint_least32_t>(
|
||||||
|
std::stoul(reg->line_num()));
|
||||||
|
}
|
||||||
column_num_ = static_cast<std::uint_least32_t>(reg->before() + 1);
|
column_num_ = static_cast<std::uint_least32_t>(reg->before() + 1);
|
||||||
region_size_ = static_cast<std::uint_least32_t>(reg->size());
|
region_size_ = static_cast<std::uint_least32_t>(reg->size());
|
||||||
file_name_ = reg->name();
|
file_name_ = reg->name();
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ throw_bad_cast(value_t actual, const ::toml::basic_value<C, T, A>& v)
|
|||||||
"[error] toml::value bad_cast to ", Expected), {
|
"[error] toml::value bad_cast to ", Expected), {
|
||||||
{std::addressof(get_region(v)),
|
{std::addressof(get_region(v)),
|
||||||
concat_to_string("the actual type is ", actual)}
|
concat_to_string("the actual type is ", actual)}
|
||||||
}));
|
}), v.location());
|
||||||
}
|
}
|
||||||
|
|
||||||
// switch by `value_t` and call the corresponding `value::as_xxx()`. {{{
|
// switch by `value_t` and call the corresponding `value::as_xxx()`. {{{
|
||||||
|
|||||||
Reference in New Issue
Block a user