mirror of
https://github.com/marzer/tomlplusplus.git
synced 2024-09-15 15:13:21 +00:00
minor improvements to the wording of some error messages
also: - added 'error_printer' example
This commit is contained in:
parent
0fbdc945bb
commit
0c2279d15a
118
examples/error_printer.cpp
Normal file
118
examples/error_printer.cpp
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
// This file is a part of toml++ and is subject to the the terms of the MIT license.
|
||||||
|
// Copyright (c) 2019-2020 Mark Gillard <mark.gillard@outlook.com.au>
|
||||||
|
// See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
/*
|
||||||
|
|
||||||
|
This example is one of diagnostics; it forces a set of specific parsing
|
||||||
|
failures and prints their error messages to stdout so you can see what the
|
||||||
|
default error messages look like.
|
||||||
|
|
||||||
|
*/
|
||||||
|
#include <iostream>
|
||||||
|
#include "utf8_console.h"
|
||||||
|
#define TOML_EXCEPTIONS 0
|
||||||
|
#define TOML_UNRELEASED_FEATURES 0
|
||||||
|
#include <toml++/toml.h>
|
||||||
|
using namespace std::string_view_literals;
|
||||||
|
using toml::operator""_sz;
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
inline constexpr std::string_view invalid_parses[] =
|
||||||
|
{
|
||||||
|
"########## comments"sv,
|
||||||
|
"# bar\rkek"sv,
|
||||||
|
"# bar\bkek"sv,
|
||||||
|
|
||||||
|
"########## inline tables"sv,
|
||||||
|
"val = {,}"sv,
|
||||||
|
"val = {a='b',}"sv, // allowed when TOML_UNRELEASED_FEATURES == 1
|
||||||
|
"val = {a='b',,}"sv,
|
||||||
|
"val = {a='b',"sv,
|
||||||
|
"val = {a='b',\n c='d'}"sv, // allowed when TOML_UNRELEASED_FEATURES == 1
|
||||||
|
"val = {?='b'}"sv,
|
||||||
|
|
||||||
|
"########## tables"sv,
|
||||||
|
"[foo"sv,
|
||||||
|
"[foo] ?"sv,
|
||||||
|
"[foo] [bar]"sv,
|
||||||
|
"[foo]\n[foo]"sv,
|
||||||
|
"? = 'foo' ?"sv,
|
||||||
|
|
||||||
|
"########## arrays"sv,
|
||||||
|
"val = [,]"sv,
|
||||||
|
"val = ['a',,]"sv,
|
||||||
|
"val = ['a',"sv,
|
||||||
|
|
||||||
|
"########## key-value pairs"sv,
|
||||||
|
"val = 'foo' ?"sv,
|
||||||
|
"val = "sv,
|
||||||
|
"val "sv,
|
||||||
|
"val ?"sv,
|
||||||
|
"val = ]"sv,
|
||||||
|
"[foo]\nbar = 'kek'\nbar = 'kek2'"sv,
|
||||||
|
"[foo]\nbar = 'kek'\nbar = 7"sv,
|
||||||
|
"[foo.bar]\n[foo]\nbar = 'kek'"sv,
|
||||||
|
"[foo]\nbar = 'kek'\nbar.kek = 7"sv,
|
||||||
|
"[foo]\nbar.? = 'kek'"sv,
|
||||||
|
|
||||||
|
"########## values"sv,
|
||||||
|
"val = _"sv,
|
||||||
|
"val = G"sv,
|
||||||
|
|
||||||
|
"########## strings"sv,
|
||||||
|
"val = \" \r \""sv,
|
||||||
|
R"(val = ")"sv,
|
||||||
|
R"(val = "\g")"sv,
|
||||||
|
R"(val = "\x20")"sv, // allowed when TOML_UNRELEASED_FEATURES == 1
|
||||||
|
R"(val = "\uFFF")"sv,
|
||||||
|
R"(val = "\uFFFG")"sv,
|
||||||
|
R"(val = "\UFFFFFFF")"sv,
|
||||||
|
R"(val = "\UFFFFFGF")"sv,
|
||||||
|
R"(val = "\uD801")"sv,
|
||||||
|
R"(val = "\U00110000")"sv,
|
||||||
|
R"(val = """ """""")"sv,
|
||||||
|
R"(val = ''' '''''')"sv,
|
||||||
|
"val = '\n'"sv,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main(int /*argc*/, char** /*argv*/)
|
||||||
|
{
|
||||||
|
std::ios_base::sync_with_stdio(false);
|
||||||
|
init_utf8_console();
|
||||||
|
|
||||||
|
for (auto str : invalid_parses)
|
||||||
|
{
|
||||||
|
if (str.empty())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (str.substr(0_sz, 10_sz) == "##########"sv)
|
||||||
|
{
|
||||||
|
const auto substr = str.substr(11_sz);
|
||||||
|
size_t cols = 80_sz;
|
||||||
|
for (size_t i = (cols - substr.length()) / 2_sz - 1_sz; i-- > 0_sz; )
|
||||||
|
{
|
||||||
|
std::cout.put('#');
|
||||||
|
cols--;
|
||||||
|
}
|
||||||
|
std::cout.put(' ');
|
||||||
|
std::cout << substr;
|
||||||
|
std::cout.put(' ');
|
||||||
|
cols -= substr.length() + 2_sz;
|
||||||
|
while (cols--)
|
||||||
|
std::cout.put('#');
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto result = toml::parse(str);
|
||||||
|
if (!result)
|
||||||
|
std::cout << result.error();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "\n\n"sv;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
@ -24,3 +24,10 @@ toml_generator = executable(
|
|||||||
include_directories : inc,
|
include_directories : inc,
|
||||||
cpp_args : args
|
cpp_args : args
|
||||||
)
|
)
|
||||||
|
|
||||||
|
error_printer = executable(
|
||||||
|
'error_printer',
|
||||||
|
[ 'error_printer.cpp' ],
|
||||||
|
include_directories : inc,
|
||||||
|
cpp_args : args
|
||||||
|
)
|
||||||
|
@ -17,6 +17,7 @@ using namespace std::string_view_literals;
|
|||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
|
std::ios_base::sync_with_stdio(false);
|
||||||
init_utf8_console();
|
init_utf8_console();
|
||||||
|
|
||||||
auto path = std::string{ argc > 1 ? argv[1] : "example.toml" };
|
auto path = std::string{ argc > 1 ? argv[1] : "example.toml" };
|
||||||
|
@ -108,6 +108,7 @@ namespace
|
|||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
|
std::ios_base::sync_with_stdio(false);
|
||||||
init_utf8_console();
|
init_utf8_console();
|
||||||
srand(static_cast<unsigned int>(time(nullptr)));
|
srand(static_cast<unsigned int>(time(nullptr)));
|
||||||
|
|
||||||
|
@ -17,6 +17,7 @@ using namespace std::string_view_literals;
|
|||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
|
std::ios_base::sync_with_stdio(false);
|
||||||
init_utf8_console();
|
init_utf8_console();
|
||||||
|
|
||||||
// read from a file if a path argument is given
|
// read from a file if a path argument is given
|
||||||
|
@ -3,7 +3,10 @@
|
|||||||
//# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
|
//# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
|
||||||
// SPDX-License-Identifier: MIT
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
#pragma once
|
//# {{
|
||||||
|
#ifndef INCLUDE_TOMLPLUSPLUS_H
|
||||||
|
#define INCLUDE_TOMLPLUSPLUS_H
|
||||||
|
//# }}
|
||||||
|
|
||||||
//# Note: most of these would be included transitively but
|
//# Note: most of these would be included transitively but
|
||||||
//# they're listed explicitly here because this file
|
//# they're listed explicitly here because this file
|
||||||
@ -489,3 +492,7 @@
|
|||||||
/// - Facebook: [marzer](https://www.facebook.com/marzer)
|
/// - Facebook: [marzer](https://www.facebook.com/marzer)
|
||||||
/// - LinkedIn: [marzer](https://www.linkedin.com/in/marzer/)
|
/// - LinkedIn: [marzer](https://www.linkedin.com/in/marzer/)
|
||||||
///
|
///
|
||||||
|
|
||||||
|
//# {{
|
||||||
|
#endif // INCLUDE_TOMLPLUSPLUS_H
|
||||||
|
//# }}
|
||||||
|
@ -155,15 +155,25 @@ namespace TOML_INTERNAL_NAMESPACE
|
|||||||
|
|
||||||
struct parse_scope final
|
struct parse_scope final
|
||||||
{
|
{
|
||||||
std::vector<std::string_view>& stack_;
|
std::string_view& storage_;
|
||||||
|
std::string_view parent_;
|
||||||
|
|
||||||
TOML_NODISCARD_CTOR
|
TOML_NODISCARD_CTOR
|
||||||
explicit parse_scope(std::vector<std::string_view>& stack) noexcept : stack_{ stack } {}
|
explicit parse_scope(std::string_view& current_scope, std::string_view new_scope) noexcept
|
||||||
~parse_scope() noexcept { stack_.pop_back(); }
|
: storage_{ current_scope },
|
||||||
|
parent_{ current_scope }
|
||||||
|
{
|
||||||
|
storage_ = new_scope;
|
||||||
|
}
|
||||||
|
|
||||||
|
~parse_scope() noexcept
|
||||||
|
{
|
||||||
|
storage_ = parent_;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
#define push_parse_scope_2(desc, line) scope_stack.push_back(desc); parse_scope ps_##line{ scope_stack }
|
#define push_parse_scope_2(scope, line) parse_scope ps_##line{ current_scope, scope }
|
||||||
#define push_parse_scope_1(desc, line) push_parse_scope_2(desc, line)
|
#define push_parse_scope_1(scope, line) push_parse_scope_2(scope, line)
|
||||||
#define push_parse_scope(desc) push_parse_scope_1(desc, __LINE__)
|
#define push_parse_scope(scope) push_parse_scope_1(scope, __LINE__)
|
||||||
|
|
||||||
struct parsed_key final
|
struct parsed_key final
|
||||||
{
|
{
|
||||||
@ -247,8 +257,8 @@ namespace toml::impl
|
|||||||
std::vector<table*> dotted_key_tables;
|
std::vector<table*> dotted_key_tables;
|
||||||
std::vector<array*> table_arrays;
|
std::vector<array*> table_arrays;
|
||||||
std::string recording_buffer; //for diagnostics
|
std::string recording_buffer; //for diagnostics
|
||||||
bool recording = false;
|
bool recording = false, recording_whitespace = true;
|
||||||
std::vector<std::string_view> scope_stack;
|
std::string_view current_scope;
|
||||||
#if !TOML_EXCEPTIONS
|
#if !TOML_EXCEPTIONS
|
||||||
mutable optional<toml::parse_error> err;
|
mutable optional<toml::parse_error> err;
|
||||||
#endif
|
#endif
|
||||||
@ -271,14 +281,13 @@ namespace toml::impl
|
|||||||
return;
|
return;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const auto current_scope = scope_stack.empty() ? ""sv : scope_stack.back();
|
|
||||||
static constexpr auto buf_size = 512_sz;
|
static constexpr auto buf_size = 512_sz;
|
||||||
char buf[buf_size];
|
char buf[buf_size];
|
||||||
auto write_pos = buf;
|
auto write_pos = buf;
|
||||||
const auto max_write_pos = buf + (buf_size - 1_sz); //allow for null terminator
|
const auto max_write_pos = buf + (buf_size - 1_sz); //allow for null terminator
|
||||||
concatenate(write_pos, max_write_pos, "Error while parsing "sv);
|
concatenate(write_pos, max_write_pos, "Error while parsing "sv);
|
||||||
concatenate(write_pos, max_write_pos, current_scope);
|
concatenate(write_pos, max_write_pos, current_scope);
|
||||||
concatenate(write_pos, max_write_pos, "; "sv);
|
concatenate(write_pos, max_write_pos, ": "sv);
|
||||||
(concatenate(write_pos, max_write_pos, reason), ...);
|
(concatenate(write_pos, max_write_pos, reason), ...);
|
||||||
*write_pos = '\0';
|
*write_pos = '\0';
|
||||||
#if TOML_EXCEPTIONS
|
#if TOML_EXCEPTIONS
|
||||||
@ -326,7 +335,10 @@ namespace toml::impl
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (recording && !is_eof())
|
if (recording && !is_eof())
|
||||||
recording_buffer.append(cp->as_view<char>());
|
{
|
||||||
|
if (recording_whitespace || !(is_whitespace(*cp) || is_line_break(*cp)))
|
||||||
|
recording_buffer.append(cp->as_view<char>());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void start_recording(bool include_current = true) noexcept
|
void start_recording(bool include_current = true) noexcept
|
||||||
@ -334,6 +346,7 @@ namespace toml::impl
|
|||||||
return_if_error();
|
return_if_error();
|
||||||
|
|
||||||
recording = true;
|
recording = true;
|
||||||
|
recording_whitespace = true;
|
||||||
recording_buffer.clear();
|
recording_buffer.clear();
|
||||||
if (include_current && !is_eof())
|
if (include_current && !is_eof())
|
||||||
recording_buffer.append(cp->as_view<char>());
|
recording_buffer.append(cp->as_view<char>());
|
||||||
@ -348,6 +361,8 @@ namespace toml::impl
|
|||||||
{
|
{
|
||||||
if (pop_bytes >= recording_buffer.length())
|
if (pop_bytes >= recording_buffer.length())
|
||||||
recording_buffer.clear();
|
recording_buffer.clear();
|
||||||
|
else if (pop_bytes == 1_sz)
|
||||||
|
recording_buffer.pop_back();
|
||||||
else
|
else
|
||||||
recording_buffer.erase(
|
recording_buffer.erase(
|
||||||
recording_buffer.begin() + static_cast<ptrdiff_t>(recording_buffer.length() - pop_bytes),
|
recording_buffer.begin() + static_cast<ptrdiff_t>(recording_buffer.length() - pop_bytes),
|
||||||
@ -427,16 +442,13 @@ namespace toml::impl
|
|||||||
// toml/issues/567 (disallow non-TAB control characters in comments)
|
// toml/issues/567 (disallow non-TAB control characters in comments)
|
||||||
if (is_nontab_control_character(*cp))
|
if (is_nontab_control_character(*cp))
|
||||||
set_error_and_return_default(
|
set_error_and_return_default(
|
||||||
"control characters "
|
"control characters other than TAB (U+0009) are explicitly prohibited"sv
|
||||||
"other than TAB (U+0009) are explicitly prohibited from appearing "
|
|
||||||
"in comments."sv
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// toml/pull/720 (disallow surrogates in comments)
|
// toml/pull/720 (disallow surrogates in comments)
|
||||||
else if (is_unicode_surrogate(*cp))
|
else if (is_unicode_surrogate(*cp))
|
||||||
set_error_and_return_default(
|
set_error_and_return_default(
|
||||||
"unicode surrogates (U+D800 to U+DFFF) are explicitly prohibited "
|
"unicode surrogates (U+D800 to U+DFFF) are explicitly prohibited"sv
|
||||||
"from appearing in comments."sv
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
advance_and_return_if_error({});
|
advance_and_return_if_error({});
|
||||||
@ -542,12 +554,9 @@ namespace toml::impl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// skip the escaped character
|
bool skipped_escaped_codepoint = false;
|
||||||
const auto escaped_codepoint = cp->value;
|
|
||||||
advance_and_return_if_error_or_eof({});
|
|
||||||
|
|
||||||
assert_not_eof();
|
assert_not_eof();
|
||||||
switch (escaped_codepoint)
|
switch (const auto escaped_codepoint = *cp)
|
||||||
{
|
{
|
||||||
// 'regular' escape codes
|
// 'regular' escape codes
|
||||||
case U'b': str += TOML_STRING_PREFIX('\b'); break;
|
case U'b': str += TOML_STRING_PREFIX('\b'); break;
|
||||||
@ -563,7 +572,7 @@ namespace toml::impl
|
|||||||
if constexpr (!TOML_LANG_UNRELEASED) // toml/pull/709 (\xHH unicode scalar sequences)
|
if constexpr (!TOML_LANG_UNRELEASED) // toml/pull/709 (\xHH unicode scalar sequences)
|
||||||
{
|
{
|
||||||
set_error_and_return_default(
|
set_error_and_return_default(
|
||||||
"escape sequence '\\x' is not supported in TOML 1.0.0 and earlier."sv
|
"escape sequence '\\x' is not supported in TOML 1.0.0 and earlier"sv
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
[[fallthrough]];
|
[[fallthrough]];
|
||||||
@ -571,13 +580,18 @@ namespace toml::impl
|
|||||||
case U'U':
|
case U'U':
|
||||||
{
|
{
|
||||||
push_parse_scope("unicode scalar escape sequence"sv);
|
push_parse_scope("unicode scalar escape sequence"sv);
|
||||||
uint32_t place_value = escaped_codepoint == U'U' ? 0x10000000u : (escaped_codepoint == U'u' ? 0x1000u : 0x10u);
|
advance_and_return_if_error_or_eof({});
|
||||||
|
skipped_escaped_codepoint = true;
|
||||||
|
|
||||||
|
uint32_t place_value = escaped_codepoint == U'U'
|
||||||
|
? 0x10000000u
|
||||||
|
: (escaped_codepoint == U'u' ? 0x1000u : 0x10u);
|
||||||
uint32_t sequence_value{};
|
uint32_t sequence_value{};
|
||||||
while (place_value)
|
while (place_value)
|
||||||
{
|
{
|
||||||
set_error_and_return_if_eof({});
|
set_error_and_return_if_eof({});
|
||||||
if (!is_hexadecimal_digit(*cp))
|
if (!is_hexadecimal_digit(*cp))
|
||||||
set_error_and_return_default("expected hex digit, saw '\\"sv, *cp, "'"sv);
|
set_error_and_return_default("expected hex digit, saw '"sv, *cp, "'"sv);
|
||||||
sequence_value += place_value * hex_to_dec(*cp);
|
sequence_value += place_value * hex_to_dec(*cp);
|
||||||
place_value /= 16u;
|
place_value /= 16u;
|
||||||
advance_and_return_if_error({});
|
advance_and_return_if_error({});
|
||||||
@ -585,10 +599,10 @@ namespace toml::impl
|
|||||||
|
|
||||||
if (is_unicode_surrogate(sequence_value))
|
if (is_unicode_surrogate(sequence_value))
|
||||||
set_error_and_return_default(
|
set_error_and_return_default(
|
||||||
"unicode surrogates (U+D800 - U+DFFF) are explicitly prohibited."sv
|
"unicode surrogates (U+D800 - U+DFFF) are explicitly prohibited"sv
|
||||||
);
|
);
|
||||||
else if (sequence_value > 0x10FFFFu)
|
else if (sequence_value > 0x10FFFFu)
|
||||||
set_error_and_return_default("values greater than U+10FFFF are invalid."sv);
|
set_error_and_return_default("values greater than U+10FFFF are invalid"sv);
|
||||||
else if (sequence_value <= 0x7Fu) //ascii
|
else if (sequence_value <= 0x7Fu) //ascii
|
||||||
str += static_cast<string_char>(sequence_value & 0x7Fu);
|
str += static_cast<string_char>(sequence_value & 0x7Fu);
|
||||||
else if (sequence_value <= 0x7FFu)
|
else if (sequence_value <= 0x7FFu)
|
||||||
@ -616,6 +630,10 @@ namespace toml::impl
|
|||||||
default:
|
default:
|
||||||
set_error_and_return_default("unknown escape sequence '\\"sv, *cp, "'"sv);
|
set_error_and_return_default("unknown escape sequence '\\"sv, *cp, "'"sv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// skip the escaped character
|
||||||
|
if (!skipped_escaped_codepoint)
|
||||||
|
advance_and_return_if_error_or_eof({});
|
||||||
}
|
}
|
||||||
else TOML_LIKELY
|
else TOML_LIKELY
|
||||||
{
|
{
|
||||||
@ -679,7 +697,7 @@ namespace toml::impl
|
|||||||
// handle escapes
|
// handle escapes
|
||||||
else if (*cp == U'\\')
|
else if (*cp == U'\\')
|
||||||
{
|
{
|
||||||
advance_and_return_if_error({}); // skip the '\'
|
advance_and_return_if_error_or_eof({}); // skip the '\'
|
||||||
skipping_whitespace = false;
|
skipping_whitespace = false;
|
||||||
escaped = true;
|
escaped = true;
|
||||||
continue;
|
continue;
|
||||||
@ -701,7 +719,7 @@ namespace toml::impl
|
|||||||
// handle control characters
|
// handle control characters
|
||||||
if (is_nontab_control_character(*cp))
|
if (is_nontab_control_character(*cp))
|
||||||
set_error_and_return_default(
|
set_error_and_return_default(
|
||||||
"unescaped control characters other than TAB (U+0009) are explicitly prohibited."sv
|
"unescaped control characters other than TAB (U+0009) are explicitly prohibited"sv
|
||||||
);
|
);
|
||||||
|
|
||||||
// handle surrogates in strings (1.0.0 and later)
|
// handle surrogates in strings (1.0.0 and later)
|
||||||
@ -709,7 +727,7 @@ namespace toml::impl
|
|||||||
{
|
{
|
||||||
if (is_unicode_surrogate(*cp))
|
if (is_unicode_surrogate(*cp))
|
||||||
set_error_and_return_default(
|
set_error_and_return_default(
|
||||||
"unescaped unicode surrogates (U+D800 to U+DFFF) are explicitly prohibited."sv
|
"unescaped unicode surrogates (U+D800 to U+DFFF) are explicitly prohibited"sv
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -826,7 +844,7 @@ namespace toml::impl
|
|||||||
// handle control characters
|
// handle control characters
|
||||||
if (is_nontab_control_character(*cp))
|
if (is_nontab_control_character(*cp))
|
||||||
set_error_and_return_default(
|
set_error_and_return_default(
|
||||||
"control characters other than TAB (U+0009) are explicitly prohibited."sv
|
"control characters other than TAB (U+0009) are explicitly prohibited"sv
|
||||||
);
|
);
|
||||||
|
|
||||||
// handle surrogates in strings (1.0.0 and later)
|
// handle surrogates in strings (1.0.0 and later)
|
||||||
@ -834,7 +852,7 @@ namespace toml::impl
|
|||||||
{
|
{
|
||||||
if (is_unicode_surrogate(*cp))
|
if (is_unicode_surrogate(*cp))
|
||||||
set_error_and_return_default(
|
set_error_and_return_default(
|
||||||
"unicode surrogates (U+D800 - U+DFFF) are explicitly prohibited."sv
|
"unicode surrogates (U+D800 - U+DFFF) are explicitly prohibited"sv
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1661,7 +1679,7 @@ namespace toml::impl
|
|||||||
if (!val->ref_cast<array>().is_homogeneous())
|
if (!val->ref_cast<array>().is_homogeneous())
|
||||||
set_error_at(
|
set_error_at(
|
||||||
begin_pos,
|
begin_pos,
|
||||||
"arrays cannot contain values of different types before TOML 1.0.0."
|
"arrays cannot contain values of different types before TOML 1.0.0"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1688,7 +1706,7 @@ namespace toml::impl
|
|||||||
|
|
||||||
// underscores at the beginning
|
// underscores at the beginning
|
||||||
else if (*cp == U'_')
|
else if (*cp == U'_')
|
||||||
set_error_and_return_default("values may not begin with underscores."sv);
|
set_error_and_return_default("values may not begin with underscores"sv);
|
||||||
|
|
||||||
return_if_error({});
|
return_if_error({});
|
||||||
if (val)
|
if (val)
|
||||||
@ -2124,6 +2142,7 @@ namespace toml::impl
|
|||||||
push_parse_scope("key"sv);
|
push_parse_scope("key"sv);
|
||||||
|
|
||||||
parsed_key key;
|
parsed_key key;
|
||||||
|
recording_whitespace = false;
|
||||||
|
|
||||||
while (!is_error())
|
while (!is_error())
|
||||||
{
|
{
|
||||||
@ -2139,7 +2158,11 @@ namespace toml::impl
|
|||||||
|
|
||||||
// "quoted key segment"
|
// "quoted key segment"
|
||||||
else if (is_string_delimiter(*cp))
|
else if (is_string_delimiter(*cp))
|
||||||
|
{
|
||||||
|
recording_whitespace = true;
|
||||||
key.segments.push_back(parse_string());
|
key.segments.push_back(parse_string());
|
||||||
|
recording_whitespace = false;
|
||||||
|
}
|
||||||
|
|
||||||
// ???
|
// ???
|
||||||
else
|
else
|
||||||
@ -2151,14 +2174,8 @@ namespace toml::impl
|
|||||||
consume_leading_whitespace();
|
consume_leading_whitespace();
|
||||||
|
|
||||||
// eof or no more key to come
|
// eof or no more key to come
|
||||||
if (is_eof())
|
if (is_eof() || *cp != U'.')
|
||||||
break;
|
break;
|
||||||
if (*cp != U'.')
|
|
||||||
{
|
|
||||||
if (recording)
|
|
||||||
stop_recording(1_sz);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// was a dotted key, so go around again to consume the next segment
|
// was a dotted key, so go around again to consume the next segment
|
||||||
advance_and_return_if_error_or_eof({});
|
advance_and_return_if_error_or_eof({});
|
||||||
@ -2179,7 +2196,8 @@ namespace toml::impl
|
|||||||
|
|
||||||
// get the key
|
// get the key
|
||||||
start_recording();
|
start_recording();
|
||||||
auto key = parse_key(); //parse_key() calls stop_recording()
|
auto key = parse_key();
|
||||||
|
stop_recording(1_sz);
|
||||||
|
|
||||||
// skip past any whitespace that followed the key
|
// skip past any whitespace that followed the key
|
||||||
consume_leading_whitespace();
|
consume_leading_whitespace();
|
||||||
@ -2232,7 +2250,8 @@ namespace toml::impl
|
|||||||
|
|
||||||
// get the actual key
|
// get the actual key
|
||||||
start_recording();
|
start_recording();
|
||||||
key = parse_key(); //parse_key() calls stop_recording()
|
key = parse_key();
|
||||||
|
stop_recording(1_sz);
|
||||||
return_if_error({});
|
return_if_error({});
|
||||||
|
|
||||||
// skip past any whitespace that followed the key
|
// skip past any whitespace that followed the key
|
||||||
@ -2452,6 +2471,8 @@ namespace toml::impl
|
|||||||
// "quoted keys"
|
// "quoted keys"
|
||||||
else if (is_bare_key_character(*cp) || is_string_delimiter(*cp))
|
else if (is_bare_key_character(*cp) || is_string_delimiter(*cp))
|
||||||
{
|
{
|
||||||
|
push_parse_scope("key-value pair"sv);
|
||||||
|
|
||||||
parse_key_value_pair_and_insert(current_table);
|
parse_key_value_pair_and_insert(current_table);
|
||||||
|
|
||||||
// handle the rest of the line after the kvp
|
// handle the rest of the line after the kvp
|
||||||
@ -2530,10 +2551,7 @@ namespace toml::impl
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (cp)
|
if (cp)
|
||||||
{
|
|
||||||
scope_stack.reserve(20_sz);
|
|
||||||
parse_document();
|
parse_document();
|
||||||
}
|
|
||||||
|
|
||||||
update_region_ends(root);
|
update_region_ends(root);
|
||||||
}
|
}
|
||||||
|
@ -53,9 +53,6 @@ class Preprocessor:
|
|||||||
self.processed_includes.append(incl)
|
self.processed_includes.append(incl)
|
||||||
text = read_all_text_from_file(path.join(get_script_folder(), '..', 'include', 'toml++', incl))
|
text = read_all_text_from_file(path.join(get_script_folder(), '..', 'include', 'toml++', incl))
|
||||||
text = re.sub(r'//[#!]\s*[{][{].*?//[#!]\s*[}][}]', '', text, 0, re.I | re.S)
|
text = re.sub(r'//[#!]\s*[{][{].*?//[#!]\s*[}][}]', '', text, 0, re.I | re.S)
|
||||||
text = re.sub(r'^\s*#\s*pragma\s+once\s*$', '', text, 0, re.I | re.M)
|
|
||||||
text = re.sub(r'^\s*//\s*clang-format\s+.+?$', '', text, 0, re.I | re.M)
|
|
||||||
text = re.sub(r'^\s*//\s*SPDX-License-Identifier:.+?$', '', text, 0, re.I | re.M)
|
|
||||||
self.current_level += 1
|
self.current_level += 1
|
||||||
text = re.sub(r'^\s*#\s*include\s+"(.+?)"', lambda m : self.preprocess(m), text, 0, re.I | re.M)
|
text = re.sub(r'^\s*#\s*include\s+"(.+?)"', lambda m : self.preprocess(m), text, 0, re.I | re.M)
|
||||||
self.current_level -= 1
|
self.current_level -= 1
|
||||||
@ -83,6 +80,9 @@ def main():
|
|||||||
# preprocess header(s)
|
# preprocess header(s)
|
||||||
source_text = Preprocessor()('toml.h')
|
source_text = Preprocessor()('toml.h')
|
||||||
source_text = re.sub('\r\n', '\n', source_text, 0, re.I | re.M) # convert windows newlines
|
source_text = re.sub('\r\n', '\n', source_text, 0, re.I | re.M) # convert windows newlines
|
||||||
|
source_text = re.sub(r'^\s*#\s*pragma\s+once\s*$', '', source_text, 0, re.I | re.M) # 'pragma once'
|
||||||
|
source_text = re.sub(r'^\s*//\s*clang-format\s+.+?$', '', source_text, 0, re.I | re.M) # clang-format directives
|
||||||
|
source_text = re.sub(r'^\s*//\s*SPDX-License-Identifier:.+?$', '', source_text, 0, re.I | re.M) # spdx
|
||||||
source_text = re.sub('(?:(?:\n|^)[ \t]*//[/#!<]+[^\n]*)+\n', '\n', source_text, 0, re.I | re.M) # remove 'magic' comment blocks
|
source_text = re.sub('(?:(?:\n|^)[ \t]*//[/#!<]+[^\n]*)+\n', '\n', source_text, 0, re.I | re.M) # remove 'magic' comment blocks
|
||||||
source_text = re.sub('(?://[/#!<].*?)\n', '\n', source_text, 0, re.I | re.M) # remove 'magic' comments
|
source_text = re.sub('(?://[/#!<].*?)\n', '\n', source_text, 0, re.I | re.M) # remove 'magic' comments
|
||||||
source_text = re.sub('([^ \t])[ \t]+\n', '\\1\n', source_text, 0, re.I | re.M) # remove trailing whitespace
|
source_text = re.sub('([^ \t])[ \t]+\n', '\\1\n', source_text, 0, re.I | re.M) # remove trailing whitespace
|
||||||
@ -169,8 +169,8 @@ v0.5.0: https://github.com/toml-lang/toml/blob/master/versions/en/toml-v0.5
|
|||||||
print('//', file=output_file)
|
print('//', file=output_file)
|
||||||
print(make_divider(), file=output_file)
|
print(make_divider(), file=output_file)
|
||||||
print('''// clang-format off
|
print('''// clang-format off
|
||||||
#ifndef TOMLPLUSPLUS_SINGLE_HEADER_H
|
#ifndef INCLUDE_TOMLPLUSPLUS_H
|
||||||
#define TOMLPLUSPLUS_SINGLE_HEADER_H
|
#define INCLUDE_TOMLPLUSPLUS_H
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
#pragma GCC diagnostic push
|
#pragma GCC diagnostic push
|
||||||
#pragma GCC diagnostic ignored "-Wunknown-pragmas"
|
#pragma GCC diagnostic ignored "-Wunknown-pragmas"
|
||||||
@ -182,7 +182,7 @@ v0.5.0: https://github.com/toml-lang/toml/blob/master/versions/en/toml-v0.5
|
|||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
#pragma GCC diagnostic pop
|
#pragma GCC diagnostic pop
|
||||||
#endif
|
#endif
|
||||||
#endif // TOMLPLUSPLUS_SINGLE_HEADER_H
|
#endif // INCLUDE_TOMLPLUSPLUS_H
|
||||||
// clang-format on''', file=output_file)
|
// clang-format on''', file=output_file)
|
||||||
|
|
||||||
|
|
||||||
|
114
toml.hpp
114
toml.hpp
@ -42,8 +42,8 @@
|
|||||||
//
|
//
|
||||||
//----------------------------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
// clang-format off
|
// clang-format off
|
||||||
#ifndef TOMLPLUSPLUS_SINGLE_HEADER_H
|
#ifndef INCLUDE_TOMLPLUSPLUS_H
|
||||||
#define TOMLPLUSPLUS_SINGLE_HEADER_H
|
#define INCLUDE_TOMLPLUSPLUS_H
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
#pragma GCC diagnostic push
|
#pragma GCC diagnostic push
|
||||||
#pragma GCC diagnostic ignored "-Wunknown-pragmas"
|
#pragma GCC diagnostic ignored "-Wunknown-pragmas"
|
||||||
@ -6802,15 +6802,25 @@ namespace TOML_INTERNAL_NAMESPACE
|
|||||||
|
|
||||||
struct parse_scope final
|
struct parse_scope final
|
||||||
{
|
{
|
||||||
std::vector<std::string_view>& stack_;
|
std::string_view& storage_;
|
||||||
|
std::string_view parent_;
|
||||||
|
|
||||||
TOML_NODISCARD_CTOR
|
TOML_NODISCARD_CTOR
|
||||||
explicit parse_scope(std::vector<std::string_view>& stack) noexcept : stack_{ stack } {}
|
explicit parse_scope(std::string_view& current_scope, std::string_view new_scope) noexcept
|
||||||
~parse_scope() noexcept { stack_.pop_back(); }
|
: storage_{ current_scope },
|
||||||
|
parent_{ current_scope }
|
||||||
|
{
|
||||||
|
storage_ = new_scope;
|
||||||
|
}
|
||||||
|
|
||||||
|
~parse_scope() noexcept
|
||||||
|
{
|
||||||
|
storage_ = parent_;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
#define push_parse_scope_2(desc, line) scope_stack.push_back(desc); parse_scope ps_##line{ scope_stack }
|
#define push_parse_scope_2(scope, line) parse_scope ps_##line{ current_scope, scope }
|
||||||
#define push_parse_scope_1(desc, line) push_parse_scope_2(desc, line)
|
#define push_parse_scope_1(scope, line) push_parse_scope_2(scope, line)
|
||||||
#define push_parse_scope(desc) push_parse_scope_1(desc, __LINE__)
|
#define push_parse_scope(scope) push_parse_scope_1(scope, __LINE__)
|
||||||
|
|
||||||
struct parsed_key final
|
struct parsed_key final
|
||||||
{
|
{
|
||||||
@ -6894,8 +6904,8 @@ namespace toml::impl
|
|||||||
std::vector<table*> dotted_key_tables;
|
std::vector<table*> dotted_key_tables;
|
||||||
std::vector<array*> table_arrays;
|
std::vector<array*> table_arrays;
|
||||||
std::string recording_buffer; //for diagnostics
|
std::string recording_buffer; //for diagnostics
|
||||||
bool recording = false;
|
bool recording = false, recording_whitespace = true;
|
||||||
std::vector<std::string_view> scope_stack;
|
std::string_view current_scope;
|
||||||
#if !TOML_EXCEPTIONS
|
#if !TOML_EXCEPTIONS
|
||||||
mutable optional<toml::parse_error> err;
|
mutable optional<toml::parse_error> err;
|
||||||
#endif
|
#endif
|
||||||
@ -6918,14 +6928,13 @@ namespace toml::impl
|
|||||||
return;
|
return;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const auto current_scope = scope_stack.empty() ? ""sv : scope_stack.back();
|
|
||||||
static constexpr auto buf_size = 512_sz;
|
static constexpr auto buf_size = 512_sz;
|
||||||
char buf[buf_size];
|
char buf[buf_size];
|
||||||
auto write_pos = buf;
|
auto write_pos = buf;
|
||||||
const auto max_write_pos = buf + (buf_size - 1_sz); //allow for null terminator
|
const auto max_write_pos = buf + (buf_size - 1_sz); //allow for null terminator
|
||||||
concatenate(write_pos, max_write_pos, "Error while parsing "sv);
|
concatenate(write_pos, max_write_pos, "Error while parsing "sv);
|
||||||
concatenate(write_pos, max_write_pos, current_scope);
|
concatenate(write_pos, max_write_pos, current_scope);
|
||||||
concatenate(write_pos, max_write_pos, "; "sv);
|
concatenate(write_pos, max_write_pos, ": "sv);
|
||||||
(concatenate(write_pos, max_write_pos, reason), ...);
|
(concatenate(write_pos, max_write_pos, reason), ...);
|
||||||
*write_pos = '\0';
|
*write_pos = '\0';
|
||||||
#if TOML_EXCEPTIONS
|
#if TOML_EXCEPTIONS
|
||||||
@ -6973,7 +6982,10 @@ namespace toml::impl
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (recording && !is_eof())
|
if (recording && !is_eof())
|
||||||
recording_buffer.append(cp->as_view<char>());
|
{
|
||||||
|
if (recording_whitespace || !(is_whitespace(*cp) || is_line_break(*cp)))
|
||||||
|
recording_buffer.append(cp->as_view<char>());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void start_recording(bool include_current = true) noexcept
|
void start_recording(bool include_current = true) noexcept
|
||||||
@ -6981,6 +6993,7 @@ namespace toml::impl
|
|||||||
return_if_error();
|
return_if_error();
|
||||||
|
|
||||||
recording = true;
|
recording = true;
|
||||||
|
recording_whitespace = true;
|
||||||
recording_buffer.clear();
|
recording_buffer.clear();
|
||||||
if (include_current && !is_eof())
|
if (include_current && !is_eof())
|
||||||
recording_buffer.append(cp->as_view<char>());
|
recording_buffer.append(cp->as_view<char>());
|
||||||
@ -6995,6 +7008,8 @@ namespace toml::impl
|
|||||||
{
|
{
|
||||||
if (pop_bytes >= recording_buffer.length())
|
if (pop_bytes >= recording_buffer.length())
|
||||||
recording_buffer.clear();
|
recording_buffer.clear();
|
||||||
|
else if (pop_bytes == 1_sz)
|
||||||
|
recording_buffer.pop_back();
|
||||||
else
|
else
|
||||||
recording_buffer.erase(
|
recording_buffer.erase(
|
||||||
recording_buffer.begin() + static_cast<ptrdiff_t>(recording_buffer.length() - pop_bytes),
|
recording_buffer.begin() + static_cast<ptrdiff_t>(recording_buffer.length() - pop_bytes),
|
||||||
@ -7074,16 +7089,13 @@ namespace toml::impl
|
|||||||
// toml/issues/567 (disallow non-TAB control characters in comments)
|
// toml/issues/567 (disallow non-TAB control characters in comments)
|
||||||
if (is_nontab_control_character(*cp))
|
if (is_nontab_control_character(*cp))
|
||||||
set_error_and_return_default(
|
set_error_and_return_default(
|
||||||
"control characters "
|
"control characters other than TAB (U+0009) are explicitly prohibited"sv
|
||||||
"other than TAB (U+0009) are explicitly prohibited from appearing "
|
|
||||||
"in comments."sv
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// toml/pull/720 (disallow surrogates in comments)
|
// toml/pull/720 (disallow surrogates in comments)
|
||||||
else if (is_unicode_surrogate(*cp))
|
else if (is_unicode_surrogate(*cp))
|
||||||
set_error_and_return_default(
|
set_error_and_return_default(
|
||||||
"unicode surrogates (U+D800 to U+DFFF) are explicitly prohibited "
|
"unicode surrogates (U+D800 to U+DFFF) are explicitly prohibited"sv
|
||||||
"from appearing in comments."sv
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
advance_and_return_if_error({});
|
advance_and_return_if_error({});
|
||||||
@ -7189,12 +7201,9 @@ namespace toml::impl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// skip the escaped character
|
bool skipped_escaped_codepoint = false;
|
||||||
const auto escaped_codepoint = cp->value;
|
|
||||||
advance_and_return_if_error_or_eof({});
|
|
||||||
|
|
||||||
assert_not_eof();
|
assert_not_eof();
|
||||||
switch (escaped_codepoint)
|
switch (const auto escaped_codepoint = *cp)
|
||||||
{
|
{
|
||||||
// 'regular' escape codes
|
// 'regular' escape codes
|
||||||
case U'b': str += TOML_STRING_PREFIX('\b'); break;
|
case U'b': str += TOML_STRING_PREFIX('\b'); break;
|
||||||
@ -7210,7 +7219,7 @@ namespace toml::impl
|
|||||||
if constexpr (!TOML_LANG_UNRELEASED) // toml/pull/709 (\xHH unicode scalar sequences)
|
if constexpr (!TOML_LANG_UNRELEASED) // toml/pull/709 (\xHH unicode scalar sequences)
|
||||||
{
|
{
|
||||||
set_error_and_return_default(
|
set_error_and_return_default(
|
||||||
"escape sequence '\\x' is not supported in TOML 1.0.0 and earlier."sv
|
"escape sequence '\\x' is not supported in TOML 1.0.0 and earlier"sv
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
[[fallthrough]];
|
[[fallthrough]];
|
||||||
@ -7218,13 +7227,18 @@ namespace toml::impl
|
|||||||
case U'U':
|
case U'U':
|
||||||
{
|
{
|
||||||
push_parse_scope("unicode scalar escape sequence"sv);
|
push_parse_scope("unicode scalar escape sequence"sv);
|
||||||
uint32_t place_value = escaped_codepoint == U'U' ? 0x10000000u : (escaped_codepoint == U'u' ? 0x1000u : 0x10u);
|
advance_and_return_if_error_or_eof({});
|
||||||
|
skipped_escaped_codepoint = true;
|
||||||
|
|
||||||
|
uint32_t place_value = escaped_codepoint == U'U'
|
||||||
|
? 0x10000000u
|
||||||
|
: (escaped_codepoint == U'u' ? 0x1000u : 0x10u);
|
||||||
uint32_t sequence_value{};
|
uint32_t sequence_value{};
|
||||||
while (place_value)
|
while (place_value)
|
||||||
{
|
{
|
||||||
set_error_and_return_if_eof({});
|
set_error_and_return_if_eof({});
|
||||||
if (!is_hexadecimal_digit(*cp))
|
if (!is_hexadecimal_digit(*cp))
|
||||||
set_error_and_return_default("expected hex digit, saw '\\"sv, *cp, "'"sv);
|
set_error_and_return_default("expected hex digit, saw '"sv, *cp, "'"sv);
|
||||||
sequence_value += place_value * hex_to_dec(*cp);
|
sequence_value += place_value * hex_to_dec(*cp);
|
||||||
place_value /= 16u;
|
place_value /= 16u;
|
||||||
advance_and_return_if_error({});
|
advance_and_return_if_error({});
|
||||||
@ -7232,10 +7246,10 @@ namespace toml::impl
|
|||||||
|
|
||||||
if (is_unicode_surrogate(sequence_value))
|
if (is_unicode_surrogate(sequence_value))
|
||||||
set_error_and_return_default(
|
set_error_and_return_default(
|
||||||
"unicode surrogates (U+D800 - U+DFFF) are explicitly prohibited."sv
|
"unicode surrogates (U+D800 - U+DFFF) are explicitly prohibited"sv
|
||||||
);
|
);
|
||||||
else if (sequence_value > 0x10FFFFu)
|
else if (sequence_value > 0x10FFFFu)
|
||||||
set_error_and_return_default("values greater than U+10FFFF are invalid."sv);
|
set_error_and_return_default("values greater than U+10FFFF are invalid"sv);
|
||||||
else if (sequence_value <= 0x7Fu) //ascii
|
else if (sequence_value <= 0x7Fu) //ascii
|
||||||
str += static_cast<string_char>(sequence_value & 0x7Fu);
|
str += static_cast<string_char>(sequence_value & 0x7Fu);
|
||||||
else if (sequence_value <= 0x7FFu)
|
else if (sequence_value <= 0x7FFu)
|
||||||
@ -7263,6 +7277,10 @@ namespace toml::impl
|
|||||||
default:
|
default:
|
||||||
set_error_and_return_default("unknown escape sequence '\\"sv, *cp, "'"sv);
|
set_error_and_return_default("unknown escape sequence '\\"sv, *cp, "'"sv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// skip the escaped character
|
||||||
|
if (!skipped_escaped_codepoint)
|
||||||
|
advance_and_return_if_error_or_eof({});
|
||||||
}
|
}
|
||||||
else TOML_LIKELY
|
else TOML_LIKELY
|
||||||
{
|
{
|
||||||
@ -7326,7 +7344,7 @@ namespace toml::impl
|
|||||||
// handle escapes
|
// handle escapes
|
||||||
else if (*cp == U'\\')
|
else if (*cp == U'\\')
|
||||||
{
|
{
|
||||||
advance_and_return_if_error({}); // skip the '\'
|
advance_and_return_if_error_or_eof({}); // skip the '\'
|
||||||
skipping_whitespace = false;
|
skipping_whitespace = false;
|
||||||
escaped = true;
|
escaped = true;
|
||||||
continue;
|
continue;
|
||||||
@ -7348,7 +7366,7 @@ namespace toml::impl
|
|||||||
// handle control characters
|
// handle control characters
|
||||||
if (is_nontab_control_character(*cp))
|
if (is_nontab_control_character(*cp))
|
||||||
set_error_and_return_default(
|
set_error_and_return_default(
|
||||||
"unescaped control characters other than TAB (U+0009) are explicitly prohibited."sv
|
"unescaped control characters other than TAB (U+0009) are explicitly prohibited"sv
|
||||||
);
|
);
|
||||||
|
|
||||||
// handle surrogates in strings (1.0.0 and later)
|
// handle surrogates in strings (1.0.0 and later)
|
||||||
@ -7356,7 +7374,7 @@ namespace toml::impl
|
|||||||
{
|
{
|
||||||
if (is_unicode_surrogate(*cp))
|
if (is_unicode_surrogate(*cp))
|
||||||
set_error_and_return_default(
|
set_error_and_return_default(
|
||||||
"unescaped unicode surrogates (U+D800 to U+DFFF) are explicitly prohibited."sv
|
"unescaped unicode surrogates (U+D800 to U+DFFF) are explicitly prohibited"sv
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -7473,7 +7491,7 @@ namespace toml::impl
|
|||||||
// handle control characters
|
// handle control characters
|
||||||
if (is_nontab_control_character(*cp))
|
if (is_nontab_control_character(*cp))
|
||||||
set_error_and_return_default(
|
set_error_and_return_default(
|
||||||
"control characters other than TAB (U+0009) are explicitly prohibited."sv
|
"control characters other than TAB (U+0009) are explicitly prohibited"sv
|
||||||
);
|
);
|
||||||
|
|
||||||
// handle surrogates in strings (1.0.0 and later)
|
// handle surrogates in strings (1.0.0 and later)
|
||||||
@ -7481,7 +7499,7 @@ namespace toml::impl
|
|||||||
{
|
{
|
||||||
if (is_unicode_surrogate(*cp))
|
if (is_unicode_surrogate(*cp))
|
||||||
set_error_and_return_default(
|
set_error_and_return_default(
|
||||||
"unicode surrogates (U+D800 - U+DFFF) are explicitly prohibited."sv
|
"unicode surrogates (U+D800 - U+DFFF) are explicitly prohibited"sv
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -8306,7 +8324,7 @@ namespace toml::impl
|
|||||||
if (!val->ref_cast<array>().is_homogeneous())
|
if (!val->ref_cast<array>().is_homogeneous())
|
||||||
set_error_at(
|
set_error_at(
|
||||||
begin_pos,
|
begin_pos,
|
||||||
"arrays cannot contain values of different types before TOML 1.0.0."
|
"arrays cannot contain values of different types before TOML 1.0.0"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -8333,7 +8351,7 @@ namespace toml::impl
|
|||||||
|
|
||||||
// underscores at the beginning
|
// underscores at the beginning
|
||||||
else if (*cp == U'_')
|
else if (*cp == U'_')
|
||||||
set_error_and_return_default("values may not begin with underscores."sv);
|
set_error_and_return_default("values may not begin with underscores"sv);
|
||||||
|
|
||||||
return_if_error({});
|
return_if_error({});
|
||||||
if (val)
|
if (val)
|
||||||
@ -8769,6 +8787,7 @@ namespace toml::impl
|
|||||||
push_parse_scope("key"sv);
|
push_parse_scope("key"sv);
|
||||||
|
|
||||||
parsed_key key;
|
parsed_key key;
|
||||||
|
recording_whitespace = false;
|
||||||
|
|
||||||
while (!is_error())
|
while (!is_error())
|
||||||
{
|
{
|
||||||
@ -8784,7 +8803,11 @@ namespace toml::impl
|
|||||||
|
|
||||||
// "quoted key segment"
|
// "quoted key segment"
|
||||||
else if (is_string_delimiter(*cp))
|
else if (is_string_delimiter(*cp))
|
||||||
|
{
|
||||||
|
recording_whitespace = true;
|
||||||
key.segments.push_back(parse_string());
|
key.segments.push_back(parse_string());
|
||||||
|
recording_whitespace = false;
|
||||||
|
}
|
||||||
|
|
||||||
// ???
|
// ???
|
||||||
else
|
else
|
||||||
@ -8796,14 +8819,8 @@ namespace toml::impl
|
|||||||
consume_leading_whitespace();
|
consume_leading_whitespace();
|
||||||
|
|
||||||
// eof or no more key to come
|
// eof or no more key to come
|
||||||
if (is_eof())
|
if (is_eof() || *cp != U'.')
|
||||||
break;
|
break;
|
||||||
if (*cp != U'.')
|
|
||||||
{
|
|
||||||
if (recording)
|
|
||||||
stop_recording(1_sz);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// was a dotted key, so go around again to consume the next segment
|
// was a dotted key, so go around again to consume the next segment
|
||||||
advance_and_return_if_error_or_eof({});
|
advance_and_return_if_error_or_eof({});
|
||||||
@ -8824,7 +8841,8 @@ namespace toml::impl
|
|||||||
|
|
||||||
// get the key
|
// get the key
|
||||||
start_recording();
|
start_recording();
|
||||||
auto key = parse_key(); //parse_key() calls stop_recording()
|
auto key = parse_key();
|
||||||
|
stop_recording(1_sz);
|
||||||
|
|
||||||
// skip past any whitespace that followed the key
|
// skip past any whitespace that followed the key
|
||||||
consume_leading_whitespace();
|
consume_leading_whitespace();
|
||||||
@ -8877,7 +8895,8 @@ namespace toml::impl
|
|||||||
|
|
||||||
// get the actual key
|
// get the actual key
|
||||||
start_recording();
|
start_recording();
|
||||||
key = parse_key(); //parse_key() calls stop_recording()
|
key = parse_key();
|
||||||
|
stop_recording(1_sz);
|
||||||
return_if_error({});
|
return_if_error({});
|
||||||
|
|
||||||
// skip past any whitespace that followed the key
|
// skip past any whitespace that followed the key
|
||||||
@ -9096,6 +9115,8 @@ namespace toml::impl
|
|||||||
// "quoted keys"
|
// "quoted keys"
|
||||||
else if (is_bare_key_character(*cp) || is_string_delimiter(*cp))
|
else if (is_bare_key_character(*cp) || is_string_delimiter(*cp))
|
||||||
{
|
{
|
||||||
|
push_parse_scope("key-value pair"sv);
|
||||||
|
|
||||||
parse_key_value_pair_and_insert(current_table);
|
parse_key_value_pair_and_insert(current_table);
|
||||||
|
|
||||||
// handle the rest of the line after the kvp
|
// handle the rest of the line after the kvp
|
||||||
@ -9173,10 +9194,7 @@ namespace toml::impl
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (cp)
|
if (cp)
|
||||||
{
|
|
||||||
scope_stack.reserve(20_sz);
|
|
||||||
parse_document();
|
parse_document();
|
||||||
}
|
|
||||||
|
|
||||||
update_region_ends(root);
|
update_region_ends(root);
|
||||||
}
|
}
|
||||||
@ -9607,5 +9625,5 @@ namespace toml
|
|||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
#pragma GCC diagnostic pop
|
#pragma GCC diagnostic pop
|
||||||
#endif
|
#endif
|
||||||
#endif // TOMLPLUSPLUS_SINGLE_HEADER_H
|
#endif // INCLUDE_TOMLPLUSPLUS_H
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
71
vs/error_printer.vcxproj
Normal file
71
vs/error_printer.vcxproj
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|Win32">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Debug|x64">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|x64">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
</ItemGroup>
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<VCProjectVersion>16.0</VCProjectVersion>
|
||||||
|
<ProjectGuid>{DAB4634D-8145-4860-AE45-5198E76FF324}</ProjectGuid>
|
||||||
|
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
|
<CharacterSet>MultiByte</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>MultiByte</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
|
<CharacterSet>MultiByte</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>MultiByte</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
|
<ImportGroup Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<Import Project="toml++.props" />
|
||||||
|
<PropertyGroup>
|
||||||
|
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\examples\</LocalDebuggerWorkingDirectory>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Natvis Include="toml++.natvis" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="..\examples\error_printer.cpp" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="..\examples\meson.build" />
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
</Project>
|
@ -63,6 +63,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="..\examples\example.toml" />
|
<None Include="..\examples\example.toml" />
|
||||||
|
<None Include="..\examples\meson.build" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Natvis Include="toml++.natvis" />
|
<Natvis Include="toml++.natvis" />
|
||||||
|
@ -47,6 +47,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "simple_parser", "simple_par
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "toml_generator", "toml_generator.vcxproj", "{23CE3B73-FEE7-436C-9B4E-3DFB202EE9A2}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "toml_generator", "toml_generator.vcxproj", "{23CE3B73-FEE7-436C-9B4E-3DFB202EE9A2}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "error_printer", "error_printer.vcxproj", "{DAB4634D-8145-4860-AE45-5198E76FF324}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Win32 = Debug|Win32
|
Debug|Win32 = Debug|Win32
|
||||||
@ -215,6 +217,14 @@ Global
|
|||||||
{23CE3B73-FEE7-436C-9B4E-3DFB202EE9A2}.Release|Win32.Build.0 = Release|Win32
|
{23CE3B73-FEE7-436C-9B4E-3DFB202EE9A2}.Release|Win32.Build.0 = Release|Win32
|
||||||
{23CE3B73-FEE7-436C-9B4E-3DFB202EE9A2}.Release|x64.ActiveCfg = Release|x64
|
{23CE3B73-FEE7-436C-9B4E-3DFB202EE9A2}.Release|x64.ActiveCfg = Release|x64
|
||||||
{23CE3B73-FEE7-436C-9B4E-3DFB202EE9A2}.Release|x64.Build.0 = Release|x64
|
{23CE3B73-FEE7-436C-9B4E-3DFB202EE9A2}.Release|x64.Build.0 = Release|x64
|
||||||
|
{DAB4634D-8145-4860-AE45-5198E76FF324}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
|
{DAB4634D-8145-4860-AE45-5198E76FF324}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
|
{DAB4634D-8145-4860-AE45-5198E76FF324}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{DAB4634D-8145-4860-AE45-5198E76FF324}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{DAB4634D-8145-4860-AE45-5198E76FF324}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
|
{DAB4634D-8145-4860-AE45-5198E76FF324}.Release|Win32.Build.0 = Release|Win32
|
||||||
|
{DAB4634D-8145-4860-AE45-5198E76FF324}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{DAB4634D-8145-4860-AE45-5198E76FF324}.Release|x64.Build.0 = Release|x64
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
@ -239,6 +249,7 @@ Global
|
|||||||
{0CAD095A-C9F2-49FC-9C9F-4508498BE488} = {4E25CF88-D7D8-4A9C-A52E-0D78281E82EC}
|
{0CAD095A-C9F2-49FC-9C9F-4508498BE488} = {4E25CF88-D7D8-4A9C-A52E-0D78281E82EC}
|
||||||
{259FCEE5-3442-4076-9547-2BA793ECA1CB} = {412816A5-9D22-4A30-BCDF-ABFB54BB3735}
|
{259FCEE5-3442-4076-9547-2BA793ECA1CB} = {412816A5-9D22-4A30-BCDF-ABFB54BB3735}
|
||||||
{23CE3B73-FEE7-436C-9B4E-3DFB202EE9A2} = {412816A5-9D22-4A30-BCDF-ABFB54BB3735}
|
{23CE3B73-FEE7-436C-9B4E-3DFB202EE9A2} = {412816A5-9D22-4A30-BCDF-ABFB54BB3735}
|
||||||
|
{DAB4634D-8145-4860-AE45-5198E76FF324} = {412816A5-9D22-4A30-BCDF-ABFB54BB3735}
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
SolutionGuid = {0926DDCC-88CD-4839-A82D-D9B99E02A0B1}
|
SolutionGuid = {0926DDCC-88CD-4839-A82D-D9B99E02A0B1}
|
||||||
|
@ -65,5 +65,8 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Natvis Include="toml++.natvis" />
|
<Natvis Include="toml++.natvis" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="..\examples\meson.build" />
|
||||||
|
</ItemGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
</Project>
|
</Project>
|
@ -65,5 +65,8 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Natvis Include="toml++.natvis" />
|
<Natvis Include="toml++.natvis" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="..\examples\meson.build" />
|
||||||
|
</ItemGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
</Project>
|
</Project>
|
Loading…
Reference in New Issue
Block a user