diff --git a/doc/Changelog.md b/doc/Changelog.md index 640a2c4..a7af80d 100644 --- a/doc/Changelog.md +++ b/doc/Changelog.md @@ -8,8 +8,9 @@ Pre-1.0.0 milestones in rough reverse chronological order. +* Restrict some phase 1 features[^1]. +* Make functions[^2] a phase 2 features. * Remove schema support (temporarily?). -* Integrate value extensions with phase 2. * Reduce member extensions to the essentials. * Remove the minus token from config keys. * Change the semantics of star and move evaluation to phase two. @@ -27,5 +28,7 @@ Development of taoCONFIG started in September 2018 to provide a more expressive Copyright (c) 2018-2024 Dr. Colin Hirsch and Daniel Frey +[^1]: Previously "member extensions". +[^2]: Previously "value extensions". [JAXN]: https://github.com/stand-art/jaxn [JSON]: https://tools.ietf.org/html/rfc8259 diff --git a/include/tao/config/internal/phase2_access.hpp b/include/tao/config/internal/phase2_access.hpp index 453ee12..c1c5842 100644 --- a/include/tao/config/internal/phase2_access.hpp +++ b/include/tao/config/internal/phase2_access.hpp @@ -129,13 +129,13 @@ namespace tao::config::internal [[nodiscard]] inline const concat* phase2_access( const concat& c, const key1& suffix, const int down ) { - if( suffix.empty() ) { - if( ( c.concat.size() < 2 ) && ( statistics( c ).references() == 0 ) ) { - return &c; - } - throw phase2_access_return(); + if( !suffix.empty() ) { + return phase2_access( c, suffix.at( 0 ), pop_front( suffix ), down ); + } + if( statistics( c ).is_primitive() ) { + return &c; } - return phase2_access( c, suffix.at( 0 ), pop_front( suffix ), down ); + throw phase2_access_return(); } [[nodiscard]] inline const concat* phase2_access( const object& o, const key1& prefix, const key1& suffix ) diff --git a/include/tao/config/internal/phase2_guard.hpp b/include/tao/config/internal/phase2_guard.hpp deleted file mode 100644 index a85a656..0000000 --- a/include/tao/config/internal/phase2_guard.hpp +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright (c) 2019-2024 Dr. Colin Hirsch and Daniel Frey -// Please see LICENSE for license or visit https://github.com/taocpp/config/ - -#ifndef TAO_CONFIG_INTERNAL_PHASE2_GUARD_HPP -#define TAO_CONFIG_INTERNAL_PHASE2_GUARD_HPP - -#include -#include -#include - -#include "pegtl.hpp" - -namespace tao::config::internal -{ - class [[nodiscard]] phase2_guard - { - public: - template< typename T > - phase2_guard( std::set< const void* >& stack, T& thing ) - : m_stack( stack ), - m_thing( &thing ) - { - if( !m_stack.insert( m_thing ).second ) { - throw pegtl::parse_error( "reference cycle detected", thing.position ); - } - } - - phase2_guard( phase2_guard&& ) = delete; - phase2_guard( const phase2_guard& ) = delete; - - ~phase2_guard() - { - const std::size_t count = m_stack.erase( m_thing ); - assert( count == 1 ); - (void)count; - } - - void operator=( phase2_guard&& ) = delete; - void operator=( const phase2_guard& ) = delete; - - private: - std::set< const void* >& m_stack; - const void* m_thing; - }; - -} // namespace tao::config::internal - -#endif diff --git a/include/tao/config/internal/phase2_references.hpp b/include/tao/config/internal/phase2_references.hpp index 814db55..8b68713 100644 --- a/include/tao/config/internal/phase2_references.hpp +++ b/include/tao/config/internal/phase2_references.hpp @@ -18,7 +18,6 @@ #include "json.hpp" #include "object.hpp" #include "phase2_access.hpp" -#include "phase2_guard.hpp" #include "string_utility.hpp" namespace tao::config::internal @@ -31,24 +30,18 @@ namespace tao::config::internal [[nodiscard]] std::size_t process() { - assert( m_stack.empty() ); - for( auto& p : m_root.object ) { process_concat( key1{ key1_part( p.first, m_root.position ) }, p.second ); } - assert( m_stack.empty() ); return m_changes; } private: object& m_root; std::size_t m_changes = 0; - std::set< const void* > m_stack; void process_concat( const key1& prefix, concat& c ) { - const phase2_guard dog( m_stack, c ); - for( auto& e : c.concat ) { if( const concat* d = process_entry( prefix, e ); d != nullptr ) { assert( d != &c ); // TODO: This needs to be ensured elsewhere/in another way. @@ -89,7 +82,7 @@ namespace tao::config::internal } assert( !prefix.empty() ); - return phase2_access( m_root, pop_back( prefix ), suffix ); + return phase2_access( m_root, pop_back( prefix ), suffix ); // Returns nullptr if not primitive. } [[nodiscard]] std::optional< key1_part > process_inner_reference( const key1& prefix, const std::vector< reference2_part >& reference ) @@ -142,7 +135,6 @@ namespace tao::config::internal } return nullptr; case entry_kind::ASTERISK: - // process_concat( prefix + key1_part( part_asterisk, m_root.position ), e.get_concat() ); return nullptr; case entry_kind::REFERENCE: return process_reference_parts( prefix, e.get_reference() ); diff --git a/src/test/config/value.cpp b/src/test/config/value.cpp index f7f4187..79a3698 100644 --- a/src/test/config/value.cpp +++ b/src/test/config/value.cpp @@ -18,7 +18,7 @@ namespace tao::config try { (void)v.as< std::string >(); - ++failed; + ++failed; // LCOV_EXCL_LINE } catch( const std::exception& e ) { TAO_CONFIG_TEST_ASSERT( e.what() == s ); diff --git a/tests/extensions.jaxn b/tests/extensions.jaxn index 885fa4c..8a28a74 100644 --- a/tests/extensions.jaxn +++ b/tests/extensions.jaxn @@ -36,5 +36,10 @@ a: "", b: "foo", c: "01" + }, + unready: { + a: "env_value", + b: "env_value", + c: "env_value" } } diff --git a/tests/extensions.success b/tests/extensions.success index a8cd6d5..9714e2f 100644 --- a/tests/extensions.success +++ b/tests/extensions.success @@ -33,3 +33,10 @@ string b = (string "foo") c = (string $3031) } + +unready +{ + a = (env "TAO_CONFIG") + b = (default (a) (c)) + c = (env "TAO_CONFIG") +}