added support for implementations without <charconv> (fixes #21)

also:
- fixed some parsing and printing ops being locale-dependent (fixes #19)
- fixed pkgconfig subdir being wrong (fixes #23)
- fixed some parsing errors at EOF when `TOML_EXCEPTIONS = 0`
- fixed some unreferenced variable warnings on older compilers
- fixed some 'maybe-uninitialized' false-positives on GCC9
- added debug/release awareness to CI tests
- added locale awareness to catch test runner
This commit is contained in:
Mark Gillard 2020-04-06 15:57:49 +03:00
parent 3f04e12b53
commit 5ca6b29cb9
47 changed files with 2440 additions and 1535 deletions

View File

@ -2,11 +2,15 @@ version: 2.1
jobs:
clang_build_with_dox:
debug_clang9_dox:
docker:
- image: marzer/misc_cpp17_dev:latest
steps:
- checkout
- run:
name: Initializing locales
command: |
sudo locale-gen 'en_US.utf8' 'ja_JP.utf8' 'de_DE.utf8' 'it_IT.utf8' 'tr_TR.utf8' 'fi_FI.utf8' 'fr_FR.utf8' 'zh_CN.utf8'
- run:
name: Checking toml.hpp
command: |
@ -17,14 +21,10 @@ jobs:
git submodule update --init extern/Catch2
git submodule update --init extern/tloptional
- run:
name: Building with clang
name: Building and testing with clang 9
command: |
CXX=clang++-9 meson build-clang
cd build-clang && ninja -v -j 4
- run:
name: Running tests
command: |
cd build-clang && ninja test
CXX=clang++-9 meson build --buildtype=debug
cd build && ninja -v && ninja test
- run:
name: Generating documentation
command: |
@ -35,11 +35,15 @@ jobs:
paths: html
clang_build:
debug_clang9:
docker:
- image: marzer/misc_cpp17_dev:latest
steps:
- checkout
- run:
name: Initializing locales
command: |
sudo locale-gen 'en_US.utf8' 'ja_JP.utf8' 'de_DE.utf8' 'it_IT.utf8' 'tr_TR.utf8' 'fi_FI.utf8' 'fr_FR.utf8' 'zh_CN.utf8'
- run:
name: Checking toml.hpp
command: |
@ -50,35 +54,77 @@ jobs:
git submodule update --init extern/Catch2
git submodule update --init extern/tloptional
- run:
name: Building with clang
name: Building and testing with clang 9
command: |
CXX=clang++-9 meson build-clang
cd build-clang && ninja -v -j 4
- run:
name: Running tests
command: |
cd build-clang && ninja test
CXX=clang++-9 meson build --buildtype=debug
cd build && ninja -v && ninja test
gcc_build:
release_clang9:
docker:
- image: marzer/misc_cpp17_dev:latest
steps:
- checkout
- run:
name: Initializing locales
command: |
sudo locale-gen 'en_US.utf8' 'ja_JP.utf8' 'de_DE.utf8' 'it_IT.utf8' 'tr_TR.utf8' 'fi_FI.utf8' 'fr_FR.utf8' 'zh_CN.utf8'
- run:
name: Checking toml.hpp
command: |
cd python && python3 ci_single_header_check.py
- run:
name: Pulling submodules
command: |
git submodule update --init extern/Catch2
git submodule update --init extern/tloptional
- run:
name: Building with gcc
name: Building and testing with clang 9
command: |
CXX=g++-9 meson build-gcc
cd build-gcc && ninja -v -j 4
CXX=clang++-9 meson build --buildtype=release
cd build && ninja -v && ninja test
debug_gcc9:
docker:
- image: marzer/misc_cpp17_dev:latest
steps:
- checkout
- run:
name: Running tests
name: Initializing locales
command: |
cd build-gcc && ninja test
sudo locale-gen 'en_US.utf8' 'ja_JP.utf8' 'de_DE.utf8' 'it_IT.utf8' 'tr_TR.utf8' 'fi_FI.utf8' 'fr_FR.utf8' 'zh_CN.utf8'
- run:
name: Pulling submodules
command: |
git submodule update --init extern/Catch2
git submodule update --init extern/tloptional
- run:
name: Building and testing with gcc9
command: |
CXX=g++-9 meson build --buildtype=debug
cd build && ninja -v -j 4 && ninja test
release_gcc9:
docker:
- image: marzer/misc_cpp17_dev:latest
steps:
- checkout
- run:
name: Initializing locales
command: |
sudo locale-gen 'en_US.utf8' 'ja_JP.utf8' 'de_DE.utf8' 'it_IT.utf8' 'tr_TR.utf8' 'fi_FI.utf8' 'fr_FR.utf8' 'zh_CN.utf8'
- run:
name: Pulling submodules
command: |
git submodule update --init extern/Catch2
git submodule update --init extern/tloptional
- run:
name: Building and testing with gcc9
command: |
CXX=g++-9 meson build --buildtype=release
cd build && ninja -v -j 4 && ninja test
deploy_dox:
@ -110,16 +156,20 @@ workflows:
version: 2
build:
jobs:
- clang_build_with_dox:
- debug_clang9_dox:
filters:
branches:
only: master
- clang_build:
- debug_clang9:
filters:
branches:
ignore: master
- gcc_build
- release_clang9
- debug_gcc9
- release_gcc9
- deploy_dox:
requires:
- clang_build_with_dox
- gcc_build
- debug_clang9_dox
- release_clang9
- debug_gcc9
- release_gcc9

View File

@ -94,7 +94,7 @@ pre a.tpp-injected
}
}
@media screen and (max-width: 576px)
@media screen and (max-width: 575px)
{
nav .m-thin, nav .github
{

View File

@ -36,6 +36,7 @@
// macro hygiene
#if TOML_UNDEF_MACROS
#undef TOML_INTEGER_CHARCONV
#undef TOML_FLOATING_POINT_CHARCONV
#undef TOML_GNU_ATTR
#undef TOML_PUSH_WARNINGS

View File

@ -192,9 +192,18 @@
#ifndef TOML_DISABLE_INIT_WARNINGS
#define TOML_DISABLE_INIT_WARNINGS
#endif
#ifndef TOML_INTEGER_CHARCONV
#define TOML_INTEGER_CHARCONV 1
#endif
#ifndef TOML_FLOATING_POINT_CHARCONV
#define TOML_FLOATING_POINT_CHARCONV 1
#endif
#if (TOML_INTEGER_CHARCONV || TOML_FLOATING_POINT_CHARCONV) && !__has_include(<charconv>)
#undef TOML_INTEGER_CHARCONV
#undef TOML_FLOATING_POINT_CHARCONV
#define TOML_INTEGER_CHARCONV 0
#define TOML_FLOATING_POINT_CHARCONV 0
#endif
#ifndef TOML_PUSH_WARNINGS
#define TOML_PUSH_WARNINGS
#endif
@ -298,7 +307,6 @@
TOML_PUSH_WARNINGS
TOML_DISABLE_ALL_WARNINGS
#if __has_include(<version>)
#include <version>
#endif
@ -310,22 +318,20 @@ TOML_DISABLE_ALL_WARNINGS
#include <vector>
#include <map>
#include <iosfwd>
#include <charconv>
#ifndef TOML_ASSERT
#if !defined(NDEBUG) || defined(_DEBUG) || defined(DEBUG)
#include <cassert>
#define TOML_ASSERT(expr) assert(expr)
#else
#define TOML_ASSERT(expr) (void)0
#endif
#endif
#ifndef TOML_OPTIONAL_TYPE
#include <optional>
#endif
#if TOML_EXCEPTIONS
#include <stdexcept>
#endif
#ifndef TOML_ASSERT
#ifdef NDEBUG
#define TOML_ASSERT(expr) (void)0
#else
#include <cassert>
#define TOML_ASSERT(expr) assert(expr)
#endif
#endif
TOML_POP_WARNINGS
#if TOML_CHAR_8_STRINGS
@ -893,9 +899,9 @@ namespace toml::impl
"date-time"sv
};
#define TOML_P2S_DECL(linkage, type) \
#define TOML_P2S_DECL(Linkage, Type) \
template <typename Char> \
linkage void print_to_stream(type, std::basic_ostream<Char>&)
Linkage void print_to_stream(Type, std::basic_ostream<Char>&)
TOML_P2S_DECL(TOML_ALWAYS_INLINE, int8_t);
TOML_P2S_DECL(TOML_ALWAYS_INLINE, int16_t);

View File

@ -210,6 +210,7 @@ namespace toml
size_t child_table_array_count{};
for (auto&& [child_k, child_v] : child_tbl)
{
(void)child_k;
const auto child_type = child_v.type();
switch (child_type)
{

View File

@ -167,6 +167,9 @@ namespace toml
/// \brief Returns a pointer to the viewed node as a toml::value<date_time>, if it is one.
[[nodiscard]] auto as_date_time() const noexcept { return as<date_time>(); }
TOML_PUSH_WARNINGS
TOML_DISABLE_INIT_WARNINGS
/// \brief Gets the raw value contained by the referenced node.
///
/// \tparam U One of the TOML value types. Can also be a string_view.
@ -182,6 +185,8 @@ namespace toml
return {};
}
TOML_POP_WARNINGS
/// \brief Gets the raw value contained by the referenced node, or a default.
///
/// \tparam U Default value type. Must be (or be promotable to) one of the TOML value types.

File diff suppressed because it is too large Load Diff

View File

@ -5,6 +5,19 @@
#pragma once
#include "toml_date_time.h"
TOML_PUSH_WARNINGS
TOML_DISABLE_ALL_WARNINGS
#if TOML_INTEGER_CHARCONV || TOML_FLOATING_POINT_CHARCONV
#include <charconv>
#endif
#if !TOML_INTEGER_CHARCONV || !TOML_FLOATING_POINT_CHARCONV
#include <sstream>
#endif
#if !TOML_INTEGER_CHARCONV
#include <iomanip>
#endif
TOML_POP_WARNINGS
namespace toml::impl
{
// Q: "why does print_to_stream() exist? why not just use ostream::write(), ostream::put() etc?"
@ -93,15 +106,29 @@ namespace toml::impl
"The stream's underlying character type must be 1 byte in size."
);
char buf[charconv_buffer_length<T>];
const auto res = std::to_chars(buf, buf + sizeof(buf), val);
print_to_stream(buf, static_cast<size_t>(res.ptr - buf), stream);
#if TOML_INTEGER_CHARCONV
char buf[charconv_buffer_length<T>];
const auto res = std::to_chars(buf, buf + sizeof(buf), val);
const auto len = static_cast<size_t>(res.ptr - buf);
print_to_stream(buf, len, stream);
#else
std::ostringstream ss;
ss.imbue(std::locale::classic());
using cast_type = std::conditional_t<std::is_signed_v<T>, int64_t, uint64_t>;
ss << static_cast<cast_type>(val);
const auto str = std::move(ss).str();
print_to_stream(str, stream);
#endif
}
#define TOML_P2S_OVERLOAD(type) \
#define TOML_P2S_OVERLOAD(Type) \
template <typename Char> \
TOML_ALWAYS_INLINE \
void print_to_stream(type val, std::basic_ostream<Char>& stream) \
void print_to_stream(Type val, std::basic_ostream<Char>& stream) \
{ \
static_assert(sizeof(Char) == 1); \
print_integer_to_stream(val, stream); \
@ -148,20 +175,13 @@ namespace toml::impl
}
#else
{
char buf[charconv_buffer_length<T> + 1_sz];
int len = -1;
std::ostringstream ss;
ss.imbue(std::locale::classic());
ss.precision(std::numeric_limits<T>::digits10 + 1);
if (hexfloat)
len = snprintf(buf, charconv_buffer_length<T> + 1_sz, "%a", static_cast<double>(val));
else
len = snprintf(
buf, charconv_buffer_length<T> + 1_sz, "%.*g",
std::numeric_limits<T>::digits10 + 1, static_cast<double>(val)
);
TOML_ASSERT(len > 0);
len = static_cast<int>(charconv_buffer_length<T>) < len
? static_cast<int>(charconv_buffer_length<T>)
: len;
const auto str = std::string_view{ buf, static_cast<size_t>(len) };
ss << std::hexfloat;
ss << val;
const auto str = std::move(ss).str();
print_to_stream(str, stream);
if (!hexfloat && needs_decimal_point(str))
print_to_stream(".0"sv, stream);
@ -174,10 +194,10 @@ namespace toml::impl
extern template TOML_API void print_floating_point_to_stream(double, std::ostream&, bool);
#endif
#define TOML_P2S_OVERLOAD(type) \
#define TOML_P2S_OVERLOAD(Type) \
template <typename Char> \
TOML_ALWAYS_INLINE \
void print_to_stream(type val, std::basic_ostream<Char>& stream) \
void print_to_stream(Type val, std::basic_ostream<Char>& stream) \
{ \
static_assert(sizeof(Char) == 1); \
print_floating_point_to_stream(val, stream); \
@ -200,12 +220,25 @@ namespace toml::impl
inline void print_to_stream(T val, std::basic_ostream<Char>& stream, size_t zero_pad_to_digits)
{
static_assert(sizeof(Char) == 1);
char buf[charconv_buffer_length<T>];
const auto res = std::to_chars(buf, buf + sizeof(buf), val);
const auto len = static_cast<size_t>(res.ptr - buf);
for (size_t i = len; i < zero_pad_to_digits; i++)
print_to_stream('0', stream);
print_to_stream(buf, static_cast<size_t>(res.ptr - buf), stream);
#if TOML_INTEGER_CHARCONV
char buf[charconv_buffer_length<T>];
const auto res = std::to_chars(buf, buf + sizeof(buf), val);
const auto len = static_cast<size_t>(res.ptr - buf);
for (size_t i = len; i < zero_pad_to_digits; i++)
print_to_stream('0', stream);
print_to_stream(buf, static_cast<size_t>(res.ptr - buf), stream);
#else
std::ostringstream ss;
ss.imbue(std::locale::classic());
using cast_type = std::conditional_t<std::is_signed_v<T>, int64_t, uint64_t>;
ss << std::setfill('0') << std::setw(zero_pad_to_digits) << static_cast<cast_type>(val);
const auto str = std::move(ss).str();
print_to_stream(str, stream);
#endif
}
template <typename Char>

View File

@ -9,6 +9,14 @@
namespace toml::impl
{
template <typename... T>
[[nodiscard]] TOML_ALWAYS_INLINE
constexpr bool is_match(char32_t codepoint, T... vals) noexcept
{
static_assert((std::is_same_v<char32_t, T> && ...));
return ((codepoint == vals) || ...);
}
[[nodiscard]] TOML_ALWAYS_INLINE
constexpr bool is_ascii_whitespace(char32_t codepoint) noexcept
{
@ -103,6 +111,24 @@ namespace toml::impl
;
}
[[nodiscard]] TOML_ALWAYS_INLINE
constexpr uint32_t hex_to_dec(char codepoint) noexcept
{
return codepoint >= 'A'
? 10u + static_cast<uint32_t>(codepoint - (codepoint >= 'a' ? 'a' : 'A'))
: static_cast<uint32_t>(codepoint - '0')
;
}
[[nodiscard]] TOML_ALWAYS_INLINE
constexpr uint32_t hex_to_dec(char32_t codepoint) noexcept
{
return codepoint >= U'A'
? 10u + static_cast<uint32_t>(codepoint - (codepoint >= U'a' ? U'a' : U'A'))
: static_cast<uint32_t>(codepoint - U'0')
;
}
[[nodiscard]]
constexpr bool is_bare_key_start_character(char32_t codepoint) noexcept
{
@ -632,7 +658,7 @@ namespace toml::impl
#undef TOML_ERROR_CHECK
#undef TOML_ERROR
#if TOML_ABI_NAMESPACES
} //end abi namespace for TOML_EXCEPTIONS
} //end abi namespace for TOML_EXCEPTIONS / !TOML_EXCEPTIONS
#endif
}

View File

@ -371,6 +371,9 @@ namespace toml
extern template TOML_API std::ostream& operator << (std::ostream&, const value<toml::date_time>&);
#endif
TOML_PUSH_WARNINGS
TOML_DISABLE_INIT_WARNINGS
template <typename T>
inline optional<T> node::value() const noexcept
{
@ -452,6 +455,8 @@ namespace toml
TOML_UNREACHABLE;
}
TOML_POP_WARNINGS
template <typename T>
inline auto node::value_or(T&& default_value) const noexcept
{

View File

@ -5,7 +5,7 @@
#pragma once
#define TOML_LIB_MAJOR 1
#define TOML_LIB_MINOR 1
#define TOML_LIB_MINOR 2
#define TOML_LIB_PATCH 0
#define TOML_LANG_MAJOR 1

View File

@ -1,13 +1,14 @@
project(
'tomlplusplus',
'cpp',
version : '1.1.0',
version : '1.2.0',
license : 'MIT',
default_options : [
'cpp_std=c++17',
'warning_level=3',
'werror=true',
'cpp_eh=default'
'cpp_eh=default',
'b_ndebug=if-release'
]
)
@ -38,7 +39,6 @@ if build_tests or build_examples
if compiler.get_id() == 'gcc'
add_project_arguments([
'-g0',
'-fmax-errors=5',
'-march=native',
'-Wno-init-list-lifetime'
@ -49,7 +49,6 @@ if build_tests or build_examples
if compiler.get_id() == 'clang'
add_project_arguments([
'-g0',
'-ferror-limit=5',
'-march=native',
'-fchar8_t',
@ -108,6 +107,5 @@ pkgc = import('pkgconfig')
pkgc.generate (
name: 'toml++',
version: meson.project_version(),
description: 'Header-only TOML config file parser and serializer for modern C++',
subdirs: 'toml++'
description: 'Header-only TOML config file parser and serializer for modern C++'
)

View File

@ -6,6 +6,7 @@
#define CATCH_CONFIG_CPP17_STRING_VIEW
#define CATCH_CONFIG_FAST_COMPILE
#define CATCH_CONFIG_CONSOLE_WIDTH 120
#define CATCH_CONFIG_CPP11_TO_STRING
//windows.h config
#ifdef _WIN32

View File

@ -1,11 +1,13 @@
#define CATCH_CONFIG_RUNNER
#include "catch2.h"
#include <clocale>
int main(int argc, char* argv[])
{
#ifdef _WIN32
SetConsoleOutputCP(65001);
SetConsoleOutputCP(65001);
#endif
std::setlocale(LC_ALL, "");
std::locale::global(std::locale(""));
return Catch::Session().run(argc, argv);
}

View File

@ -5,6 +5,7 @@ TEST_CASE("arrays - moving")
static constexpr auto filename = "foo.toml"sv;
parsing_should_succeed(
FILE_LINE_ARGS,
S(R"(test = [ "foo" ])"sv),
[&](table&& tbl) noexcept
{

View File

@ -5,6 +5,7 @@ TEST_CASE("tables - moving")
static constexpr auto filename = "foo.toml"sv;
parsing_should_succeed(
FILE_LINE_ARGS,
S(R"(test = { val1 = "foo" })"sv),
[&](table&& tbl) noexcept
{

View File

@ -0,0 +1,42 @@
#include "tests.h"
TEST_CASE("values - printing")
{
static constexpr auto print_value = [](auto&& raw) noexcept
{
auto val = toml::value{ std::forward<decltype(raw)>(raw) };
std::stringstream ss;
ss.imbue(std::locale::classic());
ss << val;
return ss.str();
};
CHECK(print_value(1) == "1");
CHECK(print_value(1.0f) == "1.0");
CHECK(print_value(1.0) == "1.0");
CHECK(print_value(1.5f) == "1.5");
CHECK(print_value(1.5) == "1.5");
CHECK(print_value(10) == "10");
CHECK(print_value(10.0f) == "10.0");
CHECK(print_value(10.0) == "10.0");
CHECK(print_value(100) == "100");
CHECK(print_value(100.0f) == "100.0");
CHECK(print_value(100.0) == "100.0");
CHECK(print_value(1000) == "1000");
CHECK(print_value(1000.0f) == "1000.0");
CHECK(print_value(1000.0) == "1000.0");
CHECK(print_value(10000) == "10000");
CHECK(print_value(10000.0f) == "10000.0");
CHECK(print_value(10000.0) == "10000.0");
// only integers for large values;
// large floats might get output as scientific notation and that's fine
CHECK(print_value(10000000000) == "10000000000");
CHECK(print_value(100000000000000) == "100000000000000");
}

View File

@ -1,11 +1,12 @@
test_sources = [
'impl_toml.cpp',
'impl_catch2.cpp',
'tests.cpp',
'parsing_floats.cpp',
'parsing_arrays.cpp',
'parsing_booleans.cpp',
'parsing_comments.cpp',
'parsing_dates_and_times.cpp',
'parsing_floats.cpp',
'parsing_integers.cpp',
'parsing_key_value_pairs.cpp',
'parsing_spec_example.cpp',
@ -13,15 +14,9 @@ test_sources = [
'parsing_tables.cpp',
'manipulating_arrays.cpp',
'manipulating_tables.cpp',
'tests.cpp'
'manipulating_values.cpp',
]
disable_exceptions = 'cpp_eh=none'
no_unreleased_features = '-DTOML_UNRELEASED_FEATURES=0'
toml_char8_strings = '-DTOML_CHAR_8_STRINGS=1'
manually_set_cpp_std = 'cpp_std=none'
cpp20 = '-std=c++2a'
use_tloptional = '-DTARTANLLAMA_OPTIONAL'
compiler_supports_char8_strings = compiler.compiles('''
#include <string_view>
#include <string>
@ -35,137 +30,78 @@ compiler_supports_char8_strings = compiler.compiles('''
args : [ '-std=c++2a' ]
)
############################################################################
### char
############################################################################
character_types = ['char', 'char8']
exception_modes = [ true, false ]
unreleased_feature_modes = [ true, false ]
tloptional_modes = [ true, false ]
executables = []
foreach character_type : character_types
if character_type == 'char8' and not compiler_supports_char8_strings
continue
endif
foreach exceptions : exception_modes
foreach unreleased_features : unreleased_feature_modes
foreach tloptional : tloptional_modes
if tloptional and not (character_type =='char' and unreleased_features and exceptions)
continue
endif
char = executable(
'char',
test_sources,
include_directories : inc
)
test('char', char)
name = character_type
overrides = []
args = []
if character_type =='char8'
overrides += 'cpp_std=none'
args += '-DTOML_CHAR_8_STRINGS=1'
args += '-std=c++2a'
endif
char_noexcept = executable(
'char_noexcept',
test_sources,
include_directories : inc,
override_options : [ disable_exceptions ]
)
test('char_noexcept', char_noexcept)
if not unreleased_features
name = name + '_strict'
args += '-DTOML_UNRELEASED_FEATURES=0'
endif
if not exceptions
name = name + '_noexcept'
overrides += 'cpp_eh=none'
endif
char_strict = executable(
'char_strict',
test_sources,
include_directories : inc,
cpp_args : [ no_unreleased_features ]
)
test('char_strict', char_strict)
if tloptional
name = name + '_tlopt'
args += '-DTARTANLLAMA_OPTIONAL'
endif
executables += [[
name,
executable(
name,
test_sources,
include_directories : inc,
cpp_args : args,
override_options : overrides
)
]]
char_strict_noexcept = executable(
'char_strict_noexcept',
test_sources,
include_directories : inc,
override_options : [ disable_exceptions ],
cpp_args : [ no_unreleased_features ]
)
test('char_strict_noexcept', char_strict_noexcept)
endforeach # tloptional_modes
endforeach # unreleased_feature_modes
endforeach # exception_modes
endforeach # character_type
locales = [
'C',
'en_US.utf8',
'ja_JP.utf8',
'it_IT.utf8',
'tr_TR.utf8',
'fi_FI.utf8',
'fr_FR.utf8',
'zh_CN.utf8',
'de_DE.utf8'
]
############################################################################
### char w/ tl::optional
############################################################################
char_tlopt = executable(
'char_tlopt',
test_sources,
include_directories : inc,
cpp_args : [ use_tloptional ]
)
test('char_tlopt', char_tlopt)
char_tlopt_strict = executable(
'char_tlopt_strict',
test_sources,
include_directories : inc,
cpp_args : [ no_unreleased_features, use_tloptional ]
)
test('char_tlopt_strict', char_tlopt_strict)
if compiler_supports_char8_strings
############################################################################
### char8
############################################################################
char8 = executable(
'char8',
test_sources,
include_directories : inc,
override_options : [ manually_set_cpp_std ],
cpp_args : [ cpp20, toml_char8_strings ]
)
test('char8', char8)
char8_noexcept = executable(
'char8_noexcept',
test_sources,
include_directories : inc,
override_options : [ manually_set_cpp_std, disable_exceptions ],
cpp_args : [ cpp20, toml_char8_strings ]
)
test('char8_noexcept', char8_noexcept)
char8_strict = executable(
'char8_strict',
test_sources,
include_directories : inc,
override_options : [ manually_set_cpp_std ],
cpp_args : [ cpp20, toml_char8_strings, no_unreleased_features ]
)
test('char8_strict', char8_strict)
char8_strict_noexcept = executable(
'char8_strict_noexcept',
test_sources,
include_directories : inc,
override_options : [ manually_set_cpp_std, disable_exceptions ],
cpp_args : [ cpp20, toml_char8_strings, no_unreleased_features ]
)
test('char8_strict_noexcept', char8_strict_noexcept)
############################################################################
### char8 w/ tl::optional
############################################################################
char8_tlopt = executable(
'char8_tlopt',
test_sources,
include_directories : inc,
override_options : [ manually_set_cpp_std ],
cpp_args : [ cpp20, toml_char8_strings, use_tloptional ]
)
test('char8_tlopt', char8_tlopt)
char8_tlopt_strict = executable(
'char8_tlopt_strict',
test_sources,
include_directories : inc,
override_options : [ manually_set_cpp_std ],
cpp_args : [ cpp20, toml_char8_strings, no_unreleased_features, use_tloptional ]
)
test('char8_tlopt_strict', char8_tlopt_strict)
endif
foreach locale : locales
foreach executable : executables
test(locale + '_' + executable[0], executable[1], env : ['LC_ALL=' + locale])
endforeach
endforeach

View File

@ -2,7 +2,9 @@
TEST_CASE("parsing - arrays")
{
parsing_should_succeed(S(R"(
parsing_should_succeed(
FILE_LINE_ARGS,
S(R"(
integers = [ 1, 2, 3 ]
integers2 = [
1, 2, 3
@ -94,7 +96,9 @@ string_array = [ "all", 'strings', """are the same""", '''type''' ]
// toml/issues/665 (heterogeneous arrays)
#if TOML_LANG_AT_LEAST(1, 0, 0)
parsing_should_succeed(S(R"(
parsing_should_succeed(
FILE_LINE_ARGS,
S(R"(
# Mixed-type arrays are allowed
numbers = [ 0.1, 0.2, 0.5, 1, 2, 5 ]
contributors = [
@ -134,7 +138,7 @@ contributors = [
#else
parsing_should_fail(S("numbers = [ 0.1, 0.2, 0.5, 1, 2, 5 ]"sv));
parsing_should_fail(FILE_LINE_ARGS, S("numbers = [ 0.1, 0.2, 0.5, 1, 2, 5 ]"sv));
#endif
}

View File

@ -2,7 +2,9 @@
TEST_CASE("parsing - booleans")
{
parsing_should_succeed(S(R"(
parsing_should_succeed(
FILE_LINE_ARGS,
S(R"(
bool1 = true
bool2 = false
)"sv),
@ -14,14 +16,14 @@ bool2 = false
);
// "Always lowercase."
parsing_should_fail(S("bool = True"sv));
parsing_should_fail(S("bool = TRUE"sv));
parsing_should_fail(S("bool = tRUE"sv));
parsing_should_fail(S("bool = False"sv));
parsing_should_fail(S("bool = FALSE"sv));
parsing_should_fail(S("bool = fALSE"sv));
parsing_should_fail(FILE_LINE_ARGS, S("bool = True"sv));
parsing_should_fail(FILE_LINE_ARGS, S("bool = TRUE"sv));
parsing_should_fail(FILE_LINE_ARGS, S("bool = tRUE"sv));
parsing_should_fail(FILE_LINE_ARGS, S("bool = False"sv));
parsing_should_fail(FILE_LINE_ARGS, S("bool = FALSE"sv));
parsing_should_fail(FILE_LINE_ARGS, S("bool = fALSE"sv));
// value tests
parse_expected_value(" true", true);
parse_expected_value("false", false);
parse_expected_value(FILE_LINE_ARGS, " true", true);
parse_expected_value(FILE_LINE_ARGS, "false", false);
}

View File

@ -2,7 +2,9 @@
TEST_CASE("parsing - comments")
{
parsing_should_succeed(S(R"(
parsing_should_succeed(
FILE_LINE_ARGS,
S(R"(
# This is a full-line comment
key = "value" # This is a comment at the end of a line
another = "# This is not a comment"
@ -15,7 +17,9 @@ another = "# This is not a comment"
}
);
parsing_should_succeed(S(R"(# this = "looks like a KVP but is commented out)"sv),
parsing_should_succeed(
FILE_LINE_ARGS,
S(R"(# this = "looks like a KVP but is commented out)"sv),
[](table&& tbl) noexcept
{
CHECK(tbl.size() == 0);
@ -26,15 +30,15 @@ another = "# This is not a comment"
{
// toml/issues/567 (disallow non-TAB control characters in comments)
// 00 - 08
parsing_should_fail(S("# \u0000"sv));
parsing_should_fail(S("# \u0001"sv));
parsing_should_fail(S("# \u0002"sv));
parsing_should_fail(S("# \u0003"sv));
parsing_should_fail(S("# \u0004"sv));
parsing_should_fail(S("# \u0005"sv));
parsing_should_fail(S("# \u0006"sv));
parsing_should_fail(S("# \u0007"sv));
parsing_should_fail(S("# \u0008"sv));
parsing_should_fail(FILE_LINE_ARGS, S("# \u0000"sv));
parsing_should_fail(FILE_LINE_ARGS, S("# \u0001"sv));
parsing_should_fail(FILE_LINE_ARGS, S("# \u0002"sv));
parsing_should_fail(FILE_LINE_ARGS, S("# \u0003"sv));
parsing_should_fail(FILE_LINE_ARGS, S("# \u0004"sv));
parsing_should_fail(FILE_LINE_ARGS, S("# \u0005"sv));
parsing_should_fail(FILE_LINE_ARGS, S("# \u0006"sv));
parsing_should_fail(FILE_LINE_ARGS, S("# \u0007"sv));
parsing_should_fail(FILE_LINE_ARGS, S("# \u0008"sv));
// skip tab and line breaks (real and otherwise)
// \u0009 is \t
@ -44,30 +48,30 @@ another = "# This is not a comment"
// \u000D is \r
// 0E - 1F
parsing_should_fail(S("# \u000E"sv));
parsing_should_fail(S("# \u000F"sv));
parsing_should_fail(S("# \u0010"sv));
parsing_should_fail(S("# \u0011"sv));
parsing_should_fail(S("# \u0012"sv));
parsing_should_fail(S("# \u0013"sv));
parsing_should_fail(S("# \u0014"sv));
parsing_should_fail(S("# \u0015"sv));
parsing_should_fail(S("# \u0016"sv));
parsing_should_fail(S("# \u0017"sv));
parsing_should_fail(S("# \u0018"sv));
parsing_should_fail(S("# \u0019"sv));
parsing_should_fail(S("# \u001A"sv));
parsing_should_fail(S("# \u001B"sv));
parsing_should_fail(S("# \u001C"sv));
parsing_should_fail(S("# \u001D"sv));
parsing_should_fail(S("# \u001E"sv));
parsing_should_fail(S("# \u001F"sv));
parsing_should_fail(FILE_LINE_ARGS, S("# \u000E"sv));
parsing_should_fail(FILE_LINE_ARGS, S("# \u000F"sv));
parsing_should_fail(FILE_LINE_ARGS, S("# \u0010"sv));
parsing_should_fail(FILE_LINE_ARGS, S("# \u0011"sv));
parsing_should_fail(FILE_LINE_ARGS, S("# \u0012"sv));
parsing_should_fail(FILE_LINE_ARGS, S("# \u0013"sv));
parsing_should_fail(FILE_LINE_ARGS, S("# \u0014"sv));
parsing_should_fail(FILE_LINE_ARGS, S("# \u0015"sv));
parsing_should_fail(FILE_LINE_ARGS, S("# \u0016"sv));
parsing_should_fail(FILE_LINE_ARGS, S("# \u0017"sv));
parsing_should_fail(FILE_LINE_ARGS, S("# \u0018"sv));
parsing_should_fail(FILE_LINE_ARGS, S("# \u0019"sv));
parsing_should_fail(FILE_LINE_ARGS, S("# \u001A"sv));
parsing_should_fail(FILE_LINE_ARGS, S("# \u001B"sv));
parsing_should_fail(FILE_LINE_ARGS, S("# \u001C"sv));
parsing_should_fail(FILE_LINE_ARGS, S("# \u001D"sv));
parsing_should_fail(FILE_LINE_ARGS, S("# \u001E"sv));
parsing_should_fail(FILE_LINE_ARGS, S("# \u001F"sv));
// 7F
parsing_should_fail(S("# \u007F"sv));
parsing_should_fail(FILE_LINE_ARGS, S("# \u007F"sv));
}
else
{
parsing_should_succeed(S(
parsing_should_succeed(FILE_LINE_ARGS, S(
"## 00 - 08"
"# \u0000 "
"# \u0001 "

View File

@ -5,7 +5,9 @@ TOML_DISABLE_INIT_WARNINGS
TEST_CASE("parsing - dates and times")
{
parsing_should_succeed(S(R"(
parsing_should_succeed(
FILE_LINE_ARGS,
S(R"(
odt1 = 1979-05-27T07:32:00Z
odt2 = 1979-05-27T00:32:00-07:00
odt3 = 1979-05-27T00:32:00.999999-07:00
@ -40,89 +42,120 @@ lt2 = 00:32:00.999999
);
//value tests
parse_expected_value( "1987-03-16"sv, date{ 1987, 3, 16 } );
parse_expected_value( "10:20:30"sv, toml::time{ 10, 20, 30 } );
parse_expected_value( "10:20:30.04"sv, toml::time{ 10, 20, 30, 40000000 } );
parse_expected_value(FILE_LINE_ARGS, "1987-03-16"sv, date{ 1987, 3, 16 } );
parse_expected_value(FILE_LINE_ARGS, "10:20:30"sv, toml::time{ 10, 20, 30 } );
parse_expected_value(FILE_LINE_ARGS, "10:20:30.04"sv, toml::time{ 10, 20, 30, 40000000 } );
{
const auto val = date_time{ { 1987, 3, 16 }, { 10, 20, 30 } };
parse_expected_value("1987-03-16T10:20:30"sv, val);
parse_expected_value("1987-03-16 10:20:30"sv, val);
parse_expected_value(FILE_LINE_ARGS, "1987-03-16T10:20:30"sv, val);
parse_expected_value(FILE_LINE_ARGS, "1987-03-16 10:20:30"sv, val);
}
{
const auto val = date_time{ { 1987, 3, 16 }, { 10, 20, 30 }, { -9, -30 } };
parse_expected_value("1987-03-16T10:20:30-09:30"sv, val);
parse_expected_value("1987-03-16 10:20:30-09:30"sv, val);
parse_expected_value(FILE_LINE_ARGS, "1987-03-16T10:20:30-09:30"sv, val);
parse_expected_value(FILE_LINE_ARGS, "1987-03-16 10:20:30-09:30"sv, val);
}
{
const auto val = date_time{ { 1987, 3, 16 }, { 10, 20, 30 }, { 9, 30 } };
parse_expected_value("1987-03-16T10:20:30+09:30"sv, val);
parse_expected_value("1987-03-16 10:20:30+09:30"sv, val);
parse_expected_value(FILE_LINE_ARGS, "1987-03-16T10:20:30+09:30"sv, val);
parse_expected_value(FILE_LINE_ARGS, "1987-03-16 10:20:30+09:30"sv, val);
}
{
const auto val = date_time{ { 1987, 3, 16 }, { 10, 20, 30, 40000000 } };
parse_expected_value("1987-03-16T10:20:30.04"sv, val);
parse_expected_value("1987-03-16 10:20:30.04"sv, val);
parse_expected_value(FILE_LINE_ARGS, "1987-03-16T10:20:30.04"sv, val);
parse_expected_value(FILE_LINE_ARGS, "1987-03-16 10:20:30.04"sv, val);
}
{
const auto val = date_time{ { 1987, 3, 16 }, { 10, 20, 30, 40000000 }, { -9, -30 } };
parse_expected_value("1987-03-16T10:20:30.04-09:30"sv, val);
parse_expected_value("1987-03-16 10:20:30.04-09:30"sv, val);
parse_expected_value(FILE_LINE_ARGS, "1987-03-16T10:20:30.04-09:30"sv, val);
parse_expected_value(FILE_LINE_ARGS, "1987-03-16 10:20:30.04-09:30"sv, val);
}
{
const auto val = date_time{ { 1987, 3, 16 }, { 10, 20, 30, 40000000 }, { 9, 30 } };
parse_expected_value("1987-03-16T10:20:30.04+09:30"sv, val);
parse_expected_value("1987-03-16 10:20:30.04+09:30"sv, val);
parse_expected_value(FILE_LINE_ARGS, "1987-03-16T10:20:30.04+09:30"sv, val);
parse_expected_value(FILE_LINE_ARGS, "1987-03-16 10:20:30.04+09:30"sv, val);
}
{
const auto val = date_time{ { 1987, 3, 16 }, { 10, 20, 30 }, {} };
parse_expected_value("1987-03-16T10:20:30Z"sv, val);
parse_expected_value("1987-03-16 10:20:30Z"sv, val);
parse_expected_value(FILE_LINE_ARGS, "1987-03-16T10:20:30Z"sv, val);
parse_expected_value(FILE_LINE_ARGS, "1987-03-16 10:20:30Z"sv, val);
}
{
const auto val = date_time{ { 1987, 3, 16 }, { 10, 20, 30, 40000000 }, {} };
parse_expected_value("1987-03-16T10:20:30.04Z"sv, val);
parse_expected_value("1987-03-16 10:20:30.04Z"sv, val);
parse_expected_value(FILE_LINE_ARGS, "1987-03-16T10:20:30.04Z"sv, val);
parse_expected_value(FILE_LINE_ARGS, "1987-03-16 10:20:30.04Z"sv, val);
}
// toml/issues/671 (allow omission of seconds)
#if TOML_LANG_UNRELEASED
parse_expected_value( "10:20"sv, toml::time{ 10, 20 } );
parse_expected_value(FILE_LINE_ARGS, "10:20"sv, toml::time{ 10, 20 } );
{
const auto val = date_time{ { 1987, 3, 16 }, { 10, 20 } };
parse_expected_value("1987-03-16T10:20"sv, val );
parse_expected_value("1987-03-16 10:20"sv, val );
parse_expected_value(FILE_LINE_ARGS, "1987-03-16T10:20"sv, val );
parse_expected_value(FILE_LINE_ARGS, "1987-03-16 10:20"sv, val );
}
{
const auto val = date_time{ { 1987, 3, 16 }, { 10, 20 }, { -9, -30 } };
parse_expected_value("1987-03-16T10:20-09:30"sv, val);
parse_expected_value("1987-03-16 10:20-09:30"sv, val);
parse_expected_value(FILE_LINE_ARGS, "1987-03-16T10:20-09:30"sv, val);
parse_expected_value(FILE_LINE_ARGS, "1987-03-16 10:20-09:30"sv, val);
}
{
const auto val = date_time{ { 1987, 3, 16 }, { 10, 20 }, { 9, 30 } };
parse_expected_value("1987-03-16T10:20+09:30"sv, val);
parse_expected_value("1987-03-16 10:20+09:30"sv, val);
parse_expected_value(FILE_LINE_ARGS, "1987-03-16T10:20+09:30"sv, val);
parse_expected_value(FILE_LINE_ARGS, "1987-03-16 10:20+09:30"sv, val);
}
{
const auto val = date_time{ { 1987, 3, 16 }, { 10, 20 }, {} };
parse_expected_value("1987-03-16T10:20Z"sv, val);
parse_expected_value("1987-03-16 10:20Z"sv, val);
parse_expected_value(FILE_LINE_ARGS, "1987-03-16T10:20Z"sv, val);
parse_expected_value(FILE_LINE_ARGS, "1987-03-16 10:20Z"sv, val);
}
#else
parsing_should_fail("10:20"sv);
parsing_should_fail("1987-03-16T10:20"sv);
parsing_should_fail("1987-03-16 10:20"sv);
parsing_should_fail("1987-03-16T10:20-09:30"sv);
parsing_should_fail("1987-03-16 10:20-09:30"sv);
parsing_should_fail("1987-03-16T10:20+09:30"sv);
parsing_should_fail("1987-03-16 10:20+09:30"sv);
parsing_should_fail("1987-03-16T10:20Z"sv);
parsing_should_fail("1987-03-16 10:20Z"sv);
parsing_should_fail(FILE_LINE_ARGS, "10:20"sv);
parsing_should_fail(FILE_LINE_ARGS, "1987-03-16T10:20"sv);
parsing_should_fail(FILE_LINE_ARGS, "1987-03-16 10:20"sv);
parsing_should_fail(FILE_LINE_ARGS, "1987-03-16T10:20-09:30"sv);
parsing_should_fail(FILE_LINE_ARGS, "1987-03-16 10:20-09:30"sv);
parsing_should_fail(FILE_LINE_ARGS, "1987-03-16T10:20+09:30"sv);
parsing_should_fail(FILE_LINE_ARGS, "1987-03-16 10:20+09:30"sv);
parsing_should_fail(FILE_LINE_ARGS, "1987-03-16T10:20Z"sv);
parsing_should_fail(FILE_LINE_ARGS, "1987-03-16 10:20Z"sv);
#endif
// eof tests
parsing_should_fail(FILE_LINE_ARGS, S("val = 1987-03-1"sv));
parsing_should_fail(FILE_LINE_ARGS, S("val = 1987-03-"sv));
parsing_should_fail(FILE_LINE_ARGS, S("val = 1987-03"sv));
parsing_should_fail(FILE_LINE_ARGS, S("val = 1987-0"sv));
parsing_should_fail(FILE_LINE_ARGS, S("val = 1987-"sv));
parsing_should_fail(FILE_LINE_ARGS, S("val = 10:20:30."sv));
parsing_should_fail(FILE_LINE_ARGS, S("val = 10:20:3"sv));
parsing_should_fail(FILE_LINE_ARGS, S("val = 10:20:"sv));
#if !TOML_LANG_UNRELEASED // toml/issues/671 (allow omission of seconds)
parsing_should_fail(FILE_LINE_ARGS, S("val = 10:20"sv));
#endif
parsing_should_fail(FILE_LINE_ARGS, S("val = 10:2"sv));
parsing_should_fail(FILE_LINE_ARGS, S("val = 10:"sv));
parsing_should_fail(FILE_LINE_ARGS, S("val = 1987-03-16 10:20:30.04-09:3"sv));
parsing_should_fail(FILE_LINE_ARGS, S("val = 1987-03-16 10:20:30.04-09:"sv));
parsing_should_fail(FILE_LINE_ARGS, S("val = 1987-03-16 10:20:30.04-09"sv));
parsing_should_fail(FILE_LINE_ARGS, S("val = 1987-03-16 10:20:30.04-0"sv));
parsing_should_fail(FILE_LINE_ARGS, S("val = 1987-03-16 10:20:30.04-"sv));
parsing_should_fail(FILE_LINE_ARGS, S("val = 1987-03-16 10:20:30."sv));
parsing_should_fail(FILE_LINE_ARGS, S("val = 1987-03-16 10:20:3"sv));
parsing_should_fail(FILE_LINE_ARGS, S("val = 1987-03-16 10:20:"sv));
#if !TOML_LANG_UNRELEASED // toml/issues/671 (allow omission of seconds)
parsing_should_fail(FILE_LINE_ARGS, S("val = 1987-03-16 10:20"sv));
#endif
parsing_should_fail(FILE_LINE_ARGS, S("val = 1987-03-16 10:2"sv));
parsing_should_fail(FILE_LINE_ARGS, S("val = 1987-03-16 10:"sv));
parsing_should_fail(FILE_LINE_ARGS, S("val = 1987-03-16 10"sv));
parsing_should_fail(FILE_LINE_ARGS, S("val = 1987-03-16 1"sv));
}
TOML_POP_WARNINGS

View File

@ -2,7 +2,9 @@
TEST_CASE("parsing - floats")
{
parsing_should_succeed(S(R"(
parsing_should_succeed(
FILE_LINE_ARGS,
S(R"(
# fractional
flt1 = +1.0
flt2 = 3.1415
@ -32,12 +34,13 @@ flt8 = 224_617.445_991_228
);
// "Each underscore must be surrounded by at least one digit on each side."
parsing_should_fail(S("flt8 = 224_617.445_991_228_"sv));
parsing_should_fail(S("flt8 = _224_617.445_991_228"sv));
parsing_should_fail(S("flt8 = 224__617.445_991_228"sv));
parsing_should_fail(FILE_LINE_ARGS, S("flt8 = 224_617.445_991_228_"sv));
parsing_should_fail(FILE_LINE_ARGS, S("flt8 = _224_617.445_991_228"sv));
parsing_should_fail(FILE_LINE_ARGS, S("flt8 = 224__617.445_991_228"sv));
// "Float values -0.0 and +0.0 are valid and should map according to IEEE 754."
parsing_should_succeed(
FILE_LINE_ARGS,
S(R"(zeroes = [-0.0, +0.0])"sv),
[](table&& tbl) noexcept
{
@ -47,76 +50,109 @@ flt8 = 224_617.445_991_228
);
//value tests
parse_expected_value( "1e1"sv, 1e1 );
parse_expected_value( "1e-1"sv, 1e-1 );
parse_expected_value( "1e+1"sv, 1e+1 );
parse_expected_value( "1.0"sv, 1.0 );
parse_expected_value( "1.0e1"sv, 1.0e1 );
parse_expected_value( "1.0e-1"sv, 1.0e-1 );
parse_expected_value( "1.0e+1"sv, 1.0e+1 );
parse_expected_value( "+1e1"sv, +1e1 );
parse_expected_value( "+1.0"sv, +1.0 );
parse_expected_value( "+1.0e1"sv, +1.0e1 );
parse_expected_value( "+1.0e+1"sv, +1.0e+1 );
parse_expected_value( "+1.0e-1"sv, +1.0e-1 );
parse_expected_value( "-1.0e+1"sv, -1.0e+1 );
parse_expected_value( "-1e1"sv, -1e1 );
parse_expected_value( "-1.0"sv, -1.0 );
parse_expected_value( "-1.0e1"sv, -1.0e1 );
parse_expected_value( "-1.0e-1"sv, -1.0e-1 );
parse_expected_value( "1.0"sv, 1.0 );
parse_expected_value( "0.1"sv, 0.1 );
parse_expected_value( "0.001"sv, 0.001 );
parse_expected_value( "0.100"sv, 0.100 );
parse_expected_value( "+3.14"sv, +3.14 );
parse_expected_value( "-3.14"sv, -3.14 );
parse_expected_value( "3.1415_9265_3589"sv, 3.141592653589 );
parse_expected_value( "+3.1415_9265_3589"sv, +3.141592653589 );
parse_expected_value( "-3.1415_9265_3589"sv, -3.141592653589 );
parse_expected_value( "123_456.789"sv, 123456.789 );
parse_expected_value( "+123_456.789"sv, +123456.789 );
parse_expected_value( "-123_456.789"sv, -123456.789 );
parse_expected_value( "+0.0"sv, +0.0 );
parse_expected_value( "-0.0"sv, -0.0 );
parse_expected_value( "1e10"sv, 1e10 );
parse_expected_value( "1e+10"sv, 1e+10 );
parse_expected_value( "1e-10"sv, 1e-10 );
parse_expected_value( "+1e10"sv, +1e10 );
parse_expected_value( "+1e+10"sv, +1e+10 );
parse_expected_value( "+1e-10"sv, +1e-10 );
parse_expected_value( "-1e10"sv, -1e10 );
parse_expected_value( "-1e+10"sv, -1e+10 );
parse_expected_value( "-1e-10"sv, -1e-10 );
parse_expected_value( "123e-10"sv, 123e-10 );
parse_expected_value( "1E10"sv, 1E10 );
parse_expected_value( "1E+10"sv, 1E+10 );
parse_expected_value( "1E-10"sv, 1E-10 );
parse_expected_value( "123E-10"sv, 123E-10 );
parse_expected_value( "1_2_3E-10"sv, 123E-10 );
parse_expected_value( "1_2_3E-1_0"sv, 123E-10 );
parse_expected_value( "+0e0"sv, +0e0 );
parse_expected_value( "-0e0"sv, -0e0 );
parse_expected_value( "1_2_3E-01"sv, 123E-01 );
parse_expected_value( "1_2_3E-0_1"sv, 123E-01 );
parse_expected_value( "6.02e23"sv, 6.02e23 );
parse_expected_value( "6.02e+23"sv, 6.02e+23 );
parse_expected_value( "1.112_650_06e-17"sv, 1.11265006e-17 );
parse_expected_value( FILE_LINE_ARGS, "1e1"sv, 1e1);
parse_expected_value( FILE_LINE_ARGS, "1e-1"sv, 1e-1);
parse_expected_value( FILE_LINE_ARGS, "1e+1"sv, 1e+1);
parse_expected_value( FILE_LINE_ARGS, "1.0"sv, 1.0);
parse_expected_value( FILE_LINE_ARGS, "1.0e1"sv, 1.0e1);
parse_expected_value( FILE_LINE_ARGS, "1.0e-1"sv, 1.0e-1);
parse_expected_value( FILE_LINE_ARGS, "1.0e+1"sv, 1.0e+1);
parse_expected_value( FILE_LINE_ARGS, "+1e1"sv, +1e1);
parse_expected_value( FILE_LINE_ARGS, "+1.0"sv, +1.0);
parse_expected_value( FILE_LINE_ARGS, "+1.0e1"sv, +1.0e1);
parse_expected_value( FILE_LINE_ARGS, "+1.0e+1"sv, +1.0e+1);
parse_expected_value( FILE_LINE_ARGS, "+1.0e-1"sv, +1.0e-1);
parse_expected_value( FILE_LINE_ARGS, "-1.0e+1"sv, -1.0e+1);
parse_expected_value( FILE_LINE_ARGS, "-1e1"sv, -1e1);
parse_expected_value( FILE_LINE_ARGS, "-1.0"sv, -1.0);
parse_expected_value( FILE_LINE_ARGS, "-1.0e1"sv, -1.0e1);
parse_expected_value( FILE_LINE_ARGS, "-1.0e-1"sv, -1.0e-1);
parse_expected_value( FILE_LINE_ARGS, "1.0"sv, 1.0);
parse_expected_value( FILE_LINE_ARGS, "0.1"sv, 0.1);
parse_expected_value( FILE_LINE_ARGS, "0.001"sv, 0.001);
parse_expected_value( FILE_LINE_ARGS, "0.100"sv, 0.100);
parse_expected_value( FILE_LINE_ARGS, "+3.14"sv, +3.14);
parse_expected_value( FILE_LINE_ARGS, "-3.14"sv, -3.14);
parse_expected_value( FILE_LINE_ARGS, "3.1415_9265_3589"sv, 3.141592653589);
parse_expected_value( FILE_LINE_ARGS, "+3.1415_9265_3589"sv, +3.141592653589);
parse_expected_value( FILE_LINE_ARGS, "-3.1415_9265_3589"sv, -3.141592653589);
parse_expected_value( FILE_LINE_ARGS, "123_456.789"sv, 123456.789);
parse_expected_value( FILE_LINE_ARGS, "+123_456.789"sv, +123456.789);
parse_expected_value( FILE_LINE_ARGS, "-123_456.789"sv, -123456.789);
parse_expected_value( FILE_LINE_ARGS, "+0.0"sv, +0.0);
parse_expected_value( FILE_LINE_ARGS, "-0.0"sv, -0.0);
parse_expected_value( FILE_LINE_ARGS, "1e10"sv, 1e10);
parse_expected_value( FILE_LINE_ARGS, "1e+10"sv, 1e+10);
parse_expected_value( FILE_LINE_ARGS, "1e-10"sv, 1e-10);
parse_expected_value( FILE_LINE_ARGS, "+1e10"sv, +1e10);
parse_expected_value( FILE_LINE_ARGS, "+1e+10"sv, +1e+10);
parse_expected_value( FILE_LINE_ARGS, "+1e-10"sv, +1e-10);
parse_expected_value( FILE_LINE_ARGS, "-1e10"sv, -1e10);
parse_expected_value( FILE_LINE_ARGS, "-1e+10"sv, -1e+10);
parse_expected_value( FILE_LINE_ARGS, "-1e-10"sv, -1e-10);
parse_expected_value( FILE_LINE_ARGS, "123e-10"sv, 123e-10);
parse_expected_value( FILE_LINE_ARGS, "1E10"sv, 1E10);
parse_expected_value( FILE_LINE_ARGS, "1E+10"sv, 1E+10);
parse_expected_value( FILE_LINE_ARGS, "1E-10"sv, 1E-10);
parse_expected_value( FILE_LINE_ARGS, "123E-10"sv, 123E-10);
parse_expected_value( FILE_LINE_ARGS, "1_2_3E-10"sv, 123E-10);
parse_expected_value( FILE_LINE_ARGS, "1_2_3E-1_0"sv, 123E-10);
parse_expected_value( FILE_LINE_ARGS, "+0e0"sv, +0e0);
parse_expected_value( FILE_LINE_ARGS, "-0e0"sv, -0e0);
parse_expected_value( FILE_LINE_ARGS, "1_2_3E-01"sv, 123E-01);
parse_expected_value( FILE_LINE_ARGS, "1_2_3E-0_1"sv, 123E-01);
parse_expected_value( FILE_LINE_ARGS, "6.02e23"sv, 6.02e23);
parse_expected_value( FILE_LINE_ARGS, "6.02e+23"sv, 6.02e+23);
parse_expected_value( FILE_LINE_ARGS, "1.112_650_06e-17"sv, 1.11265006e-17);
//toml/issues/562 (hexfloats)
#if TOML_LANG_UNRELEASED
parse_expected_value(" 0x10.1p0"sv, 0x10.1p0 );
parse_expected_value(" 0x0.3p10"sv, 0x0.3p10 );
parse_expected_value(" 0x12.2P2"sv, 0x12.2P2 );
parse_expected_value(FILE_LINE_ARGS, " 0x1.2p3"sv, 0x1.2p3);
parse_expected_value(FILE_LINE_ARGS, " 0x10p1"sv, 0x10p1);
parse_expected_value(FILE_LINE_ARGS, " 0x10p-1"sv, 0x10p-1);
parse_expected_value(FILE_LINE_ARGS, " 0x10p+1"sv, 0x10p+1);
parse_expected_value(FILE_LINE_ARGS, " -0x10p1"sv, -0x10p1);
parse_expected_value(FILE_LINE_ARGS, " -0x10p-1"sv, -0x10p-1);
parse_expected_value(FILE_LINE_ARGS, " +0x10p1"sv, +0x10p1);
parse_expected_value(FILE_LINE_ARGS, " +0x10p+1"sv, +0x10p+1);
parse_expected_value(FILE_LINE_ARGS, " -0x10p+1"sv, -0x10p+1);
parse_expected_value(FILE_LINE_ARGS, " +0x10p-1"sv, +0x10p-1);
parse_expected_value(FILE_LINE_ARGS, " 0x10.1p1"sv, 0x10.1p1);
parse_expected_value(FILE_LINE_ARGS, " 0x10.1p-1"sv, 0x10.1p-1);
parse_expected_value(FILE_LINE_ARGS, " 0x10.1p+1"sv, 0x10.1p+1);
parse_expected_value(FILE_LINE_ARGS, " -0x10.1p1"sv, -0x10.1p1);
parse_expected_value(FILE_LINE_ARGS, " -0x10.1p-1"sv, -0x10.1p-1);
parse_expected_value(FILE_LINE_ARGS, " +0x10.1p1"sv, +0x10.1p1);
parse_expected_value(FILE_LINE_ARGS, " +0x10.1p+1"sv, +0x10.1p+1);
parse_expected_value(FILE_LINE_ARGS, " -0x10.1p+1"sv, -0x10.1p+1);
parse_expected_value(FILE_LINE_ARGS, " +0x10.1p-1"sv, +0x10.1p-1);
#else
parsing_should_fail(S("val = 0x10.1p0"sv));
parsing_should_fail(S("val = 0x0.3p10"sv));
parsing_should_fail(S("val = 0x12.2P2"sv));
parsing_should_fail(FILE_LINE_ARGS, S(" val = 0x10p1"sv));
parsing_should_fail(FILE_LINE_ARGS, S(" val = 0x10p-1"sv));
parsing_should_fail(FILE_LINE_ARGS, S(" val = 0x10p+1"sv));
parsing_should_fail(FILE_LINE_ARGS, S(" val = -0x10p1"sv));
parsing_should_fail(FILE_LINE_ARGS, S(" val = -0x10p-1"sv));
parsing_should_fail(FILE_LINE_ARGS, S(" val = +0x10p1"sv));
parsing_should_fail(FILE_LINE_ARGS, S(" val = +0x10p+1"sv));
parsing_should_fail(FILE_LINE_ARGS, S(" val = -0x10p+1"sv));
parsing_should_fail(FILE_LINE_ARGS, S(" val = +0x10p-1"sv));
parsing_should_fail(FILE_LINE_ARGS, S(" val = 0x10.1p1"sv));
parsing_should_fail(FILE_LINE_ARGS, S(" val = 0x10.1p-1"sv));
parsing_should_fail(FILE_LINE_ARGS, S(" val = 0x10.1p+1"sv));
parsing_should_fail(FILE_LINE_ARGS, S(" val = -0x10.1p1"sv));
parsing_should_fail(FILE_LINE_ARGS, S(" val = -0x10.1p-1"sv));
parsing_should_fail(FILE_LINE_ARGS, S(" val = +0x10.1p1"sv));
parsing_should_fail(FILE_LINE_ARGS, S(" val = +0x10.1p+1"sv));
parsing_should_fail(FILE_LINE_ARGS, S(" val = -0x10.1p+1"sv));
parsing_should_fail(FILE_LINE_ARGS, S(" val = +0x10.1p-1"sv));
#endif
}
TEST_CASE("parsing - inf and nan")
{
parsing_should_succeed(S(R"(
parsing_should_succeed(
FILE_LINE_ARGS,
S(R"(
# infinity
sf1 = inf # positive infinity
sf2 = +inf # positive infinity

View File

@ -2,7 +2,9 @@
TEST_CASE("parsing - integers (decimal)")
{
parsing_should_succeed(S(R"(
parsing_should_succeed(
FILE_LINE_ARGS,
S(R"(
int1 = +99
int2 = 42
int3 = 0
@ -24,21 +26,22 @@ int7 = 1_2_3_4_5 # VALID but discouraged
);
// "Each underscore must be surrounded by at least one digit on each side."
parsing_should_fail(S("int5 = 1__000"sv));
parsing_should_fail(S("int5 = _1_000"sv));
parsing_should_fail(S("int5 = 1_000_"sv));
parsing_should_fail(FILE_LINE_ARGS, S("int5 = 1__000"sv));
parsing_should_fail(FILE_LINE_ARGS, S("int5 = _1_000"sv));
parsing_should_fail(FILE_LINE_ARGS, S("int5 = 1_000_"sv));
// "Leading zeroes are not allowed."
parsing_should_fail(S("int1 = +099"sv));
parsing_should_fail(S("int2 = 042"sv));
parsing_should_fail(S("int3 = 00"sv));
parsing_should_fail(S("int4 = -017"sv));
parsing_should_fail(S("int5 = 01_000"sv));
parsing_should_fail(S("int6 = 05_349_221"sv));
parsing_should_fail(S("int7 = 01_2_3_4_5"sv));
parsing_should_fail(FILE_LINE_ARGS, S("int1 = +099"sv));
parsing_should_fail(FILE_LINE_ARGS, S("int2 = 042"sv));
parsing_should_fail(FILE_LINE_ARGS, S("int3 = 00"sv));
parsing_should_fail(FILE_LINE_ARGS, S("int4 = -017"sv));
parsing_should_fail(FILE_LINE_ARGS, S("int5 = 01_000"sv));
parsing_should_fail(FILE_LINE_ARGS, S("int6 = 05_349_221"sv));
parsing_should_fail(FILE_LINE_ARGS, S("int7 = 01_2_3_4_5"sv));
// "Integer values -0 and +0 are valid and identical to an unprefixed zero."
parsing_should_succeed(
FILE_LINE_ARGS,
S("zeroes = [-0, +0]"sv),
[](table&& tbl) noexcept
{
@ -47,29 +50,31 @@ int7 = 1_2_3_4_5 # VALID but discouraged
}
);
parsing_should_fail(S("val = +-1"sv));
parsing_should_fail(S("val = -+1"sv));
parsing_should_fail(S("val = ++1"sv));
parsing_should_fail(S("val = --1"sv));
parsing_should_fail(S("val = 1-"sv));
parsing_should_fail(S("val = 1+"sv));
parsing_should_fail(S("val = -1+"sv));
parsing_should_fail(S("val = +1-"sv));
parsing_should_fail(FILE_LINE_ARGS, S("val = +-1"sv));
parsing_should_fail(FILE_LINE_ARGS, S("val = -+1"sv));
parsing_should_fail(FILE_LINE_ARGS, S("val = ++1"sv));
parsing_should_fail(FILE_LINE_ARGS, S("val = --1"sv));
parsing_should_fail(FILE_LINE_ARGS, S("val = 1-"sv));
parsing_should_fail(FILE_LINE_ARGS, S("val = 1+"sv));
parsing_should_fail(FILE_LINE_ARGS, S("val = -1+"sv));
parsing_should_fail(FILE_LINE_ARGS, S("val = +1-"sv));
// value tests
parse_expected_value( "1234"sv, 1234 );
parse_expected_value( "+1234"sv, 1234 );
parse_expected_value( "-1234"sv, -1234 );
parse_expected_value( "0"sv, 0 );
parse_expected_value( "1_2_3_4"sv, 1234 );
parse_expected_value( "+1_2_3_4"sv, 1234 );
parse_expected_value( "-1_2_3_4"sv, -1234 );
parse_expected_value( "123_456_789"sv, 123456789 );
parse_expected_value(FILE_LINE_ARGS, "1234"sv, 1234);
parse_expected_value(FILE_LINE_ARGS, "+1234"sv, 1234);
parse_expected_value(FILE_LINE_ARGS, "-1234"sv, -1234);
parse_expected_value(FILE_LINE_ARGS, "0"sv, 0);
parse_expected_value(FILE_LINE_ARGS, "1_2_3_4"sv, 1234);
parse_expected_value(FILE_LINE_ARGS, "+1_2_3_4"sv, 1234);
parse_expected_value(FILE_LINE_ARGS, "-1_2_3_4"sv, -1234);
parse_expected_value(FILE_LINE_ARGS, "123_456_789"sv, 123456789);
}
TEST_CASE("parsing - integers (hex, bin, oct)")
{
parsing_should_succeed(S(R"(
parsing_should_succeed(
FILE_LINE_ARGS,
S(R"(
# hexadecimal with prefix `0x`
hex1 = 0xDEADBEEF
hex2 = 0xdeadbeef
@ -94,16 +99,18 @@ bin1 = 0b11010110
);
// "leading + is not allowed"
parsing_should_fail(S("hex1 = +0xDEADBEEF"sv));
parsing_should_fail(S("hex2 = +0xdeadbeef"sv));
parsing_should_fail(S("hex3 = +0xdead_beef"sv));
parsing_should_fail(S("oct1 = +0o01234567"sv));
parsing_should_fail(S("oct2 = +0o7550"sv));
parsing_should_fail(S("int6 = +05_349_221"sv));
parsing_should_fail(S("bin1 = +0b11010110"sv));
parsing_should_fail(FILE_LINE_ARGS, S("hex1 = +0xDEADBEEF"sv));
parsing_should_fail(FILE_LINE_ARGS, S("hex2 = +0xdeadbeef"sv));
parsing_should_fail(FILE_LINE_ARGS, S("hex3 = +0xdead_beef"sv));
parsing_should_fail(FILE_LINE_ARGS, S("oct1 = +0o01234567"sv));
parsing_should_fail(FILE_LINE_ARGS, S("oct2 = +0o7550"sv));
parsing_should_fail(FILE_LINE_ARGS, S("int6 = +05_349_221"sv));
parsing_should_fail(FILE_LINE_ARGS, S("bin1 = +0b11010110"sv));
// "leading zeros are allowed (after the prefix)"
parsing_should_succeed(S(R"(
parsing_should_succeed(
FILE_LINE_ARGS,
S(R"(
hex1 = 0x000DEADBEEF
hex2 = 0x00000deadbeef
hex3 = 0x0dead_beef
@ -123,29 +130,29 @@ bin1 = 0b0000011010110
);
// "64 bit (signed long) range expected (9,223,372,036,854,775,808 to 9,223,372,036,854,775,807)."
parsing_should_fail(S("val = 9223372036854775809"sv));
parsing_should_fail(S("val = 9223372036854775808"sv));
parsing_should_fail(FILE_LINE_ARGS, S("val = 9223372036854775809"sv));
parsing_should_fail(FILE_LINE_ARGS, S("val = 9223372036854775808"sv));
// "***Non-negative*** integer values may also be expressed in hexadecimal, octal, or binary"
parsing_should_fail(S("val = -0o1"sv));
parsing_should_fail(S("val = -0b1"sv));
parsing_should_fail(S("val = -0x1"sv));
parsing_should_fail(FILE_LINE_ARGS, S("val = -0o1"sv));
parsing_should_fail(FILE_LINE_ARGS, S("val = -0b1"sv));
parsing_should_fail(FILE_LINE_ARGS, S("val = -0x1"sv));
// value tests
parse_expected_value( "0xDEADBEEF"sv, 0xDEADBEEF );
parse_expected_value( "0xdeadbeef"sv, 0xDEADBEEF );
parse_expected_value( "0xDEADbeef"sv, 0xDEADBEEF );
parse_expected_value( "0xDEAD_BEEF"sv, 0xDEADBEEF );
parse_expected_value( "0xdead_beef"sv, 0xDEADBEEF );
parse_expected_value( "0xdead_BEEF"sv, 0xDEADBEEF );
parse_expected_value( "0xFF"sv, 0xFF );
parse_expected_value( "0x00FF"sv, 0xFF );
parse_expected_value( "0x0000FF"sv, 0xFF );
parse_expected_value( "0o777"sv, 0777 );
parse_expected_value( "0o7_7_7"sv, 0777 );
parse_expected_value( "0o007"sv, 0007 );
parse_expected_value( "0b10000"sv, 0b10000 );
parse_expected_value( "0b010000"sv, 0b10000 );
parse_expected_value( "0b01_00_00"sv, 0b10000 );
parse_expected_value( "0b111111"sv, 0b111111 );
parse_expected_value(FILE_LINE_ARGS, "0xDEADBEEF"sv, 0xDEADBEEF);
parse_expected_value(FILE_LINE_ARGS, "0xdeadbeef"sv, 0xDEADBEEF);
parse_expected_value(FILE_LINE_ARGS, "0xDEADbeef"sv, 0xDEADBEEF);
parse_expected_value(FILE_LINE_ARGS, "0xDEAD_BEEF"sv, 0xDEADBEEF);
parse_expected_value(FILE_LINE_ARGS, "0xdead_beef"sv, 0xDEADBEEF);
parse_expected_value(FILE_LINE_ARGS, "0xdead_BEEF"sv, 0xDEADBEEF);
parse_expected_value(FILE_LINE_ARGS, "0xFF"sv, 0xFF);
parse_expected_value(FILE_LINE_ARGS, "0x00FF"sv, 0xFF);
parse_expected_value(FILE_LINE_ARGS, "0x0000FF"sv, 0xFF);
parse_expected_value(FILE_LINE_ARGS, "0o777"sv, 0777);
parse_expected_value(FILE_LINE_ARGS, "0o7_7_7"sv, 0777);
parse_expected_value(FILE_LINE_ARGS, "0o007"sv, 0007);
parse_expected_value(FILE_LINE_ARGS, "0b10000"sv, 0b10000);
parse_expected_value(FILE_LINE_ARGS, "0b010000"sv, 0b10000);
parse_expected_value(FILE_LINE_ARGS, "0b01_00_00"sv, 0b10000);
parse_expected_value(FILE_LINE_ARGS, "0b111111"sv, 0b111111);
}

View File

@ -2,7 +2,9 @@
TEST_CASE("parsing - key-value pairs")
{
parsing_should_succeed(S(R"(
parsing_should_succeed(
FILE_LINE_ARGS,
S(R"(
key = "value"
bare_key = "value"
bare-key = "value"
@ -20,9 +22,11 @@ bare-key = "value"
}
);
parsing_should_fail(S(R"(key = # INVALID)"sv));
parsing_should_fail(FILE_LINE_ARGS, S(R"(key = # INVALID)"sv));
parsing_should_succeed(S(R"(
parsing_should_succeed(
FILE_LINE_ARGS,
S(R"(
"127.0.0.1" = "value"
"character encoding" = "value"
"ʎǝʞ" = "value"
@ -41,20 +45,21 @@ bare-key = "value"
}
);
parsing_should_fail(S(R"(= "no key name")"sv));
parsing_should_fail(FILE_LINE_ARGS, S(R"(= "no key name")"sv));
parsing_should_fail(S(R"(
parsing_should_fail(FILE_LINE_ARGS, S(R"(
# DO NOT DO THIS
name = "Tom"
name = "Pradyun"
)"sv)
);
)"sv));
}
TEST_CASE("parsing - key-value pairs (dotted)")
{
parsing_should_succeed(S(R"(
parsing_should_succeed(
FILE_LINE_ARGS,
S(R"(
name = "Orange"
physical.color = "orange"
physical.shape = "round"
@ -73,7 +78,9 @@ site."google.com" = true
);
parsing_should_succeed(S(R"(
parsing_should_succeed(
FILE_LINE_ARGS,
S(R"(
fruit.apple.smooth = true
fruit.orange = 2
)"sv),
@ -84,14 +91,15 @@ fruit.orange = 2
}
);
parsing_should_fail(S(R"(
parsing_should_fail(FILE_LINE_ARGS, S(R"(
# THIS IS INVALID
fruit.apple = 1
fruit.apple.smooth = true
)"sv)
);
)"sv));
parsing_should_succeed(S(R"(
parsing_should_succeed(
FILE_LINE_ARGS,
S(R"(
# VALID BUT DISCOURAGED
apple.type = "fruit"
@ -114,7 +122,9 @@ orange.color = "orange"
}
);
parsing_should_succeed(S(R"(
parsing_should_succeed(
FILE_LINE_ARGS,
S(R"(
# RECOMMENDED
apple.type = "fruit"
@ -138,10 +148,12 @@ orange.color = "orange"
// toml/issues/644 ('+' in bare keys) & toml/issues/687 (unicode bare keys)
#if TOML_LANG_UNRELEASED
parsing_should_succeed(S(R"(
key+1 = 0
ʎǝʞ2 = 0
)"sv),
parsing_should_succeed(
FILE_LINE_ARGS,
S(R"(
key+1 = 0
ʎǝʞ2 = 0
)"sv),
[](table&& tbl) noexcept
{
CHECK(tbl.size() == 2);
@ -150,7 +162,7 @@ orange.color = "orange"
}
);
#else
parsing_should_fail(R"(key+1 = 0)"sv);
parsing_should_fail(R"(ʎǝʞ2 = 0)"sv);
parsing_should_fail(FILE_LINE_ARGS, R"(key+1 = 0)"sv);
parsing_should_fail(FILE_LINE_ARGS, R"(ʎǝʞ2 = 0)"sv);
#endif
}

View File

@ -40,49 +40,53 @@ hosts = [
"omega"
])"sv);
parsing_should_succeed(toml_text, [](table&& tbl) noexcept
{
CHECK(tbl.size() == 5);
parsing_should_succeed(
FILE_LINE_ARGS,
toml_text,
[](table&& tbl) noexcept
{
CHECK(tbl.size() == 5);
CHECK(tbl[S("title")] == S("TOML Example"sv));
CHECK(tbl[S("title")] == S("TOML Example"sv));
CHECK(tbl[S("owner")]);
CHECK(tbl[S("owner")].as<table>());
CHECK(tbl[S("owner")][S("name")] == S("Tom Preston-Werner"sv));
const auto dob = date_time{ { 1979, 5, 27 }, { 7, 32 }, { -8, 0 } };
CHECK(tbl[S("owner")][S("dob")] == dob);
CHECK(tbl[S("owner")]);
CHECK(tbl[S("owner")].as<table>());
CHECK(tbl[S("owner")][S("name")] == S("Tom Preston-Werner"sv));
const auto dob = date_time{ { 1979, 5, 27 }, { 7, 32 }, { -8, 0 } };
CHECK(tbl[S("owner")][S("dob")] == dob);
CHECK(tbl[S("database")].as<table>());
CHECK(tbl[S("database")][S("server")] == S("192.168.1.1"sv));
const auto ports = { 8001, 8001, 8002 };
CHECK(tbl[S("database")][S("ports")] == ports);
CHECK(tbl[S("database")][S("connection_max")] == 5000);
CHECK(tbl[S("database")][S("enabled")] == true);
CHECK(tbl[S("database")].as<table>());
CHECK(tbl[S("database")][S("server")] == S("192.168.1.1"sv));
const auto ports = { 8001, 8001, 8002 };
CHECK(tbl[S("database")][S("ports")] == ports);
CHECK(tbl[S("database")][S("connection_max")] == 5000);
CHECK(tbl[S("database")][S("enabled")] == true);
CHECK(tbl[S("servers")].as<table>());
CHECK(tbl[S("servers")][S("alpha")].as<table>());
CHECK(tbl[S("servers")][S("alpha")][S("ip")] == S("10.0.0.1"sv));
CHECK(tbl[S("servers")][S("alpha")][S("dc")] == S("eqdc10"sv));
CHECK(tbl[S("servers")][S("beta")].as<table>());
CHECK(tbl[S("servers")][S("beta")][S("ip")] == S("10.0.0.2"sv));
CHECK(tbl[S("servers")][S("beta")][S("dc")] == S("eqdc10"sv));
CHECK(tbl[S("servers")].as<table>());
CHECK(tbl[S("servers")][S("alpha")].as<table>());
CHECK(tbl[S("servers")][S("alpha")][S("ip")] == S("10.0.0.1"sv));
CHECK(tbl[S("servers")][S("alpha")][S("dc")] == S("eqdc10"sv));
CHECK(tbl[S("servers")][S("beta")].as<table>());
CHECK(tbl[S("servers")][S("beta")][S("ip")] == S("10.0.0.2"sv));
CHECK(tbl[S("servers")][S("beta")][S("dc")] == S("eqdc10"sv));
CHECK(tbl[S("clients")].as<table>());
REQUIRE(tbl[S("clients")][S("data")].as<array>());
CHECK(tbl[S("clients")][S("data")].as<array>()->size() == 2);
REQUIRE(tbl[S("clients")][S("data")][0].as<array>());
CHECK(tbl[S("clients")][S("data")][0].as<array>()->size() == 2);
CHECK(tbl[S("clients")][S("data")][0][0] == S("gamma"sv));
CHECK(tbl[S("clients")][S("data")][0][1] == S("delta"sv));
REQUIRE(tbl[S("clients")][S("data")][1].as<array>());
CHECK(tbl[S("clients")][S("data")][1].as<array>()->size() == 2);
CHECK(tbl[S("clients")][S("data")][1][0] == 1);
CHECK(tbl[S("clients")][S("data")][1][1] == 2);
REQUIRE(tbl[S("clients")][S("hosts")].as<array>());
CHECK(tbl[S("clients")][S("hosts")].as<array>()->size() == 2);
CHECK(tbl[S("clients")][S("hosts")][0] == S("alpha"sv));
CHECK(tbl[S("clients")][S("hosts")][1] == S("omega"sv));
});
CHECK(tbl[S("clients")].as<table>());
REQUIRE(tbl[S("clients")][S("data")].as<array>());
CHECK(tbl[S("clients")][S("data")].as<array>()->size() == 2);
REQUIRE(tbl[S("clients")][S("data")][0].as<array>());
CHECK(tbl[S("clients")][S("data")][0].as<array>()->size() == 2);
CHECK(tbl[S("clients")][S("data")][0][0] == S("gamma"sv));
CHECK(tbl[S("clients")][S("data")][0][1] == S("delta"sv));
REQUIRE(tbl[S("clients")][S("data")][1].as<array>());
CHECK(tbl[S("clients")][S("data")][1].as<array>()->size() == 2);
CHECK(tbl[S("clients")][S("data")][1][0] == 1);
CHECK(tbl[S("clients")][S("data")][1][1] == 2);
REQUIRE(tbl[S("clients")][S("hosts")].as<array>());
CHECK(tbl[S("clients")][S("hosts")].as<array>()->size() == 2);
CHECK(tbl[S("clients")][S("hosts")][0] == S("alpha"sv));
CHECK(tbl[S("clients")][S("hosts")][1] == S("omega"sv));
}
);
}
TOML_POP_WARNINGS

View File

@ -2,7 +2,9 @@
TEST_CASE("parsing - strings")
{
parsing_should_succeed(S(R"(
parsing_should_succeed(
FILE_LINE_ARGS,
S(R"(
str = "I'm a string. \"You can quote me\". Name\tJos\u00E9\nLocation\tSF."
str1 = """
@ -16,7 +18,9 @@ Violets are blue"""
}
);
parsing_should_succeed(S(R"(
parsing_should_succeed(
FILE_LINE_ARGS,
S(R"(
# The following strings are byte-for-byte equivalent:
str1 = "The quick brown fox jumps over the lazy dog."
@ -54,9 +58,11 @@ str7 = """"This," she said, "is just a pointless statement.""""
}
);
parsing_should_fail(S(R"(str5 = """Here are three quotation marks: """.""")"sv));
parsing_should_fail(FILE_LINE_ARGS, S(R"(str5 = """Here are three quotation marks: """.""")"sv));
parsing_should_succeed(S(R"(
parsing_should_succeed(
FILE_LINE_ARGS,
S(R"(
# What you see is what you get.
winpath = 'C:\Users\nodejs\templates'
winpath2 = '\\ServerX\admin$\system32\'
@ -85,7 +91,9 @@ trimmed in raw strings.
}
);
parsing_should_succeed(S(R"(
parsing_should_succeed(
FILE_LINE_ARGS,
S(R"(
quot15 = '''Here are fifteen quotation marks: """""""""""""""'''
# apos15 = '''Here are fifteen apostrophes: '''''''''''''''''' # INVALID
@ -102,57 +110,66 @@ str = ''''That's still pointless', she said.'''
}
);
parsing_should_fail(S(R"(apos15 = '''Here are fifteen apostrophes: '''''''''''''''''' # INVALID)"sv));
parsing_should_fail(FILE_LINE_ARGS, S(R"(apos15 = '''Here are fifteen apostrophes: '''''''''''''''''' # INVALID)"sv));
//value tests
parse_expected_value(
FILE_LINE_ARGS,
R"("The quick brown fox jumps over the lazy dog")"sv,
S("The quick brown fox jumps over the lazy dog"sv));
parse_expected_value(
FILE_LINE_ARGS,
R"('The quick brown fox jumps over the lazy dog')"sv,
S("The quick brown fox jumps over the lazy dog"sv));
parse_expected_value(
FILE_LINE_ARGS,
R"("""The quick brown fox jumps over the lazy dog""")"sv,
S("The quick brown fox jumps over the lazy dog"sv));
parse_expected_value(
FILE_LINE_ARGS,
R"('''The quick brown fox jumps over the lazy dog''')"sv,
S("The quick brown fox jumps over the lazy dog"sv));
parse_expected_value(
FILE_LINE_ARGS,
R"("Ýôú' λáƭè è áƒƭèř ƭλïƨ - #")"sv,
S(R"(Ýôú' λáƭè ₥è áƒƭèř ƭλïƨ - #)"sv));
parse_expected_value(
FILE_LINE_ARGS,
R"(" Âñδ ωλèñ \"'ƨ ářè ïñ ƭλè ƨƭřïñϱ, áℓôñϱ ωïƭλ # \"")"sv,
S(R"( Âñδ ωλèñ "'ƨ ářè ïñ ƭλè ƨƭřïñϱ, áôñϱ ωïƭλ # ")"sv));
parse_expected_value(
FILE_LINE_ARGS,
R"("Ýôú δôñ'ƭ ƭλïñƙ ƨôè úƨèř ωôñ'ƭ δô ƭλáƭ?")"sv,
S(R"(Ýôú δôñ'ƭ ƭλïñƙ ƨô₥è úƨèř ωôñ'ƭ δô ƭλáƭ?)"sv));
parse_expected_value(
FILE_LINE_ARGS,
R"("\"\u03B1\u03B2\u03B3\"")"sv,
S("\"\u03B1\u03B2\u03B3\""sv));
// toml/pull/709 (\xHH unicode scalars)
#if TOML_LANG_UNRELEASED
parse_expected_value(
FILE_LINE_ARGS,
R"("\x00\x10\x20\x30\x40\x50\x60\x70\x80\x90\x11\xFF\xEE")"sv,
S("\u0000\u0010\u0020\u0030\u0040\u0050\u0060\u0070\u0080\u0090\u0011\u00FF\u00EE"sv));
#else
parsing_should_fail(R"(str = "\x00\x10\x20\x30\x40\x50\x60\x70\x80\x90\x11\xFF\xEE")"sv);
parsing_should_fail(FILE_LINE_ARGS, R"(str = "\x00\x10\x20\x30\x40\x50\x60\x70\x80\x90\x11\xFF\xEE")"sv);
#endif
//check 8-digit \U scalars with insufficient digits
parsing_should_fail(R"(str = "\U1234567")"sv);
parsing_should_fail(R"(str = "\U123456")"sv);
parsing_should_fail(R"(str = "\U12345")"sv);
parsing_should_fail(R"(str = "\U1234")"sv);
parsing_should_fail(R"(str = "\U123")"sv);
parsing_should_fail(R"(str = "\U12")"sv);
parsing_should_fail(R"(str = "\U1")"sv);
parsing_should_fail(FILE_LINE_ARGS,R"(str = "\U1234567")"sv);
parsing_should_fail(FILE_LINE_ARGS,R"(str = "\U123456")"sv);
parsing_should_fail(FILE_LINE_ARGS,R"(str = "\U12345")"sv);
parsing_should_fail(FILE_LINE_ARGS,R"(str = "\U1234")"sv);
parsing_should_fail(FILE_LINE_ARGS,R"(str = "\U123")"sv);
parsing_should_fail(FILE_LINE_ARGS,R"(str = "\U12")"sv);
parsing_should_fail(FILE_LINE_ARGS,R"(str = "\U1")"sv);
//check 4-digit \u scalars with insufficient digits
parsing_should_fail(R"(str = "\u123")"sv);
parsing_should_fail(R"(str = "\u12")"sv);
parsing_should_fail(R"(str = "\u1")"sv);
parsing_should_fail(FILE_LINE_ARGS,R"(str = "\u123")"sv);
parsing_should_fail(FILE_LINE_ARGS,R"(str = "\u12")"sv);
parsing_should_fail(FILE_LINE_ARGS,R"(str = "\u1")"sv);
//check 2-digit \x scalars with insufficient digits
parsing_should_fail(R"(str = "\x1")"sv);
parsing_should_fail(FILE_LINE_ARGS, R"(str = "\x1")"sv);
}

View File

@ -2,7 +2,9 @@
TEST_CASE("parsing - tables")
{
parsing_should_succeed(S(R"(
parsing_should_succeed(
FILE_LINE_ARGS,
S(R"(
[table]
[table-1]
@ -82,7 +84,7 @@ smooth = true
);
parsing_should_fail(S(R"(
parsing_should_fail(FILE_LINE_ARGS, S(R"(
# DO NOT DO THIS
[fruit]
@ -92,7 +94,7 @@ apple = "red"
orange = "orange"
)"sv));
parsing_should_fail(S(R"(
parsing_should_fail(FILE_LINE_ARGS, S(R"(
# DO NOT DO THIS EITHER
[fruit]
@ -102,7 +104,7 @@ apple = "red"
texture = "smooth"
)"sv));
parsing_should_fail(S(R"(
parsing_should_fail(FILE_LINE_ARGS, S(R"(
[fruit]
apple.color = "red"
apple.taste.sweet = true
@ -110,7 +112,7 @@ apple.taste.sweet = true
[fruit.apple]
)"sv));
parsing_should_fail(S(R"(
parsing_should_fail(FILE_LINE_ARGS, S(R"(
[fruit]
apple.color = "red"
apple.taste.sweet = true
@ -118,7 +120,9 @@ apple.taste.sweet = true
[fruit.apple.taste]
)"sv));
parsing_should_succeed(S(R"(
parsing_should_succeed(
FILE_LINE_ARGS,
S(R"(
# VALID BUT DISCOURAGED
[fruit.apple]
[animal]
@ -138,7 +142,9 @@ apple.taste.sweet = true
);
parsing_should_succeed(S(R"(
parsing_should_succeed(
FILE_LINE_ARGS,
S(R"(
# RECOMMENDED
[fruit.apple]
[fruit.orange]
@ -160,7 +166,9 @@ apple.taste.sweet = true
TEST_CASE("parsing - inline tables")
{
parsing_should_succeed(S(R"(
parsing_should_succeed(
FILE_LINE_ARGS,
S(R"(
name = { first = "Tom", last = "Preston-Werner" }
point = { x = 1, y = 2 }
animal = { type.name = "pug" }
@ -194,20 +202,22 @@ type = { name = "Nail" }
}
);
parsing_should_fail(S(R"(
parsing_should_fail(FILE_LINE_ARGS, S(R"(
[product]
type = { name = "Nail" }
type.edible = false # INVALID
)"sv));
parsing_should_fail(S(R"(
parsing_should_fail(FILE_LINE_ARGS, S(R"(
[product]
type.name = "Nail"
type = { edible = false } # INVALID
)"sv));
// "newlines are allowed between the curly braces [if] they are valid within a value."
parsing_should_succeed(S(R"(
parsing_should_succeed(
FILE_LINE_ARGS,
S(R"(
test = { val1 = "foo", val2 = [
1, 2,
3
@ -230,7 +240,9 @@ test = { val1 = "foo", val2 = [
// toml/issues/516 (newlines/trailing commas in inline tables)
#if TOML_LANG_UNRELEASED
{
parsing_should_succeed(S(R"(
parsing_should_succeed(
FILE_LINE_ARGS,
S(R"(
name = {
first = "Tom",
last = "Preston-Werner",
@ -249,10 +261,10 @@ name = {
#else
{
// "A terminating comma (also called trailing comma) is not permitted after the last key/value pair in an inline table."
parsing_should_fail(S(R"(name = { first = "Tom", last = "Preston-Werner", })"sv));
parsing_should_fail(FILE_LINE_ARGS, S(R"(name = { first = "Tom", last = "Preston-Werner", })"sv));
// "No newlines are allowed between the curly braces unless they are valid within a value."
parsing_should_fail(S(R"(
parsing_should_fail(FILE_LINE_ARGS, S(R"(
name = {
first = "Tom",
last = "Preston-Werner"
@ -266,7 +278,9 @@ name = {
TEST_CASE("parsing - arrays-of-tables")
{
parsing_should_succeed(S(R"(
parsing_should_succeed(
FILE_LINE_ARGS,
S(R"(
points = [ { x = 1, y = 2, z = 3 },
{ x = 7, y = 8, z = 9 },
{ x = 2, y = 4, z = 8 } ]
@ -372,7 +386,7 @@ color = "gray"
}
);
parsing_should_fail(S(R"(
parsing_should_fail(FILE_LINE_ARGS, S(R"(
# INVALID TOML DOC
[fruit.physical] # subtable, but to which parent element should it belong?
color = "red"
@ -383,14 +397,14 @@ color = "gray"
name = "apple"
)"sv));
parsing_should_fail(S(R"(
parsing_should_fail(FILE_LINE_ARGS, S(R"(
# INVALID TOML DOC
fruit = []
[[fruit]] # Not allowed
)"sv));
parsing_should_fail(S(R"(
parsing_should_fail(FILE_LINE_ARGS, S(R"(
# INVALID TOML DOC
[[fruit]]
name = "apple"
@ -403,7 +417,7 @@ fruit = []
name = "granny smith"
)"sv));
parsing_should_fail(S(R"(
parsing_should_fail(FILE_LINE_ARGS, S(R"(
# INVALID TOML DOC
[[fruit]]
name = "apple"

View File

@ -1,11 +1,11 @@
#include "tests.h"
template void parse_expected_value(std::string_view, const int&) noexcept;
template void parse_expected_value(std::string_view, const unsigned int&) noexcept;
template void parse_expected_value(std::string_view, const bool&) noexcept;
template void parse_expected_value(std::string_view, const float&) noexcept;
template void parse_expected_value(std::string_view, const double&) noexcept;
template void parse_expected_value(std::string_view, const toml::string_view&) noexcept;
template void parse_expected_value(std::string_view, uint32_t, std::string_view, const int&) noexcept;
template void parse_expected_value(std::string_view, uint32_t, std::string_view, const unsigned int&) noexcept;
template void parse_expected_value(std::string_view, uint32_t, std::string_view, const bool&) noexcept;
template void parse_expected_value(std::string_view, uint32_t, std::string_view, const float&) noexcept;
template void parse_expected_value(std::string_view, uint32_t, std::string_view, const double&) noexcept;
template void parse_expected_value(std::string_view, uint32_t, std::string_view, const toml::string_view&) noexcept;
namespace std
{

View File

@ -25,15 +25,25 @@
#endif
#endif
#define FILE_LINE_ARGS std::string_view{ __FILE__ }, __LINE__
using namespace toml;
using namespace Catch::literals;
#define S(str) TOML_STRING_PREFIX(str)
template <typename Char, typename Func = std::false_type>
inline void parsing_should_succeed(std::basic_string_view<Char> toml_str, Func&& func = {}, std::string_view source_path = {}) noexcept
inline void parsing_should_succeed(
std::string_view test_file,
uint32_t test_line,
std::basic_string_view<Char> toml_str,
Func&& func = {},
std::string_view source_path = {}) noexcept
{
INFO("String being parsed: '"sv << std::string_view( reinterpret_cast<const char*>(toml_str.data()), toml_str.length() ) << "'"sv)
INFO(
"["sv << test_file << ", line "sv << test_line << "] "sv
<< "parsing_should_succeed('"sv << std::string_view(reinterpret_cast<const char*>(toml_str.data()), toml_str.length()) << "')"sv
)
constexpr auto validate_table = [](table&& tabl, std::string_view path) noexcept -> table&&
{
@ -134,9 +144,15 @@ inline void parsing_should_succeed(std::basic_string_view<Char> toml_str, Func&&
}
template <typename Char>
inline void parsing_should_fail(std::basic_string_view<Char> toml_str) noexcept
inline void parsing_should_fail(
std::string_view test_file,
uint32_t test_line,
std::basic_string_view<Char> toml_str) noexcept
{
INFO("String being parsed: '"sv << std::string_view(reinterpret_cast<const char*>(toml_str.data()), toml_str.length()) << "'"sv)
INFO(
"["sv << test_file << ", line "sv << test_line << "] "sv
<< "parsing_should_fail('"sv << std::string_view(reinterpret_cast<const char*>(toml_str.data()), toml_str.length()) << "')"sv
)
#if TOML_EXCEPTIONS
@ -200,8 +216,14 @@ inline void parsing_should_fail(std::basic_string_view<Char> toml_str) noexcept
}
template <typename T>
inline void parse_expected_value(std::string_view value_str, const T& expected) noexcept
inline void parse_expected_value(
std::string_view test_file,
uint32_t test_line,
std::string_view value_str,
const T& expected) noexcept
{
INFO("["sv << test_file << ", line "sv << test_line << "] "sv << "parse_expected_value('"sv << value_str << "')"sv)
std::string val;
static constexpr auto key = "val = "sv;
val.reserve(key.length() + value_str.length());
@ -250,84 +272,100 @@ inline void parse_expected_value(std::string_view value_str, const T& expected)
using value_type = impl::promoted<impl::remove_cvref_t<T>>;
value<value_type> val_parsed;
parsing_should_succeed(std::string_view{ val }, [&](table&& tbl) noexcept
{
CHECK(tbl.size() == 1);
auto nv = tbl[S("val"sv)];
REQUIRE(nv);
REQUIRE(nv.as<value_type>());
REQUIRE(nv.get()->type() == impl::node_type_of<T>);
INFO("["sv << test_file << ", line "sv << test_line << "] "sv << "parse_expected_value: Checking inital parse"sv)
// check the raw value
CHECK(nv.get()->value<value_type>() == expected);
CHECK(nv.get()->value_or(T{}) == expected);
CHECK(nv.as<value_type>()->get() == expected);
CHECK(nv.value<value_type>() == expected);
CHECK(nv.value_or(T{}) == expected);
CHECK(nv.ref<value_type>() == expected);
CHECK(nv.get()->ref<value_type>() == expected);
parsing_should_succeed(
test_file,
test_line,
std::string_view{ val },
[&](table&& tbl) noexcept
{
REQUIRE(tbl.size() == 1);
auto nv = tbl[S("val"sv)];
REQUIRE(nv);
REQUIRE(nv.as<value_type>());
REQUIRE(nv.get()->type() == impl::node_type_of<T>);
// check the table relops
CHECK(tbl == table{ { { S("val"sv), expected } } });
CHECK(!(tbl != table{ { { S("val"sv), expected } } }));
// check the raw value
REQUIRE(nv.get()->value<value_type>() == expected);
REQUIRE(nv.get()->value_or(T{}) == expected);
REQUIRE(nv.as<value_type>()->get() == expected);
REQUIRE(nv.value<value_type>() == expected);
REQUIRE(nv.value_or(T{}) == expected);
REQUIRE(nv.ref<value_type>() == expected);
REQUIRE(nv.get()->ref<value_type>() == expected);
// check the value relops
CHECK(*nv.as<value_type>() == expected);
CHECK(expected == *nv.as<value_type>());
CHECK(!(*nv.as<value_type>() != expected));
CHECK(!(expected != *nv.as<value_type>()));
// check the table relops
REQUIRE(tbl == table{ { { S("val"sv), expected } } });
REQUIRE(!(tbl != table{ { { S("val"sv), expected } } }));
// check the node_view relops
CHECK(nv == expected);
CHECK(expected == nv);
CHECK(!(nv != expected));
CHECK(!(expected != nv));
// check the value relops
REQUIRE(*nv.as<value_type>() == expected);
REQUIRE(expected == *nv.as<value_type>());
REQUIRE(!(*nv.as<value_type>() != expected));
REQUIRE(!(expected != *nv.as<value_type>()));
// make sure source info is correct
CHECK(nv.get()->source().begin == begin);
CHECK(nv.get()->source().end == end);
// check the node_view relops
REQUIRE(nv == expected);
REQUIRE(expected == nv);
REQUIRE(!(nv != expected));
REQUIRE(!(expected != nv));
// steal the val for round-trip tests
val_parsed = std::move(*nv.as<value_type>());
});
// make sure source info is correct
REQUIRE(nv.get()->source().begin == begin);
REQUIRE(nv.get()->source().end == end);
// steal the val for round-trip tests
val_parsed = std::move(*nv.as<value_type>());
}
);
}
// check round-tripping
value<value_type> val_reparsed;
{
std::string str;
INFO("["sv << test_file << ", line "sv << test_line << "] "sv << "parse_expected_value: Checking round-trip"sv)
value<value_type> val_reparsed;
{
auto tbl = table{ { { S("val"sv), *val_parsed } } };
std::ostringstream ss;
ss << tbl;
str = std::move(ss).str();
std::string str;
{
auto tbl = table{ { { S("val"sv), *val_parsed } } };
std::ostringstream ss;
ss << tbl;
str = std::move(ss).str();
}
parsing_should_succeed(
test_file,
test_line,
std::string_view{ str },
[&](table&& tbl) noexcept
{
REQUIRE(tbl.size() == 1);
auto nv = tbl[S("val"sv)];
REQUIRE(nv);
REQUIRE(nv.as<value_type>());
REQUIRE(nv.get()->type() == impl::node_type_of<T>);
CHECK(nv.as<value_type>()->get() == expected);
CHECK(nv.ref<value_type>() == expected);
val_reparsed = std::move(*nv.as<value_type>());
}
);
}
parsing_should_succeed(std::string_view{ str }, [&](table&& tbl) noexcept
{
CHECK(tbl.size() == 1);
auto nv = tbl[S("val"sv)];
REQUIRE(nv);
REQUIRE(nv.as<value_type>());
REQUIRE(nv.get()->type() == impl::node_type_of<T>);
CHECK(nv.as<value_type>()->get() == expected);
CHECK(nv.ref<value_type>() == expected);
val_reparsed = std::move(*nv.as<value_type>());
});
CHECK(val_reparsed == val_parsed);
CHECK(val_reparsed == expected);
}
CHECK(val_reparsed == val_parsed);
CHECK(val_reparsed == expected);
}
// manually instantiate some templates to reduce test compilation time (chosen using ClangBuildAnalyzer)
extern template void parse_expected_value(std::string_view, const int&) noexcept;
extern template void parse_expected_value(std::string_view, const unsigned int&) noexcept;
extern template void parse_expected_value(std::string_view, const bool&) noexcept;
extern template void parse_expected_value(std::string_view, const float&) noexcept;
extern template void parse_expected_value(std::string_view, const double&) noexcept;
extern template void parse_expected_value(std::string_view, const toml::string_view&) noexcept;
extern template void parse_expected_value(std::string_view, uint32_t, std::string_view, const int&) noexcept;
extern template void parse_expected_value(std::string_view, uint32_t, std::string_view, const unsigned int&) noexcept;
extern template void parse_expected_value(std::string_view, uint32_t, std::string_view, const bool&) noexcept;
extern template void parse_expected_value(std::string_view, uint32_t, std::string_view, const float&) noexcept;
extern template void parse_expected_value(std::string_view, uint32_t, std::string_view, const double&) noexcept;
extern template void parse_expected_value(std::string_view, uint32_t, std::string_view, const toml::string_view&) noexcept;
namespace std
{
extern template class unique_ptr<const Catch::IExceptionTranslator>;

1339
toml.hpp

File diff suppressed because it is too large Load Diff

View File

@ -69,6 +69,7 @@
<ClCompile Include="..\tests\manipulating_arrays.cpp" />
<ClCompile Include="..\tests\manipulating_tables.cpp" />
<ClCompile Include="..\tests\manipulating_parse_result.cpp" />
<ClCompile Include="..\tests\manipulating_values.cpp" />
<ClCompile Include="..\tests\parsing_arrays.cpp" />
<ClCompile Include="..\tests\parsing_booleans.cpp" />
<ClCompile Include="..\tests\parsing_comments.cpp" />

View File

@ -69,6 +69,7 @@
<ClCompile Include="..\tests\manipulating_arrays.cpp" />
<ClCompile Include="..\tests\manipulating_tables.cpp" />
<ClCompile Include="..\tests\manipulating_parse_result.cpp" />
<ClCompile Include="..\tests\manipulating_values.cpp" />
<ClCompile Include="..\tests\parsing_arrays.cpp" />
<ClCompile Include="..\tests\parsing_booleans.cpp" />
<ClCompile Include="..\tests\parsing_comments.cpp" />

View File

@ -71,6 +71,7 @@
<ClCompile Include="..\tests\manipulating_arrays.cpp" />
<ClCompile Include="..\tests\manipulating_tables.cpp" />
<ClCompile Include="..\tests\manipulating_parse_result.cpp" />
<ClCompile Include="..\tests\manipulating_values.cpp" />
<ClCompile Include="..\tests\parsing_arrays.cpp" />
<ClCompile Include="..\tests\parsing_booleans.cpp" />
<ClCompile Include="..\tests\parsing_comments.cpp" />

View File

@ -70,6 +70,7 @@
<ClCompile Include="..\tests\manipulating_arrays.cpp" />
<ClCompile Include="..\tests\manipulating_tables.cpp" />
<ClCompile Include="..\tests\manipulating_parse_result.cpp" />
<ClCompile Include="..\tests\manipulating_values.cpp" />
<ClCompile Include="..\tests\parsing_arrays.cpp" />
<ClCompile Include="..\tests\parsing_booleans.cpp" />
<ClCompile Include="..\tests\parsing_comments.cpp" />

View File

@ -72,6 +72,7 @@
<ClCompile Include="..\tests\manipulating_arrays.cpp" />
<ClCompile Include="..\tests\manipulating_tables.cpp" />
<ClCompile Include="..\tests\manipulating_parse_result.cpp" />
<ClCompile Include="..\tests\manipulating_values.cpp" />
<ClCompile Include="..\tests\parsing_arrays.cpp" />
<ClCompile Include="..\tests\parsing_booleans.cpp" />
<ClCompile Include="..\tests\parsing_comments.cpp" />

View File

@ -71,6 +71,7 @@
<ClCompile Include="..\tests\manipulating_arrays.cpp" />
<ClCompile Include="..\tests\manipulating_tables.cpp" />
<ClCompile Include="..\tests\manipulating_parse_result.cpp" />
<ClCompile Include="..\tests\manipulating_values.cpp" />
<ClCompile Include="..\tests\parsing_arrays.cpp" />
<ClCompile Include="..\tests\parsing_booleans.cpp" />
<ClCompile Include="..\tests\parsing_comments.cpp" />

View File

@ -70,6 +70,7 @@
<ClCompile Include="..\tests\manipulating_arrays.cpp" />
<ClCompile Include="..\tests\manipulating_tables.cpp" />
<ClCompile Include="..\tests\manipulating_parse_result.cpp" />
<ClCompile Include="..\tests\manipulating_values.cpp" />
<ClCompile Include="..\tests\parsing_arrays.cpp" />
<ClCompile Include="..\tests\parsing_booleans.cpp" />
<ClCompile Include="..\tests\parsing_comments.cpp" />

View File

@ -72,6 +72,7 @@
<ClCompile Include="..\tests\manipulating_arrays.cpp" />
<ClCompile Include="..\tests\manipulating_tables.cpp" />
<ClCompile Include="..\tests\manipulating_parse_result.cpp" />
<ClCompile Include="..\tests\manipulating_values.cpp" />
<ClCompile Include="..\tests\parsing_arrays.cpp" />
<ClCompile Include="..\tests\parsing_booleans.cpp" />
<ClCompile Include="..\tests\parsing_comments.cpp" />

View File

@ -69,6 +69,7 @@
<ClCompile Include="..\tests\manipulating_arrays.cpp" />
<ClCompile Include="..\tests\manipulating_tables.cpp" />
<ClCompile Include="..\tests\manipulating_parse_result.cpp" />
<ClCompile Include="..\tests\manipulating_values.cpp" />
<ClCompile Include="..\tests\parsing_arrays.cpp" />
<ClCompile Include="..\tests\parsing_booleans.cpp" />
<ClCompile Include="..\tests\parsing_comments.cpp" />

View File

@ -69,6 +69,7 @@
<ClCompile Include="..\tests\manipulating_arrays.cpp" />
<ClCompile Include="..\tests\manipulating_tables.cpp" />
<ClCompile Include="..\tests\manipulating_parse_result.cpp" />
<ClCompile Include="..\tests\manipulating_values.cpp" />
<ClCompile Include="..\tests\parsing_arrays.cpp" />
<ClCompile Include="..\tests\parsing_booleans.cpp" />
<ClCompile Include="..\tests\parsing_comments.cpp" />

View File

@ -71,6 +71,7 @@
<ClCompile Include="..\tests\manipulating_arrays.cpp" />
<ClCompile Include="..\tests\manipulating_tables.cpp" />
<ClCompile Include="..\tests\manipulating_parse_result.cpp" />
<ClCompile Include="..\tests\manipulating_values.cpp" />
<ClCompile Include="..\tests\parsing_arrays.cpp" />
<ClCompile Include="..\tests\parsing_booleans.cpp" />
<ClCompile Include="..\tests\parsing_comments.cpp" />

View File

@ -70,6 +70,7 @@
<ClCompile Include="..\tests\manipulating_arrays.cpp" />
<ClCompile Include="..\tests\manipulating_tables.cpp" />
<ClCompile Include="..\tests\manipulating_parse_result.cpp" />
<ClCompile Include="..\tests\manipulating_values.cpp" />
<ClCompile Include="..\tests\parsing_arrays.cpp" />
<ClCompile Include="..\tests\parsing_booleans.cpp" />
<ClCompile Include="..\tests\parsing_comments.cpp" />

View File

@ -72,6 +72,7 @@
<ClCompile Include="..\tests\manipulating_arrays.cpp" />
<ClCompile Include="..\tests\manipulating_tables.cpp" />
<ClCompile Include="..\tests\manipulating_parse_result.cpp" />
<ClCompile Include="..\tests\manipulating_values.cpp" />
<ClCompile Include="..\tests\parsing_arrays.cpp" />
<ClCompile Include="..\tests\parsing_booleans.cpp" />
<ClCompile Include="..\tests\parsing_comments.cpp" />

View File

@ -71,6 +71,7 @@
<ClCompile Include="..\tests\manipulating_arrays.cpp" />
<ClCompile Include="..\tests\manipulating_tables.cpp" />
<ClCompile Include="..\tests\manipulating_parse_result.cpp" />
<ClCompile Include="..\tests\manipulating_values.cpp" />
<ClCompile Include="..\tests\parsing_arrays.cpp" />
<ClCompile Include="..\tests\parsing_booleans.cpp" />
<ClCompile Include="..\tests\parsing_comments.cpp" />

View File

@ -70,6 +70,7 @@
<ClCompile Include="..\tests\manipulating_arrays.cpp" />
<ClCompile Include="..\tests\manipulating_tables.cpp" />
<ClCompile Include="..\tests\manipulating_parse_result.cpp" />
<ClCompile Include="..\tests\manipulating_values.cpp" />
<ClCompile Include="..\tests\parsing_arrays.cpp" />
<ClCompile Include="..\tests\parsing_booleans.cpp" />
<ClCompile Include="..\tests\parsing_comments.cpp" />

View File

@ -72,6 +72,7 @@
<ClCompile Include="..\tests\manipulating_arrays.cpp" />
<ClCompile Include="..\tests\manipulating_tables.cpp" />
<ClCompile Include="..\tests\manipulating_parse_result.cpp" />
<ClCompile Include="..\tests\manipulating_values.cpp" />
<ClCompile Include="..\tests\parsing_arrays.cpp" />
<ClCompile Include="..\tests\parsing_booleans.cpp" />
<ClCompile Include="..\tests\parsing_comments.cpp" />