diff --git a/examples/meson.build b/examples/meson.build index b300df9..a815dc1 100644 --- a/examples/meson.build +++ b/examples/meson.build @@ -1,6 +1,6 @@ -parse_file = executable( - 'parse_file', - [ 'parse_file.cpp' ], +simple_parser = executable( + 'simple_parser', + [ 'simple_parser.cpp' ], include_directories : inc ) @@ -9,3 +9,9 @@ toml_to_json_transcoder = executable( [ 'toml_to_json_transcoder.cpp' ], include_directories : inc ) + +toml_generator = executable( + 'toml_generator', + [ 'toml_generator.cpp' ], + include_directories : inc +) diff --git a/examples/parse_file.cpp b/examples/simple_parser.cpp similarity index 86% rename from examples/parse_file.cpp rename to examples/simple_parser.cpp index ed7554d..3bdc009 100644 --- a/examples/parse_file.cpp +++ b/examples/simple_parser.cpp @@ -4,8 +4,8 @@ // SPDX-License-Identifier: MIT /* - This example demonstrates how to use the toml::json_formatter to - re-serialize TOML data as JSON. + This example demonstrates how to parse TOML from a file and + re-serialize it (print it out) to stdout. */ #include @@ -29,7 +29,7 @@ int main(int argc, char** argv) try { const auto tbl = toml::parse(file, std::move(path)); - std::cout << tbl << std::endl; + //std::cout << tbl << std::endl; } catch (const toml::parse_error& err) { diff --git a/examples/toml_generator.cpp b/examples/toml_generator.cpp new file mode 100644 index 0000000..c77f13c --- /dev/null +++ b/examples/toml_generator.cpp @@ -0,0 +1,203 @@ +// This file is a part of toml++ and is subject to the the terms of the MIT license. +// Copyright (c) 2019-2020 Mark Gillard +// See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text. +// SPDX-License-Identifier: MIT +/* + + This example demonstrates some slightly advanced techniques + being used to randomly generate a tree of TOML data. + +*/ +#include +#include +#include +#include +#include "utf8_console.h" +#define TOML_UNRELEASED_FEATURES 1 +#include +using namespace std::string_view_literals; + +namespace +{ + inline constexpr auto words = std::array + { + "acceptable"sv, "contain"sv, "ghost"sv, "mark"sv, "respect"sv, "taboo"sv, + "actually"sv, "cream"sv, "gleaming"sv, "meaty"sv, "rest"sv, "tacky"sv, + "addition"sv, "creature"sv, "glorious"sv, "memory"sv, "rice"sv, "tank"sv, + "adhesive"sv, "crime"sv, "gold"sv, "messy"sv, "rich"sv, "tent"sv, + "adorable"sv, "cross"sv, "grandfather"sv, "miss"sv, "righteous"sv, "terrible"sv, + "advise"sv, "crowded"sv, "gusty"sv, "modern"sv, "room"sv, "threatening"sv, + "afraid"sv, "crown"sv, "haircut"sv, "morning"sv, "rotten"sv, "three"sv, + "ancient"sv, "cure"sv, "hard-to-find"sv, "naughty"sv, "royal"sv, "ticket"sv, + "anxious"sv, "curious"sv, "harm"sv, "neck"sv, "run"sv, "title"sv, + "aromatic"sv, "curtain"sv, "heavy"sv, "night"sv, "satisfy"sv, "torpid"sv, + "attempt"sv, "cycle"sv, "helpless"sv, "nondescript"sv, "scary"sv, "train"sv, + "babies"sv, "deadpan"sv, "high-pitched"sv, "overjoyed"sv, "scatter"sv, "umbrella"sv, + "bake"sv, "decisive"sv, "hilarious"sv, "page"sv, "scene"sv, "unadvised"sv, + "ball"sv, "deeply"sv, "history"sv, "partner"sv, "scintillating"sv, "unbecoming"sv, + "bat"sv, "delightful"sv, "hook"sv, "party"sv, "self"sv, "unbiased"sv, + "behave"sv, "deserted"sv, "ignore"sv, "pause"sv, "selfish"sv, "unite"sv, + "best"sv, "draconian"sv, "imperfect"sv, "pear"sv, "silky"sv, "uptight"sv, + "birds"sv, "dreary"sv, "impossible"sv, "picture"sv, "sisters"sv, "used"sv, + "blind"sv, "dull"sv, "incandescent"sv, "place"sv, "ski"sv, "vengeful"sv, + "blood"sv, "enthusiastic"sv, "influence"sv, "playground"sv, "skip"sv, "versed"sv, + "blue-eyed"sv, "equable"sv, "innocent"sv, "popcorn"sv, "snow"sv, "vessel"sv, + "boiling"sv, "excuse"sv, "insidious"sv, "prefer"sv, "soap"sv, "view"sv, + "bore"sv, "experience"sv, "itch"sv, "productive"sv, "spare"sv, "voyage"sv, + "borrow"sv, "fabulous"sv, "jail"sv, "profuse"sv, "spicy"sv, "wall"sv, + "broken"sv, "familiar"sv, "kindhearted"sv, "protective"sv, "spiritual"sv, "want"sv, + "capable"sv, "finger"sv, "lackadaisical"sv, "pumped"sv, "sprout"sv, "weary"sv, + "charming"sv, "finicky"sv, "laughable"sv, "rabbit"sv, "squirrel"sv, "week"sv, + "cheerful"sv, "fix"sv, "leather"sv, "rapid"sv, "stale"sv, "whip"sv, + "chubby"sv, "flagrant"sv, "legal"sv, "regret"sv, "step"sv, "wilderness"sv, + "clean"sv, "flat"sv, "lewd"sv, "reject"sv, "stingy"sv, "wistful"sv, + "close"sv, "flimsy"sv, "license"sv, "rejoice"sv, "string"sv, "worried"sv, + "cobweb"sv, "fuel"sv, "light"sv, "relation"sv, "sulky"sv, "wretched"sv, + "complex"sv, "furtive"sv, "march"sv, "remarkable"sv, "surprise"sv, "zealous"sv, + "consist"sv, "geese"sv + }; + + template + [[nodiscard]] + static T rand(T excl_max) noexcept + { + return static_cast(static_cast(::rand()) % excl_max); + } + + template + [[nodiscard]] + static T rand(T incl_min, T excl_max) noexcept + { + return static_cast(incl_min + rand(excl_max - incl_min)); + } + + static auto rand_date() noexcept + { + return toml::date + { + rand(uint16_t{ 1900 }, uint16_t{ 2021 }), + rand(uint8_t{ 1 }, uint8_t{ 13 }), + rand(uint8_t{ 1 }, uint8_t{ 29 }) + }; + } + + static auto rand_time() noexcept + { + return toml::time + { + rand(uint8_t{ 24 }), + rand(uint8_t{ 60 }), + rand(uint8_t{ 60 }), + rand(100) > 80 ? rand(1000000000u) : 0u + }; + } + + static auto rand_string(size_t word_count, char sep = ' ') noexcept + { + std::string val; + while (word_count-- > 0u) + { + if (!val.empty()) + val += sep; + val.append(words[rand(words.size())]); + } + return val; + } +} + + +int main(int argc, char** argv) +{ + init_utf8_console(); + srand(static_cast(time(nullptr))); + + size_t node_budget = 100u; + for (int i = 1; i < argc; i++) + if (std::string_view{ argv[i] } == "--many"sv) + node_budget *= 100u; + + toml::table root; + std::vector tree; + tree.push_back(&root); + constexpr size_t max_depth = 10u; + int container_min_values = 10; + + const auto add = [&](auto&& obj) noexcept -> toml::node& + { + toml::node* new_node{}; + + if (auto arr = tree.back()->as_array()) + new_node = &arr->push_back(std::forward(obj)); + else + new_node = &(*tree.back()->ref().insert_or_assign( + rand_string(rand(1u, 4u), '-'), + std::forward(obj) + ).first).value; + + if constexpr (toml::is_array || toml::is_table) + { + tree.push_back(new_node); + container_min_values = rand(2, 6); + } + else + container_min_values--; + + node_budget--; + return *new_node; + }; + + while (node_budget) + { + if (rand(100) >= 75) + { + if (container_min_values <= 0 && tree.size() < max_depth) + add(toml::table{}).ref().is_inline(tree.size() >= max_depth - 2u && rand(100) >= 70); + } + else + { + switch (static_cast((rand() % 8) + 2)) + { + case toml::node_type::array: + if (container_min_values <= 0 && tree.size() < max_depth) + add(toml::array{}); + break; + + case toml::node_type::string: + add(rand_string(rand(8u))); + break; + + case toml::node_type::integer: + add(rand()); + break; + + case toml::node_type::floating_point: + add(rand(10001u) / 10000.0); + break; + + case toml::node_type::boolean: + add(!rand(2u)); + break; + + case toml::node_type::date: + add(rand_date()); + break; + + case toml::node_type::time: + add(rand_time()); + break; + + case toml::node_type::date_time: + add(rand(100) >= 75 + ? toml::date_time{ rand_date(), rand_time() } + : toml::date_time{ rand_date(), rand_time(), toml::time_offset{ rand(-11, 12), rand(-45, +46) } } + ); + break; + } + if (container_min_values <= 0 && tree.size() >= 2u && rand(100) >= 85) + tree.pop_back(); + } + } + + std::cout << root << std::endl; + return 0; +} diff --git a/examples/toml_to_json_transcoder.cpp b/examples/toml_to_json_transcoder.cpp index 1a688cd..fb5f074 100644 --- a/examples/toml_to_json_transcoder.cpp +++ b/examples/toml_to_json_transcoder.cpp @@ -4,8 +4,8 @@ // SPDX-License-Identifier: MIT /* - This example demonstrates how to parse TOML from a file and - re-serialize it (print it out) to stdout. + This example demonstrates how to use the toml::json_formatter to + re-serialize TOML data as JSON. */ #include diff --git a/vs/parse_file.vcxproj b/vs/simple_parser.vcxproj similarity index 97% rename from vs/parse_file.vcxproj rename to vs/simple_parser.vcxproj index d9ce805..a333a95 100644 --- a/vs/parse_file.vcxproj +++ b/vs/simple_parser.vcxproj @@ -59,7 +59,7 @@ $(SolutionDir)..\examples\ - + diff --git a/vs/toml++.sln b/vs/toml++.sln index 1d9f150..8cc745c 100644 --- a/vs/toml++.sln +++ b/vs/toml++.sln @@ -25,8 +25,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_char8_strict_noexcept" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "examples", "examples", "{412816A5-9D22-4A30-BCDF-ABFB54BB3735}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "parse_file", "parse_file.vcxproj", "{259FCEE5-3442-4076-9547-2BA793ECA1CB}" -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "toml_to_json_transcoder", "toml_to_json_transcoder.vcxproj", "{BE34AA99-BEE6-4B50-B237-217E7C88FCB5}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_x86_char", "test_x86_char.vcxproj", "{150FA82E-0E9F-4449-82A6-811BFFE6B5FE}" @@ -45,6 +43,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_x86_char8_strict", "te EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_x86_char8_strict_noexcept", "test_x86_char8_strict_noexcept.vcxproj", "{0CAD095A-C9F2-49FC-9C9F-4508498BE488}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "simple_parser", "simple_parser.vcxproj", "{259FCEE5-3442-4076-9547-2BA793ECA1CB}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "toml_generator", "toml_generator.vcxproj", "{23CE3B73-FEE7-436C-9B4E-3DFB202EE9A2}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 @@ -125,14 +127,6 @@ Global {9ADB61D3-FDFA-4A9C-A34F-663007BB70F6}.Release|Win32.Build.0 = Release|x64 {9ADB61D3-FDFA-4A9C-A34F-663007BB70F6}.Release|x64.ActiveCfg = Release|x64 {9ADB61D3-FDFA-4A9C-A34F-663007BB70F6}.Release|x64.Build.0 = Release|x64 - {259FCEE5-3442-4076-9547-2BA793ECA1CB}.Debug|Win32.ActiveCfg = Debug|Win32 - {259FCEE5-3442-4076-9547-2BA793ECA1CB}.Debug|Win32.Build.0 = Debug|Win32 - {259FCEE5-3442-4076-9547-2BA793ECA1CB}.Debug|x64.ActiveCfg = Debug|x64 - {259FCEE5-3442-4076-9547-2BA793ECA1CB}.Debug|x64.Build.0 = Debug|x64 - {259FCEE5-3442-4076-9547-2BA793ECA1CB}.Release|Win32.ActiveCfg = Release|Win32 - {259FCEE5-3442-4076-9547-2BA793ECA1CB}.Release|Win32.Build.0 = Release|Win32 - {259FCEE5-3442-4076-9547-2BA793ECA1CB}.Release|x64.ActiveCfg = Release|x64 - {259FCEE5-3442-4076-9547-2BA793ECA1CB}.Release|x64.Build.0 = Release|x64 {BE34AA99-BEE6-4B50-B237-217E7C88FCB5}.Debug|Win32.ActiveCfg = Debug|Win32 {BE34AA99-BEE6-4B50-B237-217E7C88FCB5}.Debug|Win32.Build.0 = Debug|Win32 {BE34AA99-BEE6-4B50-B237-217E7C88FCB5}.Debug|x64.ActiveCfg = Debug|x64 @@ -205,6 +199,22 @@ Global {0CAD095A-C9F2-49FC-9C9F-4508498BE488}.Release|Win32.Build.0 = Release|Win32 {0CAD095A-C9F2-49FC-9C9F-4508498BE488}.Release|x64.ActiveCfg = Release|Win32 {0CAD095A-C9F2-49FC-9C9F-4508498BE488}.Release|x64.Build.0 = Release|Win32 + {259FCEE5-3442-4076-9547-2BA793ECA1CB}.Debug|Win32.ActiveCfg = Debug|Win32 + {259FCEE5-3442-4076-9547-2BA793ECA1CB}.Debug|Win32.Build.0 = Debug|Win32 + {259FCEE5-3442-4076-9547-2BA793ECA1CB}.Debug|x64.ActiveCfg = Debug|x64 + {259FCEE5-3442-4076-9547-2BA793ECA1CB}.Debug|x64.Build.0 = Debug|x64 + {259FCEE5-3442-4076-9547-2BA793ECA1CB}.Release|Win32.ActiveCfg = Release|Win32 + {259FCEE5-3442-4076-9547-2BA793ECA1CB}.Release|Win32.Build.0 = Release|Win32 + {259FCEE5-3442-4076-9547-2BA793ECA1CB}.Release|x64.ActiveCfg = Release|x64 + {259FCEE5-3442-4076-9547-2BA793ECA1CB}.Release|x64.Build.0 = Release|x64 + {23CE3B73-FEE7-436C-9B4E-3DFB202EE9A2}.Debug|Win32.ActiveCfg = Debug|Win32 + {23CE3B73-FEE7-436C-9B4E-3DFB202EE9A2}.Debug|Win32.Build.0 = Debug|Win32 + {23CE3B73-FEE7-436C-9B4E-3DFB202EE9A2}.Debug|x64.ActiveCfg = Debug|x64 + {23CE3B73-FEE7-436C-9B4E-3DFB202EE9A2}.Debug|x64.Build.0 = Debug|x64 + {23CE3B73-FEE7-436C-9B4E-3DFB202EE9A2}.Release|Win32.ActiveCfg = Release|Win32 + {23CE3B73-FEE7-436C-9B4E-3DFB202EE9A2}.Release|Win32.Build.0 = Release|Win32 + {23CE3B73-FEE7-436C-9B4E-3DFB202EE9A2}.Release|x64.ActiveCfg = Release|x64 + {23CE3B73-FEE7-436C-9B4E-3DFB202EE9A2}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -218,7 +228,6 @@ Global {F05F8C1B-7E23-4147-901E-AD91092E5752} = {4E25CF88-D7D8-4A9C-A52E-0D78281E82EC} {EAC419E9-0C72-4625-B2B9-E879F697021A} = {4E25CF88-D7D8-4A9C-A52E-0D78281E82EC} {9ADB61D3-FDFA-4A9C-A34F-663007BB70F6} = {4E25CF88-D7D8-4A9C-A52E-0D78281E82EC} - {259FCEE5-3442-4076-9547-2BA793ECA1CB} = {412816A5-9D22-4A30-BCDF-ABFB54BB3735} {BE34AA99-BEE6-4B50-B237-217E7C88FCB5} = {412816A5-9D22-4A30-BCDF-ABFB54BB3735} {150FA82E-0E9F-4449-82A6-811BFFE6B5FE} = {4E25CF88-D7D8-4A9C-A52E-0D78281E82EC} {54DD1412-20C0-4700-96D7-3FD445E70996} = {4E25CF88-D7D8-4A9C-A52E-0D78281E82EC} @@ -228,6 +237,8 @@ Global {0BBEE569-536D-452C-808C-61843FECCC7E} = {4E25CF88-D7D8-4A9C-A52E-0D78281E82EC} {A4F27C6F-601D-45C0-9F81-7C100BD93B9A} = {4E25CF88-D7D8-4A9C-A52E-0D78281E82EC} {0CAD095A-C9F2-49FC-9C9F-4508498BE488} = {4E25CF88-D7D8-4A9C-A52E-0D78281E82EC} + {259FCEE5-3442-4076-9547-2BA793ECA1CB} = {412816A5-9D22-4A30-BCDF-ABFB54BB3735} + {23CE3B73-FEE7-436C-9B4E-3DFB202EE9A2} = {412816A5-9D22-4A30-BCDF-ABFB54BB3735} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {0926DDCC-88CD-4839-A82D-D9B99E02A0B1} diff --git a/vs/toml_generator.vcxproj b/vs/toml_generator.vcxproj new file mode 100644 index 0000000..e412e8d --- /dev/null +++ b/vs/toml_generator.vcxproj @@ -0,0 +1,69 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + {23CE3B73-FEE7-436C-9B4E-3DFB202EE9A2} + 10.0 + toml_generator + + + + Application + true + v142 + MultiByte + + + Application + false + v142 + true + MultiByte + + + Application + true + v142 + MultiByte + + + Application + false + v142 + true + MultiByte + + + + + + + + $(SolutionDir)..\examples\ + + + + + + + + + \ No newline at end of file