mirror of
https://github.com/ToruNiina/toml11.git
synced 2025-09-18 02:08:09 +08:00
enable to show err msg for invalid insertion
like, with the following (invalid) toml file > a.b = "value" > a.b.c = 42 The error message becomes > terminate called after throwing an instance of 'toml::syntax_error' > what(): [error] toml::insert_value: target (a.b) is neither table nor > an array of tables > --> example.toml > 1 | a.b = "value" > | ~~~~~~~ actual type is string > ... > 2 | a.b.c = 42 > | ~~ inserting this
This commit is contained in:
@@ -1006,32 +1006,67 @@ insert_nested_key(table& root, const toml::value& v,
|
|||||||
{
|
{
|
||||||
if(!(tab->at(k).is(value_t::Array)))
|
if(!(tab->at(k).is(value_t::Array)))
|
||||||
{
|
{
|
||||||
throw syntax_error("toml::detail::insert_nested_key: "
|
throw syntax_error(format_underline(concat_to_string(
|
||||||
"target is not an array of table: " +
|
"[error] toml::insert_value: target value (\"",
|
||||||
format_dotted_keys(first, last));
|
format_dotted_keys(first, last), "\") is"
|
||||||
|
" not an array of tables"), get_region(tab->at(k)),
|
||||||
|
concat_to_string("actual type is ", tab->at(k).type()),
|
||||||
|
get_region(v), "this is an array of tables"));
|
||||||
}
|
}
|
||||||
array& a = tab->at(k).template cast<toml::value_t::Array>();
|
array& a = tab->at(k).template cast<toml::value_t::Array>();
|
||||||
if(!(a.front().is(value_t::Table)))
|
if(!(a.front().is(value_t::Table)))
|
||||||
{
|
{
|
||||||
throw syntax_error("toml::detail::insert_nested_key: "
|
throw syntax_error(format_underline(concat_to_string(
|
||||||
"target is not an array of table: " +
|
"[error] toml::insert_value: target value (\"",
|
||||||
format_dotted_keys(first, last));
|
format_dotted_keys(first, last), "\") is"
|
||||||
|
" not an array of tables"), get_region(tab->at(k)),
|
||||||
|
concat_to_string("actual type is ", tab->at(k).type()),
|
||||||
|
get_region(v), "this is an array of tables"));
|
||||||
}
|
}
|
||||||
a.push_back(v);
|
a.push_back(v);
|
||||||
return ok(true);
|
return ok(true);
|
||||||
}
|
}
|
||||||
else // if not, we need to create the array of table
|
else // if not, we need to create the array of table
|
||||||
{
|
{
|
||||||
array aot(1, v); // array having one table
|
toml::value aot(v); // copy region info from table to array
|
||||||
tab->insert(std::make_pair(k, value(aot)));
|
// update content by an array with one element
|
||||||
|
detail::assign_keeping_region(aot,
|
||||||
|
::toml::value(toml::array(1, v)));
|
||||||
|
|
||||||
|
tab->insert(std::make_pair(k, aot));
|
||||||
return ok(true);
|
return ok(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(tab->count(k) == 1)
|
if(tab->count(k) == 1)
|
||||||
{
|
{
|
||||||
throw syntax_error("[error] toml::detail::insert_nested_key: "
|
if(tab->at(k).is(value_t::Table) && v.is(value_t::Table))
|
||||||
"while inserting value to table: value already exists. " +
|
{
|
||||||
format_dotted_keys(first, last));
|
throw syntax_error(format_underline(concat_to_string(
|
||||||
|
"[error] toml::insert_value: table (\"",
|
||||||
|
format_dotted_keys(first, last), "\") already exists."),
|
||||||
|
get_region(tab->at(k)), "table already exists here",
|
||||||
|
get_region(v), "table defined twice"));
|
||||||
|
}
|
||||||
|
else if(v.is(value_t::Table) &&
|
||||||
|
tab->at(k).is(value_t::Array) &&
|
||||||
|
tab->at(k).cast<value_t::Array>().size() > 0 &&
|
||||||
|
tab->at(k).cast<value_t::Array>().front().is(value_t::Table))
|
||||||
|
{
|
||||||
|
throw syntax_error(format_underline(concat_to_string(
|
||||||
|
"[error] toml::insert_value: array of tables (\"",
|
||||||
|
format_dotted_keys(first, last), "\") already exists."),
|
||||||
|
get_region(tab->at(k)), "array of tables defined here",
|
||||||
|
get_region(v), "table conflicts with the previous array"
|
||||||
|
" of table"));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw syntax_error(format_underline(concat_to_string(
|
||||||
|
"[error] toml::insert_value: value (\"",
|
||||||
|
format_dotted_keys(first, last), "\") already exists."),
|
||||||
|
get_region(tab->at(k)), "value already exists here",
|
||||||
|
get_region(v), "value inserted twice"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
tab->insert(std::make_pair(k, v));
|
tab->insert(std::make_pair(k, v));
|
||||||
return ok(true);
|
return ok(true);
|
||||||
@@ -1039,29 +1074,46 @@ insert_nested_key(table& root, const toml::value& v,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// if there is no corresponding value, insert it first.
|
// if there is no corresponding value, insert it first.
|
||||||
if(tab->count(k) == 0) {(*tab)[k] = table{};}
|
// related: you don't need to write
|
||||||
|
// # [x]
|
||||||
|
// # [x.y]
|
||||||
|
// to write
|
||||||
|
// [x.y.z]
|
||||||
|
if(tab->count(k) == 0)
|
||||||
|
{
|
||||||
|
// the region of [x.y] is the same as [x.y.z].
|
||||||
|
(*tab)[k] = v; // copy region_info_
|
||||||
|
detail::assign_keeping_region((*tab)[k],
|
||||||
|
::toml::value(::toml::table{}));
|
||||||
|
}
|
||||||
|
|
||||||
// type checking...
|
// type checking...
|
||||||
if(tab->at(k).is(value_t::Table))
|
if(tab->at(k).is(value_t::Table))
|
||||||
{
|
{
|
||||||
tab = std::addressof((*tab)[k].template cast<value_t::Table>());
|
tab = std::addressof((*tab)[k].template cast<value_t::Table>());
|
||||||
}
|
}
|
||||||
else if(tab->at(k).is(value_t::Array)) // array-of-table case
|
else if(tab->at(k).is(value_t::Array)) // inserting to array-of-tables?
|
||||||
{
|
{
|
||||||
array& a = (*tab)[k].template cast<value_t::Array>();
|
array& a = (*tab)[k].template cast<value_t::Array>();
|
||||||
if(!a.back().is(value_t::Table))
|
if(!a.back().is(value_t::Table))
|
||||||
{
|
{
|
||||||
throw syntax_error("toml::detail::insert_nested_key: value "
|
throw syntax_error(format_underline(concat_to_string(
|
||||||
"is not a table but an array: " +
|
"[error] toml::insert_value: target (",
|
||||||
format_dotted_keys(first, last));
|
format_dotted_keys(first, std::next(iter)),
|
||||||
|
") is neither table nor an array of tables"),
|
||||||
|
get_region(a.back()), concat_to_string("actual type is ",
|
||||||
|
a.back().type()), get_region(v), "inserting this"));
|
||||||
}
|
}
|
||||||
tab = std::addressof(a.back().template cast<value_t::Table>());
|
tab = std::addressof(a.back().template cast<value_t::Table>());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
throw syntax_error("toml::detail::insert_nested_key: value "
|
throw syntax_error(format_underline(concat_to_string(
|
||||||
"is not a table but an array: " +
|
"[error] toml::insert_value: target (",
|
||||||
format_dotted_keys(first, last));
|
format_dotted_keys(first, std::next(iter)),
|
||||||
|
") is neither table nor an array of tables"),
|
||||||
|
get_region(tab->at(k)), concat_to_string("actual type is ",
|
||||||
|
tab->at(k).type()), get_region(v), "inserting this"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user