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: jobs:
clang_build_with_dox: debug_clang9_dox:
docker: docker:
- image: marzer/misc_cpp17_dev:latest - image: marzer/misc_cpp17_dev:latest
steps: steps:
- checkout - 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: - run:
name: Checking toml.hpp name: Checking toml.hpp
command: | command: |
@ -17,14 +21,10 @@ jobs:
git submodule update --init extern/Catch2 git submodule update --init extern/Catch2
git submodule update --init extern/tloptional git submodule update --init extern/tloptional
- run: - run:
name: Building with clang name: Building and testing with clang 9
command: | command: |
CXX=clang++-9 meson build-clang CXX=clang++-9 meson build --buildtype=debug
cd build-clang && ninja -v -j 4 cd build && ninja -v && ninja test
- run:
name: Running tests
command: |
cd build-clang && ninja test
- run: - run:
name: Generating documentation name: Generating documentation
command: | command: |
@ -35,11 +35,15 @@ jobs:
paths: html paths: html
clang_build: debug_clang9:
docker: docker:
- image: marzer/misc_cpp17_dev:latest - image: marzer/misc_cpp17_dev:latest
steps: steps:
- checkout - 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: - run:
name: Checking toml.hpp name: Checking toml.hpp
command: | command: |
@ -50,35 +54,77 @@ jobs:
git submodule update --init extern/Catch2 git submodule update --init extern/Catch2
git submodule update --init extern/tloptional git submodule update --init extern/tloptional
- run: - run:
name: Building with clang name: Building and testing with clang 9
command: | command: |
CXX=clang++-9 meson build-clang CXX=clang++-9 meson build --buildtype=debug
cd build-clang && ninja -v -j 4 cd build && ninja -v && ninja test
- run:
name: Running tests
command: |
cd build-clang && ninja test
gcc_build: release_clang9:
docker: docker:
- image: marzer/misc_cpp17_dev:latest - image: marzer/misc_cpp17_dev:latest
steps: steps:
- checkout - 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: - run:
name: Pulling submodules name: Pulling submodules
command: | command: |
git submodule update --init extern/Catch2 git submodule update --init extern/Catch2
git submodule update --init extern/tloptional git submodule update --init extern/tloptional
- run: - run:
name: Building with gcc name: Building and testing with clang 9
command: | command: |
CXX=g++-9 meson build-gcc CXX=clang++-9 meson build --buildtype=release
cd build-gcc && ninja -v -j 4 cd build && ninja -v && ninja test
debug_gcc9:
docker:
- image: marzer/misc_cpp17_dev:latest
steps:
- checkout
- run: - run:
name: Running tests name: Initializing locales
command: | 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: deploy_dox:
@ -110,16 +156,20 @@ workflows:
version: 2 version: 2
build: build:
jobs: jobs:
- clang_build_with_dox: - debug_clang9_dox:
filters: filters:
branches: branches:
only: master only: master
- clang_build: - debug_clang9:
filters: filters:
branches: branches:
ignore: master ignore: master
- gcc_build - release_clang9
- debug_gcc9
- release_gcc9
- deploy_dox: - deploy_dox:
requires: requires:
- clang_build_with_dox - debug_clang9_dox
- gcc_build - 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 nav .m-thin, nav .github
{ {

View File

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

View File

@ -192,9 +192,18 @@
#ifndef TOML_DISABLE_INIT_WARNINGS #ifndef TOML_DISABLE_INIT_WARNINGS
#define TOML_DISABLE_INIT_WARNINGS #define TOML_DISABLE_INIT_WARNINGS
#endif #endif
#ifndef TOML_INTEGER_CHARCONV
#define TOML_INTEGER_CHARCONV 1
#endif
#ifndef TOML_FLOATING_POINT_CHARCONV #ifndef TOML_FLOATING_POINT_CHARCONV
#define TOML_FLOATING_POINT_CHARCONV 1 #define TOML_FLOATING_POINT_CHARCONV 1
#endif #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 #ifndef TOML_PUSH_WARNINGS
#define TOML_PUSH_WARNINGS #define TOML_PUSH_WARNINGS
#endif #endif
@ -298,7 +307,6 @@
TOML_PUSH_WARNINGS TOML_PUSH_WARNINGS
TOML_DISABLE_ALL_WARNINGS TOML_DISABLE_ALL_WARNINGS
#if __has_include(<version>) #if __has_include(<version>)
#include <version> #include <version>
#endif #endif
@ -310,22 +318,20 @@ TOML_DISABLE_ALL_WARNINGS
#include <vector> #include <vector>
#include <map> #include <map>
#include <iosfwd> #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 #ifndef TOML_OPTIONAL_TYPE
#include <optional> #include <optional>
#endif #endif
#if TOML_EXCEPTIONS #if TOML_EXCEPTIONS
#include <stdexcept> #include <stdexcept>
#endif #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 TOML_POP_WARNINGS
#if TOML_CHAR_8_STRINGS #if TOML_CHAR_8_STRINGS
@ -893,9 +899,9 @@ namespace toml::impl
"date-time"sv "date-time"sv
}; };
#define TOML_P2S_DECL(linkage, type) \ #define TOML_P2S_DECL(Linkage, Type) \
template <typename Char> \ 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, int8_t);
TOML_P2S_DECL(TOML_ALWAYS_INLINE, int16_t); TOML_P2S_DECL(TOML_ALWAYS_INLINE, int16_t);

View File

@ -210,6 +210,7 @@ namespace toml
size_t child_table_array_count{}; size_t child_table_array_count{};
for (auto&& [child_k, child_v] : child_tbl) for (auto&& [child_k, child_v] : child_tbl)
{ {
(void)child_k;
const auto child_type = child_v.type(); const auto child_type = child_v.type();
switch (child_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. /// \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>(); } [[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. /// \brief Gets the raw value contained by the referenced node.
/// ///
/// \tparam U One of the TOML value types. Can also be a string_view. /// \tparam U One of the TOML value types. Can also be a string_view.
@ -182,6 +185,8 @@ namespace toml
return {}; return {};
} }
TOML_POP_WARNINGS
/// \brief Gets the raw value contained by the referenced node, or a default. /// \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. /// \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 #pragma once
#include "toml_date_time.h" #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 namespace toml::impl
{ {
// Q: "why does print_to_stream() exist? why not just use ostream::write(), ostream::put() etc?" // 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." "The stream's underlying character type must be 1 byte in size."
); );
char buf[charconv_buffer_length<T>]; #if TOML_INTEGER_CHARCONV
const auto res = std::to_chars(buf, buf + sizeof(buf), val);
print_to_stream(buf, static_cast<size_t>(res.ptr - buf), stream); 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> \ template <typename Char> \
TOML_ALWAYS_INLINE \ 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); \ static_assert(sizeof(Char) == 1); \
print_integer_to_stream(val, stream); \ print_integer_to_stream(val, stream); \
@ -148,20 +175,13 @@ namespace toml::impl
} }
#else #else
{ {
char buf[charconv_buffer_length<T> + 1_sz]; std::ostringstream ss;
int len = -1; ss.imbue(std::locale::classic());
ss.precision(std::numeric_limits<T>::digits10 + 1);
if (hexfloat) if (hexfloat)
len = snprintf(buf, charconv_buffer_length<T> + 1_sz, "%a", static_cast<double>(val)); ss << std::hexfloat;
else ss << val;
len = snprintf( const auto str = std::move(ss).str();
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) };
print_to_stream(str, stream); print_to_stream(str, stream);
if (!hexfloat && needs_decimal_point(str)) if (!hexfloat && needs_decimal_point(str))
print_to_stream(".0"sv, stream); 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); extern template TOML_API void print_floating_point_to_stream(double, std::ostream&, bool);
#endif #endif
#define TOML_P2S_OVERLOAD(type) \ #define TOML_P2S_OVERLOAD(Type) \
template <typename Char> \ template <typename Char> \
TOML_ALWAYS_INLINE \ 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); \ static_assert(sizeof(Char) == 1); \
print_floating_point_to_stream(val, stream); \ 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) inline void print_to_stream(T val, std::basic_ostream<Char>& stream, size_t zero_pad_to_digits)
{ {
static_assert(sizeof(Char) == 1); static_assert(sizeof(Char) == 1);
char buf[charconv_buffer_length<T>]; #if TOML_INTEGER_CHARCONV
const auto res = std::to_chars(buf, buf + sizeof(buf), val);
const auto len = static_cast<size_t>(res.ptr - buf); char buf[charconv_buffer_length<T>];
for (size_t i = len; i < zero_pad_to_digits; i++) const auto res = std::to_chars(buf, buf + sizeof(buf), val);
print_to_stream('0', stream); const auto len = static_cast<size_t>(res.ptr - buf);
print_to_stream(buf, static_cast<size_t>(res.ptr - buf), stream); 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> template <typename Char>

View File

@ -9,6 +9,14 @@
namespace toml::impl 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 [[nodiscard]] TOML_ALWAYS_INLINE
constexpr bool is_ascii_whitespace(char32_t codepoint) noexcept 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]] [[nodiscard]]
constexpr bool is_bare_key_start_character(char32_t codepoint) noexcept 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_CHECK
#undef TOML_ERROR #undef TOML_ERROR
#if TOML_ABI_NAMESPACES #if TOML_ABI_NAMESPACES
} //end abi namespace for TOML_EXCEPTIONS } //end abi namespace for TOML_EXCEPTIONS / !TOML_EXCEPTIONS
#endif #endif
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -5,6 +5,7 @@ TEST_CASE("tables - moving")
static constexpr auto filename = "foo.toml"sv; static constexpr auto filename = "foo.toml"sv;
parsing_should_succeed( parsing_should_succeed(
FILE_LINE_ARGS,
S(R"(test = { val1 = "foo" })"sv), S(R"(test = { val1 = "foo" })"sv),
[&](table&& tbl) noexcept [&](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 = [ test_sources = [
'impl_toml.cpp', 'impl_toml.cpp',
'impl_catch2.cpp', 'impl_catch2.cpp',
'tests.cpp',
'parsing_floats.cpp',
'parsing_arrays.cpp', 'parsing_arrays.cpp',
'parsing_booleans.cpp', 'parsing_booleans.cpp',
'parsing_comments.cpp', 'parsing_comments.cpp',
'parsing_dates_and_times.cpp', 'parsing_dates_and_times.cpp',
'parsing_floats.cpp',
'parsing_integers.cpp', 'parsing_integers.cpp',
'parsing_key_value_pairs.cpp', 'parsing_key_value_pairs.cpp',
'parsing_spec_example.cpp', 'parsing_spec_example.cpp',
@ -13,15 +14,9 @@ test_sources = [
'parsing_tables.cpp', 'parsing_tables.cpp',
'manipulating_arrays.cpp', 'manipulating_arrays.cpp',
'manipulating_tables.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(''' compiler_supports_char8_strings = compiler.compiles('''
#include <string_view> #include <string_view>
#include <string> #include <string>
@ -35,137 +30,78 @@ compiler_supports_char8_strings = compiler.compiles('''
args : [ '-std=c++2a' ] args : [ '-std=c++2a' ]
) )
############################################################################ character_types = ['char', 'char8']
### char 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( name = character_type
'char', overrides = []
test_sources, args = []
include_directories : inc
)
test('char', char)
if character_type =='char8'
overrides += 'cpp_std=none'
args += '-DTOML_CHAR_8_STRINGS=1'
args += '-std=c++2a'
endif
char_noexcept = executable( if not unreleased_features
'char_noexcept', name = name + '_strict'
test_sources, args += '-DTOML_UNRELEASED_FEATURES=0'
include_directories : inc, endif
override_options : [ disable_exceptions ]
)
test('char_noexcept', char_noexcept)
if not exceptions
name = name + '_noexcept'
overrides += 'cpp_eh=none'
endif
char_strict = executable( if tloptional
'char_strict', name = name + '_tlopt'
test_sources, args += '-DTARTANLLAMA_OPTIONAL'
include_directories : inc, endif
cpp_args : [ no_unreleased_features ]
)
test('char_strict', char_strict)
executables += [[
name,
executable(
name,
test_sources,
include_directories : inc,
cpp_args : args,
override_options : overrides
)
]]
char_strict_noexcept = executable( endforeach # tloptional_modes
'char_strict_noexcept', endforeach # unreleased_feature_modes
test_sources, endforeach # exception_modes
include_directories : inc, endforeach # character_type
override_options : [ disable_exceptions ],
cpp_args : [ no_unreleased_features ]
)
test('char_strict_noexcept', char_strict_noexcept)
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'
]
############################################################################ foreach locale : locales
### char w/ tl::optional foreach executable : executables
############################################################################ test(locale + '_' + executable[0], executable[1], env : ['LC_ALL=' + locale])
endforeach
endforeach
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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -2,7 +2,9 @@
TEST_CASE("parsing - strings") 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." str = "I'm a string. \"You can quote me\". Name\tJos\u00E9\nLocation\tSF."
str1 = """ 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: # The following strings are byte-for-byte equivalent:
str1 = "The quick brown fox jumps over the lazy dog." 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. # What you see is what you get.
winpath = 'C:\Users\nodejs\templates' winpath = 'C:\Users\nodejs\templates'
winpath2 = '\\ServerX\admin$\system32\' 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: """""""""""""""''' quot15 = '''Here are fifteen quotation marks: """""""""""""""'''
# apos15 = '''Here are fifteen apostrophes: '''''''''''''''''' # INVALID # 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 //value tests
parse_expected_value( parse_expected_value(
FILE_LINE_ARGS,
R"("The quick brown fox jumps over the lazy dog")"sv, R"("The quick brown fox jumps over the lazy dog")"sv,
S("The quick brown fox jumps over the lazy dog"sv)); S("The quick brown fox jumps over the lazy dog"sv));
parse_expected_value( parse_expected_value(
FILE_LINE_ARGS,
R"('The quick brown fox jumps over the lazy dog')"sv, R"('The quick brown fox jumps over the lazy dog')"sv,
S("The quick brown fox jumps over the lazy dog"sv)); S("The quick brown fox jumps over the lazy dog"sv));
parse_expected_value( parse_expected_value(
FILE_LINE_ARGS,
R"("""The quick brown fox jumps over the lazy dog""")"sv, R"("""The quick brown fox jumps over the lazy dog""")"sv,
S("The quick brown fox jumps over the lazy dog"sv)); S("The quick brown fox jumps over the lazy dog"sv));
parse_expected_value( parse_expected_value(
FILE_LINE_ARGS,
R"('''The quick brown fox jumps over the lazy dog''')"sv, R"('''The quick brown fox jumps over the lazy dog''')"sv,
S("The quick brown fox jumps over the lazy dog"sv)); S("The quick brown fox jumps over the lazy dog"sv));
parse_expected_value( parse_expected_value(
FILE_LINE_ARGS,
R"("Ýôú' λáƭè è áƒƭèř ƭλïƨ - #")"sv, R"("Ýôú' λáƭè è áƒƭèř ƭλïƨ - #")"sv,
S(R"(Ýôú' λáƭè ₥è áƒƭèř ƭλïƨ - #)"sv)); S(R"(Ýôú' λáƭè ₥è áƒƭèř ƭλïƨ - #)"sv));
parse_expected_value( parse_expected_value(
FILE_LINE_ARGS,
R"(" Âñδ ωλèñ \"'ƨ ářè ïñ ƭλè ƨƭřïñϱ, áℓôñϱ ωïƭλ # \"")"sv, R"(" Âñδ ωλèñ \"'ƨ ářè ïñ ƭλè ƨƭřïñϱ, áℓôñϱ ωïƭλ # \"")"sv,
S(R"( Âñδ ωλèñ "'ƨ ářè ïñ ƭλè ƨƭřïñϱ, áôñϱ ωïƭλ # ")"sv)); S(R"( Âñδ ωλèñ "'ƨ ářè ïñ ƭλè ƨƭřïñϱ, áôñϱ ωïƭλ # ")"sv));
parse_expected_value( parse_expected_value(
FILE_LINE_ARGS,
R"("Ýôú δôñ'ƭ ƭλïñƙ ƨôè úƨèř ωôñ'ƭ δô ƭλáƭ?")"sv, R"("Ýôú δôñ'ƭ ƭλïñƙ ƨôè úƨèř ωôñ'ƭ δô ƭλáƭ?")"sv,
S(R"(Ýôú δôñ'ƭ ƭλïñƙ ƨô₥è úƨèř ωôñ'ƭ δô ƭλáƭ?)"sv)); S(R"(Ýôú δôñ'ƭ ƭλïñƙ ƨô₥è úƨèř ωôñ'ƭ δô ƭλáƭ?)"sv));
parse_expected_value( parse_expected_value(
FILE_LINE_ARGS,
R"("\"\u03B1\u03B2\u03B3\"")"sv, R"("\"\u03B1\u03B2\u03B3\"")"sv,
S("\"\u03B1\u03B2\u03B3\""sv)); S("\"\u03B1\u03B2\u03B3\""sv));
// toml/pull/709 (\xHH unicode scalars) // toml/pull/709 (\xHH unicode scalars)
#if TOML_LANG_UNRELEASED #if TOML_LANG_UNRELEASED
parse_expected_value( parse_expected_value(
FILE_LINE_ARGS,
R"("\x00\x10\x20\x30\x40\x50\x60\x70\x80\x90\x11\xFF\xEE")"sv, 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)); S("\u0000\u0010\u0020\u0030\u0040\u0050\u0060\u0070\u0080\u0090\u0011\u00FF\u00EE"sv));
#else #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 #endif
//check 8-digit \U scalars with insufficient digits //check 8-digit \U scalars with insufficient digits
parsing_should_fail(R"(str = "\U1234567")"sv); parsing_should_fail(FILE_LINE_ARGS,R"(str = "\U1234567")"sv);
parsing_should_fail(R"(str = "\U123456")"sv); parsing_should_fail(FILE_LINE_ARGS,R"(str = "\U123456")"sv);
parsing_should_fail(R"(str = "\U12345")"sv); parsing_should_fail(FILE_LINE_ARGS,R"(str = "\U12345")"sv);
parsing_should_fail(R"(str = "\U1234")"sv); parsing_should_fail(FILE_LINE_ARGS,R"(str = "\U1234")"sv);
parsing_should_fail(R"(str = "\U123")"sv); parsing_should_fail(FILE_LINE_ARGS,R"(str = "\U123")"sv);
parsing_should_fail(R"(str = "\U12")"sv); parsing_should_fail(FILE_LINE_ARGS,R"(str = "\U12")"sv);
parsing_should_fail(R"(str = "\U1")"sv); parsing_should_fail(FILE_LINE_ARGS,R"(str = "\U1")"sv);
//check 4-digit \u scalars with insufficient digits //check 4-digit \u scalars with insufficient digits
parsing_should_fail(R"(str = "\u123")"sv); parsing_should_fail(FILE_LINE_ARGS,R"(str = "\u123")"sv);
parsing_should_fail(R"(str = "\u12")"sv); parsing_should_fail(FILE_LINE_ARGS,R"(str = "\u12")"sv);
parsing_should_fail(R"(str = "\u1")"sv); parsing_should_fail(FILE_LINE_ARGS,R"(str = "\u1")"sv);
//check 2-digit \x scalars with insufficient digits //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") TEST_CASE("parsing - tables")
{ {
parsing_should_succeed(S(R"( parsing_should_succeed(
FILE_LINE_ARGS,
S(R"(
[table] [table]
[table-1] [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 # DO NOT DO THIS
[fruit] [fruit]
@ -92,7 +94,7 @@ apple = "red"
orange = "orange" orange = "orange"
)"sv)); )"sv));
parsing_should_fail(S(R"( parsing_should_fail(FILE_LINE_ARGS, S(R"(
# DO NOT DO THIS EITHER # DO NOT DO THIS EITHER
[fruit] [fruit]
@ -102,7 +104,7 @@ apple = "red"
texture = "smooth" texture = "smooth"
)"sv)); )"sv));
parsing_should_fail(S(R"( parsing_should_fail(FILE_LINE_ARGS, S(R"(
[fruit] [fruit]
apple.color = "red" apple.color = "red"
apple.taste.sweet = true apple.taste.sweet = true
@ -110,7 +112,7 @@ apple.taste.sweet = true
[fruit.apple] [fruit.apple]
)"sv)); )"sv));
parsing_should_fail(S(R"( parsing_should_fail(FILE_LINE_ARGS, S(R"(
[fruit] [fruit]
apple.color = "red" apple.color = "red"
apple.taste.sweet = true apple.taste.sweet = true
@ -118,7 +120,9 @@ apple.taste.sweet = true
[fruit.apple.taste] [fruit.apple.taste]
)"sv)); )"sv));
parsing_should_succeed(S(R"( parsing_should_succeed(
FILE_LINE_ARGS,
S(R"(
# VALID BUT DISCOURAGED # VALID BUT DISCOURAGED
[fruit.apple] [fruit.apple]
[animal] [animal]
@ -138,7 +142,9 @@ apple.taste.sweet = true
); );
parsing_should_succeed(S(R"( parsing_should_succeed(
FILE_LINE_ARGS,
S(R"(
# RECOMMENDED # RECOMMENDED
[fruit.apple] [fruit.apple]
[fruit.orange] [fruit.orange]
@ -160,7 +166,9 @@ apple.taste.sweet = true
TEST_CASE("parsing - inline tables") TEST_CASE("parsing - inline tables")
{ {
parsing_should_succeed(S(R"( parsing_should_succeed(
FILE_LINE_ARGS,
S(R"(
name = { first = "Tom", last = "Preston-Werner" } name = { first = "Tom", last = "Preston-Werner" }
point = { x = 1, y = 2 } point = { x = 1, y = 2 }
animal = { type.name = "pug" } 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] [product]
type = { name = "Nail" } type = { name = "Nail" }
type.edible = false # INVALID type.edible = false # INVALID
)"sv)); )"sv));
parsing_should_fail(S(R"( parsing_should_fail(FILE_LINE_ARGS, S(R"(
[product] [product]
type.name = "Nail" type.name = "Nail"
type = { edible = false } # INVALID type = { edible = false } # INVALID
)"sv)); )"sv));
// "newlines are allowed between the curly braces [if] they are valid within a value." // "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 = [ test = { val1 = "foo", val2 = [
1, 2, 1, 2,
3 3
@ -230,7 +240,9 @@ test = { val1 = "foo", val2 = [
// toml/issues/516 (newlines/trailing commas in inline tables) // toml/issues/516 (newlines/trailing commas in inline tables)
#if TOML_LANG_UNRELEASED #if TOML_LANG_UNRELEASED
{ {
parsing_should_succeed(S(R"( parsing_should_succeed(
FILE_LINE_ARGS,
S(R"(
name = { name = {
first = "Tom", first = "Tom",
last = "Preston-Werner", last = "Preston-Werner",
@ -249,10 +261,10 @@ name = {
#else #else
{ {
// "A terminating comma (also called trailing comma) is not permitted after the last key/value pair in an inline table." // "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." // "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 = { name = {
first = "Tom", first = "Tom",
last = "Preston-Werner" last = "Preston-Werner"
@ -266,7 +278,9 @@ name = {
TEST_CASE("parsing - arrays-of-tables") 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 }, points = [ { x = 1, y = 2, z = 3 },
{ x = 7, y = 8, z = 9 }, { x = 7, y = 8, z = 9 },
{ x = 2, y = 4, z = 8 } ] { 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 # INVALID TOML DOC
[fruit.physical] # subtable, but to which parent element should it belong? [fruit.physical] # subtable, but to which parent element should it belong?
color = "red" color = "red"
@ -383,14 +397,14 @@ color = "gray"
name = "apple" name = "apple"
)"sv)); )"sv));
parsing_should_fail(S(R"( parsing_should_fail(FILE_LINE_ARGS, S(R"(
# INVALID TOML DOC # INVALID TOML DOC
fruit = [] fruit = []
[[fruit]] # Not allowed [[fruit]] # Not allowed
)"sv)); )"sv));
parsing_should_fail(S(R"( parsing_should_fail(FILE_LINE_ARGS, S(R"(
# INVALID TOML DOC # INVALID TOML DOC
[[fruit]] [[fruit]]
name = "apple" name = "apple"
@ -403,7 +417,7 @@ fruit = []
name = "granny smith" name = "granny smith"
)"sv)); )"sv));
parsing_should_fail(S(R"( parsing_should_fail(FILE_LINE_ARGS, S(R"(
# INVALID TOML DOC # INVALID TOML DOC
[[fruit]] [[fruit]]
name = "apple" name = "apple"

View File

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

View File

@ -25,15 +25,25 @@
#endif #endif
#endif #endif
#define FILE_LINE_ARGS std::string_view{ __FILE__ }, __LINE__
using namespace toml; using namespace toml;
using namespace Catch::literals; using namespace Catch::literals;
#define S(str) TOML_STRING_PREFIX(str) #define S(str) TOML_STRING_PREFIX(str)
template <typename Char, typename Func = std::false_type> 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&& 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> 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 #if TOML_EXCEPTIONS
@ -200,8 +216,14 @@ inline void parsing_should_fail(std::basic_string_view<Char> toml_str) noexcept
} }
template <typename T> 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; std::string val;
static constexpr auto key = "val = "sv; static constexpr auto key = "val = "sv;
val.reserve(key.length() + value_str.length()); 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>>; using value_type = impl::promoted<impl::remove_cvref_t<T>>;
value<value_type> val_parsed; value<value_type> val_parsed;
parsing_should_succeed(std::string_view{ val }, [&](table&& tbl) noexcept
{ {
CHECK(tbl.size() == 1); INFO("["sv << test_file << ", line "sv << test_line << "] "sv << "parse_expected_value: Checking inital parse"sv)
auto nv = tbl[S("val"sv)];
REQUIRE(nv);
REQUIRE(nv.as<value_type>());
REQUIRE(nv.get()->type() == impl::node_type_of<T>);
// check the raw value parsing_should_succeed(
CHECK(nv.get()->value<value_type>() == expected); test_file,
CHECK(nv.get()->value_or(T{}) == expected); test_line,
CHECK(nv.as<value_type>()->get() == expected); std::string_view{ val },
CHECK(nv.value<value_type>() == expected); [&](table&& tbl) noexcept
CHECK(nv.value_or(T{}) == expected); {
CHECK(nv.ref<value_type>() == expected); REQUIRE(tbl.size() == 1);
CHECK(nv.get()->ref<value_type>() == expected); 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 the raw value
CHECK(tbl == table{ { { S("val"sv), expected } } }); REQUIRE(nv.get()->value<value_type>() == expected);
CHECK(!(tbl != table{ { { S("val"sv), 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 the table relops
CHECK(*nv.as<value_type>() == expected); REQUIRE(tbl == table{ { { S("val"sv), expected } } });
CHECK(expected == *nv.as<value_type>()); REQUIRE(!(tbl != table{ { { S("val"sv), expected } } }));
CHECK(!(*nv.as<value_type>() != expected));
CHECK(!(expected != *nv.as<value_type>()));
// check the node_view relops // check the value relops
CHECK(nv == expected); REQUIRE(*nv.as<value_type>() == expected);
CHECK(expected == nv); REQUIRE(expected == *nv.as<value_type>());
CHECK(!(nv != expected)); REQUIRE(!(*nv.as<value_type>() != expected));
CHECK(!(expected != nv)); REQUIRE(!(expected != *nv.as<value_type>()));
// make sure source info is correct // check the node_view relops
CHECK(nv.get()->source().begin == begin); REQUIRE(nv == expected);
CHECK(nv.get()->source().end == end); REQUIRE(expected == nv);
REQUIRE(!(nv != expected));
REQUIRE(!(expected != nv));
// steal the val for round-trip tests // make sure source info is correct
val_parsed = std::move(*nv.as<value_type>()); 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 // 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::string str;
std::ostringstream ss; {
ss << tbl; auto tbl = table{ { { S("val"sv), *val_parsed } } };
str = std::move(ss).str(); 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>());
}
);
} }
CHECK(val_reparsed == val_parsed);
parsing_should_succeed(std::string_view{ str }, [&](table&& tbl) noexcept CHECK(val_reparsed == expected);
{
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);
} }
// manually instantiate some templates to reduce test compilation time (chosen using ClangBuildAnalyzer) // 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, uint32_t, 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, uint32_t, 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, uint32_t, 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, uint32_t, 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, uint32_t, 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 toml::string_view&) noexcept;
namespace std namespace std
{ {
extern template class unique_ptr<const Catch::IExceptionTranslator>; 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_arrays.cpp" />
<ClCompile Include="..\tests\manipulating_tables.cpp" /> <ClCompile Include="..\tests\manipulating_tables.cpp" />
<ClCompile Include="..\tests\manipulating_parse_result.cpp" /> <ClCompile Include="..\tests\manipulating_parse_result.cpp" />
<ClCompile Include="..\tests\manipulating_values.cpp" />
<ClCompile Include="..\tests\parsing_arrays.cpp" /> <ClCompile Include="..\tests\parsing_arrays.cpp" />
<ClCompile Include="..\tests\parsing_booleans.cpp" /> <ClCompile Include="..\tests\parsing_booleans.cpp" />
<ClCompile Include="..\tests\parsing_comments.cpp" /> <ClCompile Include="..\tests\parsing_comments.cpp" />

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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