From ec681a2484ae0e197848a357c37216380db247a8 Mon Sep 17 00:00:00 2001 From: Nana Sakisaka <1901813+saki7@users.noreply.github.com> Date: Sat, 13 Sep 2025 08:57:11 +0900 Subject: [PATCH] Revert "Merge pull request #808 from saki7/refine-ci-cpp23" This reverts commit f66350f9dc3aaea72c74b72ed5ecf89452b5d490, reversing changes made to d21af8b48d0b94ed7b290d5ac7df31ed37673141. --- .appveyor.yml | 77 +++ .drone.star | 50 ++ .drone/drone.sh | 88 +++ .github/workflows/ci.yml | 526 +++++++++--------- .gitignore | 1 - .travis.yml | 155 ++++++ README.md | 50 +- .../spirit/home/lex/lexer/lexertl/token.hpp | 209 ++++--- repository/test/test_headers/Jamfile | 79 +++ repository/test/test_headers/main.cpp | 14 + repository/test/test_headers/test.cpp | 22 + test/test_headers/Jamfile | 76 +++ test/test_headers/main.cpp | 14 + test/test_headers/test.cpp | 22 + 14 files changed, 988 insertions(+), 395 deletions(-) create mode 100644 .appveyor.yml create mode 100644 .drone.star create mode 100755 .drone/drone.sh create mode 100644 .travis.yml create mode 100644 repository/test/test_headers/Jamfile create mode 100644 repository/test/test_headers/main.cpp create mode 100644 repository/test/test_headers/test.cpp create mode 100644 test/test_headers/Jamfile create mode 100644 test/test_headers/main.cpp create mode 100644 test/test_headers/test.cpp diff --git a/.appveyor.yml b/.appveyor.yml new file mode 100644 index 000000000..119310148 --- /dev/null +++ b/.appveyor.yml @@ -0,0 +1,77 @@ +#============================================================================== +# Copyright (c) 2016-2020 Nikita Kniazev +# +# Use, modification and distribution is 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) +#============================================================================== + +clone_depth: 50 + +environment: + global: + PROJECT: libs\spirit + + matrix: + - { APPVEYOR_BUILD_WORKER_IMAGE: 'Visual Studio 2019', ADDRMDL: 64, TOOLSET: 'msvc-14.2' } + - { APPVEYOR_BUILD_WORKER_IMAGE: 'Visual Studio 2017', ADDRMDL: 64, TOOLSET: 'msvc-14.1' } + - { APPVEYOR_BUILD_WORKER_IMAGE: 'Visual Studio 2015', ADDRMDL: 64, TOOLSET: 'msvc-14.0' } + +init: + - set BOOST_ROOT=%APPVEYOR_BUILD_FOLDER%\..\boost + - set BOOST_BUILD_PATH=%BOOST_ROOT%\..\boost-build + - set B2_ARGS=link=shared threading=multi variant=release + address-model=%ADDRMDL% toolset=%TOOLSET% + define=BOOST_ALL_NO_LIB + define=BOOST_SPIRIT_X3_HIDE_CXX17_WARNING + +before_build: + - set PATH=%BOOST_ROOT%;C:\Python36-x64\Scripts;%PATH% + - ps: | + # Creating %USERPROFILE%/user-config.jam file + @' + + import feature os regex toolset pch ; + + + # A subfeature that tells Spirit tests to use PCH + feature.subfeature pch on : version : spirit : optional propagated incidental ; + + '@ | sc "$env:USERPROFILE/user-config.jam" + + - set BRANCH=%APPVEYOR_REPO_BRANCH% + # TODO: Determine the root branch when PR targeted/build from not our main branches. + - if not "%BRANCH%" == "master" + if not "%BRANCH%" == "develop" + set BRANCH=develop + - echo Root branch is %BRANCH% + + # Sadly git's --shallow-submodules has hardcoded depth of 1 commit + # Patch the git binary with a little more depth to deal with boost-commitbot's lag + - ps: | + $git = Get-Command git | Select-Object -ExpandProperty Definition + $git = Split-Path -Parent $git | Split-Path -Parent + Get-ChildItem -Path "$git\mingw64\*" -Include *.exe -Recurse | + ForEach-Object -Process {(Get-Content -Raw $_).Replace("--depth=1","--depth=9") | Set-Content $_} + + # Checkout Boost + - git clone -j10 --branch=%BRANCH% --depth=1 --quiet + --recurse-submodules=":(exclude)%PROJECT%" --shallow-submodules + https://github.com/boostorg/boost.git %BOOST_ROOT% + - pushd %BOOST_ROOT% + # Remove empty folder + - rmdir /S /Q %PROJECT% + # Move the repository to boost/libs and make a link to previous place + - move %APPVEYOR_BUILD_FOLDER% %PROJECT% + - mklink /J %APPVEYOR_BUILD_FOLDER% %PROJECT% + +build_script: + - bootstrap.bat --with-toolset=msvc + + # Let's have less noise (Appveyor cannot collapse command output) + - b2 headers 2>&1 >> deps_build.log + || ( echo === deps_build.log === && cat deps_build.log ) + +test_script: + - b2 %B2_ARGS% %PROJECT%\classic\test %PROJECT%\repository\test %PROJECT%\test + warnings=extra warnings-as-errors=on pch=on-spirit diff --git a/.drone.star b/.drone.star new file mode 100644 index 000000000..08578208b --- /dev/null +++ b/.drone.star @@ -0,0 +1,50 @@ +# Use, modification, and distribution are +# subject to the Boost Software License, Version 1.0. (See accompanying +# file LICENSE.txt) +# +# Copyright Rene Rivera 2020. + +# For Drone CI we use the Starlark scripting language to reduce duplication. +# As the yaml syntax for Drone CI is rather limited. +# +# +globalenv={'PROJECT': 'libs/spirit'} +linuxglobalimage="cppalliance/droneubuntu1804:1" +windowsglobalimage="cppalliance/dronevs2019" + +def main(ctx): + return [ + linux_cxx("STD=14 JOB=test/x3 Job 0", "clang-10", packages="clang-10 libc++-10-dev libc++abi-10-dev jq", llvm_os="bionic", llvm_ver="10", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'STD': '14', 'JOB': 'test/x3', 'TRAVIS_COMPILER': 'clang-10', 'DRONE_JOB_UUID': 'b6589fc6ab'}, globalenv=globalenv), + linux_cxx("STD=14 JOB=test/x3 Job 1", "gcc-10", packages="g++-10 jq", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'STD': '14', 'JOB': 'test/x3', 'TRAVIS_COMPILER': 'gcc-10', 'DRONE_JOB_UUID': '356a192b79'}, globalenv=globalenv), + linux_cxx("STD=11 JOB=test/qi Job 2", "clang-10", packages="clang-10 libc++-10-dev libc++abi-10-dev jq", llvm_os="bionic", llvm_ver="10", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'STD': '11', 'JOB': 'test/qi', 'TRAVIS_COMPILER': 'clang-10', 'DRONE_JOB_UUID': 'da4b9237ba'}, globalenv=globalenv), + linux_cxx("STD=11 JOB=test/karma Job 3", "clang-10", packages="clang-10 libc++-10-dev libc++abi-10-dev jq", llvm_os="bionic", llvm_ver="10", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'STD': '11', 'JOB': 'test/karma', 'TRAVIS_COMPILER': 'clang-10', 'DRONE_JOB_UUID': '77de68daec'}, globalenv=globalenv), + linux_cxx("STD=11 JOB=test/lex Job 4", "clang-10", packages="clang-10 libc++-10-dev libc++abi-10-dev jq", llvm_os="bionic", llvm_ver="10", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'STD': '11', 'JOB': 'test/lex', 'TRAVIS_COMPILER': 'clang-10', 'DRONE_JOB_UUID': '1b64538924'}, globalenv=globalenv), + linux_cxx("STD=11 JOB=test/support Job 5", "clang-10", packages="clang-10 libc++-10-dev libc++abi-10-dev jq", llvm_os="bionic", llvm_ver="10", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'STD': '11', 'JOB': 'test/support', 'TRAVIS_COMPILER': 'clang-10', 'DRONE_JOB_UUID': 'ac3478d69a'}, globalenv=globalenv), + linux_cxx("STD=11 JOB=repository/test Job 6", "clang-10", packages="clang-10 libc++-10-dev libc++abi-10-dev jq", llvm_os="bionic", llvm_ver="10", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'STD': '11', 'JOB': 'repository/test', 'TRAVIS_COMPILER': 'clang-10', 'DRONE_JOB_UUID': 'c1dfd96eea'}, globalenv=globalenv), + # Not building # + # linux_cxx("STD=03 JOB=test/qi Job 7", "clang-10", packages="clang-10 libc++-10-dev libc++abi-10-dev jq", llvm_os="bionic", llvm_ver="10", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'STD': '03', 'JOB': 'test/qi', 'TRAVIS_COMPILER': 'clang-10', 'DRONE_JOB_UUID': '902ba3cda1'}, globalenv=globalenv), + # Not building # + # linux_cxx("STD=03 JOB=test/karma Job 8", "clang-10", packages="clang-10 libc++-10-dev libc++abi-10-dev jq", llvm_os="bionic", llvm_ver="10", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'STD': '03', 'JOB': 'test/karma', 'TRAVIS_COMPILER': 'clang-10', 'DRONE_JOB_UUID': 'fe5dbbcea5'}, globalenv=globalenv), + linux_cxx("STD=03 JOB=test/lex Job 9", "clang-10", packages="clang-10 libc++-10-dev libc++abi-10-dev jq", llvm_os="bionic", llvm_ver="10", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'STD': '03', 'JOB': 'test/lex', 'TRAVIS_COMPILER': 'clang-10', 'DRONE_JOB_UUID': '0ade7c2cf9'}, globalenv=globalenv), + linux_cxx("STD=03 JOB=test/support Job 10", "clang-10", packages="clang-10 libc++-10-dev libc++abi-10-dev jq", llvm_os="bionic", llvm_ver="10", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'STD': '03', 'JOB': 'test/support', 'TRAVIS_COMPILER': 'clang-10', 'DRONE_JOB_UUID': 'b1d5781111'}, globalenv=globalenv), + linux_cxx("STD=03 JOB=repository/test Job 11", "clang-10", packages="clang-10 libc++-10-dev libc++abi-10-dev jq", llvm_os="bionic", llvm_ver="10", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'STD': '03', 'JOB': 'repository/test', 'TRAVIS_COMPILER': 'clang-10', 'DRONE_JOB_UUID': '17ba079149'}, globalenv=globalenv), + linux_cxx("STD=11 JOB=test/qi Job 12", "gcc-10", packages="g++-10 jq", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'STD': '11', 'JOB': 'test/qi', 'TRAVIS_COMPILER': 'gcc-10', 'DRONE_JOB_UUID': '7b52009b64'}, globalenv=globalenv), + linux_cxx("STD=11 JOB=test/karma Job 13", "gcc-10", packages="g++-10 jq", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'STD': '11', 'JOB': 'test/karma', 'TRAVIS_COMPILER': 'gcc-10', 'DRONE_JOB_UUID': 'bd307a3ec3'}, globalenv=globalenv), + linux_cxx("STD=11 JOB=test/lex Job 14", "gcc-10", packages="g++-10 jq", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'STD': '11', 'JOB': 'test/lex', 'TRAVIS_COMPILER': 'gcc-10', 'DRONE_JOB_UUID': 'fa35e19212'}, globalenv=globalenv), + linux_cxx("STD=11 JOB=test/support Job 15", "gcc-10", packages="g++-10 jq", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'STD': '11', 'JOB': 'test/support', 'TRAVIS_COMPILER': 'gcc-10', 'DRONE_JOB_UUID': 'f1abd67035'}, globalenv=globalenv), + linux_cxx("STD=11 JOB=repository/test Job 16", "gcc-10", packages="g++-10 jq", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'STD': '11', 'JOB': 'repository/test', 'TRAVIS_COMPILER': 'gcc-10', 'DRONE_JOB_UUID': '1574bddb75'}, globalenv=globalenv), + # Not building # + # linux_cxx("STD=03 JOB=test/qi Job 17", "gcc-10", packages="g++-10 jq", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'STD': '03', 'JOB': 'test/qi', 'TRAVIS_COMPILER': 'gcc-10', 'DRONE_JOB_UUID': '0716d9708d'}, globalenv=globalenv), + # Not building # + # linux_cxx("STD=03 JOB=test/karma Job 18", "gcc-10", packages="g++-10 jq", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'STD': '03', 'JOB': 'test/karma', 'TRAVIS_COMPILER': 'gcc-10', 'DRONE_JOB_UUID': '9e6a55b6b4'}, globalenv=globalenv), + linux_cxx("STD=03 JOB=test/lex Job 19", "gcc-10", packages="g++-10 jq", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'STD': '03', 'JOB': 'test/lex', 'TRAVIS_COMPILER': 'gcc-10', 'DRONE_JOB_UUID': 'b3f0c7f6bb'}, globalenv=globalenv), + linux_cxx("STD=03 JOB=test/support Job 20", "gcc-10", packages="g++-10 jq", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'STD': '03', 'JOB': 'test/support', 'TRAVIS_COMPILER': 'gcc-10', 'DRONE_JOB_UUID': '91032ad7bb'}, globalenv=globalenv), + linux_cxx("STD=03 JOB=repository/test Job 21", "gcc-10", packages="g++-10 jq", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'STD': '03', 'JOB': 'repository/test', 'TRAVIS_COMPILER': 'gcc-10', 'DRONE_JOB_UUID': '472b07b9fc'}, globalenv=globalenv), + # Not building # + # linux_cxx("STD=03 JOB=classic/test Job 22", "clang-10", packages="clang-10 libc++-10-dev libc++abi-10-dev jq", llvm_os="bionic", llvm_ver="10", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'STD': '03', 'JOB': 'classic/test', 'TRAVIS_COMPILER': 'clang-10', 'DRONE_JOB_UUID': '12c6fc06c9'}, globalenv=globalenv), + # Not building # + # linux_cxx("STD=03 JOB=classic/test Job 23", "gcc-10", packages="g++-10 jq", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'STD': '03', 'JOB': 'classic/test', 'TRAVIS_COMPILER': 'gcc-10', 'DRONE_JOB_UUID': 'd435a6cdd7'}, globalenv=globalenv), + ] + +# from https://github.com/boostorg/boost-ci +load("@boost_ci//ci/drone/:functions.star", "linux_cxx","windows_cxx","osx_cxx","freebsd_cxx") diff --git a/.drone/drone.sh b/.drone/drone.sh new file mode 100755 index 000000000..1ead0dce8 --- /dev/null +++ b/.drone/drone.sh @@ -0,0 +1,88 @@ +#!/bin/bash + +# Copyright 2020 Rene Rivera, Sam Darwin +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE.txt or copy at http://boost.org/LICENSE_1_0.txt) + +set -e +export TRAVIS_BUILD_DIR=$(pwd) +export DRONE_BUILD_DIR=$(pwd) +export TRAVIS_BRANCH=$DRONE_BRANCH +export VCS_COMMIT_ID=$DRONE_COMMIT +export GIT_COMMIT=$DRONE_COMMIT +export REPO_NAME=$DRONE_REPO +export USER=$(whoami) +export CC=${CC:-gcc} +export PATH=~/.local/bin:/usr/local/bin:$PATH +export BOOST_ROOT="$HOME/boost" +export BOOST_BUILD_PATH="$HOME/build-boost" +export TRAVIS_PULL_REQUEST=${DRONE_PULL_REQUEST:-false} +export TRAVIS_REPO_SLUG=$REPO_NAME + +if [ "$DRONE_JOB_BUILDTYPE" == "boost" ]; then + +echo '==================================> INSTALL' + +export CACHE_NAME=$TRAVIS_OS_NAME-$TOOLSET-$STD-$JOB +export PATH=$BOOST_ROOT:$PATH +if [[ "$TRAVIS_COMPILER" =~ ^clang- ]]; then export STDLIB=stdlib=libc++ ; fi +# Creating ~/user-config.jam file +sed 's/^ //' > ~/user-config.jam << 'EOF' + +import feature ; +import os ; +import regex ; +import toolset ; + + +local TOOLSET = [ os.environ TRAVIS_COMPILER ] ; +local toolset-parts = [ regex.split $(TOOLSET) "-" ] ; +local toolset-name = $(toolset-parts[1]) ; +local toolset-feature = $(toolset-parts[2-]:J="-") ; + +local cxx ; +switch $(toolset-name) { + case gcc : cxx ?= [ regex.replace $(TOOLSET) "gcc" "g++" ] ; + case clang : cxx ?= [ regex.replace $(TOOLSET) "clang" "clang++" ] ; + case * : EXIT "user-config: Unsupported toolset $(toolset-name)" ; +} + +using $(toolset-name) : $(toolset-feature) : ccache $(cxx) ; + +# Release variant with enabled asserts +variant sanitize : speed off full + off ; + +# Determining the root branch +if [[ "$TRAVIS_PULL_REQUEST" == "false" ]]; then + export BRANCH=$TRAVIS_BRANCH +else + # It is a pull request. Retrieve the base branch from GitHub + GH_PR_API=https://api.github.com/repos/$TRAVIS_REPO_SLUG/pulls/$TRAVIS_PULL_REQUEST + export BRANCH=`curl -s $GH_PR_API | jq -r .head.ref`; +fi +if [[ ! "$BRANCH" =~ ^(master|develop)$ ]]; then + # Travis has been triggered not from our main branches. + # Find out the base branch from the git history + # TODO: Not implemented yet, but in most cases it will be develop branch + export BRANCH=develop +fi +echo Root branch is $BRANCH + +env +sed 's/--depth=1/--depth=9/g' `which git` > ~/git && chmod +x ~/git +~/git clone -j10 --branch=$BRANCH --depth=1 --quiet --recurse-submodules=":(exclude)$PROJECT" --shallow-submodules https://github.com/boostorg/boost.git $BOOST_ROOT +pushd $BOOST_ROOT +rm -rf $PROJECT +./bootstrap.sh --with-toolset=clang +./b2 headers +cp -rp $TRAVIS_BUILD_DIR $PROJECT +ln -s $PROJECT $TRAVIS_BUILD_DIR +cd $PROJECT +cd $JOB + +echo '==================================> SCRIPT' + +b2 link=shared threading=multi variant=release,sanitize toolset=$TRAVIS_COMPILER cxxstd=$STD $STDLIB warnings=extra warnings-as-errors=on + +fi diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b4d7d8acb..80b3bf83c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -9,292 +9,300 @@ concurrency: cancel-in-progress: true env: - BOOST_SPIRIT_BUILD_JOBS: 4 - BOOST_SPIRIT_CACHED_UPSTREAM_LIBS: --with-regex --with-thread --with-atomic --with-chrono --with-container --with-date_time --with-exception --with-math + PROJECT: libs/spirit jobs: - changes: - runs-on: ubuntu-latest - outputs: - spirit_component: ${{ steps.filter.outputs.changes }} - karma: ${{ steps.filter.outputs.karma }} - lex: ${{ steps.filter.outputs.lex }} - qi: ${{ steps.filter.outputs.qi }} - support: ${{ steps.filter.outputs.support }} - repository: ${{ steps.filter.outputs.repository }} - x3: ${{ steps.filter.outputs.x3 }} - steps: - - uses: actions/checkout@v5 - - uses: dorny/paths-filter@v3 - id: filter - with: - # Note: references to "support" directory in X3 can be completely - # eliminated as soon as those components are moved to X3's - # self-contained location - filters: | - karma: - - '.github/workflows/*.yml' - - 'include/boost/spirit/home/support/**/*' - - 'include/boost/spirit/home/support.hpp' - - 'include/boost/spirit/home/karma/**/*' - - 'include/boost/spirit/home/karma.hpp' - - 'test/karma/**/*' - lex: - - '.github/workflows/*.yml' - - 'include/boost/spirit/home/support/**/*' - - 'include/boost/spirit/home/support.hpp' - - 'include/boost/spirit/home/lex/**/*' - - 'include/boost/spirit/home/lex.hpp' - - 'test/lex/**/*' - qi: - - '.github/workflows/*.yml' - - 'include/boost/spirit/home/support/**/*' - - 'include/boost/spirit/home/support.hpp' - - 'include/boost/spirit/home/qi/**/*' - - 'include/boost/spirit/home/qi.hpp' - - 'test/qi/**/*' - support: - - '.github/workflows/*.yml' - - 'include/boost/spirit/home/support/**/*' - - 'include/boost/spirit/home/support.hpp' - - 'test/support/**/*' - repository: - - '.github/workflows/*.yml' - - 'include/boost/spirit/repository/**/*' - - 'repository/**/*' - x3: - - '.github/workflows/*.yml' - - 'include/boost/spirit/home/x3/**/*' - - 'include/boost/spirit/home/x3.hpp' - - 'test/x3/**/*' - - 'include/boost/spirit/home/support/char_set/**/*' - - 'include/boost/spirit/home/support/char_encoding/**/*' - - build: - name: "[${{ matrix.cpp_version.name }}] ${{ matrix.spirit_component }} | ${{ matrix.compiler.toolset }}-${{ matrix.compiler.version }} (${{ matrix.build_type.name }}) @ ${{ matrix.os.name }}-${{ matrix.os.version }}" - - needs: changes - runs-on: ${{ matrix.os.name }}-${{ matrix.os.version }} - + posix: strategy: fail-fast: false - matrix: - os: - - name: ubuntu - version: 24.04 - - name: windows - version: 2022 - build_type: - - name: Debug - lowercase: debug - - name: Release - lowercase: release - cpp_version: - - name: C++11 - number: 11 - - name: C++23 - number: 23 - msvc_std: /std:c++23preview - - name: C++26 - number: 26 - msvc_std: /std:c++latest - compiler: - - name: GCC - toolset: gcc - version: 14 - cxxflags: -fdiagnostics-color=always - - name: Clang - toolset: clang - version: 22 - cxxflags: -fcolor-diagnostics - - name: MSVC - toolset: msvc - version: 2022 - cxxflags: /EHsc /utf-8 + include: + - name: "C++23 test/x3" + buildtype: "boost" + packages: "clang++-20 libc++-20-dev libc++abi-20-dev libunwind-20-dev jq ccache" + packages_to_remove: "" + os: "ubuntu-24.04" + cxx: "clang++-20" + sources: "" + llvm_os: "noble" + llvm_ver: "20" + std: "23" + job: "test/x3" + travis_compiler: "clang-20" + - name: "C++23 test/x3" + buildtype: "boost" + packages: "g++-14 jq ccache" + packages_to_remove: "" + os: "ubuntu-24.04" + cxx: "g++-14" + sources: "" + llvm_os: "" + llvm_ver: "" + std: "23" + job: "test/x3" + travis_compiler: "gcc-14" + - name: "C++11 test/qi" + buildtype: "boost" + packages: "clang-14 libc++-14-dev libc++abi-14-dev libunwind-14-dev jq ccache" + packages_to_remove: "" + os: "ubuntu-22.04" + cxx: "clang-14" + sources: "" + llvm_os: "jammy" + llvm_ver: "14" + std: "11" + job: "test/qi" + travis_compiler: "clang-14" + - name: "C++11 test/karma" + buildtype: "boost" + packages: "clang-14 libc++-14-dev libc++abi-14-dev libunwind-14-dev jq ccache" + packages_to_remove: "" + os: "ubuntu-22.04" + cxx: "clang-14" + sources: "" + llvm_os: "jammy" + llvm_ver: "14" + std: "11" + job: "test/karma" + travis_compiler: "clang-14" + - name: "C++11 test/lex" + buildtype: "boost" + packages: "clang-14 libc++-14-dev libc++abi-14-dev libunwind-14-dev jq ccache" + packages_to_remove: "" + os: "ubuntu-22.04" + cxx: "clang-14" + sources: "" + llvm_os: "jammy" + llvm_ver: "14" + std: "11" + job: "test/lex" + travis_compiler: "clang-14" + - name: "C++11 test/support" + buildtype: "boost" + packages: "clang-14 libc++-14-dev libc++abi-14-dev libunwind-14-dev jq ccache" + packages_to_remove: "" + os: "ubuntu-22.04" + cxx: "clang-14" + sources: "" + llvm_os: "jammy" + llvm_ver: "14" + std: "11" + job: "test/support" + travis_compiler: "clang-14" + - name: "C++11 repository/test" + buildtype: "boost" + packages: "clang-14 libc++-14-dev libc++abi-14-dev libunwind-14-dev jq ccache" + packages_to_remove: "" + os: "ubuntu-22.04" + cxx: "clang-14" + sources: "" + llvm_os: "jammy" + llvm_ver: "14" + std: "11" + job: "repository/test" + travis_compiler: "clang-14" + - name: "C++11 test/qi" + buildtype: "boost" + packages: "g++-11 jq ccache" + packages_to_remove: "" + os: "ubuntu-22.04" + cxx: "gcc-11" + sources: "" + llvm_os: "" + llvm_ver: "" + std: "11" + job: "test/qi" + travis_compiler: "gcc-11" + - name: "C++11 test/karma" + buildtype: "boost" + packages: "g++-11 jq ccache" + packages_to_remove: "" + os: "ubuntu-22.04" + cxx: "gcc-11" + sources: "" + llvm_os: "" + llvm_ver: "" + std: "11" + job: "test/karma" + travis_compiler: "gcc-11" + - name: "C++11 test/lex" + buildtype: "boost" + packages: "g++-11 jq ccache" + packages_to_remove: "" + os: "ubuntu-22.04" + cxx: "gcc-11" + sources: "" + llvm_os: "" + llvm_ver: "" + std: "11" + job: "test/lex" + travis_compiler: "gcc-11" + - name: "C++11 test/support" + buildtype: "boost" + packages: "g++-11 jq ccache" + packages_to_remove: "" + os: "ubuntu-22.04" + cxx: "gcc-11" + sources: "" + llvm_os: "" + llvm_ver: "" + std: "11" + job: "test/support" + travis_compiler: "gcc-11" + - name: "C++11 repository/test" + buildtype: "boost" + packages: "g++-11 jq ccache" + packages_to_remove: "" + os: "ubuntu-22.04" + cxx: "gcc-11" + sources: "" + llvm_os: "" + llvm_ver: "" + std: "11" + job: "repository/test" + travis_compiler: "gcc-11" - spirit_component: ${{ fromJSON(needs.changes.outputs.spirit_component) }} - - exclude: - # Blacklist all invalid combinations of environments - - os: - name: windows - cpp_version: - number: 11 # /std:c++11 is no longer supported - - os: - name: windows - compiler: - name: GCC - - os: - name: windows - compiler: - name: Clang - - os: - name: ubuntu - compiler: - name: MSVC - - # Blacklist incompatible toolchains - - spirit_component: karma - cpp_version: - number: 23 - - spirit_component: karma - cpp_version: - number: 26 - - spirit_component: lex - cpp_version: - number: 23 - - spirit_component: lex - cpp_version: - number: 26 - - spirit_component: qi - cpp_version: - number: 23 - - spirit_component: qi - cpp_version: - number: 26 - - spirit_component: support - cpp_version: - number: 23 - - spirit_component: support - cpp_version: - number: 26 - - spirit_component: repository - cpp_version: - number: 23 - - spirit_component: repository - cpp_version: - number: 26 - - spirit_component: x3 - cpp_version: - number: 11 + runs-on: ${{ matrix.os }} + container: ${{ matrix.container }} steps: - - uses: actions/checkout@v5 - with: - # required for upstream Boost version detection - # sadly not working due to upstream bug: https://github.com/actions/checkout/issues/1471 - fetch-tags: true + - name: Check if running in container + if: matrix.container != '' + run: echo "GHA_CONTAINER=${{ matrix.container }}" >> $GITHUB_ENV - - name: Fetch git tags - run: | - git fetch --depth=1 origin +refs/tags/*:refs/tags/* + - uses: actions/checkout@v2 - name: Initialize Ubuntu - if: matrix.os.name == 'ubuntu' + if: matrix.os == 'ubuntu-22.04' run: | sudo echo "set man-db/auto-update false" | sudo debconf-communicate sudo dpkg-reconfigure man-db - sudo apt-get install -y jq - - name: Setup GCC - if: matrix.compiler.toolset == 'gcc' - run: | - sudo apt-get update - sudo apt-get install -y g++-${{ matrix.compiler.version }} - - - name: Setup Clang - if: matrix.compiler.toolset == 'clang' - run: | - wget https://apt.llvm.org/llvm.sh - chmod +x ./llvm.sh - sudo ./llvm.sh ${{ matrix.compiler.version }} - sudo apt-get install -y libc++-${{ matrix.compiler.version }}-dev libc++abi-${{ matrix.compiler.version }}-dev - echo "BOOST_SPIRIT_STDLIB=stdlib=libc++" >> "$GITHUB_ENV" - - - name: Fetch Environment Info - id: env-info + - name: Linux shell: bash + env: + CXX: ${{ matrix.cxx }} + SOURCES: ${{ matrix.sources }} + LLVM_OS: ${{ matrix.llvm_os }} + LLVM_VER: ${{ matrix.llvm_ver }} + PACKAGES: ${{ matrix.packages }} + PACKAGES_TO_REMOVE: ${{ matrix.packages_to_remove }} + JOB_BUILDTYPE: ${{ matrix.buildtype }} + STD: ${{ matrix.std }} + JOB: ${{ matrix.job }} + TRAVIS_COMPILER: ${{ matrix.travis_compiler }} + TRAVIS_BRANCH: ${{ github.base_ref }} + TRAVIS_OS_NAME: "linux" run: | + echo '==================================> SETUP' + echo '==================================> PACKAGES' set -e - export BOOST_RELEASE_VERSION_NAME=$(git for-each-ref refs/tags --sort=-refname --format='%(refname:lstrip=-1)' --count=1) - echo "BOOST_RELEASE_VERSION_NAME: $BOOST_RELEASE_VERSION_NAME" - echo "BOOST_RELEASE_VERSION_NAME=$BOOST_RELEASE_VERSION_NAME" >> "$GITHUB_OUTPUT" + if [ -n "$PACKAGES_TO_REMOVE" ]; then sudo apt-get purge -y $PACKAGES_TO_REMOVE; fi + echo ">>>>> APT: REPO.." + for i in {1..3}; do sudo -E apt-add-repository -y "ppa:ubuntu-toolchain-r/test" && break || sleep 2; done - if [ "${{ matrix.os.name }}" = "windows" ]; then - export BOOST_ROOT=$(cygpath -w $HOME/boost) - else - export BOOST_ROOT=$HOME/boost + if test -n "${LLVM_OS}" ; then + wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add - + if test -n "${LLVM_VER}" ; then + sudo -E apt-add-repository "deb http://apt.llvm.org/${LLVM_OS}/ llvm-toolchain-${LLVM_OS}-${LLVM_VER} main" + else + # Snapshot (i.e. trunk) build of clang + sudo -E apt-add-repository "deb http://apt.llvm.org/${LLVM_OS}/ llvm-toolchain-${LLVM_OS} main" + fi fi - echo "BOOST_ROOT: $BOOST_ROOT" - echo "BOOST_ROOT=$BOOST_ROOT" >> "$GITHUB_OUTPUT" + echo ">>>>> APT: UPDATE.." + sudo -E apt-get -o Acquire::Retries=3 update + if test -n "${SOURCES}" ; then + echo ">>>>> APT: INSTALL SOURCES.." + for SOURCE in $SOURCES; do + sudo -E apt-add-repository ppa:$SOURCE + done + fi + echo ">>>>> APT: INSTALL ${PACKAGES}.." + sudo -E DEBIAN_FRONTEND=noninteractive apt-get -o Acquire::Retries=3 -y install ${PACKAGES} - - name: Cache upstream Boost libraries (restore) - id: cache-boost - uses: actions/cache/restore@v4 - with: - key: ${{ steps.env-info.outputs.BOOST_RELEASE_VERSION_NAME }}-${{ matrix.os.name }}-${{ matrix.os.version }}-${{ matrix.compiler.toolset }}-${{ matrix.compiler.version }}-${{ matrix.cpp_version.name }}-${{ matrix.build_type.name }} - path: | - ${{ steps.env-info.outputs.BOOST_ROOT }} + echo '==================================> INSTALL AND COMPILE' + set -e + export TRAVIS_BUILD_DIR=$(pwd) + export TRAVIS_BRANCH=${TRAVIS_BRANCH:-$(echo $GITHUB_REF | awk 'BEGIN { FS = "/" } ; { print $3 }')} + export VCS_COMMIT_ID=$GITHUB_SHA + export GIT_COMMIT=$GITHUB_SHA + export REPO_NAME=$(basename $GITHUB_REPOSITORY) + export USER=$(whoami) + export CC=${CC:-gcc} + export PATH=~/.local/bin:/usr/local/bin:$PATH + export BOOST_ROOT="$HOME/boost" + export BOOST_BUILD_PATH="$HOME/build-boost" + export GITHUB_EVENT_NUMBER=${{ github.event.number }} + export TRAVIS_PULL_REQUEST=${GITHUB_EVENT_NUMBER:-false} + export TRAVIS_REPO_SLUG=$REPO_NAME - - name: Clone upstream Boost libraries - if: steps.cache-boost.outputs.cache-hit != 'true' - run: | - git -c advice.detachedHead=false clone --no-tags --single-branch --branch=${{ steps.env-info.outputs.BOOST_RELEASE_VERSION_NAME }} --depth=1 --quiet --recurse-submodules=":(exclude)libs/spirit" --shallow-submodules https://github.com/boostorg/boost.git ${{ steps.env-info.outputs.BOOST_ROOT }} - - name: Build upstream Boost libraries (Ubuntu) - if: matrix.os.name == 'ubuntu' && steps.cache-boost.outputs.cache-hit != 'true' - env: - BOOST_ROOT: ${{ steps.env-info.outputs.BOOST_ROOT }} - working-directory: ${{ steps.env-info.outputs.BOOST_ROOT }} - shell: bash - run: | - set -xe - rm -rf libs/spirit - ./bootstrap.sh --with-toolset=${{ matrix.compiler.toolset }} - ./b2 -d0 headers - ./b2 -d1 -j$BOOST_SPIRIT_BUILD_JOBS $BOOST_SPIRIT_CACHED_UPSTREAM_LIBS link=shared threading=multi variant=${{ matrix.build_type.lowercase }} toolset=${{ matrix.compiler.toolset }}-${{ matrix.compiler.version }} cxxstd=${{ matrix.cpp_version.number }} cxxflags="${{ matrix.compiler.cxxflags }}" $BOOST_SPIRIT_STDLIB warnings=extra warnings-as-errors=off + if [ "$JOB_BUILDTYPE" == "boost" ]; then - - uses: TheMrMilchmann/setup-msvc-dev@v3 - if: matrix.os.name == 'windows' - with: - arch: x64 + echo '==================================> INSTALL' - - name: Build upstream Boost libraries (Windows) - if: matrix.os.name == 'windows' && steps.cache-boost.outputs.cache-hit != 'true' - env: - BOOST_ROOT: ${{ steps.env-info.outputs.BOOST_ROOT }} - working-directory: ${{ steps.env-info.outputs.BOOST_ROOT }} - shell: cmd - run: | - rd /s /q libs\spirit - .\bootstrap.bat --with-toolset=${{ matrix.compiler.toolset }} - .\b2 -d0 headers - .\b2 -d1 -j%BOOST_SPIRIT_BUILD_JOBS% %BOOST_SPIRIT_CACHED_UPSTREAM_LIBS% link=shared threading=multi variant=${{ matrix.build_type.lowercase }} toolset=${{ matrix.compiler.toolset }} cxxflags="${{ matrix.cpp_version.msvc_std }} ${{matrix.compiler.cxxflags}}" warnings=extra warnings-as-errors=off + export CACHE_NAME=$TRAVIS_OS_NAME-$TOOLSET-$STD-$JOB + export PATH=$BOOST_ROOT:$PATH + if [[ "$TRAVIS_COMPILER" =~ ^clang- ]]; then export STDLIB=stdlib=libc++ ; fi + # Creating ~/user-config.jam file + sed 's/^ //' > ~/user-config.jam << 'EOF' - - name: Cache upstream Boost libraries - if: steps.cache-boost.outputs.cache-hit != 'true' - uses: actions/cache/save@v4 - with: - key: ${{ steps.cache-boost.outputs.cache-primary-key }} - path: | - ${{ steps.env-info.outputs.BOOST_ROOT }} - !${{ steps.env-info.outputs.BOOST_ROOT }}/.git + import feature ; + import os ; + import regex ; + import toolset ; - - name: Build and test (Ubuntu) - if: matrix.os.name == 'ubuntu' - env: - BOOST_ROOT: ${{ steps.env-info.outputs.BOOST_ROOT }} - working-directory: ${{ steps.env-info.outputs.BOOST_ROOT }} - shell: bash - run: | - set -xe - cp -rp $GITHUB_WORKSPACE libs/spirit - cd libs/spirit/test - ln -s ../repository/test repository # workaround legacy directory structure - cd ${{ matrix.spirit_component }} - $BOOST_ROOT/b2 -d1 -j$BOOST_SPIRIT_BUILD_JOBS link=shared threading=multi variant=${{ matrix.build_type.lowercase }} toolset=${{ matrix.compiler.toolset }}-${{ matrix.compiler.version }} cxxstd=${{ matrix.cpp_version.number }} cxxflags="${{ matrix.compiler.cxxflags }}" $BOOST_SPIRIT_STDLIB warnings=extra warnings-as-errors=off + local TOOLSET = [ os.environ TRAVIS_COMPILER ] ; + local toolset-parts = [ regex.split $(TOOLSET) "-" ] ; + local toolset-name = $(toolset-parts[1]) ; + local toolset-feature = $(toolset-parts[2-]:J="-") ; - - name: Build and test (Windows) - if: matrix.os.name == 'windows' - env: - BOOST_ROOT: ${{ steps.env-info.outputs.BOOST_ROOT }} - working-directory: ${{ steps.env-info.outputs.BOOST_ROOT }} - shell: cmd - run: | - xcopy /S /E /Q %GITHUB_WORKSPACE% libs\spirit\ - cd libs\spirit\test - cd ${{ matrix.spirit_component }} + local cxx ; + switch $(toolset-name) { + case gcc : cxx ?= [ regex.replace $(TOOLSET) "gcc" "g++" ] ; + case clang : cxx ?= [ regex.replace $(TOOLSET) "clang" "clang++" ] ; + case * : EXIT "user-config: Unsupported toolset $(toolset-name)" ; + } - %BOOST_ROOT%\b2 -d1 -j%BOOST_SPIRIT_BUILD_JOBS% link=shared threading=multi variant=${{ matrix.build_type.lowercase }} toolset=${{ matrix.compiler.toolset }} cxxflags="${{ matrix.cpp_version.msvc_std }} ${{matrix.compiler.cxxflags}}" warnings=extra warnings-as-errors=off + using $(toolset-name) : $(toolset-feature) : ccache $(cxx) ; + + # Release variant with enabled asserts + variant sanitize : speed off full + off ; + + EOF + # Determining the root branch + if [[ "$TRAVIS_PULL_REQUEST" == "false" ]]; then + export BRANCH=$TRAVIS_BRANCH + else + # It is a pull request. Retrieve the base branch from GitHub + GH_PR_API=https://api.github.com/repos/$TRAVIS_REPO_SLUG/pulls/$TRAVIS_PULL_REQUEST + export BRANCH=`curl -s $GH_PR_API | jq -r .head.ref`; + fi + if [[ ! "$BRANCH" =~ ^(master|develop)$ ]]; then + # Travis has been triggered not from our main branches. + # Find out the base branch from the git history + # TODO: Not implemented yet, but in most cases it will be develop branch + export BRANCH=develop + fi + echo Root branch is $BRANCH + + env + sed 's/--depth=1/--depth=9/g' `which git` > ~/git && chmod +x ~/git + ~/git clone -j10 --branch=$BRANCH --depth=1 --quiet --recurse-submodules=":(exclude)$PROJECT" --shallow-submodules https://github.com/boostorg/boost.git $BOOST_ROOT + pushd $BOOST_ROOT + rm -rf $PROJECT + ./bootstrap.sh --with-toolset=clang + ./b2 headers + cp -rp $TRAVIS_BUILD_DIR $PROJECT + ln -s $PROJECT $TRAVIS_BUILD_DIR + cd $PROJECT + cd $JOB + + echo '==================================> SCRIPT' + + b2 link=shared threading=multi variant=release,sanitize toolset=$TRAVIS_COMPILER cxxstd=$STD $STDLIB warnings=extra warnings-as-errors=off define=BOOST_SPIRIT_X3_HIDE_CXX17_WARNING + + fi diff --git a/.gitignore b/.gitignore index 257758b65..91d924b0f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,5 @@ .DS_Store -/build*/ test/lex/matlib_static_switch.h diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 000000000..be14bd637 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,155 @@ +#============================================================================== +# Copyright (c) 2016-2021 Nikita Kniazev +# +# Use, modification and distribution is 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) +#============================================================================== + +language: cpp + +sudo: false + +addon_shortcuts: + clang-12: &clang-12 + apt: + sources: + - sourceline: 'deb http://apt.llvm.org/bionic/ llvm-toolchain-bionic-12 main' + key_url: 'https://apt.llvm.org/llvm-snapshot.gpg.key' + packages: + - clang-12 + - libc++-12-dev + - libc++abi-12-dev + + gcc-11: &gcc-11 + apt: + sources: + - sourceline: 'ppa:ubuntu-toolchain-r/test' + packages: + - g++-11 + +os: linux +dist: bionic + +env: + global: + - PROJECT=libs/spirit + - BOOST_ROOT=$HOME/boost + - BOOST_BUILD_PATH=$HOME/build-boost + +matrix: + include: + ### Spirit 3 + - { env: 'STD=14 JOB=test/x3', compiler: clang-12, addons: *clang-12 } + - { env: 'STD=14 JOB=test/x3', compiler: gcc-11, addons: *gcc-11 } + ### Spirit 2 + ## Clang + # 11 + - { env: 'STD=11 JOB=test/qi', compiler: clang-12, addons: *clang-12 } + - { env: 'STD=11 JOB=test/karma', compiler: clang-12, addons: *clang-12 } + - { env: 'STD=11 JOB=test/lex', compiler: clang-12, addons: *clang-12 } + - { env: 'STD=11 JOB=test/support', compiler: clang-12, addons: *clang-12 } + - { env: 'STD=11 JOB=repository/test', compiler: clang-12, addons: *clang-12 } + # 03 + - { env: 'STD=03 JOB=test/qi', compiler: clang-12, addons: *clang-12 } + - { env: 'STD=03 JOB=test/karma', compiler: clang-12, addons: *clang-12 } + - { env: 'STD=03 JOB=test/lex', compiler: clang-12, addons: *clang-12 } + - { env: 'STD=03 JOB=test/support', compiler: clang-12, addons: *clang-12 } + - { env: 'STD=03 JOB=repository/test', compiler: clang-12, addons: *clang-12 } + ## GCC + # 11 + - { env: 'STD=11 JOB=test/qi', compiler: gcc-11, addons: *gcc-11 } + - { env: 'STD=11 JOB=test/karma', compiler: gcc-11, addons: *gcc-11 } + - { env: 'STD=11 JOB=test/lex', compiler: gcc-11, addons: *gcc-11 } + - { env: 'STD=11 JOB=test/support', compiler: gcc-11, addons: *gcc-11 } + - { env: 'STD=11 JOB=repository/test', compiler: gcc-11, addons: *gcc-11 } + # 03 + - { env: 'STD=03 JOB=test/qi', compiler: gcc-11, addons: *gcc-11 } + - { env: 'STD=03 JOB=test/karma', compiler: gcc-11, addons: *gcc-11 } + - { env: 'STD=03 JOB=test/lex', compiler: gcc-11, addons: *gcc-11 } + - { env: 'STD=03 JOB=test/support', compiler: gcc-11, addons: *gcc-11 } + - { env: 'STD=03 JOB=repository/test', compiler: gcc-11, addons: *gcc-11 } + ### Spirit 1 + - { env: 'STD=03 JOB=classic/test', compiler: clang-12, addons: *clang-12 } + - { env: 'STD=03 JOB=classic/test', compiler: gcc-11, addons: *gcc-11 } + +cache: ccache + +before_install: + - export CACHE_NAME=$TRAVIS_OS_NAME-$TOOLSET-$STD-$JOB + - export PATH=$BOOST_ROOT:$PATH + - if [[ "$TRAVIS_COMPILER" =~ ^clang- ]]; then export STDLIB=stdlib=libc++ ; fi + - | + # Creating ~/user-config.jam file + sed 's/^ //' > ~/user-config.jam << 'EOF' + + import feature ; + import os ; + import regex ; + import toolset ; + + + local TOOLSET = [ os.environ TRAVIS_COMPILER ] ; + local toolset-parts = [ regex.split $(TOOLSET) "-" ] ; + local toolset-name = $(toolset-parts[1]) ; + local toolset-feature = $(toolset-parts[2-]:J="-") ; + + local cxx ; + switch $(toolset-name) { + case gcc : cxx ?= [ regex.replace $(TOOLSET) "gcc" "g++" ] ; + case clang : cxx ?= [ regex.replace $(TOOLSET) "clang" "clang++" ] ; + case * : EXIT "user-config: Unsupported toolset $(toolset-name)" ; + } + + using $(toolset-name) : $(toolset-feature) : ccache $(cxx) ; + + # Release variant with enabled asserts + variant sanitize : speed off full + off ; + + - | + # Determining the root branch + if [[ "$TRAVIS_PULL_REQUEST" == "false" ]]; then + export BRANCH=$TRAVIS_BRANCH + else + # It is a pull request. Retrieve the base branch from GitHub + GH_PR_API=https://api.github.com/repos/$TRAVIS_REPO_SLUG/pulls/$TRAVIS_PULL_REQUEST + export BRANCH=`curl -s $GH_PR_API | jq -r .head.ref`; + fi + if [[ ! "$BRANCH" =~ ^(master|develop)$ ]]; then + # Travis has been triggered not from our main branches. + # Find out the base branch from the git history + # TODO: Not implemented yet, but in most cases it will be develop branch + export BRANCH=develop + fi + echo Root branch is $BRANCH + + # Dump environment variables + - env + + # Sadly git's --shallow-submodules has hardcoded depth of 1 commit + # Patch the git binary with a little more depth to deal with boost-commitbot's lag + - sed 's/--depth=1/--depth=9/g' `which git` > ~/git && chmod +x ~/git + + # Checkout Boost + - ~/git clone -j10 --branch=$BRANCH --depth=1 --quiet + --recurse-submodules=":(exclude)$PROJECT" --shallow-submodules + https://github.com/boostorg/boost.git $BOOST_ROOT + - pushd $BOOST_ROOT + # Remove the empty folder + - rm -rf $PROJECT + - ./bootstrap.sh --with-toolset=clang + - ./b2 headers + + # Move the repository to boost/libs and make a link to previous place + - mv $TRAVIS_BUILD_DIR $PROJECT + - ln -s $PROJECT $TRAVIS_BUILD_DIR + + - cd $PROJECT + - cd $JOB + +script: + - b2 link=shared threading=multi variant=release,sanitize + toolset=$TRAVIS_COMPILER cxxstd=$STD $STDLIB + warnings=extra warnings-as-errors=on + define=BOOST_SPIRIT_X3_HIDE_CXX17_WARNING diff --git a/README.md b/README.md index ca4f0e8a2..317787564 100644 --- a/README.md +++ b/README.md @@ -1,56 +1,48 @@ Spirit ====== -Spirit is a set of C++ libraries for parsing and output generation implemented as -Domain Specific Embedded Languages (DSEL) using Expression templates and Template -Meta-Programming. The Spirit libraries enable a target grammar to be written -exclusively in C++. Inline grammar specifications can mix freely with other -C++ code and, thanks to the generative power of C++ templates, are immediately +Spirit is a set of C++ libraries for parsing and output generation implemented as +Domain Specific Embedded Languages (DSEL) using Expression templates and Template +Meta-Programming. The Spirit libraries enable a target grammar to be written +exclusively in C++. Inline grammar specifications can mix freely with other +C++ code and, thanks to the generative power of C++ templates, are immediately executable. -## Spirit.X3 (3rd generation) +### Spirit.X3 (3rd generation) [Documentation](http://www.boost.org/doc/libs/develop/libs/spirit/doc/x3/html/index.html) -The newest Spirit shines faster compile times. Currently only a parser framework (no serialization support). +The newest Spirit shines faster compile times. Currently only a parser framework. -### Supported environments +*WARNING*: C++14 compilers support will be dropped soon. -- C++23 and C++26 -- GCC 14 -- Clang 22 -- MSVC (2022) +Spirit X3 in Boost 1.81 (scheduled to November 2022) will use C++17 features. +Supported compilers will be: +* Clang 4 (currently 3.6) +* GCC 7 (currently 5) +* VS 2017 v15.8 (currently 2015 U3) -## Spirit V2 (2nd generation) +### Spirit V2 (2nd generation) [Documentation](http://www.boost.org/doc/libs/develop/libs/spirit/doc/html/index.html) The latest Long Term Support version of Spirit. A Swiss Army knife for data manipulation on any kind of input. -Note: Spirit V2 is no longer actively maintained. For new projects, use X3. - Consists of: - -- [Qi]: Parser framework. -- [Karma]: Generator framework. -- [Lex]: Lexical analyzer framework. + - [Qi]: Parser framework. + - [Karma]: Generator framework. + - [Lex]: Lexical analyzer framework. + +Runs on most C++03 compilers (GCC 4.1, Clang 3.0, VS 2005). [Spirit V2]: http://www.boost.org/doc/libs/develop/libs/spirit/doc/html/index.html [Qi]: http://www.boost.org/doc/libs/develop/libs/spirit/doc/html/spirit/qi.html [Karma]: http://www.boost.org/doc/libs/develop/libs/spirit/doc/html/spirit/karma.html [Lex]: http://www.boost.org/doc/libs/develop/libs/spirit/doc/html/spirit/lex.html -### Supported environments - -- C++11 only -- GCC 14 -- Clang 22 -- **Windows is no longer supported** because [C++11 support was removed in Visual Studio 2017 and later](https://learn.microsoft.com/en-us/cpp/build/reference/std-specify-language-standard-version?view=msvc-170#remarks). - - -## Spirit.Classic (1st generation) +### Spirit.Classic (1st generation) [Documentation](http://www.boost.org/doc/libs/develop/libs/spirit/classic/index.html) @@ -58,7 +50,7 @@ An elderling member of Spirit. It receives only limited maintanance, but it is still used even inside Boost by [Boost.Serialization] and [Boost.Wave] libraries. It also contains Phoenix V1. -Spirit.Classic should support even ancient compilers. +Spririt.Classic should support even ancient compilers. [Boost.Serialization]: http://boost.org/libs/serialization [Boost.Wave]: http://boost.org/libs/wave diff --git a/include/boost/spirit/home/lex/lexer/lexertl/token.hpp b/include/boost/spirit/home/lex/lexer/lexertl/token.hpp index c0940e5dd..a1d8c8d37 100644 --- a/include/boost/spirit/home/lex/lexer/lexertl/token.hpp +++ b/include/boost/spirit/home/lex/lexer/lexertl/token.hpp @@ -1,7 +1,6 @@ // Copyright (c) 2001-2011 Hartmut Kaiser -// Copyright (c) 2025 Nana Sakisaka -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying +// +// 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) #if !defined(BOOST_SPIRIT_LEX_TOKEN_FEB_10_2008_0751PM) @@ -38,33 +37,31 @@ #include #include -#include - #if defined(BOOST_SPIRIT_DEBUG) #include #endif namespace boost { namespace spirit { namespace lex { namespace lexertl -{ +{ /////////////////////////////////////////////////////////////////////////// // - // The token is the type of the objects returned by default by the + // The token is the type of the objects returned by default by the // iterator. // // template parameters: // Iterator The type of the iterator used to access the // underlying character stream. - // AttributeTypes A mpl sequence containing the types of all - // required different token values to be supported + // AttributeTypes A mpl sequence containing the types of all + // required different token values to be supported // by this token type. // HasState A mpl::bool_ indicating, whether this token type // should support lexer states. - // Idtype The type to use for the token id (defaults to + // Idtype The type to use for the token id (defaults to // std::size_t). // - // It is possible to use other token types with the spirit::lex - // framework as well. If you plan to use a different type as your token - // type, you'll need to expose the following things from your token type + // It is possible to use other token types with the spirit::lex + // framework as well. If you plan to use a different type as your token + // type, you'll need to expose the following things from your token type // to make it compatible with spirit::lex: // // typedefs @@ -75,28 +72,28 @@ namespace boost { namespace spirit { namespace lex { namespace lexertl // // methods // default constructor - // This should initialize the token as an end of + // This should initialize the token as an end of // input token. - // constructors The prototype of the other required + // constructors The prototype of the other required // constructors should be: // // token(int) - // This constructor should initialize the token as - // an invalid token (not carrying any specific + // This constructor should initialize the token as + // an invalid token (not carrying any specific // values) // - // where: the int is used as a tag only and its value is + // where: the int is used as a tag only and its value is // ignored // // and: // - // token(Idtype id, std::size_t state, + // token(Idtype id, std::size_t state, // iterator_type first, iterator_type last); // // where: id: token id // state: lexer state this token was matched in - // first, last: pair of iterators marking the matched - // range in the underlying input stream + // first, last: pair of iterators marking the matched + // range in the underlying input stream // // accessors // id() return the token id of the matched input sequence @@ -107,16 +104,16 @@ namespace boost { namespace spirit { namespace lex { namespace lexertl // value() return the token value // // Additionally, you will have to implement a couple of helper functions - // in the same namespace as the token type: a comparison operator==() to - // compare your token instances, a token_is_valid() function and different - // specializations of the Spirit customization point + // in the same namespace as the token type: a comparison operator==() to + // compare your token instances, a token_is_valid() function and different + // specializations of the Spirit customization point // assign_to_attribute_from_value as shown below. // /////////////////////////////////////////////////////////////////////////// template , typename HasState = mpl::true_ - , typename Idtype = std::size_t> + , typename Idtype = std::size_t> struct token; /////////////////////////////////////////////////////////////////////////// @@ -130,7 +127,7 @@ namespace boost { namespace spirit { namespace lex { namespace lexertl typedef mpl::false_ has_state; typedef Idtype id_type; typedef unused_type token_value_type; - typedef typename std::make_unsigned::type uid_type; + typedef typename make_unsigned::type uid_type; // default constructed tokens correspond to EOI tokens token() : id_(boost::lexer::npos) {} @@ -156,32 +153,32 @@ namespace boost { namespace spirit { namespace lex { namespace lexertl : id_(id) {} #endif - // this default conversion operator is needed to allow the direct - // usage of tokens in conjunction with the primitive parsers defined + // this default conversion operator is needed to allow the direct + // usage of tokens in conjunction with the primitive parsers defined // in Qi operator id_type() const { return id_type(uid_type(id_)); } - // Retrieve or set the token id of this token instance. + // Retrieve or set the token id of this token instance. id_type id() const { return id_type(uid_type(id_)); } void id(id_type newid) { id_ = uid_type(newid); } std::size_t state() const { return 0; } // always '0' (INITIAL state) - bool is_valid() const - { - return 0 != id_ && boost::lexer::npos != id_; + bool is_valid() const + { + return 0 != id_ && boost::lexer::npos != id_; } #if defined(BOOST_SPIRIT_DEBUG) #if BOOST_WORKAROUND(BOOST_MSVC, == 1600) - // workaround for MSVC10 which has problems copying a default + // workaround for MSVC10 which has problems copying a default // constructed iterator_range token& operator= (token const& rhs) { - if (this != &rhs) + if (this != &rhs) { id_ = rhs.id_; - if (is_valid()) + if (is_valid()) matched_ = rhs.matched_; } return *this; @@ -196,8 +193,8 @@ namespace boost { namespace spirit { namespace lex { namespace lexertl #if defined(BOOST_SPIRIT_DEBUG) template - inline std::basic_ostream& + , typename AttributeTypes, typename HasState, typename Idtype> + inline std::basic_ostream& operator<< (std::basic_ostream& os , token const& t) { @@ -251,11 +248,11 @@ namespace boost { namespace spirit { namespace lex { namespace lexertl std::size_t state() const { return state_; } #if defined(BOOST_SPIRIT_DEBUG) && BOOST_WORKAROUND(BOOST_MSVC, == 1600) - // workaround for MSVC10 which has problems copying a default + // workaround for MSVC10 which has problems copying a default // constructed iterator_range token& operator= (token const& rhs) { - if (this != &rhs) + if (this != &rhs) { this->base_type::operator=(static_cast(rhs)); state_ = rhs.state_; @@ -269,21 +266,21 @@ namespace boost { namespace spirit { namespace lex { namespace lexertl }; /////////////////////////////////////////////////////////////////////////// - // The generic version of the token type derives from the - // specialization above and adds a single data member holding the item + // The generic version of the token type derives from the + // specialization above and adds a single data member holding the item // data carried by the token instance. /////////////////////////////////////////////////////////////////////////// namespace detail { /////////////////////////////////////////////////////////////////////// - // Meta-function to calculate the type of the variant data item to be + // Meta-function to calculate the type of the variant data item to be // stored with each token instance. // - // Note: The iterator pair needs to be the first type in the list of - // types supported by the generated variant type (this is being - // used to identify whether the stored data item in a particular - // token instance needs to be converted from the pair of - // iterators (see the first of the assign_to_attribute_from_value + // Note: The iterator pair needs to be the first type in the list of + // types supported by the generated variant type (this is being + // used to identify whether the stored data item in a particular + // token instance needs to be converted from the pair of + // iterators (see the first of the assign_to_attribute_from_value // specializations below). /////////////////////////////////////////////////////////////////////// template @@ -298,22 +295,22 @@ namespace boost { namespace spirit { namespace lex { namespace lexertl }; /////////////////////////////////////////////////////////////////////// - // The type of the data item stored with a token instance is defined + // The type of the data item stored with a token instance is defined // by the template parameter 'AttributeTypes' and may be: - // - // lex::omit: no data item is stored with the token - // instance (this is handled by the + // + // lex::omit: no data item is stored with the token + // instance (this is handled by the // specializations of the token class // below) - // mpl::vector0<>: each token instance stores a pair of - // iterators pointing to the matched input + // mpl::vector0<>: each token instance stores a pair of + // iterators pointing to the matched input // sequence - // mpl::vector<...>: each token instance stores a variant being - // able to store the pair of iterators pointing - // to the matched input sequence, or any of the + // mpl::vector<...>: each token instance stores a variant being + // able to store the pair of iterators pointing + // to the matched input sequence, or any of the // types a specified in the mpl::vector<> // - // All this is done to ensure the token type is as small (in terms + // All this is done to ensure the token type is as small (in terms // of its byte-size) as possible. /////////////////////////////////////////////////////////////////////// template @@ -332,16 +329,16 @@ namespace boost { namespace spirit { namespace lex { namespace lexertl struct token : token { private: // precondition assertions - BOOST_STATIC_ASSERT((mpl::is_sequence::value || + BOOST_STATIC_ASSERT((mpl::is_sequence::value || is_same::value)); typedef token base_type; - protected: - // If no additional token value types are given, the token will + protected: + // If no additional token value types are given, the token will // hold the plain pair of iterators pointing to the matched range - // in the underlying input sequence. Otherwise the token value is + // in the underlying input sequence. Otherwise the token value is // stored as a variant and will again hold the pair of iterators but - // is able to hold any of the given data types as well. The conversion + // is able to hold any of the given data types as well. The conversion // from the iterator pair to the required data type is done when it is // accessed for the first time. typedef iterator_range iterpair_type; @@ -375,14 +372,14 @@ namespace boost { namespace spirit { namespace lex { namespace lexertl token_value_type const& value() const { return value_; } #if BOOST_WORKAROUND(BOOST_MSVC, == 1600) - // workaround for MSVC10 which has problems copying a default + // workaround for MSVC10 which has problems copying a default // constructed iterator_range token& operator= (token const& rhs) { - if (this != &rhs) + if (this != &rhs) { this->base_type::operator=(static_cast(rhs)); - if (this->is_valid()) + if (this->is_valid()) value_ = rhs.value_; } return *this; @@ -397,21 +394,21 @@ namespace boost { namespace spirit { namespace lex { namespace lexertl // tokens are considered equal, if their id's match (these are unique) template - inline bool - operator== (token const& lhs, + inline bool + operator== (token const& lhs, token const& rhs) { return lhs.id() == rhs.id(); } /////////////////////////////////////////////////////////////////////////// - // This overload is needed by the multi_pass/functor_input_policy to - // validate a token instance. It has to be defined in the same namespace + // This overload is needed by the multi_pass/functor_input_policy to + // validate a token instance. It has to be defined in the same namespace // as the token class itself to allow ADL to find it. /////////////////////////////////////////////////////////////////////////// template - inline bool + inline bool token_is_valid(token const& t) { return t.is_valid(); @@ -422,8 +419,8 @@ namespace boost { namespace spirit { namespace traits { /////////////////////////////////////////////////////////////////////////// // We have to provide specializations for the customization point - // assign_to_attribute_from_value allowing to extract the needed value - // from the token. + // assign_to_attribute_from_value allowing to extract the needed value + // from the token. /////////////////////////////////////////////////////////////////////////// // This is called from the parse function of token_def if the token_def @@ -433,15 +430,15 @@ namespace boost { namespace spirit { namespace traits struct assign_to_attribute_from_value > { - static void + static void call(lex::lexertl::token const& t , Attribute& attr) { // The goal of this function is to avoid the conversion of the pair of - // iterators (to the matched character sequence) into the token value - // of the required type being done more than once. For this purpose it - // checks whether the stored value type is still the default one (pair - // of iterators) and if yes, replaces the pair of iterators with the + // iterators (to the matched character sequence) into the token value + // of the required type being done more than once. For this purpose it + // checks whether the stored value type is still the default one (pair + // of iterators) and if yes, replaces the pair of iterators with the // converted value to be returned from subsequent calls. if (0 == t.value().which()) { @@ -449,38 +446,38 @@ namespace boost { namespace spirit { namespace traits typedef iterator_range iterpair_type; iterpair_type const& ip = boost::get(t.value()); - // Interestingly enough we use the assign_to() framework defined in - // Spirit.Qi allowing to convert the pair of iterators to almost any - // required type (assign_to(), if available, uses the standard Spirit + // Interestingly enough we use the assign_to() framework defined in + // Spirit.Qi allowing to convert the pair of iterators to almost any + // required type (assign_to(), if available, uses the standard Spirit // parsers to do the conversion). spirit::traits::assign_to(ip.begin(), ip.end(), attr); - // If you get an error during the compilation of the following - // assignment expression, you probably forgot to list one or more - // types used as token value types (in your token_def<...> - // definitions) in your definition of the token class. I.e. any token - // value type used for a token_def<...> definition has to be listed - // during the declaration of the token type to use. For instance let's + // If you get an error during the compilation of the following + // assignment expression, you probably forgot to list one or more + // types used as token value types (in your token_def<...> + // definitions) in your definition of the token class. I.e. any token + // value type used for a token_def<...> definition has to be listed + // during the declaration of the token type to use. For instance let's // assume we have two token_def's: // // token_def number; number = "..."; // token_def identifier; identifier = "..."; // - // Then you'll have to use the following token type definition + // Then you'll have to use the following token type definition // (assuming you are using the token class): // // typedef mpl::vector token_values; // typedef token token_type; // - // where: base_iter_type is the iterator type used to expose the + // where: base_iter_type is the iterator type used to expose the // underlying input stream. // - // This token_type has to be used as the second template parameter + // This token_type has to be used as the second template parameter // to the lexer class: // // typedef lexer lexer_type; // - // again, assuming you're using the lexer<> template for your + // again, assuming you're using the lexer<> template for your // tokenization. typedef lex::lexertl::token< @@ -515,7 +512,7 @@ namespace boost { namespace spirit { namespace traits struct assign_to_container_from_value< iterator_range, iterator_range > { - static void + static void call(iterator_range const& val, iterator_range& attr) { attr = val; @@ -523,18 +520,18 @@ namespace boost { namespace spirit { namespace traits }; // These are called from the parse function of token_def if the token type - // has no special attribute type assigned + // has no special attribute type assigned template struct assign_to_attribute_from_value, HasState, Idtype> > { - static void + static void call(lex::lexertl::token, HasState, Idtype> const& t , Attribute& attr) { - // The default type returned by the token_def parser component (if - // it has no token value type assigned) is the pair of iterators + // The default type returned by the token_def parser component (if + // it has no token value type assigned) is the pair of iterators // to the matched character sequence. spirit::traits::assign_to(t.value().begin(), t.value().end(), attr); } @@ -554,12 +551,12 @@ namespace boost { namespace spirit { namespace traits struct assign_to_attribute_from_value, HasState, Idtype> > { - static void + static void call(lex::lexertl::token, HasState, Idtype> const& t , Attribute& attr) { - // The default type returned by the token_def parser component (if - // it has no token value type assigned) is the pair of iterators + // The default type returned by the token_def parser component (if + // it has no token value type assigned) is the pair of iterators // to the matched character sequence. spirit::traits::assign_to(t.value().begin(), t.value().end(), attr); } @@ -575,14 +572,14 @@ namespace boost { namespace spirit { namespace traits // This is called from the parse function of token_def if the token type // has been explicitly omitted (i.e. no attribute value is used), which - // essentially means that every attribute gets initialized using default + // essentially means that every attribute gets initialized using default // constructed values. template struct assign_to_attribute_from_value > { - static void + static void call(lex::lexertl::token const& , Attribute&) { @@ -605,15 +602,15 @@ namespace boost { namespace spirit { namespace traits fusion::vector2 > , lex::lexertl::token > { - static void + static void call(lex::lexertl::token const& t , fusion::vector2 >& attr) { - // The type returned by the lexer_def_ parser components is a - // fusion::vector containing the token id of the matched token + // The type returned by the lexer_def_ parser components is a + // fusion::vector containing the token id of the matched token // and the pair of iterators to the matched character sequence. typedef iterator_range iterpair_type; - typedef fusion::vector2 > + typedef fusion::vector2 > attribute_type; iterpair_type const& ip = boost::get(t.value()); @@ -632,7 +629,7 @@ namespace boost { namespace spirit { namespace traits {}; /////////////////////////////////////////////////////////////////////////// - // Overload debug output for a single token, this integrates lexer tokens + // Overload debug output for a single token, this integrates lexer tokens // with Qi's simple_trace debug facilities template @@ -642,7 +639,7 @@ namespace boost { namespace spirit { namespace traits typedef lex::lexertl::token token_type; template - static void print(Out& out, token_type const& val) + static void print(Out& out, token_type const& val) { out << '['; spirit::traits::print_token(out, val.value()); diff --git a/repository/test/test_headers/Jamfile b/repository/test/test_headers/Jamfile new file mode 100644 index 000000000..e1f704cba --- /dev/null +++ b/repository/test/test_headers/Jamfile @@ -0,0 +1,79 @@ +# Jamfile +# +# Copyright (c) 2007-2008 Steven Watanabe +# Copyright (c) 2009 Joel de Guzman +# Copyright (c) 2009 Hartmut Kaiser +# Copyright (c) 2009 Francois Barel +# +# 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 + +import testing ; +import path ; +import regex ; +import print ; +import sequence ; +import feature ; + +project boost/spirit/repository/test/test_headers + : requirements + 300 + ; + +headers = +[ + path.glob-tree ../../../include/boost/spirit/repository/include : *.hpp +] ; + +main_headers = +[ + path.glob-tree ../../../include/boost/spirit/include : *.hpp : classic* phoenix1* +] ; + +for local file in $(headers) +{ + compile test.cpp + : # requirements + BOOST_SPIRIT_HEADER_NAME=$(file) + $(file) + : # test name + [ regex.replace [ path.relative-to ../../../include/boost/spirit/repository $(file) ] "/" "_" ] + ; +} + +feature.feature : forward reverse : incidental ; + +rule generate-include-all ( target : sources * : properties * ) +{ + print.output $(target) ; + + if reverse in $(properties) + { + sources = [ sequence.reverse $(sources) ] ; + } + + for local file in $(sources) + { + print.text "#include <$(file:G=)> +" : overwrite ; + } + +} + +make auto_all1.cpp + : $(headers) $(main_headers) + : @generate-include-all + ; + +make auto_all2.cpp + : $(headers) $(main_headers) + : @generate-include-all + : reverse + ; + +# this ought to catch non-inlined functions and other duplicate definitions +link auto_all1.cpp auto_all2.cpp main.cpp + : . + : auto_all_headers + ; diff --git a/repository/test/test_headers/main.cpp b/repository/test/test_headers/main.cpp new file mode 100644 index 000000000..99aacc627 --- /dev/null +++ b/repository/test/test_headers/main.cpp @@ -0,0 +1,14 @@ +// Copyright (c) 2003-2008 Matthias Christian Schabel +// Copyright (c) 2007-2008 Steven Watanabe +// Copyright (c) 2010 Joel de Guzman +// Copyright (c) 2010 Hartmut Kaiser +// Copyright (c) 2009 Francois Barel +// +// 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) + +int main() +{ + return 0; +} diff --git a/repository/test/test_headers/test.cpp b/repository/test/test_headers/test.cpp new file mode 100644 index 000000000..c6814198a --- /dev/null +++ b/repository/test/test_headers/test.cpp @@ -0,0 +1,22 @@ +// Copyright (c) 2003-2008 Matthias Christian Schabel +// Copyright (c) 2007-2008 Steven Watanabe +// Copyright (c) 2010 Joel de Guzman +// Copyright (c) 2010 Hartmut Kaiser +// Copyright (c) 2009 Francois Barel +// +// 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) + +#define BOOST_SPIRIT_STRINGIZE_IMPL(x) #x +#define BOOST_SPIRIT_STRINGIZE(x) BOOST_SPIRIT_STRINGIZE_IMPL(x) + +#define BOOST_SPIRIT_HEADER BOOST_SPIRIT_STRINGIZE(BOOST_SPIRIT_HEADER_NAME) + +#include BOOST_SPIRIT_HEADER +#include BOOST_SPIRIT_HEADER + +int main() +{ + return 0; +} diff --git a/test/test_headers/Jamfile b/test/test_headers/Jamfile new file mode 100644 index 000000000..84594f337 --- /dev/null +++ b/test/test_headers/Jamfile @@ -0,0 +1,76 @@ +# Jamfile +# +# Copyright (c) 2007-2008 Steven Watanabe +# Copyright (c) 2009 Joel de Guzman +# Copyright (c) 2009 Hartmut Kaiser +# Copyright (c) 2009 Francois Barel +# +# 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 + +import testing ; +import path ; +import regex ; +import print ; +import sequence ; +import feature ; + +project + : requirements + 300 + ; + +headers = +[ + glob-tree-ex ../../include/boost/spirit/include : *.hpp : classic* phoenix1* +] ; + +for local file in $(headers) +{ + compile test.cpp + : # requirements + BOOST_SPIRIT_HEADER_NAME=$(file) + $(file) + : # test name + [ regex.replace [ path.relative-to ../../include/boost/spirit/include $(file) ] "/" "_" ] + ; +} + +feature.feature : forward reverse : incidental ; + +rule generate-include-all ( target : sources * : properties * ) +{ + print.output $(target) ; + + sources = [ MATCH "(.*[.]hpp)" : $(sources) ] ; + + if reverse in $(properties) + { + sources = [ sequence.reverse $(sources) ] ; + } + + for local file in $(sources) + { + print.text "#include <$(file:G=)> +" : overwrite ; + } + +} + +make auto_all1.cpp + : $(headers) + : @generate-include-all + ; + +make auto_all2.cpp + : $(headers) + : @generate-include-all + : reverse + ; + +# this ought to catch non-inlined functions and other duplicate definitions +link auto_all1.cpp auto_all2.cpp main.cpp + : . + : auto_all_headers + ; diff --git a/test/test_headers/main.cpp b/test/test_headers/main.cpp new file mode 100644 index 000000000..99aacc627 --- /dev/null +++ b/test/test_headers/main.cpp @@ -0,0 +1,14 @@ +// Copyright (c) 2003-2008 Matthias Christian Schabel +// Copyright (c) 2007-2008 Steven Watanabe +// Copyright (c) 2010 Joel de Guzman +// Copyright (c) 2010 Hartmut Kaiser +// Copyright (c) 2009 Francois Barel +// +// 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) + +int main() +{ + return 0; +} diff --git a/test/test_headers/test.cpp b/test/test_headers/test.cpp new file mode 100644 index 000000000..c6814198a --- /dev/null +++ b/test/test_headers/test.cpp @@ -0,0 +1,22 @@ +// Copyright (c) 2003-2008 Matthias Christian Schabel +// Copyright (c) 2007-2008 Steven Watanabe +// Copyright (c) 2010 Joel de Guzman +// Copyright (c) 2010 Hartmut Kaiser +// Copyright (c) 2009 Francois Barel +// +// 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) + +#define BOOST_SPIRIT_STRINGIZE_IMPL(x) #x +#define BOOST_SPIRIT_STRINGIZE(x) BOOST_SPIRIT_STRINGIZE_IMPL(x) + +#define BOOST_SPIRIT_HEADER BOOST_SPIRIT_STRINGIZE(BOOST_SPIRIT_HEADER_NAME) + +#include BOOST_SPIRIT_HEADER +#include BOOST_SPIRIT_HEADER + +int main() +{ + return 0; +}