diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8c104347..f5be324a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -4,7 +4,14 @@ # (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt) name: CI -on: [ push, pull_request ] +on: + push: + branches: + - master + - develop + pull_request: + release: + types: [published, created, edited] jobs: ubuntu-focal: runs-on: ubuntu-20.04 @@ -27,7 +34,7 @@ jobs: - name: Add repository run: sudo apt-add-repository -y "ppa:ubuntu-toolchain-r/test" - name: Install packages - run: sudo apt install g++-9 g++-10 clang-9 clang-10 + run: sudo apt install g++-9 g++-10 clang-9 clang-10 libicu-dev - name: Checkout main boost run: git clone -b develop --depth 1 https://github.com/boostorg/boost.git ../boost-root - name: Update tools/boostdep @@ -78,7 +85,7 @@ jobs: - name: Add repository run: sudo apt-add-repository -y "ppa:ubuntu-toolchain-r/test" - name: Install packages - run: sudo apt install g++-7 g++-8 clang-7 clang-8 + run: sudo apt install g++-7 g++-8 clang-7 clang-8 libicu-dev - name: Checkout main boost run: git clone -b develop --depth 1 https://github.com/boostorg/boost.git ../boost-root - name: Update tools/boostdep @@ -108,57 +115,6 @@ jobs: - name: Test run: ../../../b2 toolset=$TOOLSET define=CI_SUPPRESS_KNOWN_ISSUES define=SLOW_COMPILER working-directory: ../boost-root/libs/regex/test - ubuntu-xenial: - runs-on: ubuntu-16.04 - strategy: - fail-fast: false - matrix: - compiler: [ g++-5, g++-6, clang++-5.0, clang++-6.0 ] - standard: [ c++03 c++11, c++14, c++1z ] - steps: - - uses: actions/checkout@v2 - with: - fetch-depth: '0' - - uses: mstachniuk/ci-skip@v1 - with: - commit-filter: '[skip ci];[ci skip];[CI SKIP];[SKIP CI];***CI SKIP***;***SKIP CI***;[windows];[Windows];[WINDOWS];[apple];[Apple];[APPLE]' - commit-filter-separator: ';' - fail-fast: true - - name: Set TOOLSET - run: echo ${{ matrix.compiler }} | awk '/^g/ { print "TOOLSET=gcc" } /^clang/ { print "TOOLSET=clang" }' >> $GITHUB_ENV - - name: Add repository - run: sudo apt-add-repository -y "ppa:ubuntu-toolchain-r/test" - - name: Install packages - run: sudo apt install g++-5 g++-6 clang-5.0 clang-6.0 - - name: Checkout main boost - run: git clone -b develop --depth 1 https://github.com/boostorg/boost.git ../boost-root - - name: Update tools/boostdep - run: git submodule update --init tools/boostdep - working-directory: ../boost-root - - name: Copy files - run: cp -r $GITHUB_WORKSPACE/* libs/regex - working-directory: ../boost-root - - name: Install deps - run: python tools/boostdep/depinst/depinst.py -I example -g "--jobs 3" regex - working-directory: ../boost-root - - name: Bootstrap - run: ./bootstrap.sh - working-directory: ../boost-root - - name: Generate headers - run: ./b2 headers - working-directory: ../boost-root - - name: Generate user config - run: 'echo "using $TOOLSET : : ${{ matrix.compiler }} : -std=${{ matrix.standard }} ;" > ~/user-config.jam' - working-directory: ../boost-root - - name: Config info install - run: ../../../b2 config_info_travis_install toolset=$TOOLSET - working-directory: ../boost-root/libs/config/test - - name: Config info - run: ./config_info_travis - working-directory: ../boost-root/libs/config/test - - name: Test - run: ../../../b2 toolset=$TOOLSET - working-directory: ../boost-root/libs/regex/test macos: runs-on: macos-latest strategy: @@ -382,6 +338,8 @@ jobs: - uses: actions/checkout@v2 with: fetch-depth: '0' + - name: Install packages + run: sudo apt install libicu-dev - name: Checkout main boost run: git clone -b develop --depth 1 https://github.com/boostorg/boost.git ../boost-root - name: Update tools/boostdep @@ -403,3 +361,17 @@ jobs: cmake .. cmake --build . cmake --build . --target check + rm -rf * + echo Standalone configuration + cmake -DBOOST_REGEX_STANDALONE=on .. + cmake --build . + cmake --build . --target check + cd ../../cmake_subdir_test_icu && mkdir __build__ && cd __build__ + cmake .. + cmake --build . + cmake --build . --target check + rm -rf * + echo Standalone configuration + cmake -DBOOST_REGEX_STANDALONE=on .. + cmake --build . + cmake --build . --target check diff --git a/CMakeLists.txt b/CMakeLists.txt index 2fc093ef..ccd42230 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,11 +13,57 @@ add_library(Boost::regex ALIAS boost_regex) target_include_directories(boost_regex INTERFACE include) -target_link_libraries(boost_regex - INTERFACE - Boost::config - Boost::throw_exception - Boost::predef - Boost::assert -) +option(BOOST_REGEX_STANDALONE "Boost.Regex: Enable Standalone Mode (i.e. no Boost dependencies)") + +if(NOT BOOST_REGEX_STANDALONE) + + target_link_libraries(boost_regex + INTERFACE + Boost::config + Boost::throw_exception + Boost::predef + Boost::assert + ) + +else() + + target_compile_definitions(boost_regex + INTERFACE BOOST_REGEX_STANDALONE + ) + +endif() + +find_package(ICU COMPONENTS data i18n uc QUIET) +#option(BOOST_REGEX_ENABLE_ICU "Boost.Regex: enable ICU support" ${ICU_FOUND}) + +if(ICU_FOUND) + + add_library(boost_regex_icu INTERFACE) + add_library(Boost::regex_icu ALIAS boost_regex_icu) + + target_include_directories(boost_regex_icu INTERFACE include) + + if(NOT BOOST_REGEX_STANDALONE) + + target_link_libraries(boost_regex_icu + INTERFACE + Boost::config + Boost::throw_exception + Boost::predef + Boost::assert + ) + + else() + + target_compile_definitions(boost_regex_icu + INTERFACE BOOST_REGEX_STANDALONE + ) + + endif() + + find_package(ICU COMPONENTS data i18n uc REQUIRED) + + target_link_libraries(boost_regex_icu INTERFACE ICU::data ICU::i18n ICU::uc) + +endif() diff --git a/doc/history.qbk b/doc/history.qbk index be64bb13..c1381818 100644 --- a/doc/history.qbk +++ b/doc/history.qbk @@ -14,6 +14,16 @@ Currently open issues can be viewed [@https://github.com/boostorg/regex/issues?q All issues including closed ones can be viewed [@https://github.com/boostorg/regex/issues?q=is%3Aissue+is%3Aclosed here]. +[h4 Boost.Regex-7.0.0 (Boost-1.78.0)] + +* [*Breaking Change:] Change \B to be the opposite of \b as per Perl behaviour. +* Change w32_regex_traits.hpp so that windows.h is no longer included. + +[h4 Boost.Regex-6.0.0 (Boost-1.77.0)] + +* Big change to header only library. +* Deprecate C++03 support. + [h4 Boost.Regex-5.1.4 (Boost-172.0)] * Minor build fixes, see [@https://github.com/boostorg/regex/issues/89 #89]. diff --git a/doc/html/boost_regex/background.html b/doc/html/boost_regex/background.html index 426e00dc..56e8ac4e 100644 --- a/doc/html/boost_regex/background.html +++ b/doc/html/boost_regex/background.html @@ -4,8 +4,8 @@ Background Information - - + + diff --git a/doc/html/boost_regex/background/acknowledgements.html b/doc/html/boost_regex/background/acknowledgements.html index af25e802..a129b3ff 100644 --- a/doc/html/boost_regex/background/acknowledgements.html +++ b/doc/html/boost_regex/background/acknowledgements.html @@ -4,7 +4,7 @@ Acknowledgements - + diff --git a/doc/html/boost_regex/background/examples.html b/doc/html/boost_regex/background/examples.html index 4c8fb18f..5222e586 100644 --- a/doc/html/boost_regex/background/examples.html +++ b/doc/html/boost_regex/background/examples.html @@ -4,7 +4,7 @@ Test and Example Programs - + diff --git a/doc/html/boost_regex/background/faq.html b/doc/html/boost_regex/background/faq.html index c5c60367..9928883c 100644 --- a/doc/html/boost_regex/background/faq.html +++ b/doc/html/boost_regex/background/faq.html @@ -4,7 +4,7 @@ FAQ - + diff --git a/doc/html/boost_regex/background/futher.html b/doc/html/boost_regex/background/futher.html index 14f59e3f..6501b1be 100644 --- a/doc/html/boost_regex/background/futher.html +++ b/doc/html/boost_regex/background/futher.html @@ -4,7 +4,7 @@ References and Further Information - + diff --git a/doc/html/boost_regex/background/headers.html b/doc/html/boost_regex/background/headers.html index 88707122..ea964e17 100644 --- a/doc/html/boost_regex/background/headers.html +++ b/doc/html/boost_regex/background/headers.html @@ -4,7 +4,7 @@ Headers - + diff --git a/doc/html/boost_regex/background/history.html b/doc/html/boost_regex/background/history.html index 8421ab54..f329fd41 100644 --- a/doc/html/boost_regex/background/history.html +++ b/doc/html/boost_regex/background/history.html @@ -4,7 +4,7 @@ History - + @@ -36,6 +36,33 @@

+ Boost.Regex-7.0.0 + (Boost-1.78.0) +
+
+
+ + Boost.Regex-6.0.0 + (Boost-1.77.0) +
+
+
+ Boost.Regex-5.1.4 (Boost-172.0)
@@ -43,7 +70,7 @@ Minor build fixes, see #89.
- + Boost.Regex-5.1.3 (Boost-1.64.0)
@@ -57,7 +84,7 @@
- + Boost.Regex-5.1.2 (Boost-1.62.0)
@@ -78,7 +105,7 @@
- + Boost.Regex-5.1.1 (Boost-1.61.0)
@@ -86,7 +113,7 @@ Change to lockfree implementation of memory cache, see PR#23.
- + Boost.Regex-5.1.0 (Boost-1.60.0)
@@ -109,7 +136,7 @@
- + Boost.Regex-5.0.1 (Boost-1.58.0)
@@ -142,7 +169,7 @@
- + Boost.Regex-5.0.0 (Boost-1.56.0)
@@ -175,14 +202,14 @@
- + Boost-1.54

Fixed issue #8569.

- + Boost-1.53

@@ -190,7 +217,7 @@ #7644.

- + Boost-1.51

@@ -200,7 +227,7 @@ #6346.

- + Boost-1.50

@@ -209,7 +236,7 @@ expression.

- + Boost-1.48

@@ -219,7 +246,7 @@ #5736.

- + Boost 1.47
@@ -232,7 +259,7 @@ #5504.

- + Boost 1.44
@@ -251,7 +278,7 @@ #3890

- + Boost 1.42
@@ -280,7 +307,7 @@
- + Boost 1.40
@@ -289,7 +316,7 @@ branch resets and recursive regular expressions.
- + Boost 1.38
@@ -317,7 +344,7 @@
- + Boost 1.34
@@ -340,7 +367,7 @@
- + Boost 1.33.1
@@ -410,7 +437,7 @@
- + Boost 1.33.0
@@ -465,7 +492,7 @@
- + Boost 1.32.1
@@ -473,7 +500,7 @@ Fixed bug in partial matches of bounded repeats of '.'.
- + Boost 1.31.0
diff --git a/doc/html/boost_regex/background/locale.html b/doc/html/boost_regex/background/locale.html index e679a550..5d5f0cd2 100644 --- a/doc/html/boost_regex/background/locale.html +++ b/doc/html/boost_regex/background/locale.html @@ -4,7 +4,7 @@ Localization - + diff --git a/doc/html/boost_regex/background/performance.html b/doc/html/boost_regex/background/performance.html index 3a0ca9ad..e84f6465 100644 --- a/doc/html/boost_regex/background/performance.html +++ b/doc/html/boost_regex/background/performance.html @@ -4,7 +4,7 @@ Performance - + diff --git a/doc/html/boost_regex/background/performance/section_id1378460593.html b/doc/html/boost_regex/background/performance/section_id1378460593.html index 872020dc..60b9852e 100644 --- a/doc/html/boost_regex/background/performance/section_id1378460593.html +++ b/doc/html/boost_regex/background/performance/section_id1378460593.html @@ -4,7 +4,7 @@ Testing simple leftmost-longest matches (platform = linux, compiler = GNU C++ version 6.3.0) - + diff --git a/doc/html/boost_regex/background/performance/section_id1675827111.html b/doc/html/boost_regex/background/performance/section_id1675827111.html index 72b2bc8c..43cafa56 100644 --- a/doc/html/boost_regex/background/performance/section_id1675827111.html +++ b/doc/html/boost_regex/background/performance/section_id1675827111.html @@ -4,7 +4,7 @@ Testing Perl searches (platform = linux, compiler = GNU C++ version 6.3.0) - + diff --git a/doc/html/boost_regex/background/performance/section_id3141719723.html b/doc/html/boost_regex/background/performance/section_id3141719723.html index 129834c6..b9c91f9d 100644 --- a/doc/html/boost_regex/background/performance/section_id3141719723.html +++ b/doc/html/boost_regex/background/performance/section_id3141719723.html @@ -4,7 +4,7 @@ Testing simple leftmost-longest matches (platform = Windows x64, compiler = Microsoft Visual C++ version 14.1) - + diff --git a/doc/html/boost_regex/background/performance/section_id3258595385.html b/doc/html/boost_regex/background/performance/section_id3258595385.html index 716f62b9..ecc996e6 100644 --- a/doc/html/boost_regex/background/performance/section_id3258595385.html +++ b/doc/html/boost_regex/background/performance/section_id3258595385.html @@ -4,7 +4,7 @@ Testing leftmost-longest searches (platform = Windows x64, compiler = Microsoft Visual C++ version 14.1) - + diff --git a/doc/html/boost_regex/background/performance/section_id3261825021.html b/doc/html/boost_regex/background/performance/section_id3261825021.html index b71be600..b243694a 100644 --- a/doc/html/boost_regex/background/performance/section_id3261825021.html +++ b/doc/html/boost_regex/background/performance/section_id3261825021.html @@ -4,7 +4,7 @@ Testing simple Perl matches (platform = linux, compiler = GNU C++ version 6.3.0) - + diff --git a/doc/html/boost_regex/background/performance/section_id3752650613.html b/doc/html/boost_regex/background/performance/section_id3752650613.html index 67b83440..ac11c594 100644 --- a/doc/html/boost_regex/background/performance/section_id3752650613.html +++ b/doc/html/boost_regex/background/performance/section_id3752650613.html @@ -4,7 +4,7 @@ Testing Perl searches (platform = Windows x64, compiler = Microsoft Visual C++ version 14.1) - + diff --git a/doc/html/boost_regex/background/performance/section_id4128344975.html b/doc/html/boost_regex/background/performance/section_id4128344975.html index 89720415..d77b3ae2 100644 --- a/doc/html/boost_regex/background/performance/section_id4128344975.html +++ b/doc/html/boost_regex/background/performance/section_id4128344975.html @@ -4,7 +4,7 @@ Testing simple Perl matches (platform = Windows x64, compiler = Microsoft Visual C++ version 14.1) - + diff --git a/doc/html/boost_regex/background/performance/section_id4148872883.html b/doc/html/boost_regex/background/performance/section_id4148872883.html index 8495bf1a..f9876309 100644 --- a/doc/html/boost_regex/background/performance/section_id4148872883.html +++ b/doc/html/boost_regex/background/performance/section_id4148872883.html @@ -4,7 +4,7 @@ Testing leftmost-longest searches (platform = linux, compiler = GNU C++ version 6.3.0) - + diff --git a/doc/html/boost_regex/background/redist.html b/doc/html/boost_regex/background/redist.html index ef12c43f..4f85a62a 100644 --- a/doc/html/boost_regex/background/redist.html +++ b/doc/html/boost_regex/background/redist.html @@ -4,7 +4,7 @@ Redistributables - + diff --git a/doc/html/boost_regex/background/standards.html b/doc/html/boost_regex/background/standards.html index aeecebf3..817b51fb 100644 --- a/doc/html/boost_regex/background/standards.html +++ b/doc/html/boost_regex/background/standards.html @@ -4,7 +4,7 @@ Standards Conformance - + diff --git a/doc/html/boost_regex/background/thread_safety.html b/doc/html/boost_regex/background/thread_safety.html index 1f1fb819..7ba59e9a 100644 --- a/doc/html/boost_regex/background/thread_safety.html +++ b/doc/html/boost_regex/background/thread_safety.html @@ -4,7 +4,7 @@ Thread Safety - + diff --git a/doc/html/boost_regex/captures.html b/doc/html/boost_regex/captures.html index 55e59822..ef532ae5 100644 --- a/doc/html/boost_regex/captures.html +++ b/doc/html/boost_regex/captures.html @@ -4,8 +4,8 @@ Understanding Marked Sub-Expressions and Captures - - + + diff --git a/doc/html/boost_regex/configuration.html b/doc/html/boost_regex/configuration.html index bfc70b20..0f2e9468 100644 --- a/doc/html/boost_regex/configuration.html +++ b/doc/html/boost_regex/configuration.html @@ -4,9 +4,9 @@ Configuration - - - + + + @@ -28,6 +28,8 @@
Compiler Setup
+
Use in Standalone + Mode (without the rest of Boost)
Locale and traits class selection
Algorithm Tuning
diff --git a/doc/html/boost_regex/configuration/compiler.html b/doc/html/boost_regex/configuration/compiler.html index 59cd9329..54af44a7 100644 --- a/doc/html/boost_regex/configuration/compiler.html +++ b/doc/html/boost_regex/configuration/compiler.html @@ -4,10 +4,10 @@ Compiler Setup - + - + @@ -20,7 +20,7 @@

-PrevUpHomeNext +PrevUpHomeNext

@@ -44,7 +44,7 @@
-PrevUpHomeNext +PrevUpHomeNext
diff --git a/doc/html/boost_regex/configuration/locale.html b/doc/html/boost_regex/configuration/locale.html index eb3ba937..2a482463 100644 --- a/doc/html/boost_regex/configuration/locale.html +++ b/doc/html/boost_regex/configuration/locale.html @@ -4,9 +4,9 @@ Locale and traits class selection - + - + @@ -20,7 +20,7 @@
-PrevUpHomeNext +PrevUpHomeNext

@@ -103,7 +103,7 @@
-PrevUpHomeNext +PrevUpHomeNext
diff --git a/doc/html/boost_regex/configuration/tuning.html b/doc/html/boost_regex/configuration/tuning.html index 30ddc99f..608db62e 100644 --- a/doc/html/boost_regex/configuration/tuning.html +++ b/doc/html/boost_regex/configuration/tuning.html @@ -4,7 +4,7 @@ Algorithm Tuning - + diff --git a/doc/html/boost_regex/format.html b/doc/html/boost_regex/format.html index bbd3e55a..1192a07f 100644 --- a/doc/html/boost_regex/format.html +++ b/doc/html/boost_regex/format.html @@ -4,8 +4,8 @@ Search and Replace Format String Syntax - - + + diff --git a/doc/html/boost_regex/format/boost_format_syntax.html b/doc/html/boost_regex/format/boost_format_syntax.html index 32b841ab..3dfdf7fb 100644 --- a/doc/html/boost_regex/format/boost_format_syntax.html +++ b/doc/html/boost_regex/format/boost_format_syntax.html @@ -4,7 +4,7 @@ Boost-Extended Format String Syntax - + diff --git a/doc/html/boost_regex/format/perl_format.html b/doc/html/boost_regex/format/perl_format.html index c0b9698b..ce11ccd0 100644 --- a/doc/html/boost_regex/format/perl_format.html +++ b/doc/html/boost_regex/format/perl_format.html @@ -4,7 +4,7 @@ Perl Format String Syntax - + diff --git a/doc/html/boost_regex/format/sed_format.html b/doc/html/boost_regex/format/sed_format.html index dd37fbb7..3dfac65c 100644 --- a/doc/html/boost_regex/format/sed_format.html +++ b/doc/html/boost_regex/format/sed_format.html @@ -4,7 +4,7 @@ Sed Format String Syntax - + diff --git a/doc/html/boost_regex/install.html b/doc/html/boost_regex/install.html index 7070210a..8088bc13 100644 --- a/doc/html/boost_regex/install.html +++ b/doc/html/boost_regex/install.html @@ -4,8 +4,8 @@ Building and Installing the Library - - + + @@ -73,17 +73,52 @@ Define BOOST_REGEX_STANDALONE when building.

+

+ If you are using this library with ICU, note that since it is now header only, + it will be up to you to link to the ICU libraries if you use <boost/regex/icu.hpp> unless you are using the supplied CMake + script. +

- C++03 users only (Deprecated) Building with bjam + Usage + with CMake

- This is now the preferred method for building and installing this library, - please refer to the getting + The library comes with a very basic CMakeLists.txt that allows this library + to be used from other CMake scripts. +

+

+ CMakeLists.txt defines two targets: +

+
    +
  • + Boost::regex This is the target to use for normal + header only builds. +
  • +
  • + Boost::regex_icu This is the target to use if + you are using <boost/regex/icu.hpp> in your code, and wish to have the + ICU dependencies taken care of for you. +
  • +
+

+ There is also one configuration option: +

+
  • + BOOST_REGEX_STANDALONE when set then no other Boost libraries are targeted + as dependencies, and Boost.Regex is placed in standalone mode. +
+
+ + C++03 users only (DEPRECATED) Building with bjam +
+

+ This is now the preferred method for building and installing legacy versions + this library, please refer to the getting started guide for more information.

- + Building With Unicode and ICU Support
@@ -293,7 +328,7 @@ header-include and linker-search paths).

- + Building from Source
diff --git a/doc/html/boost_regex/intro.html b/doc/html/boost_regex/intro.html index af487a5d..2e674614 100644 --- a/doc/html/boost_regex/intro.html +++ b/doc/html/boost_regex/intro.html @@ -4,8 +4,8 @@ Introduction and Overview - - + + diff --git a/doc/html/boost_regex/partial_matches.html b/doc/html/boost_regex/partial_matches.html index 3b2fabbd..67ab8382 100644 --- a/doc/html/boost_regex/partial_matches.html +++ b/doc/html/boost_regex/partial_matches.html @@ -4,8 +4,8 @@ Partial Matches - - + + diff --git a/doc/html/boost_regex/ref.html b/doc/html/boost_regex/ref.html index ef2f7259..913f1460 100644 --- a/doc/html/boost_regex/ref.html +++ b/doc/html/boost_regex/ref.html @@ -4,8 +4,8 @@ Reference - - + + diff --git a/doc/html/boost_regex/ref/bad_expression.html b/doc/html/boost_regex/ref/bad_expression.html index 9eca074b..c53c53c6 100644 --- a/doc/html/boost_regex/ref/bad_expression.html +++ b/doc/html/boost_regex/ref/bad_expression.html @@ -4,7 +4,7 @@ bad_expression - + diff --git a/doc/html/boost_regex/ref/basic_regex.html b/doc/html/boost_regex/ref/basic_regex.html index 3b590011..bb7b74b0 100644 --- a/doc/html/boost_regex/ref/basic_regex.html +++ b/doc/html/boost_regex/ref/basic_regex.html @@ -4,7 +4,7 @@ basic_regex - + diff --git a/doc/html/boost_regex/ref/concepts.html b/doc/html/boost_regex/ref/concepts.html index ea87d335..31a14caa 100644 --- a/doc/html/boost_regex/ref/concepts.html +++ b/doc/html/boost_regex/ref/concepts.html @@ -4,7 +4,7 @@ Concepts - + diff --git a/doc/html/boost_regex/ref/concepts/charT_concept.html b/doc/html/boost_regex/ref/concepts/charT_concept.html index 32c4694d..22027035 100644 --- a/doc/html/boost_regex/ref/concepts/charT_concept.html +++ b/doc/html/boost_regex/ref/concepts/charT_concept.html @@ -4,7 +4,7 @@ charT Requirements - + diff --git a/doc/html/boost_regex/ref/concepts/iterator_concepts.html b/doc/html/boost_regex/ref/concepts/iterator_concepts.html index d93ed168..29686ba5 100644 --- a/doc/html/boost_regex/ref/concepts/iterator_concepts.html +++ b/doc/html/boost_regex/ref/concepts/iterator_concepts.html @@ -4,7 +4,7 @@ Iterator Requirements - + diff --git a/doc/html/boost_regex/ref/concepts/traits_concept.html b/doc/html/boost_regex/ref/concepts/traits_concept.html index c8e71c94..ec08ca00 100644 --- a/doc/html/boost_regex/ref/concepts/traits_concept.html +++ b/doc/html/boost_regex/ref/concepts/traits_concept.html @@ -4,7 +4,7 @@ Traits Class Requirements - + diff --git a/doc/html/boost_regex/ref/deprecated.html b/doc/html/boost_regex/ref/deprecated.html index ca0c184b..0c8c050d 100644 --- a/doc/html/boost_regex/ref/deprecated.html +++ b/doc/html/boost_regex/ref/deprecated.html @@ -4,7 +4,7 @@ Deprecated Interfaces - + diff --git a/doc/html/boost_regex/ref/deprecated/old_regex.html b/doc/html/boost_regex/ref/deprecated/old_regex.html index 029957fb..dc157a1a 100644 --- a/doc/html/boost_regex/ref/deprecated/old_regex.html +++ b/doc/html/boost_regex/ref/deprecated/old_regex.html @@ -4,7 +4,7 @@ High Level Class RegEx (Deprecated) - + diff --git a/doc/html/boost_regex/ref/deprecated/regex_format.html b/doc/html/boost_regex/ref/deprecated/regex_format.html index f2f38a35..c92f8b2d 100644 --- a/doc/html/boost_regex/ref/deprecated/regex_format.html +++ b/doc/html/boost_regex/ref/deprecated/regex_format.html @@ -4,7 +4,7 @@ regex_format (Deprecated) - + diff --git a/doc/html/boost_regex/ref/deprecated/regex_grep.html b/doc/html/boost_regex/ref/deprecated/regex_grep.html index 8672b0ce..4ab54d04 100644 --- a/doc/html/boost_regex/ref/deprecated/regex_grep.html +++ b/doc/html/boost_regex/ref/deprecated/regex_grep.html @@ -4,7 +4,7 @@ regex_grep (Deprecated) - + diff --git a/doc/html/boost_regex/ref/deprecated/regex_split.html b/doc/html/boost_regex/ref/deprecated/regex_split.html index fe12903e..cb514d3c 100644 --- a/doc/html/boost_regex/ref/deprecated/regex_split.html +++ b/doc/html/boost_regex/ref/deprecated/regex_split.html @@ -4,7 +4,7 @@ regex_split (deprecated) - + diff --git a/doc/html/boost_regex/ref/error_type.html b/doc/html/boost_regex/ref/error_type.html index ee125f73..4352b36d 100644 --- a/doc/html/boost_regex/ref/error_type.html +++ b/doc/html/boost_regex/ref/error_type.html @@ -4,7 +4,7 @@ error_type - + diff --git a/doc/html/boost_regex/ref/internals.html b/doc/html/boost_regex/ref/internals.html index 05adf247..623f5bad 100644 --- a/doc/html/boost_regex/ref/internals.html +++ b/doc/html/boost_regex/ref/internals.html @@ -4,7 +4,7 @@ Internal Details - + diff --git a/doc/html/boost_regex/ref/internals/uni_iter.html b/doc/html/boost_regex/ref/internals/uni_iter.html index 6d59d683..1fa31efc 100644 --- a/doc/html/boost_regex/ref/internals/uni_iter.html +++ b/doc/html/boost_regex/ref/internals/uni_iter.html @@ -4,7 +4,7 @@ Unicode Iterators - + diff --git a/doc/html/boost_regex/ref/match_flag_type.html b/doc/html/boost_regex/ref/match_flag_type.html index 3f9b07f5..eacee16f 100644 --- a/doc/html/boost_regex/ref/match_flag_type.html +++ b/doc/html/boost_regex/ref/match_flag_type.html @@ -4,7 +4,7 @@ match_flag_type - + diff --git a/doc/html/boost_regex/ref/match_results.html b/doc/html/boost_regex/ref/match_results.html index 760d6388..d9583536 100644 --- a/doc/html/boost_regex/ref/match_results.html +++ b/doc/html/boost_regex/ref/match_results.html @@ -4,7 +4,7 @@ match_results - + diff --git a/doc/html/boost_regex/ref/non_std_strings.html b/doc/html/boost_regex/ref/non_std_strings.html index d65da1a7..9de0357c 100644 --- a/doc/html/boost_regex/ref/non_std_strings.html +++ b/doc/html/boost_regex/ref/non_std_strings.html @@ -4,7 +4,7 @@ Interfacing With Non-Standard String Types - + diff --git a/doc/html/boost_regex/ref/non_std_strings/icu.html b/doc/html/boost_regex/ref/non_std_strings/icu.html index 18c53182..4eab757a 100644 --- a/doc/html/boost_regex/ref/non_std_strings/icu.html +++ b/doc/html/boost_regex/ref/non_std_strings/icu.html @@ -4,7 +4,7 @@ Working With Unicode and ICU String Types - + diff --git a/doc/html/boost_regex/ref/non_std_strings/icu/intro.html b/doc/html/boost_regex/ref/non_std_strings/icu/intro.html index 6578a44b..a4e80e1e 100644 --- a/doc/html/boost_regex/ref/non_std_strings/icu/intro.html +++ b/doc/html/boost_regex/ref/non_std_strings/icu/intro.html @@ -4,7 +4,7 @@ Introduction to using Regex with ICU - + @@ -38,9 +38,7 @@

In order to use this header you will need the ICU - library, and you will need to have built the Boost.Regex library - with ICU - support enabled. + library.

The header will enable you to: @@ -59,6 +57,11 @@ UTF-16 or UTF-32.

+

+ CMake users should link to the Boost::regex_icu + target in our CMakeLists.txt in order to have ICU dependencies taken + care of when using this header. +

diff --git a/doc/html/boost_regex/ref/non_std_strings/icu/unicode_algo.html b/doc/html/boost_regex/ref/non_std_strings/icu/unicode_algo.html index 447bed6c..afe9d7a3 100644 --- a/doc/html/boost_regex/ref/non_std_strings/icu/unicode_algo.html +++ b/doc/html/boost_regex/ref/non_std_strings/icu/unicode_algo.html @@ -4,7 +4,7 @@ Unicode Regular Expression Algorithms - + diff --git a/doc/html/boost_regex/ref/non_std_strings/icu/unicode_iter.html b/doc/html/boost_regex/ref/non_std_strings/icu/unicode_iter.html index 3496e89d..a8630203 100644 --- a/doc/html/boost_regex/ref/non_std_strings/icu/unicode_iter.html +++ b/doc/html/boost_regex/ref/non_std_strings/icu/unicode_iter.html @@ -4,7 +4,7 @@ Unicode Aware Regex Iterators - + diff --git a/doc/html/boost_regex/ref/non_std_strings/icu/unicode_types.html b/doc/html/boost_regex/ref/non_std_strings/icu/unicode_types.html index 5137a787..1aab1bbd 100644 --- a/doc/html/boost_regex/ref/non_std_strings/icu/unicode_types.html +++ b/doc/html/boost_regex/ref/non_std_strings/icu/unicode_types.html @@ -4,7 +4,7 @@ Unicode regular expression types - + diff --git a/doc/html/boost_regex/ref/non_std_strings/mfc_strings.html b/doc/html/boost_regex/ref/non_std_strings/mfc_strings.html index 7318b0c7..92d9b767 100644 --- a/doc/html/boost_regex/ref/non_std_strings/mfc_strings.html +++ b/doc/html/boost_regex/ref/non_std_strings/mfc_strings.html @@ -4,7 +4,7 @@ Using Boost Regex With MFC Strings - + diff --git a/doc/html/boost_regex/ref/non_std_strings/mfc_strings/mfc_algo.html b/doc/html/boost_regex/ref/non_std_strings/mfc_strings/mfc_algo.html index 0a4d3d28..a6b64d00 100644 --- a/doc/html/boost_regex/ref/non_std_strings/mfc_strings/mfc_algo.html +++ b/doc/html/boost_regex/ref/non_std_strings/mfc_strings/mfc_algo.html @@ -4,7 +4,7 @@ Overloaded Algorithms For MFC String Types - + diff --git a/doc/html/boost_regex/ref/non_std_strings/mfc_strings/mfc_intro.html b/doc/html/boost_regex/ref/non_std_strings/mfc_strings/mfc_intro.html index 4531171e..00fb2acd 100644 --- a/doc/html/boost_regex/ref/non_std_strings/mfc_strings/mfc_intro.html +++ b/doc/html/boost_regex/ref/non_std_strings/mfc_strings/mfc_intro.html @@ -4,7 +4,7 @@ Introduction to Boost.Regex and MFC Strings - + diff --git a/doc/html/boost_regex/ref/non_std_strings/mfc_strings/mfc_iter.html b/doc/html/boost_regex/ref/non_std_strings/mfc_strings/mfc_iter.html index 3241d399..28da789a 100644 --- a/doc/html/boost_regex/ref/non_std_strings/mfc_strings/mfc_iter.html +++ b/doc/html/boost_regex/ref/non_std_strings/mfc_strings/mfc_iter.html @@ -4,7 +4,7 @@ Iterating Over the Matches Within An MFC String - + diff --git a/doc/html/boost_regex/ref/non_std_strings/mfc_strings/mfc_regex_create.html b/doc/html/boost_regex/ref/non_std_strings/mfc_strings/mfc_regex_create.html index b149e6fd..869bcf69 100644 --- a/doc/html/boost_regex/ref/non_std_strings/mfc_strings/mfc_regex_create.html +++ b/doc/html/boost_regex/ref/non_std_strings/mfc_strings/mfc_regex_create.html @@ -4,7 +4,7 @@ Regular Expression Creation From an MFC String - + diff --git a/doc/html/boost_regex/ref/non_std_strings/mfc_strings/mfc_regex_types.html b/doc/html/boost_regex/ref/non_std_strings/mfc_strings/mfc_regex_types.html index a31aef42..f5f76e76 100644 --- a/doc/html/boost_regex/ref/non_std_strings/mfc_strings/mfc_regex_types.html +++ b/doc/html/boost_regex/ref/non_std_strings/mfc_strings/mfc_regex_types.html @@ -4,7 +4,7 @@ Regex Types Used With MFC Strings - + diff --git a/doc/html/boost_regex/ref/posix.html b/doc/html/boost_regex/ref/posix.html index 2ffabed1..4ca51ca7 100644 --- a/doc/html/boost_regex/ref/posix.html +++ b/doc/html/boost_regex/ref/posix.html @@ -4,7 +4,7 @@ POSIX Compatible C API's - + diff --git a/doc/html/boost_regex/ref/regex_iterator.html b/doc/html/boost_regex/ref/regex_iterator.html index 39aa982f..f0d69fd3 100644 --- a/doc/html/boost_regex/ref/regex_iterator.html +++ b/doc/html/boost_regex/ref/regex_iterator.html @@ -4,7 +4,7 @@ regex_iterator - + diff --git a/doc/html/boost_regex/ref/regex_match.html b/doc/html/boost_regex/ref/regex_match.html index 7af902e3..e1127cad 100644 --- a/doc/html/boost_regex/ref/regex_match.html +++ b/doc/html/boost_regex/ref/regex_match.html @@ -4,7 +4,7 @@ regex_match - + diff --git a/doc/html/boost_regex/ref/regex_replace.html b/doc/html/boost_regex/ref/regex_replace.html index 660788c5..fec865cf 100644 --- a/doc/html/boost_regex/ref/regex_replace.html +++ b/doc/html/boost_regex/ref/regex_replace.html @@ -4,7 +4,7 @@ regex_replace - + diff --git a/doc/html/boost_regex/ref/regex_search.html b/doc/html/boost_regex/ref/regex_search.html index 219df924..08f58710 100644 --- a/doc/html/boost_regex/ref/regex_search.html +++ b/doc/html/boost_regex/ref/regex_search.html @@ -4,7 +4,7 @@ regex_search - + diff --git a/doc/html/boost_regex/ref/regex_token_iterator.html b/doc/html/boost_regex/ref/regex_token_iterator.html index 52df6907..5e8bdd50 100644 --- a/doc/html/boost_regex/ref/regex_token_iterator.html +++ b/doc/html/boost_regex/ref/regex_token_iterator.html @@ -4,7 +4,7 @@ regex_token_iterator - + diff --git a/doc/html/boost_regex/ref/regex_traits.html b/doc/html/boost_regex/ref/regex_traits.html index 4aeb4206..990403c9 100644 --- a/doc/html/boost_regex/ref/regex_traits.html +++ b/doc/html/boost_regex/ref/regex_traits.html @@ -4,7 +4,7 @@ regex_traits - + diff --git a/doc/html/boost_regex/ref/sub_match.html b/doc/html/boost_regex/ref/sub_match.html index ce0c8f7a..03f884d2 100644 --- a/doc/html/boost_regex/ref/sub_match.html +++ b/doc/html/boost_regex/ref/sub_match.html @@ -4,7 +4,7 @@ sub_match - + diff --git a/doc/html/boost_regex/ref/syntax_option_type.html b/doc/html/boost_regex/ref/syntax_option_type.html index cf9eea91..90fda68c 100644 --- a/doc/html/boost_regex/ref/syntax_option_type.html +++ b/doc/html/boost_regex/ref/syntax_option_type.html @@ -4,7 +4,7 @@ syntax_option_type - + diff --git a/doc/html/boost_regex/ref/syntax_option_type/syntax_option_type_basic.html b/doc/html/boost_regex/ref/syntax_option_type/syntax_option_type_basic.html index b9566637..80652e33 100644 --- a/doc/html/boost_regex/ref/syntax_option_type/syntax_option_type_basic.html +++ b/doc/html/boost_regex/ref/syntax_option_type/syntax_option_type_basic.html @@ -4,7 +4,7 @@ Options for POSIX Basic Regular Expressions - + diff --git a/doc/html/boost_regex/ref/syntax_option_type/syntax_option_type_extended.html b/doc/html/boost_regex/ref/syntax_option_type/syntax_option_type_extended.html index fbc34d37..6e102bce 100644 --- a/doc/html/boost_regex/ref/syntax_option_type/syntax_option_type_extended.html +++ b/doc/html/boost_regex/ref/syntax_option_type/syntax_option_type_extended.html @@ -4,7 +4,7 @@ Options for POSIX Extended Regular Expressions - + diff --git a/doc/html/boost_regex/ref/syntax_option_type/syntax_option_type_literal.html b/doc/html/boost_regex/ref/syntax_option_type/syntax_option_type_literal.html index 3956e5d6..0f274b5f 100644 --- a/doc/html/boost_regex/ref/syntax_option_type/syntax_option_type_literal.html +++ b/doc/html/boost_regex/ref/syntax_option_type/syntax_option_type_literal.html @@ -4,7 +4,7 @@ Options for Literal Strings - + diff --git a/doc/html/boost_regex/ref/syntax_option_type/syntax_option_type_overview.html b/doc/html/boost_regex/ref/syntax_option_type/syntax_option_type_overview.html index e5431456..42fcaa3d 100644 --- a/doc/html/boost_regex/ref/syntax_option_type/syntax_option_type_overview.html +++ b/doc/html/boost_regex/ref/syntax_option_type/syntax_option_type_overview.html @@ -4,7 +4,7 @@ Overview of syntax_option_type - + diff --git a/doc/html/boost_regex/ref/syntax_option_type/syntax_option_type_perl.html b/doc/html/boost_regex/ref/syntax_option_type/syntax_option_type_perl.html index e66df75a..f611257d 100644 --- a/doc/html/boost_regex/ref/syntax_option_type/syntax_option_type_perl.html +++ b/doc/html/boost_regex/ref/syntax_option_type/syntax_option_type_perl.html @@ -4,7 +4,7 @@ Options for Perl Regular Expressions - + diff --git a/doc/html/boost_regex/ref/syntax_option_type/syntax_option_type_synopsis.html b/doc/html/boost_regex/ref/syntax_option_type/syntax_option_type_synopsis.html index 446af451..add41de1 100644 --- a/doc/html/boost_regex/ref/syntax_option_type/syntax_option_type_synopsis.html +++ b/doc/html/boost_regex/ref/syntax_option_type/syntax_option_type_synopsis.html @@ -4,7 +4,7 @@ syntax_option_type Synopsis - + diff --git a/doc/html/boost_regex/syntax.html b/doc/html/boost_regex/syntax.html index efc5f481..f2812897 100644 --- a/doc/html/boost_regex/syntax.html +++ b/doc/html/boost_regex/syntax.html @@ -4,8 +4,8 @@ Regular Expression Syntax - - + + diff --git a/doc/html/boost_regex/syntax/basic_extended.html b/doc/html/boost_regex/syntax/basic_extended.html index 60d814f3..9161bcde 100644 --- a/doc/html/boost_regex/syntax/basic_extended.html +++ b/doc/html/boost_regex/syntax/basic_extended.html @@ -4,7 +4,7 @@ POSIX Extended Regular Expression Syntax - + diff --git a/doc/html/boost_regex/syntax/basic_syntax.html b/doc/html/boost_regex/syntax/basic_syntax.html index f7067ed5..f2aef14b 100644 --- a/doc/html/boost_regex/syntax/basic_syntax.html +++ b/doc/html/boost_regex/syntax/basic_syntax.html @@ -4,7 +4,7 @@ POSIX Basic Regular Expression Syntax - + diff --git a/doc/html/boost_regex/syntax/character_classes.html b/doc/html/boost_regex/syntax/character_classes.html index 9b072e25..bc8f1933 100644 --- a/doc/html/boost_regex/syntax/character_classes.html +++ b/doc/html/boost_regex/syntax/character_classes.html @@ -4,7 +4,7 @@ Character Class Names - + diff --git a/doc/html/boost_regex/syntax/character_classes/optional_char_class_names.html b/doc/html/boost_regex/syntax/character_classes/optional_char_class_names.html index 061763ef..259d0fc0 100644 --- a/doc/html/boost_regex/syntax/character_classes/optional_char_class_names.html +++ b/doc/html/boost_regex/syntax/character_classes/optional_char_class_names.html @@ -4,7 +4,7 @@ Character classes that are supported by Unicode Regular Expressions - + diff --git a/doc/html/boost_regex/syntax/character_classes/std_char_classes.html b/doc/html/boost_regex/syntax/character_classes/std_char_classes.html index 640c5e10..f6a978a4 100644 --- a/doc/html/boost_regex/syntax/character_classes/std_char_classes.html +++ b/doc/html/boost_regex/syntax/character_classes/std_char_classes.html @@ -4,7 +4,7 @@ Character Classes that are Always Supported - + diff --git a/doc/html/boost_regex/syntax/collating_names.html b/doc/html/boost_regex/syntax/collating_names.html index 9b08b76e..2969f7fa 100644 --- a/doc/html/boost_regex/syntax/collating_names.html +++ b/doc/html/boost_regex/syntax/collating_names.html @@ -4,7 +4,7 @@ Collating Names - + diff --git a/doc/html/boost_regex/syntax/collating_names/digraphs.html b/doc/html/boost_regex/syntax/collating_names/digraphs.html index 3630f6bb..92633356 100644 --- a/doc/html/boost_regex/syntax/collating_names/digraphs.html +++ b/doc/html/boost_regex/syntax/collating_names/digraphs.html @@ -4,7 +4,7 @@ Digraphs - + diff --git a/doc/html/boost_regex/syntax/collating_names/named_unicode.html b/doc/html/boost_regex/syntax/collating_names/named_unicode.html index 8c5e94c9..9d8492c8 100644 --- a/doc/html/boost_regex/syntax/collating_names/named_unicode.html +++ b/doc/html/boost_regex/syntax/collating_names/named_unicode.html @@ -4,7 +4,7 @@ Named Unicode Characters - + diff --git a/doc/html/boost_regex/syntax/collating_names/posix_symbolic_names.html b/doc/html/boost_regex/syntax/collating_names/posix_symbolic_names.html index 4e1e920d..a0c3b969 100644 --- a/doc/html/boost_regex/syntax/collating_names/posix_symbolic_names.html +++ b/doc/html/boost_regex/syntax/collating_names/posix_symbolic_names.html @@ -4,7 +4,7 @@ POSIX Symbolic Names - + diff --git a/doc/html/boost_regex/syntax/leftmost_longest_rule.html b/doc/html/boost_regex/syntax/leftmost_longest_rule.html index 06b8c52c..94600780 100644 --- a/doc/html/boost_regex/syntax/leftmost_longest_rule.html +++ b/doc/html/boost_regex/syntax/leftmost_longest_rule.html @@ -4,7 +4,7 @@ The Leftmost Longest Rule - + diff --git a/doc/html/boost_regex/syntax/perl_syntax.html b/doc/html/boost_regex/syntax/perl_syntax.html index 10e30e5f..05e7e635 100644 --- a/doc/html/boost_regex/syntax/perl_syntax.html +++ b/doc/html/boost_regex/syntax/perl_syntax.html @@ -4,7 +4,7 @@ Perl Regular Expression Syntax - + diff --git a/doc/html/boost_regex/unicode.html b/doc/html/boost_regex/unicode.html index 45be4b66..bff988ae 100644 --- a/doc/html/boost_regex/unicode.html +++ b/doc/html/boost_regex/unicode.html @@ -4,8 +4,8 @@ Unicode and Boost.Regex - - + + @@ -63,11 +63,10 @@

If you have the ICU - library, then Boost.Regex can be configured - to make use of it, and provide a distinct regular expression type (boost::u32regex), - that supports both Unicode specific character properties, and the searching - of text that is encoded in either UTF-8, UTF-16, or UTF-32. See: ICU - string class support. + library, then Boost.Regex provides a distinct regular expression type + (boost::u32regex), that supports both Unicode specific character properties, + and the searching of text that is encoded in either UTF-8, UTF-16, or UTF-32. + See: ICU string class support.

diff --git a/doc/html/index.html b/doc/html/index.html index 49e7612f..da504393 100644 --- a/doc/html/index.html +++ b/doc/html/index.html @@ -1,10 +1,10 @@ -Boost.Regex 5.1.4 +Boost.Regex 7.0.0 - + @@ -22,7 +22,7 @@

-Boost.Regex 5.1.4

+Boost.Regex 7.0.0

John Maddock

@@ -42,6 +42,8 @@
Configuration
Compiler Setup
+
Use in Standalone + Mode (without the rest of Boost)
Locale and traits class selection
Algorithm Tuning
@@ -213,7 +215,7 @@

- +

Last revised: January 25, 2021 at 11:08:05 GMT

Last revised: October 10, 2021 at 15:39:14 GMT


diff --git a/doc/icu_strings.qbk b/doc/icu_strings.qbk index e38e0431..d13c7880 100644 --- a/doc/icu_strings.qbk +++ b/doc/icu_strings.qbk @@ -18,9 +18,7 @@ contains the data types and algorithms necessary for working with regular expressions in a Unicode aware environment. In order to use this header you will need the -[@http://www.ibm.com/software/globalization/icu/ ICU library], and you will need -to have built the Boost.Regex library with -[link boost_regex.install.building_with_unicode_and_icu_su ICU support enabled]. +[@http://www.ibm.com/software/globalization/icu/ ICU library]. The header will enable you to: @@ -28,6 +26,9 @@ The header will enable you to: * Create regular expressions that support various Unicode data properties, including character classification. * Transparently search Unicode strings that are encoded as either UTF-8, UTF-16 or UTF-32. +CMake users should link to the `Boost::regex_icu` target in our CMakeLists.txt in order to have ICU dependencies +taken care of when using this header. + [endsect] [section:unicode_types Unicode regular expression types] diff --git a/doc/install.qbk b/doc/install.qbk index 041439ef..8648790e 100644 --- a/doc/install.qbk +++ b/doc/install.qbk @@ -35,9 +35,26 @@ in order to do this you must either: then the library will automoatically enter standalone mode. Or: * Define BOOST_REGEX_STANDALONE when building. -[h4 [*C++03 users only (Deprecated)] Building with bjam] +If you are using this library with ICU, note that since it is now header only, it will be up to you +to link to the ICU libraries if you use `` unless you are using the supplied CMake script. -This is now the preferred method for building and installing this library, +[h4 Usage with CMake] + +The library comes with a very basic CMakeLists.txt that allows this library to be used from other CMake scripts. + +CMakeLists.txt defines two targets: + +* `Boost::regex` This is the target to use for normal header only builds. +* `Boost::regex_icu` This is the target to use if you are using `` in your code, and wish to have the ICU dependencies taken care of for you. + +There is also one configuration option: + +* BOOST_REGEX_STANDALONE when set then no other Boost libraries are targeted as dependencies, and Boost.Regex is placed in standalone mode. Invoke CMake +with -DBOOST_REGEX_STANDALONE=on to enable standalone mode. + +[h4 [*C++03 users only (DEPRECATED)] Building with bjam] + +This is now the preferred method for building and installing legacy versions this library, please refer to the [@../../../../more/getting_started.html getting started guide] for more information. diff --git a/doc/regex.qbk b/doc/regex.qbk index c13e5587..49cc7f89 100644 --- a/doc/regex.qbk +++ b/doc/regex.qbk @@ -8,7 +8,7 @@ [@http://www.boost.org/LICENSE_1_0.txt]) ] [authors [Maddock, John]] - [version 5.1.4] + [version 7.0.0] [/last-revision $Date$] ] diff --git a/doc/syntax_perl.qbk b/doc/syntax_perl.qbk index 233db3cf..6d062f46 100644 --- a/doc/syntax_perl.qbk +++ b/doc/syntax_perl.qbk @@ -195,7 +195,11 @@ You can also use the \g escape for the same function, for example: [[[^\g{one}]][Match whatever matched the sub-expression named "one"]] ] -Finally the \k escape can be used to refer to named subexpressions, for example [^\k] will match +Note that a back reference can also be a forward-reference to a sub-expression that has not yet +been seen - this only really makes sense within a repeat, so for example `(\2two|(one))+` will +match "oneonetwo". + +Finally the \k escape can be used to refer to named subexpressions, for example [^\k] will whatever matched the subexpression named "two". [h4 Alternation] diff --git a/doc/unicode.qbk b/doc/unicode.qbk index 2e86ad0c..8ab64fcd 100644 --- a/doc/unicode.qbk +++ b/doc/unicode.qbk @@ -29,10 +29,7 @@ characters, it is not possible to search UTF-8, or even UTF-16 on many platforms If you have the [@http://www.ibm.com/software/globalization/icu/ ICU library], then -Boost.Regex can be -[link boost_regex.install.building_with_unicode_and_icu_su -configured to make use -of it], and provide a distinct regular expression type (boost::u32regex), +Boost.Regex provides a distinct regular expression type (boost::u32regex), that supports both Unicode specific character properties, and the searching of text that is encoded in either UTF-8, UTF-16, or UTF-32. See: [link boost_regex.ref.non_std_strings.icu diff --git a/include/boost/regex/v4/basic_regex_parser.hpp b/include/boost/regex/v4/basic_regex_parser.hpp index 57f4c26e..1b7121f0 100644 --- a/include/boost/regex/v4/basic_regex_parser.hpp +++ b/include/boost/regex/v4/basic_regex_parser.hpp @@ -1055,6 +1055,7 @@ bool basic_regex_parser::parse_repeat(std::size_t low, std::size_ case syntax_element_jump: case syntax_element_startmark: case syntax_element_backstep: + case syntax_element_toggle_case: // can't legally repeat any of the above: fail(regex_constants::error_badrepeat, m_position - m_base); return false; @@ -3140,7 +3141,13 @@ bool basic_regex_parser::unwind_alts(std::ptrdiff_t last_paren_st m_alt_jumps.pop_back(); this->m_pdata->m_data.align(); re_jump* jmp = static_cast(this->getaddress(jump_offset)); - BOOST_REGEX_ASSERT(jmp->type == syntax_element_jump); + if (jmp->type != syntax_element_jump) + { + // Something really bad happened, this used to be an assert, + // but we'll make it an error just in case we should ever get here. + fail(regex_constants::error_unknown, this->m_position - this->m_base, "Internal logic failed while compiling the expression, probably you added a repeat to something non-repeatable!"); + return false; + } jmp->alt.i = this->m_pdata->m_data.size() - jump_offset; } return true; diff --git a/include/boost/regex/v4/icu.hpp b/include/boost/regex/v4/icu.hpp index 9724b0f8..7e70f57e 100644 --- a/include/boost/regex/v4/icu.hpp +++ b/include/boost/regex/v4/icu.hpp @@ -187,7 +187,7 @@ namespace boost { } char_type translate_nocase(char_type c) const { - return ::u_tolower(c); + return ::u_foldCase(c, U_FOLD_CASE_DEFAULT); } char_type translate(char_type c, bool icase) const { diff --git a/include/boost/regex/v4/pattern_except.hpp b/include/boost/regex/v4/pattern_except.hpp index 56e83cc9..7aba564b 100644 --- a/include/boost/regex/v4/pattern_except.hpp +++ b/include/boost/regex/v4/pattern_except.hpp @@ -88,7 +88,8 @@ typedef regex_error bad_expression; namespace BOOST_REGEX_DETAIL_NS{ -inline void BOOST_REGEX_CALL raise_runtime_error(const std::runtime_error& ex) +template +inline void raise_runtime_error(const E& ex) { #ifndef BOOST_REGEX_STANDALONE ::boost::throw_exception(ex); @@ -101,7 +102,7 @@ template void raise_error(const traits& t, regex_constants::error_type code) { (void)t; // warning suppression - std::runtime_error e(t.error_string(code)); + regex_error e(t.error_string(code), code, 0); ::boost::BOOST_REGEX_DETAIL_NS::raise_runtime_error(e); } diff --git a/include/boost/regex/v4/perl_matcher_non_recursive.hpp b/include/boost/regex/v4/perl_matcher_non_recursive.hpp index 9b770f15..670efbab 100644 --- a/include/boost/regex/v4/perl_matcher_non_recursive.hpp +++ b/include/boost/regex/v4/perl_matcher_non_recursive.hpp @@ -1354,6 +1354,7 @@ bool perl_matcher::unwind_alt(bool r) template bool perl_matcher::unwind_repeater_counter(bool) { + ++used_block_count; saved_repeater* pmp = static_cast*>(m_backup_state); boost::BOOST_REGEX_DETAIL_NS::inplace_destroy(pmp++); m_backup_state = pmp; diff --git a/include/boost/regex/v5/basic_regex_creator.hpp b/include/boost/regex/v5/basic_regex_creator.hpp index ddd2f257..82306d36 100644 --- a/include/boost/regex/v5/basic_regex_creator.hpp +++ b/include/boost/regex/v5/basic_regex_creator.hpp @@ -20,8 +20,6 @@ #ifndef BOOST_REGEX_V5_BASIC_REGEX_CREATOR_HPP #define BOOST_REGEX_V5_BASIC_REGEX_CREATOR_HPP -#include - #ifdef BOOST_REGEX_MSVC # pragma warning(push) #pragma warning(disable:4459) @@ -30,6 +28,8 @@ #endif #endif +#include + namespace boost{ namespace BOOST_REGEX_DETAIL_NS{ @@ -232,7 +232,6 @@ protected: bool m_icase; // true for case insensitive matches unsigned m_repeater_id; // the state_id of the next repeater bool m_has_backrefs; // true if there are actually any backrefs - indexed_bit_flag m_backrefs; // bitmask of permitted backrefs std::uintmax_t m_bad_repeats; // bitmask of repeats we can't deduce a startmap for; bool m_has_recursions; // set when we have recursive expressions to fixup std::vector m_recursion_checks; // notes which recursions we've followed while analysing this expression diff --git a/include/boost/regex/v5/basic_regex_parser.hpp b/include/boost/regex/v5/basic_regex_parser.hpp index 11d581d9..34d775ef 100644 --- a/include/boost/regex/v5/basic_regex_parser.hpp +++ b/include/boost/regex/v5/basic_regex_parser.hpp @@ -98,6 +98,7 @@ private: std::ptrdiff_t m_alt_insert_point; // where to insert the next alternative bool m_has_case_change; // true if somewhere in the current block the case has changed unsigned m_recursion_count; // How many times we've called parse_all. + unsigned m_max_backref; // Largest index of any backref. #if defined(BOOST_REGEX_MSVC) && defined(_M_IX86) // This is an ugly warning suppression workaround (for warnings *inside* std::vector // that can not otherwise be suppressed)... @@ -114,7 +115,7 @@ private: template basic_regex_parser::basic_regex_parser(regex_data* data) : basic_regex_creator(data), m_parser_proc(), m_base(0), m_end(0), m_position(0), - m_mark_count(0), m_mark_reset(-1), m_max_mark(0), m_paren_start(0), m_alt_insert_point(0), m_has_case_change(false), m_recursion_count(0) + m_mark_count(0), m_mark_reset(-1), m_max_mark(0), m_paren_start(0), m_alt_insert_point(0), m_has_case_change(false), m_recursion_count(0), m_max_backref(0) { } @@ -184,6 +185,13 @@ void basic_regex_parser::parse(const charT* p1, const charT* p2, return; // fill in our sub-expression count: this->m_pdata->m_mark_count = 1u + (std::size_t)m_mark_count; + // + // Check we don't have backreferences to sub-expressions which don't exist: + // + if (m_max_backref > m_mark_count) + { + fail(regex_constants::error_backref, std::distance(m_base, m_position), "Found a backreference to a non-existant sub-expression."); + } this->finalize(p1, p2); } @@ -529,11 +537,6 @@ bool basic_regex_parser::parse_open_paren() // restore the alternate insertion point: // this->m_alt_insert_point = last_alt_point; - // - // allow backrefs to this mark: - // - if(markid > 0) - this->m_backrefs.set(markid); return true; } @@ -899,12 +902,14 @@ escape_type_class_jump: } if(negative) i = 1 + (static_cast(m_mark_count) - i); - if(((i < hash_value_mask) && (i > 0) && (this->m_backrefs.test((std::size_t)i))) || ((i >= hash_value_mask) && (this->m_pdata->get_id((int)i) > 0) && (this->m_backrefs.test(this->m_pdata->get_id((int)i))))) + if(((i < hash_value_mask) && (i > 0)) || ((i >= hash_value_mask) && (this->m_pdata->get_id((int)i) > 0))) { m_position = pc; re_brace* pb = static_cast(this->append_state(syntax_element_backref, sizeof(re_brace))); pb->index = (int)i; pb->icase = this->flags() & regbase::icase; + if ((i > m_max_backref) && (i < hash_value_mask)) + m_max_backref = i; } else { @@ -1029,6 +1034,7 @@ bool basic_regex_parser::parse_repeat(std::size_t low, std::size_ case syntax_element_jump: case syntax_element_startmark: case syntax_element_backstep: + case syntax_element_toggle_case: // can't legally repeat any of the above: fail(regex_constants::error_badrepeat, m_position - m_base); return false; @@ -1934,12 +1940,14 @@ bool basic_regex_parser::parse_backref() charT c = unescape_character(); this->append_literal(c); } - else if((i > 0) && (this->m_backrefs.test((std::size_t)i))) + else if((i > 0)) { m_position = pc; re_brace* pb = static_cast(this->append_state(syntax_element_backref, sizeof(re_brace))); pb->index = (int)i; pb->icase = this->flags() & regbase::icase; + if(i > m_max_backref) + m_max_backref = i; } else { @@ -2695,10 +2703,6 @@ option_group_jump: { if(this->flags() & regbase::save_subexpression_location) this->m_pdata->m_subs.at((std::size_t)markid - 1).second = std::distance(m_base, m_position) - 1; - // - // allow backrefs to this mark: - // - this->m_backrefs.set(markid); } return true; } @@ -3104,7 +3108,13 @@ bool basic_regex_parser::unwind_alts(std::ptrdiff_t last_paren_st m_alt_jumps.pop_back(); this->m_pdata->m_data.align(); re_jump* jmp = static_cast(this->getaddress(jump_offset)); - BOOST_REGEX_ASSERT(jmp->type == syntax_element_jump); + if (jmp->type != syntax_element_jump) + { + // Something really bad happened, this used to be an assert, + // but we'll make it an error just in case we should ever get here. + fail(regex_constants::error_unknown, this->m_position - this->m_base, "Internal logic failed while compiling the expression, probably you added a repeat to something non-repeatable!"); + return false; + } jmp->alt.i = this->m_pdata->m_data.size() - jump_offset; } return true; diff --git a/include/boost/regex/v5/icu.hpp b/include/boost/regex/v5/icu.hpp index a9264965..f172553d 100644 --- a/include/boost/regex/v5/icu.hpp +++ b/include/boost/regex/v5/icu.hpp @@ -161,7 +161,7 @@ public: } char_type translate_nocase(char_type c) const { - return ::u_tolower(c); + return ::u_foldCase(c, U_FOLD_CASE_DEFAULT); } char_type translate(char_type c, bool icase) const { diff --git a/include/boost/regex/v5/indexed_bit_flag.hpp b/include/boost/regex/v5/indexed_bit_flag.hpp deleted file mode 100644 index b61e5cad..00000000 --- a/include/boost/regex/v5/indexed_bit_flag.hpp +++ /dev/null @@ -1,54 +0,0 @@ -/* - * - * Copyright (c) 2020 - * John Maddock - * - * Use, modification and distribution are subject to the - * Boost Software License, Version 1.0. (See accompanying file - * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - * - */ - - /* - * LOCATION: see http://www.boost.org for most recent version. - * FILE basic_regex_parser.cpp - * VERSION see - * DESCRIPTION: Declares template class basic_regex_parser. - */ - -#include -#include - -#ifndef BOOST_REGEX_V5_INDEXED_BIT_FLAG_HPP -#define BOOST_REGEX_V5_INDEXED_BIT_FLAG_HPP - -namespace boost{ -namespace BOOST_REGEX_DETAIL_NS{ - -class indexed_bit_flag -{ - std::uint64_t low_mask; - std::set mask_set; -public: - indexed_bit_flag() : low_mask(0) {} - void set(std::size_t i) - { - if (i < std::numeric_limits::digits - 1) - low_mask |= static_cast(1u) << i; - else - mask_set.insert(i); - } - bool test(std::size_t i) - { - if (i < std::numeric_limits::digits - 1) - return low_mask & static_cast(1u) << i ? true : false; - else - return mask_set.find(i) != mask_set.end(); - } -}; - -} // namespace BOOST_REGEX_DETAIL_NS -} // namespace boost - - -#endif diff --git a/include/boost/regex/v5/pattern_except.hpp b/include/boost/regex/v5/pattern_except.hpp index 731aefb6..3fbdca0a 100644 --- a/include/boost/regex/v5/pattern_except.hpp +++ b/include/boost/regex/v5/pattern_except.hpp @@ -77,7 +77,8 @@ typedef regex_error bad_expression; namespace BOOST_REGEX_DETAIL_NS{ -inline void raise_runtime_error(const std::runtime_error& ex) +template +inline void raise_runtime_error(const E& ex) { #ifndef BOOST_REGEX_STANDALONE ::boost::throw_exception(ex); @@ -90,7 +91,7 @@ template void raise_error(const traits& t, regex_constants::error_type code) { (void)t; // warning suppression - std::runtime_error e(t.error_string(code)); + regex_error e(t.error_string(code), code, 0); ::boost::BOOST_REGEX_DETAIL_NS::raise_runtime_error(e); } diff --git a/include/boost/regex/v5/perl_matcher_common.hpp b/include/boost/regex/v5/perl_matcher_common.hpp index 5b29d893..dcce9e6a 100644 --- a/include/boost/regex/v5/perl_matcher_common.hpp +++ b/include/boost/regex/v5/perl_matcher_common.hpp @@ -471,6 +471,11 @@ bool perl_matcher::match_word_boundary() template bool perl_matcher::match_within_word() { + bool b = !match_word_boundary(); + if(b) + pstate = pstate->next.p; + return b; + /* if(position == last) return false; // both prev and this character must be m_word_mask: @@ -492,6 +497,7 @@ bool perl_matcher::match_within_word() } } return false; + */ } template diff --git a/include/boost/regex/v5/perl_matcher_non_recursive.hpp b/include/boost/regex/v5/perl_matcher_non_recursive.hpp index 1d2f0a53..28d6c462 100644 --- a/include/boost/regex/v5/perl_matcher_non_recursive.hpp +++ b/include/boost/regex/v5/perl_matcher_non_recursive.hpp @@ -417,7 +417,8 @@ bool perl_matcher::match_startmark() { // Must be unwinding from a COMMIT/SKIP/PRUNE and the independent // sub failed, need to unwind everything else: - while(unwind(false)); + while (m_backup_state->state_id) + unwind(false); return false; } #if !defined(BOOST_NO_EXCEPTIONS) @@ -1353,6 +1354,7 @@ bool perl_matcher::unwind_repeater_counter(bool template bool perl_matcher::unwind_extra_block(bool) { + ++used_block_count; saved_extra_block* pmp = static_cast(m_backup_state); void* condemmed = m_stack_base; m_stack_base = pmp->base; diff --git a/include/boost/regex/v5/w32_regex_traits.hpp b/include/boost/regex/v5/w32_regex_traits.hpp index 5a9e93b6..16f7ee4e 100644 --- a/include/boost/regex/v5/w32_regex_traits.hpp +++ b/include/boost/regex/v5/w32_regex_traits.hpp @@ -29,14 +29,6 @@ #include #include -#ifndef VC_EXTRALEAN -# define VC_EXTRALEAN -#endif -#ifndef WIN32_LEAN_AND_MEAN -# define WIN32_LEAN_AND_MEAN -#endif -#include - #if defined(_MSC_VER) && !defined(_WIN32_WCE) && !defined(UNDER_CE) #pragma comment(lib, "user32.lib") #endif @@ -49,6 +41,31 @@ #endif #endif +#ifndef BASETYPES +// +// windows.h not included, so lets forward declare what we need: +// +#ifndef NO_STRICT +#ifndef STRICT +#define STRICT 1 +#endif +#endif + +#if defined(STRICT) +#define BOOST_RE_DETAIL_DECLARE_HANDLE(x) struct x##__; typedef struct x##__ *x +#else +#define BOOST_RE_DETAIL_DECLARE_HANDLE(x) typedef void* x +#endif +// +// This must be in the global namespace: +// +extern "C" { + + BOOST_RE_DETAIL_DECLARE_HANDLE(HINSTANCE); + typedef HINSTANCE HMODULE; +} +#endif + namespace boost{ // @@ -62,7 +79,7 @@ namespace BOOST_REGEX_DETAIL_NS{ // // start by typedeffing the types we'll need: // -typedef std::uint32_t lcid_type; // placeholder for LCID. +typedef unsigned long lcid_type; // placeholder for LCID. typedef std::shared_ptr cat_type; // placeholder for dll HANDLE. // @@ -97,6 +114,125 @@ wchar_t w32_toupper(wchar_t c, lcid_type); bool w32_is(lcid_type, std::uint32_t mask, char c); #ifndef BOOST_NO_WREGEX bool w32_is(lcid_type, std::uint32_t mask, wchar_t c); +#endif + +#ifndef BASETYPES +// +// Forward declarations of the small number of windows types and API's we use: +// + +#if !defined(__LP64__) +using dword = unsigned long; +#else +using DWORD = unsigned int; +#endif +using word = unsigned short; +using lctype = dword; + +static constexpr dword ct_ctype1 = 0x00000001; +static constexpr dword c1_upper = 0x0001; // upper case +static constexpr dword c1_lower = 0x0002; // lower case +static constexpr dword c1_digit = 0x0004; // decimal digits +static constexpr dword c1_space = 0x0008; // spacing characters +static constexpr dword c1_punct = 0x0010; // punctuation characters +static constexpr dword c1_cntrl = 0x0020; // control characters +static constexpr dword c1_blank = 0x0040; // blank characters +static constexpr dword c1_xdigit = 0x0080; // other digits +static constexpr dword c1_alpha = 0x0100; // any linguistic character +static constexpr dword c1_defined = 0x0200; // defined character +static constexpr unsigned int cp_acp = 0; +static constexpr dword lcmap_lowercase = 0x00000100; +static constexpr dword lcmap_uppercase = 0x00000200; +static constexpr dword lcmap_sortkey = 0x00000400; // WC sort key (normalize) +static constexpr lctype locale_idefaultansicodepage = 0x00001004; + +# ifdef UNDER_CE +# ifndef WINAPI +# ifndef _WIN32_WCE_EMULATION +# define BOOST_RE_STDCALL __cdecl // Note this doesn't match the desktop definition +# else +# define BOOST_RE_STDCALL __stdcall +# endif +# endif +# else +# if defined(_M_IX86) || defined(__i386__) +# define BOOST_RE_STDCALL __stdcall +# else + // On architectures other than 32-bit x86 __stdcall is ignored. Clang also issues a warning. +# define BOOST_RE_STDCALL +# endif +# endif + +#if defined (WIN32_PLATFORM_PSPC) +#define BOOST_RE_IMPORT __declspec( dllimport ) +#elif defined (_WIN32_WCE) +#define BOOST_RE_IMPORT +#else +#define BOOST_RE_IMPORT __declspec( dllimport ) +#endif + +extern "C" { + + BOOST_RE_IMPORT int BOOST_RE_STDCALL FreeLibrary(HMODULE hLibModule); + BOOST_RE_IMPORT int BOOST_RE_STDCALL LCMapStringA(lcid_type Locale, dword dwMapFlags, const char* lpSrcStr, int cchSrc, char* lpDestStr, int cchDest); + BOOST_RE_IMPORT int BOOST_RE_STDCALL LCMapStringW(lcid_type Locale, dword dwMapFlags, const wchar_t* lpSrcStr, int cchSrc, wchar_t* lpDestStr, int cchDest); + BOOST_RE_IMPORT int BOOST_RE_STDCALL MultiByteToWideChar(unsigned int CodePage, dword dwFlags, const char* lpMultiByteStr, int cbMultiByte, wchar_t* lpWideCharStr, int cchWideChar); + BOOST_RE_IMPORT int BOOST_RE_STDCALL LCMapStringW(lcid_type Locale, dword dwMapFlags, const wchar_t* lpSrcStr, int cchSrc, wchar_t* lpDestStr, int cchDest); + BOOST_RE_IMPORT int BOOST_RE_STDCALL WideCharToMultiByte(unsigned int CodePage, dword dwFlags, const wchar_t* lpWideCharStr, int cchWideChar, char* lpMultiByteStr, int cbMultiByte, const char* lpDefaultChar, int* lpUsedDefaultChar); + BOOST_RE_IMPORT int BOOST_RE_STDCALL GetStringTypeExA(lcid_type Locale, dword dwInfoType, const char* lpSrcStr, int cchSrc, word* lpCharType); + BOOST_RE_IMPORT int BOOST_RE_STDCALL GetStringTypeExW(lcid_type Locale, dword dwInfoType, const wchar_t* lpSrcStr, int cchSrc, word* lpCharType); + BOOST_RE_IMPORT lcid_type BOOST_RE_STDCALL GetUserDefaultLCID(); + BOOST_RE_IMPORT int BOOST_RE_STDCALL GetStringTypeExA(lcid_type Locale, dword dwInfoType, const char* lpSrcStr, int cchSrc, word* lpCharType); + BOOST_RE_IMPORT int BOOST_RE_STDCALL GetStringTypeExW(lcid_type Locale, dword dwInfoType, const wchar_t* lpSrcStr, int cchSrc, word* lpCharType); + BOOST_RE_IMPORT HMODULE BOOST_RE_STDCALL LoadLibraryA(const char* lpLibFileName); + BOOST_RE_IMPORT HMODULE BOOST_RE_STDCALL LoadLibraryW(const wchar_t* lpLibFileName); + BOOST_RE_IMPORT int BOOST_RE_STDCALL LoadStringW(HINSTANCE hInstance, unsigned int uID, wchar_t* lpBuffer, int cchBufferMax); + BOOST_RE_IMPORT int BOOST_RE_STDCALL LoadStringA(HINSTANCE hInstance, unsigned int uID, char* lpBuffer, int cchBufferMax); + BOOST_RE_IMPORT int BOOST_RE_STDCALL GetLocaleInfoW(lcid_type Locale, lctype LCType, wchar_t* lpLCData, int cchData); +} + +#else +// +// We have windows.h already included: +// +using dword = DWORD; +using word = WORD; +using lctype = LCTYPE; + +static constexpr dword ct_ctype1 = 0x00000001; +static constexpr dword c1_upper = 0x0001; // upper case +static constexpr dword c1_lower = 0x0002; // lower case +static constexpr dword c1_digit = 0x0004; // decimal digits +static constexpr dword c1_space = 0x0008; // spacing characters +static constexpr dword c1_punct = 0x0010; // punctuation characters +static constexpr dword c1_cntrl = 0x0020; // control characters +static constexpr dword c1_blank = 0x0040; // blank characters +static constexpr dword c1_xdigit = 0x0080; // other digits +static constexpr dword c1_alpha = 0x0100; // any linguistic character +static constexpr dword c1_defined = 0x0200; // defined character +static constexpr unsigned int cp_acp = 0; +static constexpr dword lcmap_lowercase = 0x00000100; +static constexpr dword lcmap_uppercase = 0x00000200; +static constexpr dword lcmap_sortkey = 0x00000400; // WC sort key (normalize) +static constexpr lctype locale_idefaultansicodepage = 0x00001004; + +using ::FreeLibrary; +using ::LCMapStringA; +using ::LCMapStringW; +using ::MultiByteToWideChar; +using ::LCMapStringW; +using ::WideCharToMultiByte; +using ::GetStringTypeExA; +using ::GetStringTypeExW; +using ::GetUserDefaultLCID; +using ::GetStringTypeExA; +using ::GetStringTypeExW; +using ::LoadLibraryA; +using ::LoadLibraryW; +using ::LoadStringW; +using ::LoadStringA; +using ::GetLocaleInfoW; + #endif // // class w32_regex_traits_base: @@ -679,13 +815,13 @@ std::mutex& w32_regex_traits::get_mutex_inst() namespace BOOST_REGEX_DETAIL_NS { #ifdef BOOST_NO_ANSI_APIS - inline UINT get_code_page_for_locale_id(lcid_type idx) + inline unsigned int get_code_page_for_locale_id(lcid_type idx) { - WCHAR code_page_string[7]; - if (::GetLocaleInfoW(idx, LOCALE_IDEFAULTANSICODEPAGE, code_page_string, 7) == 0) + wchar_t code_page_string[7]; + if (boost::BOOST_REGEX_DETAIL_NS::GetLocaleInfoW(idx, locale_idefaultansicodepage, code_page_string, 7) == 0) return 0; - return static_cast(_wtol(code_page_string)); + return static_cast(_wtol(code_page_string)); } #endif @@ -755,21 +891,21 @@ namespace BOOST_REGEX_DETAIL_NS { for (int ii = 0; ii < (1 << CHAR_BIT); ++ii) char_map[ii] = static_cast(ii); #ifndef BOOST_NO_ANSI_APIS - int r = ::LCMapStringA(this->m_locale, LCMAP_LOWERCASE, char_map, 1 << CHAR_BIT, this->m_lower_map, 1 << CHAR_BIT); + int r = boost::BOOST_REGEX_DETAIL_NS::LCMapStringA(this->m_locale, lcmap_lowercase, char_map, 1 << CHAR_BIT, this->m_lower_map, 1 << CHAR_BIT); BOOST_REGEX_ASSERT(r != 0); #else - UINT code_page = get_code_page_for_locale_id(this->m_locale); + unsigned int code_page = get_code_page_for_locale_id(this->m_locale); BOOST_REGEX_ASSERT(code_page != 0); - WCHAR wide_char_map[1 << CHAR_BIT]; - int conv_r = ::MultiByteToWideChar(code_page, 0, char_map, 1 << CHAR_BIT, wide_char_map, 1 << CHAR_BIT); + wchar_t wide_char_map[1 << CHAR_BIT]; + int conv_r = boost::BOOST_REGEX_DETAIL_NS::MultiByteToWideChar(code_page, 0, char_map, 1 << CHAR_BIT, wide_char_map, 1 << CHAR_BIT); BOOST_REGEX_ASSERT(conv_r != 0); - WCHAR wide_lower_map[1 << CHAR_BIT]; - int r = ::LCMapStringW(this->m_locale, LCMAP_LOWERCASE, wide_char_map, 1 << CHAR_BIT, wide_lower_map, 1 << CHAR_BIT); + wchar_t wide_lower_map[1 << CHAR_BIT]; + int r = boost::BOOST_REGEX_DETAIL_NS::LCMapStringW(this->m_locale, lcmap_lowercase, wide_char_map, 1 << CHAR_BIT, wide_lower_map, 1 << CHAR_BIT); BOOST_REGEX_ASSERT(r != 0); - conv_r = ::WideCharToMultiByte(code_page, 0, wide_lower_map, r, this->m_lower_map, 1 << CHAR_BIT, NULL, NULL); + conv_r = boost::BOOST_REGEX_DETAIL_NS::WideCharToMultiByte(code_page, 0, wide_lower_map, r, this->m_lower_map, 1 << CHAR_BIT, NULL, NULL); BOOST_REGEX_ASSERT(conv_r != 0); #endif if (r < (1 << CHAR_BIT)) @@ -781,36 +917,36 @@ namespace BOOST_REGEX_DETAIL_NS { } #ifndef BOOST_NO_ANSI_APIS - r = ::GetStringTypeExA(this->m_locale, CT_CTYPE1, char_map, 1 << CHAR_BIT, this->m_type_map); + r = boost::BOOST_REGEX_DETAIL_NS::GetStringTypeExA(this->m_locale, ct_ctype1, char_map, 1 << CHAR_BIT, this->m_type_map); #else - r = ::GetStringTypeExW(this->m_locale, CT_CTYPE1, wide_char_map, 1 << CHAR_BIT, this->m_type_map); + r = boost::BOOST_REGEX_DETAIL_NS::GetStringTypeExW(this->m_locale, ct_ctype1, wide_char_map, 1 << CHAR_BIT, this->m_type_map); #endif BOOST_REGEX_ASSERT(0 != r); } inline lcid_type w32_get_default_locale() { - return ::GetUserDefaultLCID(); + return boost::BOOST_REGEX_DETAIL_NS::GetUserDefaultLCID(); } inline bool w32_is_lower(char c, lcid_type idx) { #ifndef BOOST_NO_ANSI_APIS - WORD mask; - if (::GetStringTypeExA(idx, CT_CTYPE1, &c, 1, &mask) && (mask & C1_LOWER)) + word mask; + if (boost::BOOST_REGEX_DETAIL_NS::GetStringTypeExA(idx, ct_ctype1, &c, 1, &mask) && (mask & c1_lower)) return true; return false; #else - UINT code_page = get_code_page_for_locale_id(idx); + unsigned int code_page = get_code_page_for_locale_id(idx); if (code_page == 0) return false; - WCHAR wide_c; - if (::MultiByteToWideChar(code_page, 0, &c, 1, &wide_c, 1) == 0) + wchar_t wide_c; + if (boost::BOOST_REGEX_DETAIL_NS::MultiByteToWideChar(code_page, 0, &c, 1, &wide_c, 1) == 0) return false; - WORD mask; - if (::GetStringTypeExW(idx, CT_CTYPE1, &wide_c, 1, &mask) && (mask & C1_LOWER)) + word mask; + if (boost::BOOST_REGEX_DETAIL_NS::GetStringTypeExW(idx, ct_ctype1, &wide_c, 1, &mask) && (mask & c1_lower)) return true; return false; #endif @@ -818,8 +954,8 @@ namespace BOOST_REGEX_DETAIL_NS { inline bool w32_is_lower(wchar_t c, lcid_type idx) { - WORD mask; - if (::GetStringTypeExW(idx, CT_CTYPE1, &c, 1, &mask) && (mask & C1_LOWER)) + word mask; + if (boost::BOOST_REGEX_DETAIL_NS::GetStringTypeExW(idx, ct_ctype1, &c, 1, &mask) && (mask & c1_lower)) return true; return false; } @@ -827,21 +963,21 @@ namespace BOOST_REGEX_DETAIL_NS { inline bool w32_is_upper(char c, lcid_type idx) { #ifndef BOOST_NO_ANSI_APIS - WORD mask; - if (::GetStringTypeExA(idx, CT_CTYPE1, &c, 1, &mask) && (mask & C1_UPPER)) + word mask; + if (boost::BOOST_REGEX_DETAIL_NS::GetStringTypeExA(idx, ct_ctype1, &c, 1, &mask) && (mask & c1_upper)) return true; return false; #else - UINT code_page = get_code_page_for_locale_id(idx); + unsigned int code_page = get_code_page_for_locale_id(idx); if (code_page == 0) return false; - WCHAR wide_c; - if (::MultiByteToWideChar(code_page, 0, &c, 1, &wide_c, 1) == 0) + wchar_t wide_c; + if (boost::BOOST_REGEX_DETAIL_NS::MultiByteToWideChar(code_page, 0, &c, 1, &wide_c, 1) == 0) return false; - WORD mask; - if (::GetStringTypeExW(idx, CT_CTYPE1, &wide_c, 1, &mask) && (mask & C1_UPPER)) + word mask; + if (boost::BOOST_REGEX_DETAIL_NS::GetStringTypeExW(idx, ct_ctype1, &wide_c, 1, &mask) && (mask & c1_upper)) return true; return false; #endif @@ -849,28 +985,28 @@ namespace BOOST_REGEX_DETAIL_NS { inline bool w32_is_upper(wchar_t c, lcid_type idx) { - WORD mask; - if (::GetStringTypeExW(idx, CT_CTYPE1, &c, 1, &mask) && (mask & C1_UPPER)) + word mask; + if (boost::BOOST_REGEX_DETAIL_NS::GetStringTypeExW(idx, ct_ctype1, &c, 1, &mask) && (mask & c1_upper)) return true; return false; } inline void free_module(void* mod) { - ::FreeLibrary(static_cast(mod)); + boost::BOOST_REGEX_DETAIL_NS::FreeLibrary(static_cast(mod)); } inline cat_type w32_cat_open(const std::string& name) { #ifndef BOOST_NO_ANSI_APIS - cat_type result(::LoadLibraryA(name.c_str()), &free_module); + cat_type result(boost::BOOST_REGEX_DETAIL_NS::LoadLibraryA(name.c_str()), &free_module); return result; #else - LPWSTR wide_name = (LPWSTR)_alloca((name.size() + 1) * sizeof(WCHAR)); - if (::MultiByteToWideChar(CP_ACP, 0, name.c_str(), name.size(), wide_name, name.size() + 1) == 0) + wchar_t* wide_name = (wchar_t*)_alloca((name.size() + 1) * sizeof(wchar_t)); + if (boost::BOOST_REGEX_DETAIL_NS::MultiByteToWideChar(cp_acp, 0, name.c_str(), (int)name.size(), wide_name, (int)(name.size() + 1)) == 0) return cat_type(); - cat_type result(::LoadLibraryW(wide_name), &free_module); + cat_type result(boost::BOOST_REGEX_DETAIL_NS::LoadLibraryW(wide_name), &free_module); return result; #endif } @@ -879,7 +1015,7 @@ namespace BOOST_REGEX_DETAIL_NS { { #ifndef BOOST_NO_ANSI_APIS char buf[256]; - if (0 == ::LoadStringA( + if (0 == boost::BOOST_REGEX_DETAIL_NS::LoadStringA( static_cast(cat.get()), i, buf, @@ -889,8 +1025,8 @@ namespace BOOST_REGEX_DETAIL_NS { return def; } #else - WCHAR wbuf[256]; - int r = ::LoadStringW( + wchar_t wbuf[256]; + int r = boost::BOOST_REGEX_DETAIL_NS::LoadStringW( static_cast(cat.get()), i, wbuf, @@ -900,9 +1036,9 @@ namespace BOOST_REGEX_DETAIL_NS { return def; - int buf_size = 1 + ::WideCharToMultiByte(CP_ACP, 0, wbuf, r, NULL, 0, NULL, NULL); - LPSTR buf = (LPSTR)_alloca(buf_size); - if (::WideCharToMultiByte(CP_ACP, 0, wbuf, r, buf, buf_size, NULL, NULL) == 0) + int buf_size = 1 + boost::BOOST_REGEX_DETAIL_NS::WideCharToMultiByte(cp_acp, 0, wbuf, r, NULL, 0, NULL, NULL); + char* buf = (char*)_alloca(buf_size); + if (boost::BOOST_REGEX_DETAIL_NS::WideCharToMultiByte(cp_acp, 0, wbuf, r, buf, buf_size, NULL, NULL) == 0) return def; // failed conversion. #endif return std::string(buf); @@ -912,12 +1048,7 @@ namespace BOOST_REGEX_DETAIL_NS { inline std::wstring w32_cat_get(const cat_type& cat, lcid_type, int i, const std::wstring& def) { wchar_t buf[256]; - if (0 == ::LoadStringW( - static_cast(cat.get()), - i, - buf, - 256 - )) + if (0 == boost::BOOST_REGEX_DETAIL_NS::LoadStringW(static_cast(cat.get()), i, buf, 256)) { return def; } @@ -927,9 +1058,9 @@ namespace BOOST_REGEX_DETAIL_NS { inline std::string w32_transform(lcid_type idx, const char* p1, const char* p2) { #ifndef BOOST_NO_ANSI_APIS - int bytes = ::LCMapStringA( + int bytes = boost::BOOST_REGEX_DETAIL_NS::LCMapStringA( idx, // locale identifier - LCMAP_SORTKEY, // mapping transformation type + lcmap_sortkey, // mapping transformation type p1, // source string static_cast(p2 - p1), // number of characters in source string 0, // destination buffer @@ -938,27 +1069,27 @@ namespace BOOST_REGEX_DETAIL_NS { if (!bytes) return std::string(p1, p2); std::string result(++bytes, '\0'); - bytes = ::LCMapStringA( + bytes = boost::BOOST_REGEX_DETAIL_NS::LCMapStringA( idx, // locale identifier - LCMAP_SORTKEY, // mapping transformation type + lcmap_sortkey, // mapping transformation type p1, // source string static_cast(p2 - p1), // number of characters in source string &*result.begin(), // destination buffer bytes // size of destination buffer ); #else - UINT code_page = get_code_page_for_locale_id(idx); + unsigned int code_page = get_code_page_for_locale_id(idx); if (code_page == 0) return std::string(p1, p2); int src_len = static_cast(p2 - p1); - LPWSTR wide_p1 = (LPWSTR)_alloca((src_len + 1) * 2); - if (::MultiByteToWideChar(code_page, 0, p1, src_len, wide_p1, src_len + 1) == 0) + wchar_t* wide_p1 = (wchar_t*)_alloca((src_len + 1) * 2); + if (boost::BOOST_REGEX_DETAIL_NS::MultiByteToWideChar(code_page, 0, p1, src_len, wide_p1, src_len + 1) == 0) return std::string(p1, p2); - int bytes = ::LCMapStringW( + int bytes = boost::BOOST_REGEX_DETAIL_NS::LCMapStringW( idx, // locale identifier - LCMAP_SORTKEY, // mapping transformation type + lcmap_sortkey, // mapping transformation type wide_p1, // source string src_len, // number of characters in source string 0, // destination buffer @@ -967,12 +1098,12 @@ namespace BOOST_REGEX_DETAIL_NS { if (!bytes) return std::string(p1, p2); std::string result(++bytes, '\0'); - bytes = ::LCMapStringW( + bytes = boost::BOOST_REGEX_DETAIL_NS::LCMapStringW( idx, // locale identifier - LCMAP_SORTKEY, // mapping transformation type + lcmap_sortkey, // mapping transformation type wide_p1, // source string src_len, // number of characters in source string - (LPWSTR) & *result.begin(), // destination buffer + (wchar_t*) & *result.begin(), // destination buffer bytes // size of destination buffer ); #endif @@ -988,9 +1119,9 @@ namespace BOOST_REGEX_DETAIL_NS { #ifndef BOOST_NO_WREGEX inline std::wstring w32_transform(lcid_type idx, const wchar_t* p1, const wchar_t* p2) { - int bytes = ::LCMapStringW( + int bytes = boost::BOOST_REGEX_DETAIL_NS::LCMapStringW( idx, // locale identifier - LCMAP_SORTKEY, // mapping transformation type + lcmap_sortkey, // mapping transformation type p1, // source string static_cast(p2 - p1), // number of characters in source string 0, // destination buffer @@ -999,9 +1130,9 @@ namespace BOOST_REGEX_DETAIL_NS { if (!bytes) return std::wstring(p1, p2); std::string result(++bytes, '\0'); - bytes = ::LCMapStringW( + bytes = boost::BOOST_REGEX_DETAIL_NS::LCMapStringW( idx, // locale identifier - LCMAP_SORTKEY, // mapping transformation type + lcmap_sortkey, // mapping transformation type p1, // source string static_cast(p2 - p1), // number of characters in source string reinterpret_cast(&*result.begin()), // destination buffer *of bytes* @@ -1023,9 +1154,9 @@ namespace BOOST_REGEX_DETAIL_NS { { char result[2]; #ifndef BOOST_NO_ANSI_APIS - int b = ::LCMapStringA( + int b = boost::BOOST_REGEX_DETAIL_NS::LCMapStringA( idx, // locale identifier - LCMAP_LOWERCASE, // mapping transformation type + lcmap_lowercase, // mapping transformation type &c, // source string 1, // number of characters in source string result, // destination buffer @@ -1033,18 +1164,18 @@ namespace BOOST_REGEX_DETAIL_NS { if (b == 0) return c; #else - UINT code_page = get_code_page_for_locale_id(idx); + unsigned int code_page = get_code_page_for_locale_id(idx); if (code_page == 0) return c; - WCHAR wide_c; - if (::MultiByteToWideChar(code_page, 0, &c, 1, &wide_c, 1) == 0) + wchar_t wide_c; + if (boost::BOOST_REGEX_DETAIL_NS::MultiByteToWideChar(code_page, 0, &c, 1, &wide_c, 1) == 0) return c; - WCHAR wide_result; - int b = ::LCMapStringW( + wchar_t wide_result; + int b = boost::BOOST_REGEX_DETAIL_NS::LCMapStringW( idx, // locale identifier - LCMAP_LOWERCASE, // mapping transformation type + lcmap_lowercase, // mapping transformation type &wide_c, // source string 1, // number of characters in source string &wide_result, // destination buffer @@ -1052,7 +1183,7 @@ namespace BOOST_REGEX_DETAIL_NS { if (b == 0) return c; - if (::WideCharToMultiByte(code_page, 0, &wide_result, 1, result, 2, NULL, NULL) == 0) + if (boost::BOOST_REGEX_DETAIL_NS::WideCharToMultiByte(code_page, 0, &wide_result, 1, result, 2, NULL, NULL) == 0) return c; // No single byte lower case equivalent available #endif return result[0]; @@ -1062,9 +1193,9 @@ namespace BOOST_REGEX_DETAIL_NS { inline wchar_t w32_tolower(wchar_t c, lcid_type idx) { wchar_t result[2]; - int b = ::LCMapStringW( + int b = boost::BOOST_REGEX_DETAIL_NS::LCMapStringW( idx, // locale identifier - LCMAP_LOWERCASE, // mapping transformation type + lcmap_lowercase, // mapping transformation type &c, // source string 1, // number of characters in source string result, // destination buffer @@ -1078,9 +1209,9 @@ namespace BOOST_REGEX_DETAIL_NS { { char result[2]; #ifndef BOOST_NO_ANSI_APIS - int b = ::LCMapStringA( + int b = boost::BOOST_REGEX_DETAIL_NS::LCMapStringA( idx, // locale identifier - LCMAP_UPPERCASE, // mapping transformation type + lcmap_uppercase, // mapping transformation type &c, // source string 1, // number of characters in source string result, // destination buffer @@ -1088,18 +1219,18 @@ namespace BOOST_REGEX_DETAIL_NS { if (b == 0) return c; #else - UINT code_page = get_code_page_for_locale_id(idx); + unsigned int code_page = get_code_page_for_locale_id(idx); if (code_page == 0) return c; - WCHAR wide_c; - if (::MultiByteToWideChar(code_page, 0, &c, 1, &wide_c, 1) == 0) + wchar_t wide_c; + if (boost::BOOST_REGEX_DETAIL_NS::MultiByteToWideChar(code_page, 0, &c, 1, &wide_c, 1) == 0) return c; - WCHAR wide_result; - int b = ::LCMapStringW( + wchar_t wide_result; + int b = boost::BOOST_REGEX_DETAIL_NS::LCMapStringW( idx, // locale identifier - LCMAP_UPPERCASE, // mapping transformation type + lcmap_uppercase, // mapping transformation type &wide_c, // source string 1, // number of characters in source string &wide_result, // destination buffer @@ -1107,7 +1238,7 @@ namespace BOOST_REGEX_DETAIL_NS { if (b == 0) return c; - if (::WideCharToMultiByte(code_page, 0, &wide_result, 1, result, 2, NULL, NULL) == 0) + if (boost::BOOST_REGEX_DETAIL_NS::WideCharToMultiByte(code_page, 0, &wide_result, 1, result, 2, NULL, NULL) == 0) return c; // No single byte upper case equivalent available. #endif return result[0]; @@ -1117,9 +1248,9 @@ namespace BOOST_REGEX_DETAIL_NS { inline wchar_t w32_toupper(wchar_t c, lcid_type idx) { wchar_t result[2]; - int b = ::LCMapStringW( + int b = boost::BOOST_REGEX_DETAIL_NS::LCMapStringW( idx, // locale identifier - LCMAP_UPPERCASE, // mapping transformation type + lcmap_uppercase, // mapping transformation type &c, // source string 1, // number of characters in source string result, // destination buffer @@ -1131,20 +1262,20 @@ namespace BOOST_REGEX_DETAIL_NS { #endif inline bool w32_is(lcid_type idx, std::uint32_t m, char c) { - WORD mask; + word mask; #ifndef BOOST_NO_ANSI_APIS - if (::GetStringTypeExA(idx, CT_CTYPE1, &c, 1, &mask) && (mask & m & w32_regex_traits_implementation::mask_base)) + if (boost::BOOST_REGEX_DETAIL_NS::GetStringTypeExA(idx, ct_ctype1, &c, 1, &mask) && (mask & m & w32_regex_traits_implementation::mask_base)) return true; #else - UINT code_page = get_code_page_for_locale_id(idx); + unsigned int code_page = get_code_page_for_locale_id(idx); if (code_page == 0) return false; - WCHAR wide_c; - if (::MultiByteToWideChar(code_page, 0, &c, 1, &wide_c, 1) == 0) + wchar_t wide_c; + if (boost::BOOST_REGEX_DETAIL_NS::MultiByteToWideChar(code_page, 0, &c, 1, &wide_c, 1) == 0) return false; - if (::GetStringTypeExW(idx, CT_CTYPE1, &wide_c, 1, &mask) && (mask & m & w32_regex_traits_implementation::mask_base)) + if (boost::BOOST_REGEX_DETAIL_NS::GetStringTypeExW(idx, ct_ctype1, &wide_c, 1, &mask) && (mask & m & w32_regex_traits_implementation::mask_base)) return true; #endif if ((m & w32_regex_traits_implementation::mask_word) && (c == '_')) @@ -1155,8 +1286,8 @@ namespace BOOST_REGEX_DETAIL_NS { #ifndef BOOST_NO_WREGEX inline bool w32_is(lcid_type idx, std::uint32_t m, wchar_t c) { - WORD mask; - if (::GetStringTypeExW(idx, CT_CTYPE1, &c, 1, &mask) && (mask & m & w32_regex_traits_implementation::mask_base)) + word mask; + if (boost::BOOST_REGEX_DETAIL_NS::GetStringTypeExW(idx, ct_ctype1, &c, 1, &mask) && (mask & m & w32_regex_traits_implementation::mask_base)) return true; if ((m & w32_regex_traits_implementation::mask_word) && (c == '_')) return true; diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 9cef46b7..87bc1607 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -122,6 +122,9 @@ test-suite regex [ run unicode/unicode_iterator_test.cpp : : : [ check-target-builds ../build//is_legacy_03 : : ../build//boost_regex ] release TEST_UTF16 : unicode_iterator_test_utf16 ] + [ run unicode/unicode_casefold_test.cpp + ../build//boost_regex ../build//icu_options + ] [ run static_mutex/static_mutex_test.cpp ../../thread/build//boost_thread ../build//boost_regex ] @@ -221,3 +224,10 @@ compile test_warnings.cpp BOOST_REGEX_STANDALONE [ check-target-builds ../build//is_legacy_03 : : no ] : test_warnings_standalone ; + +compile test_windows_defs_1.cpp ; +compile test_windows_defs_2.cpp ; +compile test_windows_defs_3.cpp ; +compile test_windows_defs_4.cpp ; + +run issue153.cpp : : : msvc:-STACK:2097152 ; diff --git a/test/cmake_subdir_test/CMakeLists.txt b/test/cmake_subdir_test/CMakeLists.txt index ddb7b024..52f8d97d 100644 --- a/test/cmake_subdir_test/CMakeLists.txt +++ b/test/cmake_subdir_test/CMakeLists.txt @@ -10,6 +10,7 @@ add_subdirectory(../.. boostorg/reegx) add_subdirectory(../../../config boostorg/config) add_subdirectory(../../../core boostorg/core) add_subdirectory(../../../assert boostorg/assert) +add_subdirectory(../../../static_assert boostorg/static_assert) add_subdirectory(../../../throw_exception boostorg/throw_exception) add_subdirectory(../../../predef boostorg/predef) diff --git a/test/cmake_subdir_test_icu/CMakeLists.txt b/test/cmake_subdir_test_icu/CMakeLists.txt new file mode 100644 index 00000000..62e4f0a6 --- /dev/null +++ b/test/cmake_subdir_test_icu/CMakeLists.txt @@ -0,0 +1,22 @@ +# Copyright 2018, 2019 Peter Dimov +# Distributed under the Boost Software License, Version 1.0. +# See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt + +cmake_minimum_required(VERSION 3.5...3.16) + +project(cmake_subdir_test LANGUAGES CXX) + +add_subdirectory(../.. boostorg/regex) +add_subdirectory(../../../config boostorg/config) +add_subdirectory(../../../core boostorg/core) +add_subdirectory(../../../assert boostorg/assert) +add_subdirectory(../../../throw_exception boostorg/throw_exception) +add_subdirectory(../../../predef boostorg/predef) + +add_executable(quick_icu ../quick_icu.cpp) +target_link_libraries(quick_icu Boost::regex_icu) + +enable_testing() +add_test(quick_icu quick_icu) + +add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure -C $) diff --git a/test/issue153.cpp b/test/issue153.cpp new file mode 100644 index 00000000..78726a0a --- /dev/null +++ b/test/issue153.cpp @@ -0,0 +1,33 @@ +/* +* Copyright (c) 2021 +* John Maddock +* +* Use, modification and distribution are subject to the +* Boost Software License, Version 1.0. (See accompanying file +* LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +* +*/ + +//#define BOOST_REGEX_MAX_BLOCKS 10 +// See https://github.com/boostorg/regex/issues/153 +#include +#include + +int main(int argc, char** argv) +{ + try + { + boost::regex e("\x28\x28\x1f\x28\x28\x28\x3f\x31\x29\x8\x29\xf3\x29\x21\x3d\x29\x3f\x3f\xe4\x2e\x2b\x1f\x3f\x7c\x28\x3f\x21\x28\x28\x61\x3f\x3f\x28\x2a\x53\x4b\x49\x50\x29\x4\x3f\x2e\x2a\x3f\x28\x3f\x31\x29\x30\x77\x29\x29\x29\x49\x29\x61\x63\xbe\x45\x30\xa1\x5c\xfe\x5\xd2\x26\xc0\xf5\x17\x6c\xd4\xc3\x72\xe9\xb6\x74"); + if (boost::regex_match("\xb9\x32\x7c\xbc\x2d\xa0\xb\x85\xf3\xcf\x93\xa7\xd0\x44\x7b\x21\x12\x93\x6a\x7b\x72\x6d\x1e\x69\x56\x31\x37\x30\x31\x34\x31\x31\x38\x33\x34\x36\x30\x34\x36\x39\x32\x33\x31\x37\x33\x31\x36\x38\x37\x33\x30\x33\x37\x31\x35\x38\x38\x34\x31\x30\x35\x37\x32\x37\xba\x3e\x4\xc7\x27\xe9\xae\xf2\x01\x84\x47\x1f\xdc\xc9\x4c\xe5\xbc\xcf\x17\x31\x37\x30\x31\x34\x31\x31\x38\x33\x34\x36\x30\x34\x36\x39\x32\x33\x31\x37\x33\x31\x36\x38\x37\x33\x30\x33\x37\x31\x35\x38\x38\x34\x31\x2c\xd6\xf5\x42\xe4\x13\x15\xde\x7e\xa1\x84\x5a\x32\xf5\x67\xd5\x13\x9a\xd1\xa6\x99\x18\x23\xf7\x5c\xf6\x40\x80\x9c\x79\xbe\x4a\xc2\x54\x94\x93\xa3\x50\x27\xaf\xd4\xc4\x3b\xd3\x49\x95\xe7\xa9\xa0\xa5\x14\x81\xd2\x9a\x77\x92\xa8\x81\xb0\xf4\x5b\xa8\x9c\x3e\x17\x3b\xbd\x86\x26\x9a\x57\x56\x12\xce\x8c\x4a\xca\x68\x86\x3d\xf5\xba\x75\xab\xb1\x76\x2d\xd\xf1\xc\x24\x5e\xc5\x6d\xc8\xdf\xa6\x18\x86\x5e\x56", e, boost::regex_constants::match_default | boost::regex_constants::match_partial)) + { + std::cout << "OK" << std::endl; + } + } + catch (const boost::regex_error& e) + { + assert(e.code() == boost::regex_constants::error_complexity); + std::cout << e.what() << std::endl; + } + return 0; +} + diff --git a/test/quick.cpp b/test/quick.cpp index 0598823d..649339c7 100644 --- a/test/quick.cpp +++ b/test/quick.cpp @@ -10,7 +10,7 @@ // See library home page at http://www.boost.org/libs/regex #include -#include +#include #include bool validate_card_format(const std::string& s) @@ -37,19 +37,19 @@ int main() { std::string s[ 4 ] = { "0000111122223333", "0000 1111 2222 3333", "0000-1111-2222-3333", "000-1111-2222-3333" }; - BOOST_TEST( !validate_card_format( s[0] ) ); - BOOST_TEST_EQ( machine_readable_card_number( s[0] ), s[0] ); - BOOST_TEST_EQ( human_readable_card_number( s[0] ), s[2] ); + assert(!validate_card_format(s[0])); + assert(machine_readable_card_number(s[0]) == s[0]); + assert(human_readable_card_number(s[0]) == s[2]); - BOOST_TEST( validate_card_format( s[1] ) ); - BOOST_TEST_EQ( machine_readable_card_number( s[1] ), s[0] ); - BOOST_TEST_EQ( human_readable_card_number( s[1] ), s[2] ); + assert(validate_card_format(s[1])); + assert(machine_readable_card_number(s[1]) == s[0]); + assert(human_readable_card_number(s[1]) == s[2]); - BOOST_TEST( validate_card_format( s[2] ) ); - BOOST_TEST_EQ( machine_readable_card_number( s[2] ), s[0] ); - BOOST_TEST_EQ( human_readable_card_number( s[2] ), s[2] ); + assert(validate_card_format(s[2])); + assert(machine_readable_card_number(s[2]) == s[0]); + assert(human_readable_card_number(s[2]) == s[2]); - BOOST_TEST( !validate_card_format( s[3] ) ); + assert(!validate_card_format(s[3])); - return boost::report_errors(); + return 0; } diff --git a/test/quick_icu.cpp b/test/quick_icu.cpp new file mode 100644 index 00000000..74058c00 --- /dev/null +++ b/test/quick_icu.cpp @@ -0,0 +1,55 @@ + +// Copyright 1998-2002 John Maddock +// Copyright 2017 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. +// +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt + +// See library home page at http://www.boost.org/libs/regex + +#include +#include +#include + +bool validate_card_format(const std::string& s) +{ + static const boost::u32regex e = boost::make_u32regex("(\\d{4}[- ]){3}\\d{4}"); + return boost::u32regex_match(s, e); +} + +const boost::u32regex card_rx = boost::make_u32regex("\\A(\\d{3,4})[- ]?(\\d{4})[- ]?(\\d{4})[- ]?(\\d{4})\\z"); +const std::string machine_format("\\1\\2\\3\\4"); +const std::string human_format("\\1-\\2-\\3-\\4"); + +std::string machine_readable_card_number(const std::string& s) +{ + return boost::u32regex_replace(s, card_rx, machine_format, boost::match_default | boost::format_sed); +} + +std::string human_readable_card_number(const std::string& s) +{ + return boost::u32regex_replace(s, card_rx, human_format, boost::match_default | boost::format_sed); +} + +int main() +{ + std::string s[ 4 ] = { "0000111122223333", "0000 1111 2222 3333", "0000-1111-2222-3333", "000-1111-2222-3333" }; + + assert( !validate_card_format( s[0] ) ); + assert( machine_readable_card_number( s[0] ) == s[0] ); + assert( human_readable_card_number( s[0] ) == s[2] ); + + assert( validate_card_format( s[1] ) ); + assert( machine_readable_card_number( s[1] ) == s[0] ); + assert( human_readable_card_number( s[1] ) == s[2] ); + + assert( validate_card_format( s[2] ) ); + assert( machine_readable_card_number( s[2] ) == s[0] ); + assert( human_readable_card_number( s[2] ) == s[2] ); + + assert( !validate_card_format( s[3] ) ); + + return 0; +} diff --git a/test/regress/test_backrefs.cpp b/test/regress/test_backrefs.cpp index be9f54ca..aafa8101 100644 --- a/test/regress/test_backrefs.cpp +++ b/test/regress/test_backrefs.cpp @@ -19,13 +19,19 @@ void test_backrefs() { using namespace boost::regex_constants; TEST_INVALID_REGEX("a(b)\\2c", perl); +#ifdef BOOST_REGEX_CXX03 TEST_INVALID_REGEX("a(b\\1)c", perl); +#endif TEST_REGEX_SEARCH("a(b*)c\\1d", perl, "abbcbbd", match_default, make_array(0, 7, 1, 3, -2, -2)); TEST_REGEX_SEARCH("a(b*)c\\1d", perl, "abbcbd", match_default, make_array(-2, -2)); TEST_REGEX_SEARCH("a(b*)c\\1d", perl, "abbcbbbd", match_default, make_array(-2, -2)); TEST_REGEX_SEARCH("^(.)\\1", perl, "abc", match_default, make_array(-2, -2)); TEST_REGEX_SEARCH("a([bc])\\1d", perl, "abcdabbd", match_default, make_array(4, 8, 5, 6, -2, -2)); TEST_REGEX_SEARCH("a\\([bc]\\)\\1d", basic, "abcdabbd", match_default, make_array(4, 8, 5, 6, -2, -2)); +#ifndef BOOST_REGEX_CXX03 + TEST_REGEX_SEARCH("(\\2two|(one))+", perl, "oneonetwo", match_default, make_array(0, 9, 3, 9, 0, 3, -2, -2)); + TEST_INVALID_REGEX("(\\3two|(one))+", perl); +#endif // strictly speaking this is at best ambiguous, at worst wrong, this is what most // re implimentations will match though. TEST_REGEX_SEARCH("a(([bc])\\2)*d", perl, "abbccd", match_default, make_array(0, 6, 3, 5, 3, 4, -2, -2)); @@ -59,7 +65,9 @@ void test_backrefs() // Now test the \g version: // TEST_INVALID_REGEX("a(b)\\g2c", perl); +#ifdef BOOST_REGEX_CXX03 TEST_INVALID_REGEX("a(b\\g1)c", perl); +#endif TEST_INVALID_REGEX("a(b\\g0)c", perl); TEST_REGEX_SEARCH("a(b*)c\\g1d", perl, "abbcbbd", match_default, make_array(0, 7, 1, 3, -2, -2)); TEST_REGEX_SEARCH("a(b*)c\\g1d", perl, "abbcbd", match_default, make_array(-2, -2)); @@ -67,8 +75,14 @@ void test_backrefs() TEST_REGEX_SEARCH("^(.)\\g1", perl, "abc", match_default, make_array(-2, -2)); TEST_REGEX_SEARCH("a([bc])\\g1d", perl, "abcdabbd", match_default, make_array(4, 8, 5, 6, -2, -2)); TEST_INVALID_REGEX("a(b)\\g{2}c", perl); +#ifdef BOOST_REGEX_CXX03 TEST_INVALID_REGEX("a(b\\g{1})c", perl); +#endif TEST_INVALID_REGEX("a(b\\g{0})c", perl); +#ifndef BOOST_REGEX_CXX03 + TEST_REGEX_SEARCH("(\\g{2}two|(one))+", perl, "oneonetwo", match_default, make_array(0, 9, 3, 9, 0, 3, -2, -2)); + TEST_INVALID_REGEX("(\\g{3}two|(one))+", perl); +#endif TEST_REGEX_SEARCH("a(b*)c\\g{1}d", perl, "abbcbbd", match_default, make_array(0, 7, 1, 3, -2, -2)); TEST_REGEX_SEARCH("a(b*)c\\g{1}d", perl, "abbcbd", match_default, make_array(-2, -2)); TEST_REGEX_SEARCH("a(b*)c\\g{1}d", perl, "abbcbbbd", match_default, make_array(-2, -2)); @@ -76,7 +90,9 @@ void test_backrefs() TEST_REGEX_SEARCH("a([bc])\\g{1}d", perl, "abcdabbd", match_default, make_array(4, 8, 5, 6, -2, -2)); // And again but with negative indexes: TEST_INVALID_REGEX("a(b)\\g-2c", perl); +#ifdef BOOST_REGEX_CXX03 TEST_INVALID_REGEX("a(b\\g-1)c", perl); +#endif TEST_INVALID_REGEX("a(b\\g-0)c", perl); TEST_REGEX_SEARCH("a(b*)c\\g-1d", perl, "abbcbbd", match_default, make_array(0, 7, 1, 3, -2, -2)); TEST_REGEX_SEARCH("a(b*)c\\g-1d", perl, "abbcbd", match_default, make_array(-2, -2)); @@ -84,7 +100,9 @@ void test_backrefs() TEST_REGEX_SEARCH("^(.)\\g1", perl, "abc", match_default, make_array(-2, -2)); TEST_REGEX_SEARCH("a([bc])\\g1d", perl, "abcdabbd", match_default, make_array(4, 8, 5, 6, -2, -2)); TEST_INVALID_REGEX("a(b)\\g{-2}c", perl); +#ifdef BOOST_REGEX_CXX03 TEST_INVALID_REGEX("a(b\\g{-1})c", perl); +#endif TEST_REGEX_SEARCH("a(b*)c\\g{-1}d", perl, "abbcbbd", match_default, make_array(0, 7, 1, 3, -2, -2)); TEST_REGEX_SEARCH("a(b*)c\\g{-1}d", perl, "abbcbd", match_default, make_array(-2, -2)); TEST_REGEX_SEARCH("a(b*)c\\g{-1}d", perl, "abbcbbbd", match_default, make_array(-2, -2)); diff --git a/test/regress/test_escapes.cpp b/test/regress/test_escapes.cpp index 74212677..a8a2b859 100644 --- a/test/regress/test_escapes.cpp +++ b/test/regress/test_escapes.cpp @@ -112,6 +112,7 @@ void test_assertion_escapes() TEST_REGEX_SEARCH("\\By\\b", perl, "xy", match_default, make_array(1, 2, -2, -2)); TEST_REGEX_SEARCH("\\by\\B", perl, "yz", match_default, make_array(0, 1, -2, -2)); TEST_REGEX_SEARCH("\\B\\*\\B", perl, " * ", match_default, make_array(1, 2, -2, -2)); + TEST_REGEX_SEARCH(".\\B.", perl, "!?", match_default, make_array(0, 2, -2, -2)); // buffer operators: TEST_REGEX_SEARCH("\\`abc", perl, "abc", match_default, make_array(0, 3, -2, -2)); TEST_REGEX_SEARCH("\\`abc", perl, "\nabc", match_default, make_array(-2, -2)); diff --git a/test/regress/test_perl_ex.cpp b/test/regress/test_perl_ex.cpp index 7f47ecc2..b3b76151 100644 --- a/test/regress/test_perl_ex.cpp +++ b/test/regress/test_perl_ex.cpp @@ -999,6 +999,9 @@ void test_verbs() TEST_REGEX_SEARCH("AA+(*SKIP)(B|Z)|C", perl, "AAAC", match_default, make_array(3, 4, -1, -1, -2, -2)); TEST_REGEX_SEARCH("AA+(*SKIP)(B|Z)|AC", perl, "AAAC", match_default, make_array(-2, -2)); TEST_REGEX_SEARCH("AA+(*SKIP)B|C", perl, "AAAC", match_default, make_array(3, 4, -2, -2)); + + // https://github.com/boostorg/regex/issues/152 + TEST_REGEX_SEARCH("\\A((\x1f((?1) )?+)?+(*SKIP) *?(?2)*?)\\z", perl, "\x20\x1f\x1f\x20", match_default, make_array(-2, -2)); TEST_REGEX_SEARCH("^(?:aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})", perl, "aaaxxxxxx", match_default, make_array(0, 9, -2, -2)); TEST_REGEX_SEARCH("^(?:aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})", perl, "aaa++++++", match_default, make_array(-2, -2)); diff --git a/test/regress/test_simple_repeats.cpp b/test/regress/test_simple_repeats.cpp index 1a73fde6..a87fa830 100644 --- a/test/regress/test_simple_repeats.cpp +++ b/test/regress/test_simple_repeats.cpp @@ -496,5 +496,13 @@ void test_pocessive_repeats() TEST_INVALID_REGEX("(ab + + +)", perl | mod_x); TEST_INVALID_REGEX("(ab + + ?)", perl | mod_x); +#ifndef BOOST_REGEX_CXX03 + // Some bug cases from https://github.com/boostorg/regex/issues/151 + TEST_INVALID_REGEX("a|?+", perl | mod_x); + TEST_INVALID_REGEX("(?xi)a|?+", perl | mod_x); + TEST_INVALID_REGEX("(?xi)a|#\r*", perl | mod_x); + TEST_INVALID_REGEX("(?xi)|#\r*", perl | mod_x); + TEST_INVALID_REGEX("(?xi)|?+#\r*", perl | mod_x); +#endif } diff --git a/test/test_windows_defs_1.cpp b/test/test_windows_defs_1.cpp new file mode 100644 index 00000000..5415a607 --- /dev/null +++ b/test/test_windows_defs_1.cpp @@ -0,0 +1,29 @@ +/* +* +* Copyright (c) 2021 +* John Maddock +* +* Use, modification and distribution are subject to the +* Boost Software License, Version 1.0. (See accompanying file +* LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +* +*/ + +#if defined(_WIN32) && !defined(BOOST_REGEX_NO_W32) +// +// Make sure our forward declarations match those in windows.h: +// + +#define STRICT + +#include +#include + +void test_proc() +{ + std::string text, re; + boost::regex exp(re); + regex_match(text, exp); +} + +#endif diff --git a/test/test_windows_defs_2.cpp b/test/test_windows_defs_2.cpp new file mode 100644 index 00000000..8707b36b --- /dev/null +++ b/test/test_windows_defs_2.cpp @@ -0,0 +1,29 @@ +/* +* +* Copyright (c) 2021 +* John Maddock +* +* Use, modification and distribution are subject to the +* Boost Software License, Version 1.0. (See accompanying file +* LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +* +*/ + +#if defined(_WIN32) && !defined(BOOST_REGEX_NO_W32) +// +// Make sure our forward declarations match those in windows.h: +// + +#define NO_STRICT + +#include +#include + +void test_proc() +{ + std::string text, re; + boost::regex exp(re); + regex_match(text, exp); +} + +#endif diff --git a/test/test_windows_defs_3.cpp b/test/test_windows_defs_3.cpp new file mode 100644 index 00000000..bc369d34 --- /dev/null +++ b/test/test_windows_defs_3.cpp @@ -0,0 +1,27 @@ +/* +* +* Copyright (c) 2021 +* John Maddock +* +* Use, modification and distribution are subject to the +* Boost Software License, Version 1.0. (See accompanying file +* LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +* +*/ + +#if defined(_WIN32) && !defined(BOOST_REGEX_NO_W32) +// +// Make sure our forward declarations match those in windows.h: +// + +#include +#include + +void test_proc() +{ + std::string text, re; + boost::regex exp(re); + regex_match(text, exp); +} + +#endif diff --git a/test/test_windows_defs_4.cpp b/test/test_windows_defs_4.cpp new file mode 100644 index 00000000..09a0015c --- /dev/null +++ b/test/test_windows_defs_4.cpp @@ -0,0 +1,28 @@ +/* +* +* Copyright (c) 2021 +* John Maddock +* +* Use, modification and distribution are subject to the +* Boost Software License, Version 1.0. (See accompanying file +* LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +* +*/ + +#if defined(_WIN32) && !defined(BOOST_REGEX_NO_W32) +// +// Make sure our forward declarations match those in windows.h: +// +#define STRICT +#define BOOST_NO_ANSI_APIS +#include +#include + +void test_proc() +{ + std::string text, re; + boost::regex exp(re); + regex_match(text, exp); +} + +#endif diff --git a/test/unicode/unicode_casefold_test.cpp b/test/unicode/unicode_casefold_test.cpp new file mode 100644 index 00000000..d1597c81 --- /dev/null +++ b/test/unicode/unicode_casefold_test.cpp @@ -0,0 +1,204 @@ +/* + * + * Copyright (c) 2021 John Maddock + * Copyright (c) 2021 Daniel Kruegler + * + * Use, modification and distribution are subject to the + * Boost Software License, Version 1.0. (See accompanying file + * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + * + */ + + /* + * LOCATION: see http://www.boost.org for most recent version. + * FILE unicode_casefold_test.cpp + * VERSION see + * DESCRIPTION: Simple test suite for Unicode case folding. + */ + +#include +#include +#include "../test_macros.hpp" + +#if defined(BOOST_HAS_ICU) + +#include + +#include + +#include +#include + +typedef std::pair unicode_verinfo; + +// Function to query the effective Unicode major and minor +// version, because some spot test cases can only be tested +// for specific Unicode versions. +unicode_verinfo get_unicode_version() +{ + UVersionInfo versionArray = {}; + u_getUnicodeVersion(versionArray); + unicode_verinfo result(versionArray[0] , versionArray[1]); + return result; +} + +void latin_1_checks() +{ + typedef boost::icu_regex_traits traits_type; + traits_type traits; + + // Test range [U+0000, U+0041): Identity fold + for (traits_type::char_type c = 0x0; c < 0x41; ++c) + { + traits_type::char_type nc = traits.translate_nocase(c); + BOOST_CHECK_EQUAL(nc, c); + } + + // Test ASCII upper case letters [A, Z]: Each character folds + // to its lowercase variant: + for (traits_type::char_type c = 0x41; c <= 0x5A; ++c) + { + traits_type::char_type nc = traits.translate_nocase(c); + const int shift = 0x61 - 0x41; + BOOST_CHECK_EQUAL(nc, c + shift); + BOOST_CHECK_EQUAL(nc, traits.tolower(c)); + } + + // Test range (U+005A, U+00B5): Identity fold + for (traits_type::char_type c = 0x5A + 1; c < 0xB5; ++c) + { + traits_type::char_type nc = traits.translate_nocase(c); + BOOST_CHECK_EQUAL(nc, c); + } + + // U+00B5 maps to its decomposition GREEK SMALL LETTER MU + // (U+03BC): + { + traits_type::char_type c = 0xB5; + traits_type::char_type nc = traits.translate_nocase(c); + BOOST_CHECK_EQUAL(nc, 0x03BC); + } + + // Test range (U+00B5, U+00BF]: Identity fold + for (traits_type::char_type c = 0xB5 + 1; c <= 0xBF; ++c) + { + traits_type::char_type nc = traits.translate_nocase(c); + BOOST_CHECK_EQUAL(nc, c); + } + + // Test range [U+00C0, U+00D6]: Each character folds + // to its lowercase variant: + for (traits_type::char_type c = 0xC0; c <= 0xD6; ++c) + { + traits_type::char_type nc = traits.translate_nocase(c); + traits_type::char_type lc = traits.tolower(c); + BOOST_CHECK_EQUAL(nc, lc); + BOOST_CHECK_NE(nc, c); + } + + // U+00D7: Identity fold + { + traits_type::char_type c = 0xD7; + traits_type::char_type nc = traits.translate_nocase(c); + BOOST_CHECK_EQUAL(nc, c); + } + + // Test range [U+00D8, U+00DE]: Each character folds + // to its lowercase variant: + for (traits_type::char_type c = 0xD8; c <= 0xDE; ++c) + { + traits_type::char_type nc = traits.translate_nocase(c); + traits_type::char_type lc = traits.tolower(c); + BOOST_CHECK_EQUAL(nc, lc); + BOOST_CHECK_NE(nc, c); + } + + // Test range [U+00DF, U+00BF]: Identity fold + // Note that case folding of U+00DF (LATIN SMALL + // LETTER SHARP S) does not fold to U+1E9E (LATIN + // CAPITAL LETTER SHARP S) due to case folding + // stability contract + for (traits_type::char_type c = 0xDF; c <= 0xFF; ++c) + { + traits_type::char_type nc = traits.translate_nocase(c); + BOOST_CHECK_EQUAL(nc, c); + } +} + +void spot_checks() +{ + // test specific values ripped straight out of the Unicode standard + // to verify that our case folding is the same as theirs: + typedef boost::icu_regex_traits traits_type; + traits_type traits; + + const unicode_verinfo unicode_version = get_unicode_version(); + + // 'LATIN CAPITAL LETTER SHARP S' folds to + // 'LATIN SMALL LETTER SHARP S' + if (unicode_version >= unicode_verinfo(5, 1)) + { + traits_type::char_type c = 0x1E9E; + traits_type::char_type nc = traits.translate_nocase(c); + traits_type::char_type lc = traits.tolower(c); + BOOST_CHECK_EQUAL(nc, lc); + BOOST_CHECK_EQUAL(nc, 0xDF); + } + + // Capital sigma (U+03A3) is the uppercase form of both the regular (U+03C2) + // and final (U+03C3) lowercase sigma. All these characters exists since + // Unicode 1.1.0. + { + traits_type::char_type c = 0x03A3; + traits_type::char_type nc = traits.translate_nocase(c); + traits_type::char_type lc = traits.tolower(c); + BOOST_CHECK_EQUAL(nc, lc); + BOOST_CHECK_EQUAL(nc, 0x03C3); + c = 0x03C2; + nc = traits.translate_nocase(c); + BOOST_CHECK_EQUAL(nc, 0x03C3); + c = 0x03C3; + nc = traits.translate_nocase(c); + BOOST_CHECK_EQUAL(nc, c); + } + + // In Turkish languages the lowercase letter 'i' (U+0069) maps to an + // uppercase dotted I (U+0130 LATIN CAPITAL LETTER I WITH DOT ABOVE), + // while the uppercase letter 'I' (U+0049) maps to the dotless lowercase + // i (U+0131). The Unicode simple default mapping folds U+0130 to itself, + // but folds U+0049 to U+0069. + { + traits_type::char_type c = 0x0130; + traits_type::char_type nc = traits.translate_nocase(c); + BOOST_CHECK_EQUAL(nc, c); + c = 0x0049; + nc = traits.translate_nocase(c); + traits_type::char_type lc = traits.tolower(c); + BOOST_CHECK_EQUAL(nc, lc); + BOOST_CHECK_EQUAL(nc, 0x0069); + } + + // Cherokee small letters were added with Unicode 8.0, + // but the upper case letters existed before, therefore + // the small letters case fold to upper case letters. + if (unicode_version >= unicode_verinfo(8, 0)) + { + traits_type::char_type c = 0x13F8; + traits_type::char_type nc = traits.translate_nocase(c); + traits_type::char_type uc = traits.toupper(c); + BOOST_CHECK_EQUAL(nc, uc); + BOOST_CHECK_EQUAL(nc, 0x13F0); + } + +} + +#endif + +int cpp_main( int, char* [] ) +{ +#if defined(BOOST_HAS_ICU) + latin_1_checks(); + spot_checks(); +#endif + return boost::report_errors(); +}