From b05a86a4860c9cb4823ad52c3c70e4d35c0ac0df Mon Sep 17 00:00:00 2001 From: "Dr. Colin Hirsch" Date: Sat, 17 Feb 2024 17:22:15 +0100 Subject: [PATCH] More tests and check ci jobs. --- {dot.github => .github}/workflows/android.yml | 1 - .../workflows/clang-analyze.yml | 0 .../workflows/clang-format.yml | 0 .../workflows/clang-tidy.yml | 2 +- .../workflows/code-coverage.yml | 0 .../workflows/codeql-analysis.yml | 1 - {dot.github => .github}/workflows/linux.yml | 13 ++-- {dot.github => .github}/workflows/macos.yml | 12 ++++ .../workflows/sanitizer.yml | 0 {dot.github => .github}/workflows/windows.yml | 0 include/tao/pegtl/internal/analyze_traits.hpp | 46 +++++++----- include/tao/pegtl/internal/consume.hpp | 2 +- include/tao/pegtl/internal/integer_adapt.hpp | 2 + include/tao/pegtl/internal/integer_size.hpp | 8 ++- include/tao/pegtl/internal/math_utility.hpp | 20 +++--- src/test/pegtl/internal_integer_size.cpp | 33 +++++++++ src/test/pegtl/internal_math_utility.cpp | 49 +++++++++++++ src/test/pegtl/rule_partial.cpp | 26 ++++--- src/test/pegtl/rule_strict.cpp | 72 +++++++++++++++++++ 19 files changed, 238 insertions(+), 49 deletions(-) rename {dot.github => .github}/workflows/android.yml (97%) rename {dot.github => .github}/workflows/clang-analyze.yml (100%) rename {dot.github => .github}/workflows/clang-format.yml (100%) rename {dot.github => .github}/workflows/clang-tidy.yml (83%) rename {dot.github => .github}/workflows/code-coverage.yml (100%) rename {dot.github => .github}/workflows/codeql-analysis.yml (99%) rename {dot.github => .github}/workflows/linux.yml (93%) rename {dot.github => .github}/workflows/macos.yml (81%) rename {dot.github => .github}/workflows/sanitizer.yml (100%) rename {dot.github => .github}/workflows/windows.yml (100%) create mode 100644 src/test/pegtl/internal_integer_size.cpp create mode 100644 src/test/pegtl/internal_math_utility.cpp create mode 100644 src/test/pegtl/rule_strict.cpp diff --git a/dot.github/workflows/android.yml b/.github/workflows/android.yml similarity index 97% rename from dot.github/workflows/android.yml rename to .github/workflows/android.yml index 11b3c2e00..b8ea1e341 100644 --- a/dot.github/workflows/android.yml +++ b/.github/workflows/android.yml @@ -21,7 +21,6 @@ jobs: - android-27 - android-29 abi: - - armeabi-v7a - arm64-v8a build_type: [Debug, Release] diff --git a/dot.github/workflows/clang-analyze.yml b/.github/workflows/clang-analyze.yml similarity index 100% rename from dot.github/workflows/clang-analyze.yml rename to .github/workflows/clang-analyze.yml diff --git a/dot.github/workflows/clang-format.yml b/.github/workflows/clang-format.yml similarity index 100% rename from dot.github/workflows/clang-format.yml rename to .github/workflows/clang-format.yml diff --git a/dot.github/workflows/clang-tidy.yml b/.github/workflows/clang-tidy.yml similarity index 83% rename from dot.github/workflows/clang-tidy.yml rename to .github/workflows/clang-tidy.yml index d095bce35..c1fc1af82 100644 --- a/dot.github/workflows/clang-tidy.yml +++ b/.github/workflows/clang-tidy.yml @@ -21,6 +21,6 @@ jobs: - run: sudo apt-get install -yq clang-tidy - - run: find include/ -name '*.hpp' | grep -vF mmap_file_win32.hpp | grep -vF endian_win.hpp | xargs -I '{}' clang-tidy --quiet '{}' -- --std=c++17 -Iinclude + - run: find include/ -name '*.hpp' | grep -vF mmap_file_win32.hpp | grep -vF byteswap_win32.hpp | xargs -I '{}' clang-tidy --quiet '{}' -- --std=c++17 -Iinclude - run: find src/ -name '*.cpp' | xargs -I '{}' clang-tidy --quiet '{}' -- --std=c++17 -Iinclude diff --git a/dot.github/workflows/code-coverage.yml b/.github/workflows/code-coverage.yml similarity index 100% rename from dot.github/workflows/code-coverage.yml rename to .github/workflows/code-coverage.yml diff --git a/dot.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml similarity index 99% rename from dot.github/workflows/codeql-analysis.yml rename to .github/workflows/codeql-analysis.yml index 5f688f37b..755e8da39 100644 --- a/dot.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -36,7 +36,6 @@ jobs: matrix: language: [ 'cpp' ] # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ] - # Learn more: # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed steps: diff --git a/dot.github/workflows/linux.yml b/.github/workflows/linux.yml similarity index 93% rename from dot.github/workflows/linux.yml rename to .github/workflows/linux.yml index 53c5f849c..b0f52235f 100644 --- a/dot.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -16,12 +16,15 @@ jobs: fail-fast: false matrix: compiler: - - g++-9 - g++-10 - g++-11 - g++-12 + - g++-13 - clang++-13 - clang++-14 + - clang++-15 + - clang++-16 + - clang++-17 build_type: [Debug, Release] runs-on: ubuntu-latest @@ -48,12 +51,14 @@ jobs: fail-fast: false matrix: compiler: - - clang++-7 - - clang++-8 - - clang++-9 + - g++-10 + - g++-11 - clang++-10 - clang++-11 - clang++-12 + - clang++-13 + - clang++-14 + - clang++-15 build_type: [Debug, Release] runs-on: ubuntu-20.04 diff --git a/dot.github/workflows/macos.yml b/.github/workflows/macos.yml similarity index 81% rename from dot.github/workflows/macos.yml rename to .github/workflows/macos.yml index 842b1ab7c..e8967959c 100644 --- a/dot.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -40,6 +40,18 @@ jobs: - xcode: 14 build_type: Release os: macos-12 + - xcode: 15 + build_type: Debug + os: macos-13 + - xcode: 15 + build_type: Release + os: macos-13 + - xcode: 15 + build_type: Debug + os: macos-14 + - xcode: 15 + build_type: Release + os: macos-14 runs-on: ${{ matrix.os }} steps: diff --git a/dot.github/workflows/sanitizer.yml b/.github/workflows/sanitizer.yml similarity index 100% rename from dot.github/workflows/sanitizer.yml rename to .github/workflows/sanitizer.yml diff --git a/dot.github/workflows/windows.yml b/.github/workflows/windows.yml similarity index 100% rename from dot.github/workflows/windows.yml rename to .github/workflows/windows.yml diff --git a/include/tao/pegtl/internal/analyze_traits.hpp b/include/tao/pegtl/internal/analyze_traits.hpp index aa5486f06..b580c37e0 100644 --- a/include/tao/pegtl/internal/analyze_traits.hpp +++ b/include/tao/pegtl/internal/analyze_traits.hpp @@ -17,7 +17,7 @@ namespace TAO_PEGTL_NAMESPACE { template< typename Name, template< typename... > class Action, typename... Rules > struct analyze_traits< Name, internal::action< Action, Rules... > > - : analyze_traits< Name, typename internal::seq< Rules... >::rule_t > + : analyze_seq_traits< Rules... > {}; template< typename Name, typename Peek > @@ -27,7 +27,7 @@ namespace TAO_PEGTL_NAMESPACE template< typename Name, typename... Actions > struct analyze_traits< Name, internal::apply< Actions... > > - : analyze_opt_traits<> + : analyze_opt_traits<> {}; template< typename Name, typename... Actions > @@ -51,7 +51,7 @@ namespace TAO_PEGTL_NAMESPACE template< typename Name, typename... Rules > struct analyze_traits< Name, internal::at< Rules... > > - : analyze_traits< Name, typename internal::opt< Rules... >::rule_t > + : analyze_opt_traits< Rules... > {}; template< typename Name > @@ -71,17 +71,17 @@ namespace TAO_PEGTL_NAMESPACE template< typename Name, template< typename... > class Control, typename... Rules > struct analyze_traits< Name, internal::control< Control, Rules... > > - : analyze_traits< Name, typename internal::seq< Rules... >::rule_t > + : analyze_seq_traits< Rules... > {}; template< typename Name, typename... Rules > struct analyze_traits< Name, internal::disable< Rules... > > - : analyze_traits< Name, typename internal::seq< Rules... >::rule_t > + : analyze_seq_traits< Rules... > {}; template< typename Name, typename... Rules > struct analyze_traits< Name, internal::enable< Rules... > > - : analyze_traits< Name, typename internal::seq< Rules... >::rule_t > + : analyze_seq_traits< Rules... > {}; template< typename Name > @@ -128,7 +128,7 @@ namespace TAO_PEGTL_NAMESPACE template< typename Name, typename... Rules > struct analyze_traits< Name, internal::not_at< Rules... > > - : analyze_traits< Name, typename internal::opt< Rules... >::rule_t > + : analyze_opt_traits< Rules... > {}; template< typename Name, typename... Rules > @@ -153,17 +153,17 @@ namespace TAO_PEGTL_NAMESPACE template< typename Name, unsigned Cnt, typename... Rules > struct analyze_traits< Name, internal::rep< Cnt, Rules... > > - : analyze_traits< Name, std::conditional_t< ( Cnt != 0 ), typename internal::seq< Rules... >::rule_t, typename internal::opt< Rules... >::rule_t > > + : std::conditional_t< ( Cnt != 0 ), analyze_seq_traits< Rules... >, analyze_opt_traits< Rules... > > {}; template< typename Name, unsigned Min, unsigned Max, typename... Rules > struct analyze_traits< Name, internal::rep_min_max< Min, Max, Rules... > > - : analyze_traits< Name, std::conditional_t< ( Min != 0 ), typename internal::seq< Rules... >::rule_t, typename internal::opt< Rules... >::rule_t > > + : std::conditional_t< ( Min != 0 ), analyze_seq_traits< Rules... >, analyze_opt_traits< Rules... > > {}; template< typename Name, unsigned Max, typename... Rules > struct analyze_traits< Name, internal::rep_opt< Max, Rules... > > - : analyze_traits< Name, typename internal::opt< Rules... >::rule_t > + : analyze_opt_traits< Rules... > {}; template< typename Name, typename Rule, typename... Rules > @@ -178,17 +178,27 @@ namespace TAO_PEGTL_NAMESPACE template< typename Name, typename... Rules > struct analyze_traits< Name, internal::star< Rules... > > - : analyze_traits< Name, typename internal::opt< Rules..., Name >::rule_t > + : analyze_opt_traits< Rules..., Name > {}; template< typename Name, typename... Rules > struct analyze_traits< Name, internal::star_partial< Rules... > > - : analyze_traits< Name, typename internal::opt< Rules..., Name >::rule_t > + : analyze_opt_traits< Rules..., Name > + {}; + + template< typename Name, typename... Rules > + struct analyze_traits< Name, internal::star_strict< Rules... > > + : analyze_opt_traits< Rules..., Name > {}; template< typename Name, typename State, typename... Rules > struct analyze_traits< Name, internal::state< State, Rules... > > - : analyze_traits< Name, typename internal::seq< Rules... >::rule_t > + : analyze_seq_traits< Rules... > + {}; + + template< typename Name, typename... Rules > + struct analyze_traits< Name, internal::strict< Rules... > > + : analyze_opt_traits< Rules... > {}; template< typename Name > @@ -221,17 +231,17 @@ namespace TAO_PEGTL_NAMESPACE #if defined( __cpp_exceptions ) template< typename Name, typename Cond, typename... Rules > struct analyze_traits< Name, internal::if_must< true, Cond, Rules... > > - : analyze_traits< Name, typename internal::opt< Cond, Rules... >::rule_t > + : analyze_opt_traits< Cond, Rules... > {}; template< typename Name, typename Cond, typename... Rules > struct analyze_traits< Name, internal::if_must< false, Cond, Rules... > > - : analyze_traits< Name, typename internal::seq< Cond, Rules... >::rule_t > + : analyze_seq_traits< Cond, Rules... > {}; template< typename Name, typename... Rules > struct analyze_traits< Name, internal::must< Rules... > > - : analyze_traits< Name, typename internal::seq< Rules... >::rule_t > + : analyze_seq_traits< Rules... > {}; template< typename Name, typename T > @@ -241,12 +251,12 @@ namespace TAO_PEGTL_NAMESPACE template< typename Name, typename Exception, typename... Rules > struct analyze_traits< Name, internal::try_catch_raise_nested< Exception, Rules... > > - : analyze_traits< Name, typename internal::seq< Rules... >::rule_t > + : analyze_seq_traits< Rules... > {}; template< typename Name, typename Exception, typename... Rules > struct analyze_traits< Name, internal::try_catch_return_false< Exception, Rules... > > - : analyze_traits< Name, typename internal::seq< Rules... >::rule_t > + : analyze_seq_traits< Rules... > {}; #endif diff --git a/include/tao/pegtl/internal/consume.hpp b/include/tao/pegtl/internal/consume.hpp index 0d08276dd..20a72456b 100644 --- a/include/tao/pegtl/internal/consume.hpp +++ b/include/tao/pegtl/internal/consume.hpp @@ -27,7 +27,7 @@ namespace TAO_PEGTL_NAMESPACE::internal template< typename ParseInput > [[nodiscard]] static bool match( ParseInput& in ) noexcept { - static_assert( is_integer_fraction( sizeof( Reference ), sizeof( *in.current() ) ) ); + static_assert( is_divisible( sizeof( Reference ), sizeof( *in.current() ) ) ); if( in.size( Count ) >= Count ) { in.template consume< eol_unknown_tag >( Count ); diff --git a/include/tao/pegtl/internal/integer_adapt.hpp b/include/tao/pegtl/internal/integer_adapt.hpp index b715e0fb5..122d43672 100644 --- a/include/tao/pegtl/internal/integer_adapt.hpp +++ b/include/tao/pegtl/internal/integer_adapt.hpp @@ -14,6 +14,8 @@ namespace TAO_PEGTL_NAMESPACE::internal { + // TODO: Use C++20 std::bit_cast. + template< typename Type, typename Data > [[nodiscard]] Type integer_adapt( const Data* pointer ) noexcept { diff --git a/include/tao/pegtl/internal/integer_size.hpp b/include/tao/pegtl/internal/integer_size.hpp index e6a179a00..bf867e334 100644 --- a/include/tao/pegtl/internal/integer_size.hpp +++ b/include/tao/pegtl/internal/integer_size.hpp @@ -28,16 +28,18 @@ namespace TAO_PEGTL_NAMESPACE::internal return sizeof( Type ); } else { - static_assert( dependent_false< Data > ); + static_assert( dependent_false< Type, Data > ); } } template< typename Type, typename Input> [[nodiscard]] constexpr std::size_t integer_input_size() noexcept { - static_assert( std::is_same_v< typename Input::data_t, std::decay_t< decltype( *( std::declval< const Input& >().current() ) ) > > ); + using Data = typename Input::data_t; - return integer_size< Type, typename Input::data_t >(); + static_assert( std::is_same_v< Data, std::decay_t< decltype( *( std::declval< const Input& >().current() ) ) > > ); + + return integer_size< Type, Data >(); } } // namespace TAO_PEGTL_NAMESPACE::internal diff --git a/include/tao/pegtl/internal/math_utility.hpp b/include/tao/pegtl/internal/math_utility.hpp index e31ce84d6..3a0b44190 100644 --- a/include/tao/pegtl/internal/math_utility.hpp +++ b/include/tao/pegtl/internal/math_utility.hpp @@ -11,27 +11,29 @@ namespace TAO_PEGTL_NAMESPACE::internal { + [[nodiscard]] constexpr bool is_divisible( const std::size_t n, const std::size_t d ) noexcept + { + return ( n / d ) * d == n; + } + + // Here "range" is like for the range rules, i.e. including both boundaries. + template< typename Data > [[nodiscard]] constexpr bool ranges_disjoint( const Data ll, const Data lh, const Data rl, const Data rh ) noexcept { - // assert( ll < lh ); - // assert( rl < rh ); + // assert( ll <= lh ); + // assert( rl <= rh ); return ( lh < rl ) || ( rh < ll ); } template< typename Data > [[nodiscard]] constexpr bool ranges_overlap( const Data ll, const Data lh, const Data rl, const Data rh ) noexcept { - // assert( ll < lh ); - // assert( rl < rh ); + // assert( ll <= lh ); + // assert( rl <= rh ); return ( lh >= rl ) && ( rh >= ll ); } - [[nodiscard]] constexpr bool is_integer_fraction( const std::size_t n, const std::size_t d ) noexcept - { - return ( n / d ) * d == n; - } - } // namespace TAO_PEGTL_NAMESPACE::internal #endif diff --git a/src/test/pegtl/internal_integer_size.cpp b/src/test/pegtl/internal_integer_size.cpp new file mode 100644 index 000000000..75393a94f --- /dev/null +++ b/src/test/pegtl/internal_integer_size.cpp @@ -0,0 +1,33 @@ +// Copyright (c) 2024 Dr. Colin Hirsch and Daniel Frey +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) + +#include + +#include +#include + +using namespace TAO_PEGTL_NAMESPACE; + +int main() +{ + static_assert( internal::integer_size< char, char >() == 1 ); + static_assert( internal::integer_size< char, std::uint8_t >() == 1 ); + static_assert( internal::integer_size< short, std::uint16_t >() == 1 ); // Yes, I know... + static_assert( internal::integer_size< int, unsigned >() == 1 ); + static_assert( internal::integer_size< std::int32_t, char32_t >() == 1 ); + + static_assert( internal::integer_size< char32_t, char >() == sizeof( char32_t ) ); + static_assert( internal::integer_size< std::int64_t, std::byte >() == sizeof( std::int64_t ) ); + + static_assert( internal::integer_input_size< char, internal::view_input< char > >() == 1 ); + static_assert( internal::integer_input_size< char, internal::view_input< std::uint8_t > >() == 1 ); + static_assert( internal::integer_input_size< short, internal::view_input< std::uint16_t > >() == 1 ); // Yes, I know... + static_assert( internal::integer_input_size< int, internal::view_input< unsigned > >() == 1 ); + static_assert( internal::integer_input_size< std::int32_t, internal::view_input< char32_t > >() == 1 ); + + static_assert( internal::integer_input_size< char32_t, internal::view_input< char > >() == sizeof( char32_t ) ); + static_assert( internal::integer_input_size< std::int64_t, internal::view_input< std::byte > >() == sizeof( std::int64_t ) ); + + return 0; +} diff --git a/src/test/pegtl/internal_math_utility.cpp b/src/test/pegtl/internal_math_utility.cpp new file mode 100644 index 000000000..c007d9bb1 --- /dev/null +++ b/src/test/pegtl/internal_math_utility.cpp @@ -0,0 +1,49 @@ +// Copyright (c) 2024 Dr. Colin Hirsch and Daniel Frey +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) + +#include + +using namespace TAO_PEGTL_NAMESPACE; + +int main() +{ + static_assert( internal::is_divisible( 4, 1 ) ); + static_assert( internal::is_divisible( 4, 2 ) ); + static_assert( internal::is_divisible( 40, 40 ) ); + static_assert( internal::is_divisible( 400, 20 ) ); + + static_assert( !internal::is_divisible( 1, 2 ) ); + static_assert( !internal::is_divisible( 20, 400 ) ); + static_assert( !internal::is_divisible( 21, 14 ) ); + + static_assert( internal::ranges_disjoint( 10, 20, 30, 40 ) ); + static_assert( internal::ranges_disjoint( 30, 40, 10, 20 ) ); + static_assert( internal::ranges_disjoint( 10, 20, 21, 40 ) ); + static_assert( internal::ranges_disjoint( 21, 40, 10, 20 ) ); + + static_assert( !internal::ranges_overlap( 10, 20, 30, 40 ) ); + static_assert( !internal::ranges_overlap( 30, 40, 10, 20 ) ); + static_assert( !internal::ranges_overlap( 10, 20, 21, 40 ) ); + static_assert( !internal::ranges_overlap( 21, 40, 10, 20 ) ); + + static_assert( internal::ranges_overlap( 10, 20, 10, 10 ) ); + static_assert( internal::ranges_overlap( 10, 20, 20, 20 ) ); + static_assert( internal::ranges_overlap( 10, 20, 15, 20 ) ); + static_assert( internal::ranges_overlap( 10, 20, 10, 15 ) ); + static_assert( internal::ranges_overlap( 10, 30, 20, 40 ) ); + static_assert( internal::ranges_overlap( 20, 40, 10, 30 ) ); + static_assert( internal::ranges_overlap( 10, 30, 30, 40 ) ); + static_assert( internal::ranges_overlap( 30, 40, 10, 30 ) ); + + static_assert( !internal::ranges_disjoint( 10, 20, 10, 10 ) ); + static_assert( !internal::ranges_disjoint( 10, 20, 20, 20 ) ); + static_assert( !internal::ranges_disjoint( 10, 20, 15, 20 ) ); + static_assert( !internal::ranges_disjoint( 10, 20, 10, 15 ) ); + static_assert( !internal::ranges_disjoint( 10, 30, 20, 40 ) ); + static_assert( !internal::ranges_disjoint( 20, 40, 10, 30 ) ); + static_assert( !internal::ranges_disjoint( 10, 30, 30, 40 ) ); + static_assert( !internal::ranges_disjoint( 30, 40, 10, 30 ) ); + + return 0; +} diff --git a/src/test/pegtl/rule_partial.cpp b/src/test/pegtl/rule_partial.cpp index 60a891955..6161eacb3 100644 --- a/src/test/pegtl/rule_partial.cpp +++ b/src/test/pegtl/rule_partial.cpp @@ -16,7 +16,7 @@ namespace TAO_PEGTL_NAMESPACE template<> struct my_action< eof > { - static void apply0( bool& b ) + static void apply0( bool& b ) noexcept { b = true; } @@ -30,30 +30,34 @@ namespace TAO_PEGTL_NAMESPACE verify_analyze< partial< any > >( __LINE__, __FILE__, false, false ); verify_analyze< partial< eof > >( __LINE__, __FILE__, false, false ); - verify_rule< partial< one< 'a' > > >( __LINE__, __FILE__, "", result_type::success, 0 ); - verify_rule< partial< one< 'a' > > >( __LINE__, __FILE__, "a", result_type::success, 0 ); + verify_rule< partial< one< 'a' > > >( __LINE__, __FILE__, "", result_type::success ); + verify_rule< partial< one< 'a' > > >( __LINE__, __FILE__, "a", result_type::success ); + verify_rule< partial< one< 'a' > > >( __LINE__, __FILE__, "b", result_type::success, 1 ); + verify_rule< partial< one< 'a' > > >( __LINE__, __FILE__, "bb", result_type::success, 2 ); verify_rule< partial< one< 'a' > > >( __LINE__, __FILE__, "aa", result_type::success, 1 ); verify_rule< partial< one< 'a' > > >( __LINE__, __FILE__, "ab", result_type::success, 1 ); verify_rule< partial< one< 'a' > > >( __LINE__, __FILE__, "ba", result_type::success, 2 ); - verify_rule< partial< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "", result_type::success, 0 ); - verify_rule< partial< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "a", result_type::success, 0 ); - verify_rule< partial< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "ab", result_type::success, 0 ); + verify_rule< partial< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "", result_type::success ); + verify_rule< partial< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "a", result_type::success ); + verify_rule< partial< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "ab", result_type::success ); verify_rule< partial< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "aba", result_type::success, 1 ); verify_rule< partial< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "abab", result_type::success, 2 ); verify_rule< partial< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "bab", result_type::success, 3 ); verify_rule< partial< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "cb", result_type::success, 2 ); #if defined( __cpp_exceptions ) - verify_rule< must< partial< one< 'a' > > > >( __LINE__, __FILE__, "", result_type::success, 0 ); - verify_rule< must< partial< one< 'a' > > > >( __LINE__, __FILE__, "a", result_type::success, 0 ); + verify_rule< must< partial< one< 'a' > > > >( __LINE__, __FILE__, "", result_type::success ); + verify_rule< must< partial< one< 'a' > > > >( __LINE__, __FILE__, "a", result_type::success ); verify_rule< must< partial< one< 'a' > > > >( __LINE__, __FILE__, "aa", result_type::success, 1 ); verify_rule< must< partial< one< 'a' > > > >( __LINE__, __FILE__, "ab", result_type::success, 1 ); verify_rule< must< partial< one< 'a' > > > >( __LINE__, __FILE__, "ba", result_type::success, 2 ); - verify_rule< must< partial< one< 'a' >, one< 'b' > > > >( __LINE__, __FILE__, "", result_type::success, 0 ); - verify_rule< must< partial< one< 'a' >, one< 'b' > > > >( __LINE__, __FILE__, "a", result_type::success, 0 ); - verify_rule< must< partial< one< 'a' >, one< 'b' > > > >( __LINE__, __FILE__, "ab", result_type::success, 0 ); + verify_rule< must< partial< one< 'a' >, one< 'b' > > > >( __LINE__, __FILE__, "", result_type::success ); + verify_rule< must< partial< one< 'a' >, one< 'b' > > > >( __LINE__, __FILE__, "a", result_type::success ); + verify_rule< must< partial< one< 'a' >, one< 'b' > > > >( __LINE__, __FILE__, "b", result_type::success, 1 ); + verify_rule< must< partial< one< 'a' >, one< 'b' > > > >( __LINE__, __FILE__, "bb", result_type::success, 2 ); + verify_rule< must< partial< one< 'a' >, one< 'b' > > > >( __LINE__, __FILE__, "ab", result_type::success ); verify_rule< must< partial< one< 'a' >, one< 'b' > > > >( __LINE__, __FILE__, "aba", result_type::success, 1 ); verify_rule< must< partial< one< 'a' >, one< 'b' > > > >( __LINE__, __FILE__, "abab", result_type::success, 2 ); verify_rule< must< partial< one< 'a' >, one< 'b' > > > >( __LINE__, __FILE__, "bab", result_type::success, 3 ); diff --git a/src/test/pegtl/rule_strict.cpp b/src/test/pegtl/rule_strict.cpp new file mode 100644 index 000000000..39af58bd2 --- /dev/null +++ b/src/test/pegtl/rule_strict.cpp @@ -0,0 +1,72 @@ +// Copyright (c) 2024 Dr. Colin Hirsch and Daniel Frey +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) + +#include "test.hpp" +#include "test_utility.hpp" +#include "verify_meta.hpp" +#include "verify_rule.hpp" + +namespace TAO_PEGTL_NAMESPACE +{ + template< typename Rule > + struct my_action + {}; + + template<> + struct my_action< eof > + { + static void apply0( bool& b ) noexcept + { + b = true; + } + }; + + void unit_test() + { + verify_meta< strict< eof >, internal::strict< eof >, eof >(); + verify_meta< strict< eof, any >, internal::strict< eof, any >, eof, any >(); + + verify_analyze< strict< any > >( __LINE__, __FILE__, false, false ); + verify_analyze< strict< eof > >( __LINE__, __FILE__, false, false ); + + verify_rule< strict< one< 'a' > > >( __LINE__, __FILE__, "", result_type::success ); + verify_rule< strict< one< 'a' > > >( __LINE__, __FILE__, "a", result_type::success ); + verify_rule< strict< one< 'a' > > >( __LINE__, __FILE__, "b", result_type::success, 1 ); + verify_rule< strict< one< 'a' > > >( __LINE__, __FILE__, "aa", result_type::success, 1 ); + verify_rule< strict< one< 'a' > > >( __LINE__, __FILE__, "ab", result_type::success, 1 ); + verify_rule< strict< one< 'a' > > >( __LINE__, __FILE__, "ba", result_type::success, 2 ); + + verify_rule< strict< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "", result_type::success ); + verify_rule< strict< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "a", result_type::local_failure ); + verify_rule< strict< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "b", result_type::success, 1 ); + verify_rule< strict< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "ab", result_type::success ); + verify_rule< strict< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "aba", result_type::success, 1 ); + verify_rule< strict< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "abab", result_type::success, 2 ); + verify_rule< strict< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "bab", result_type::success, 3 ); + verify_rule< strict< one< 'a' >, one< 'b' > > >( __LINE__, __FILE__, "cb", result_type::success, 2 ); + +#if defined( __cpp_exceptions ) + verify_rule< must< strict< one< 'a' > > > >( __LINE__, __FILE__, "", result_type::success ); + verify_rule< must< strict< one< 'a' > > > >( __LINE__, __FILE__, "a", result_type::success ); + verify_rule< must< strict< one< 'a' > > > >( __LINE__, __FILE__, "aa", result_type::success, 1 ); + verify_rule< must< strict< one< 'a' > > > >( __LINE__, __FILE__, "ab", result_type::success, 1 ); + verify_rule< must< strict< one< 'a' > > > >( __LINE__, __FILE__, "ba", result_type::success, 2 ); + + verify_rule< must< strict< one< 'a' >, one< 'b' > > > >( __LINE__, __FILE__, "", result_type::success ); + verify_rule< must< strict< one< 'a' >, one< 'b' > > > >( __LINE__, __FILE__, "a", result_type::global_failure ); + verify_rule< must< strict< one< 'a' >, one< 'b' > > > >( __LINE__, __FILE__, "ab", result_type::success ); + verify_rule< must< strict< one< 'a' >, one< 'b' > > > >( __LINE__, __FILE__, "aba", result_type::success, 1 ); + verify_rule< must< strict< one< 'a' >, one< 'b' > > > >( __LINE__, __FILE__, "abab", result_type::success, 2 ); + verify_rule< must< strict< one< 'a' >, one< 'b' > > > >( __LINE__, __FILE__, "bab", result_type::success, 3 ); + verify_rule< must< strict< one< 'a' >, one< 'b' > > > >( __LINE__, __FILE__, "cb", result_type::success, 2 ); +#endif + + bool success = false; + TAO_PEGTL_TEST_ASSERT( parse< strict< eof >, my_action >( text_view_input< scan::lf >( "" ), success ) ); + TAO_PEGTL_TEST_ASSERT( success ); + } + +} // namespace TAO_PEGTL_NAMESPACE + +#include "main.hpp"