diff --git a/.github/workflows/test-cpp.yml b/.github/workflows/test-cpp.yml index 0ea60fd06..10a477360 100644 --- a/.github/workflows/test-cpp.yml +++ b/.github/workflows/test-cpp.yml @@ -4,39 +4,36 @@ on: push: branches: - main - - renovate/** - paths: - cpp* - - testdata/** - - gherkin-languages.json + - renovate/** pull_request: branches: - main - paths: - - cpp* - - testdata/** - - gherkin-languages.json workflow_call: jobs: test-cpp: strategy: matrix: - os: - #- ubuntu-20.04 - #- ubuntu-22.04 - #- windows-2019 - - windows-2022 - runs-on: ${{ matrix.os }} + config: + - os: ubuntu-latest + cc: gcc + - os: ubuntu-latest + cc: clang + - os: macos-latest + cc: clang + - os: windows-latest + cc: cl + runs-on: ${{ matrix.config.os }} steps: - uses: actions/checkout@v4 + - uses: ilammy/msvc-dev-cmd@v1 - name: install dependencies working-directory: cpp run: | - cmake -P cmake/cmate update + cmake -P cmake/cmate --cc=${{ matrix.config.cc }} install - name: configure and build working-directory: cpp run: | - cmake -P cmake/cmate configure - cmake -P cmake/cmate build + cmake -P cmake/cmate --cc=${{ matrix.config.cc }} build --release diff --git a/cpp/Makefile b/cpp/Makefile index 159492366..8598c844d 100644 --- a/cpp/Makefile +++ b/cpp/Makefile @@ -29,6 +29,8 @@ ERRORS = $(patsubst ../testdata/%,acceptance/testdata/%.errors.ndjson,$(BA .DEFAULT_GOAL = help +# Dummy 1 + help: ## Show this help @awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \n\nWhere is one of:\n"} /^[$$()% a-zA-Z_-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST) @@ -107,9 +109,9 @@ install-deps: .deps-installed .PHONY: install-deps .deps-installed: - ./cmake/cmade install + ./cmake/cmate install touch $@ clean-deps: - rm -rf .deps-installed build/root build/ext + ./cmake/cmate clean --purge .PHONY: clean-deps diff --git a/cpp/cmake/cmate b/cpp/cmake/cmate index 69dff0f13..01ec6ca2e 100755 --- a/cpp/cmake/cmate +++ b/cpp/cmake/cmate @@ -42,26 +42,9 @@ function(cmate_setg VAR VAL) set(${VAR} "${VAL}" CACHE INTERNAL "${VAR}") endfunction() -function(cmate_state_file STATE VAR) - set(${VAR} "${CMATE_STATE_DIR}/.${STATE}" PARENT_SCOPE) -endfunction() - -function(cmate_clear_state STATE) - file(MAKE_DIRECTORY ${CMATE_STATE_DIR}) - cmate_state_file(${STATE} FILE) - file(REMOVE ${FILE}) -endfunction() - -function(cmate_set_state STATE) - file(MAKE_DIRECTORY ${CMATE_STATE_DIR}) - cmate_state_file(${STATE} FILE) - file(TOUCH ${FILE}) -endfunction() - -function(cmate_clear_states) - if (IS_DIRECTORY ${CMATE_STATE_DIR}) - file(REMOVE_RECURSE ${CMATE_STATE_DIR}) - endif() +function(cmate_setgdir VAR VAL) + cmate_setg(${VAR} "${VAL}") + file(MAKE_DIRECTORY ${${VAR}}) endfunction() function(cmate_load_version) @@ -203,6 +186,105 @@ function(cmate_download URL FILE) cmate_die("download of ${URL} failed: ${ST}") endif() endfunction() + +function(cmate_set_build_type RELEASE_FLAG_VAR) + if(CMATE_BUILD_DIR) + return() + endif() + + if(${RELEASE_FLAG_VAR}) + set(TYPE "Release") + else() + set(TYPE "Debug") + endif() + + string(TOLOWER ${TYPE} TDIR) + cmate_setg(CMATE_BUILD_DIR "${CMATE_BUILD_BASE_DIR}/${TDIR}") +endfunction() + +function(cmate_github_get_latest REPO VAR RE) + set(URL "https://api.github.com/repos/${REPO}/releases/latest") + set(TDIR "${CMATE_TMP_DIR}/${REPO}") + set(INFO "${TDIR}/info.json") + + if (NOT EXISTS ${INFO}) + file(MAKE_DIRECTORY ${TDIR}) + cmate_download(${URL} ${INFO}) + endif() + + file(READ ${INFO} VINFO) + cmate_json_get_array(${VINFO} "assets" ASSETS) + + foreach(ASSET ${ASSETS}) + string( + JSON + BDURL + ERROR_VARIABLE ERR + GET "${ASSET}" "browser_download_url" + ) + + if(NOT ERR AND ${BDURL} MATCHES ${RE}) + string(JSON FILE GET "${ASSET}" "name") + set(FILE "${CMATE_DL_DIR}/${FILE}") + + if (NOT EXISTS ${FILE}) + cmate_download(${BDURL} ${FILE}) + endif() + + set(${VAR} ${FILE} PARENT_SCOPE) + break() + endif() + endforeach() + + file(REMOVE_RECURSE ${TDIR}) +endfunction() + +function(cmate_check_ninja VAR) + find_program(NINJA ninja) + set(TDIR "${CMATE_TMP_DIR}/ninja") + + if(NOT NINJA) + set(NOS "") + set(NCMD "ninja") + + if(${CMAKE_HOST_SYSTEM_NAME} STREQUAL "Linux") + set(NOS "linux") + elseif(${CMAKE_HOST_SYSTEM_NAME} STREQUAL "Windows") + set(NOS "win") + set(NCMD "ninja.exe") + elseif(${CMAKE_HOST_SYSTEM_NAME} STREQUAL "Darwin") + set(NOS "mac") + else() + cmate_die("Please install ninja: ${CMAKE_SYSTEM_NAME}") + endif() + + if(NOT EXISTS "${CMATE_ENV_BIN_DIR}/${NCMD}") + cmate_github_get_latest( + "ninja-build/ninja" + NZIP + "ninja-${NOS}.zip$" + ) + + file(REMOVE_RECURSE ${TDIR}) + file(ARCHIVE_EXTRACT INPUT ${NZIP} DESTINATION ${TDIR}) + file(COPY_FILE "${TDIR}/${NCMD}" "${CMATE_ENV_BIN_DIR}/${NCMD}") + file(REMOVE_RECURSE ${TDIR}) + endif() + + set(NINJA "${CMATE_ENV_BIN_DIR}/${NCMD}") + endif() + + set(${VAR} ${NINJA} PARENT_SCOPE) +endfunction() + +function(cmate_set_ninja) + if(NOT CMATE_NINJA) + cmate_check_ninja(NINJA) + cmate_setg(CMATE_NINJA ${NINJA}) + endif() + + cmate_setg(CMAKE_MAKE_PROGRAM ${CMATE_NINJA}) +endfunction() ############################################################################### # # Content of cmate/args.cmake @@ -380,7 +462,7 @@ endfunction() ############################################################################### function(cmate_dep_set_cache_dir NAME) string(REPLACE "/" "_" DIR ${NAME}) - set(DIR "${CMATE_DEPS_DIR}/${DIR}") + set(DIR "${CMATE_DL_DIR}/${DIR}") cmate_setg(CMATE_DEP_CACHE_DIR ${DIR}) cmate_setg(CMATE_DEP_SOURCE_DIR "${DIR}/sources") cmate_setg(CMATE_DEP_BUILD_DIR "${DIR}/build") @@ -451,7 +533,7 @@ function(cmate_dep_get_url URL) if(NOT EXISTS ${CFILE}) cmate_info("downloading ${URL} in ${CDIR}") cmate_download(${URL} ${CFILE}) - cmate_set_state("fetched") + cmate_dep_set_state("fetched") endif() if(NOT IS_DIRECTORY ${CMATE_DEP_SOURCE_DIR} OR NOT EXISTS ${EXTRACTED}) @@ -728,6 +810,10 @@ set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) set(CMAKE_POSITION_INDEPENDENT_CODE ON) + +if (CMAKE_CXX_COMPILER_ID STREQUAL \"MSVC\") + add_compile_definitions(_CRT_SECURE_NO_WARNINGS _SCL_SECURE_NO_WARNINGS) +endif() " ) @@ -795,6 +881,46 @@ install( file(WRITE ${CM_FILE} ${CONTENT}) endfunction() +function(cmate_configure_run_cmake TYPE) + string(TOLOWER ${TYPE} TDIR) + set(BUILD_DIR "${CMATE_ROOT_DIR}/build/${TDIR}") + set(STAGE_DIR "${CMATE_ROOT_DIR}/stage/${TDIR}") + + if (IS_DIRECTORY ${BUILD_DIR}) + return() + endif() + + file(MAKE_DIRECTORY ${BUILD_DIR}) + + set(ARGS "") + + if (EXISTS "${CMATE_ENV_DIR}") + list(APPEND ARGS "-DCMAKE_PREFIX_PATH=${CMATE_ENV_DIR}") + endif() + + list(APPEND ARGS "-DCMAKE_INSTALL_PREFIX=${STAGE_DIR}") + list(APPEND ARGS "-DCMAKE_BUILD_TYPE=${TYPE}") + + find_program(CMATE_CCACHE ccache) + + if(CMATE_CCACHE) + list(APPEND ARGS "-DCMAKE_C_COMPILER_LAUNCHER=${CMATE_CCACHE}") + list(APPEND ARGS "-DCMAKE_CXX_COMPILER_LAUNCHER=${CMATE_CCACHE}") + endif() + + if(CMATE_TOOLCHAIN) + list(APPEND ARGS "--toolchain" "${CMATE_TOOLCHAIN}") + endif() + + cmate_set_ninja() + + list(APPEND ARGS "-G" "Ninja") + list(APPEND ARGS "-S" "${CMATE_ROOT_DIR}") + list(APPEND ARGS "-B" "${BUILD_DIR}") + + cmate_run_prog(CMD ${CMAKE_COMMAND} ${ARGS}) +endfunction() + function(cmate_configure) # Find libraries (libraries have headers) file(GLOB LIB_INC_DIRS "${CMATE_ROOT_DIR}/include/*") @@ -835,58 +961,8 @@ function(cmate_configure) # Top-level project cmate_configure_project("${TARGETS}" "${SUBDIRS}") - - cmate_state_file("configured" CONFIGURED) - - if(NOT EXISTS ${CONFIGURED}) - set(BUILD_DIR "${CMATE_ROOT_DIR}/build") - set(STAGE_DIR "${CMATE_ROOT_DIR}/stage") - file(MAKE_DIRECTORY ${BUILD_DIR}) - - set(ARGS "") - - if (EXISTS "${CMATE_ENV_DIR}") - list(APPEND ARGS "-DCMAKE_PREFIX_PATH=${CMATE_ENV_DIR}") - endif() - - list(APPEND ARGS "-DCMAKE_INSTALL_PREFIX=${STAGE_DIR}") - list(APPEND ARGS "-DCMAKE_BUILD_TYPE:STRING=Release") - - find_program(CMATE_CCACHE ccache) - - if(CMATE_CCACHE) - list(APPEND ARGS "-DCMAKE_C_COMPILER_LAUNCHER=${CMATE_CCACHE}") - list(APPEND ARGS "-DCMAKE_CXX_COMPILER_LAUNCHER=${CMATE_CCACHE}") - endif() - - find_program(CMATE_NINJA ninja) - - if(CMATE_NINJA) - list(APPEND ARGS "-G" "Ninja") - endif() - - if(CMATE_TOOLCHAIN) - list(APPEND ARGS "--toolchain" "${CMATE_TOOLCHAIN}") - endif() - - list(APPEND ARGS "-S" "${CMATE_ROOT_DIR}") - list(APPEND ARGS "-B" "${BUILD_DIR}") - - execute_process( - COMMAND - ${CMAKE_COMMAND} - ${ARGS} - WORKING_DIRECTORY "${BUILD_DIR}" - RESULTS_VARIABLE RC - ) - - if(RC) - list(JOIN ARGS " " RUN_CMD) - cmate_die("command failed: ${RUN_CMD}") - endif() - - cmate_set_state("configured") - endif() + cmate_configure_run_cmake("Debug") + cmate_configure_run_cmake("Release") endfunction() ############################################################################### # @@ -917,36 +993,23 @@ set(CMATE_BUILD_SHORT_HELP "Build local project") set( CMATE_BUILD_HELP " -Usage: cmate build +Usage: cmate build [OPTIONS] -${CMATE_BUILD_SHORT_HELP}" +${CMATE_BUILD_SHORT_HELP} + +Options: + --release Build in release mode" ) function(cmate_build) - cmate_state_file("configured" CONFIGURED) - - if(NOT EXISTS ${CONFIGURED}) - cmate_die("please configure first") - endif() + cmate_set_build_type(CMATE_BUILD_RELEASE) + cmate_configure() - set(BUILD_DIR "${CMATE_ROOT_DIR}/build") - set(STAGE_DIR "${CMATE_ROOT_DIR}/stage") set(ARGS "") - - list(APPEND ARGS "--build" "${BUILD_DIR}") + list(APPEND ARGS "--build" "${CMATE_BUILD_DIR}") list(APPEND ARGS "--parallel") - execute_process( - COMMAND - ${CMAKE_COMMAND} - ${ARGS} - RESULTS_VARIABLE RC - ) - - if(RC) - list(JOIN ARGS " " RUN_CMD) - cmate_die("command failed: ${RUN_CMD}") - endif() + cmate_run_prog(CMD ${CMAKE_COMMAND} ${ARGS}) endfunction() ############################################################################### # @@ -979,26 +1042,21 @@ set( " Usage: cmate stage -${CMATE_STAGE_SHORT_HELP}" +${CMATE_STAGE_SHORT_HELP} + +Options: + --release Stage release build" ) function(cmate_stage) - set(BUILD_DIR "${CMATE_ROOT_DIR}/build") - set(ARGS "") + cmate_set_build_type(CMATE_STAGE_RELEASE) + cmate_build() - list(APPEND ARGS "--install" "${BUILD_DIR}") + set(ARGS "") - execute_process( - COMMAND - ${CMAKE_COMMAND} - ${ARGS} - RESULTS_VARIABLE RC - ) + list(APPEND ARGS "--install" "${CMATE_BUILD_DIR}") - if(RC) - list(JOIN ARGS " " RUN_CMD) - cmate_die("command failed: ${RUN_CMD}") - endif() + cmate_run_prog(CMD ${CMAKE_COMMAND} ${ARGS}) endfunction() ############################################################################### # @@ -1036,20 +1094,20 @@ function(cmate_clean) endfunction() ############################################################################### # -# Content of cmate/commands/update.cmake +# Content of cmate/commands/install.cmake # ############################################################################### -list(APPEND CMATE_CMDS "update") -set(CMATE_UPDATE_SHORT_HELP "Update dependencies listed in deps.txt") +list(APPEND CMATE_CMDS "install") +set(CMATE_INSTALL_SHORT_HELP "Install dependencies listed in deps.txt") set( - CMATE_UPDATE_HELP + CMATE_INSTALL_HELP " -Usage: cmate update +Usage: cmate install -${CMATE_UPDATE_SHORT_HELP}" +${CMATE_INSTALL_SHORT_HELP}" ) -function(cmate_update_cmake_dep) +function(cmate_install_cmake_dep) cmate_dep_state_file("configured" CONFIGURED) cmate_dep_state_file("built" BUILT) cmate_dep_state_file("installed" INSTALLED) @@ -1066,18 +1124,15 @@ function(cmate_update_cmake_dep) list(APPEND ARGS "-DCMAKE_CXX_COMPILER_LAUNCHER=${CMATE_CCACHE}") endif() - find_program(CMATE_NINJA ninja) - - if(CMATE_NINJA) - list(APPEND ARGS "-G" "Ninja") - endif() + cmate_set_ninja() cmate_run_prog( CMD ${CMAKE_COMMAND} -DCMAKE_PREFIX_PATH=${CMATE_ENV_DIR} -DCMAKE_INSTALL_PREFIX=${CMATE_ENV_DIR} - -DCMAKE_BUILD_TYPE:STRING=Release + -DCMAKE_BUILD_TYPE=Release + -G Ninja ${ARGS} -S ${CMATE_DEP_SOURCE_DIR} -B ${CMATE_DEP_BUILD_DIR} ${ARGV} @@ -1089,17 +1144,23 @@ function(cmate_update_cmake_dep) CMD ${CMAKE_COMMAND} --build ${CMATE_DEP_BUILD_DIR} + --config Release --parallel - ) + ) cmate_dep_set_state("built") endif() if(NOT EXISTS ${INSTALLED}) - cmate_run_prog(CMD ${CMAKE_COMMAND} --install ${CMATE_DEP_BUILD_DIR}) + cmate_run_prog( + CMD + ${CMAKE_COMMAND} + --install ${CMATE_DEP_BUILD_DIR} + --config Release + ) cmate_dep_set_state("installed") endif() endfunction() -function(cmate_update_meson_dep) +function(cmate_install_meson_dep) cmate_dep_state_file("configured" CONFIGURED) cmate_dep_state_file("installed" INSTALLED) file(MAKE_DIRECTORY ${CMATE_DEP_BUILD_DIR}) @@ -1123,7 +1184,7 @@ function(cmate_update_meson_dep) endif() endfunction() -function(cmate_update_autotools_dep) +function(cmate_install_autotools_dep) cmate_dep_state_file("configured" CONFIGURED) cmate_dep_state_file("installed" INSTALLED) file(MAKE_DIRECTORY ${CMATE_DEP_BUILD_DIR}) @@ -1147,7 +1208,7 @@ function(cmate_update_autotools_dep) endif() endfunction() -function(cmate_update_makefile_dep) +function(cmate_install_makefile_dep) cmate_dep_state_file("built" BUILT) cmate_dep_state_file("installed" INSTALLED) file(MAKE_DIRECTORY ${CMATE_DEP_BUILD_DIR}) @@ -1168,7 +1229,7 @@ function(cmate_update_makefile_dep) endif() endfunction() -function(cmate_update_dep ARGS) +function(cmate_install_dep ARGS) set(OPT_PROC ON) string(REGEX MATCHALL "[^ \"']+|\"([^\"]*)\"|'([^']*)'" ARGS "${ARGS}") @@ -1192,29 +1253,29 @@ function(cmate_update_dep ARGS) endif() if(EXISTS "${CMATE_DEP_SOURCE_DIR}/CMakeLists.txt") - cmate_update_cmake_dep(${CONF_ARGS}) + cmate_install_cmake_dep(${CONF_ARGS}) elseif(EXISTS "${CMATE_DEP_SOURCE_DIR}/meson.build") - cmate_update_meson_dep(${CONF_ARGS}) + cmate_install_meson_dep(${CONF_ARGS}) elseif(EXISTS "${CMATE_DEP_SOURCE_DIR}/configure") - cmate_update_autotools_dep(${CONF_ARGS}) + cmate_install_autotools_dep(${CONF_ARGS}) elseif(EXISTS "${CMATE_DEP_SOURCE_DIR}/Makefile") - cmate_update_makefile_dep(${CONF_ARGS}) + cmate_install_makefile_dep(${CONF_ARGS}) else() cmate_die("don't know how to build in ${CMATE_DEP_SOURCE_DIR}") endif() endfunction() -function(cmate_update_repo HOST REPO TAG ARGS) +function(cmate_install_repo HOST REPO TAG ARGS) cmate_dep_get_repo(${HOST} ${REPO} "${TAG}") - cmate_update_dep("${ARGS}") + cmate_install_dep("${ARGS}") endfunction() -function(cmate_update_url URL ARGS) +function(cmate_install_url URL ARGS) cmate_deps_get_url(${URL}) - cmate_update_dep("${ARGS}") + cmate_install_dep("${ARGS}") endfunction() -function(cmate_update) +function(cmate_install) if(NOT EXISTS ${CMATE_DEPSFILE}) cmate_msg("no dependencies") return() @@ -1234,7 +1295,7 @@ function(cmate_update) set(URL ${CMAKE_MATCH_1}) set(ARGS "${CMAKE_MATCH_3}") cmate_msg("checking ${URL}") - cmate_update_url(${URL} "${ARGS}") + cmate_install_url(${URL} "${ARGS}") elseif(SPEC MATCHES "^(([^: ]+):)?([^@ ]+)(@([^ ]+))?([ ](.+))?$") # GitHub/GitLab style project short ref if(CMAKE_MATCH_2) @@ -1251,7 +1312,7 @@ function(cmate_update) set(TAG ${CMAKE_MATCH_5}) set(ARGS "${CMAKE_MATCH_7}") cmate_msg("checking ${REPO}") - cmate_update_repo(${HOST} ${REPO} "${TAG}" "${ARGS}") + cmate_install_repo(${HOST} ${REPO} "${TAG}" "${ARGS}") else() cmate_die("invalid dependency line: ${SPEC}") endif() @@ -1269,6 +1330,7 @@ list( APPEND CMATE_OPTIONS "verbose" + "cc" ) function(cmate_build_help VAR) @@ -1278,7 +1340,9 @@ function(cmate_build_help VAR) Usage: cmate [OPTIONS] COMMAND Options: - --verbose Verbose operation + --verbose Verbose operation + --cc=ID Compiler suite to use (overrides CMATE_CC) + (e.g.: gcc, clang, gcc-10, clang-16, cl) Commands: " @@ -1354,20 +1418,47 @@ function(cmate_set_defaults) get_filename_component(DIR ".cenv" ABSOLUTE) cmate_setg(CMATE_ENV_DIR ${DIR}) + cmate_setgdir(CMATE_ENV_BIN_DIR "${DIR}/bin") + cmate_setgdir(CMATE_DL_DIR "${CMATE_ENV_DIR}/downloads") get_filename_component(DIR ".cmate" ABSOLUTE) cmate_setg(CMATE_HOME_DIR ${DIR}) - cmate_setg(CMATE_DEPS_DIR "${CMATE_HOME_DIR}/deps") cmate_setg(CMATE_STATE_DIR "${CMATE_HOME_DIR}/state") cmate_setg(CMATE_TOOLCHAINS_DIR "${CMATE_HOME_DIR}/toolchains") - cmate_setg(CMATE_BUILD_DIR "${CMATE_ROOT_DIR}/build") + cmate_setg(CMATE_BUILD_BASE_DIR "${CMATE_ROOT_DIR}/build") cmate_setg(CMATE_STAGE_DIR "${CMATE_ROOT_DIR}/stage") + cmate_setg(CMATE_TMP_DIR "${CMATE_HOME_DIR}/tmp") + cmate_setg(CMATE_HEADER_PAT "*.hpp") cmate_setg(CMATE_SOURCE_PAT "*.[ch]pp") endfunction() +function(cmate_set_compilers) + set(CC "$ENV{CMATE_CC}") + + if(CMATE_CC) + set(CC "${CMATE_CC}") + endif() + + if(CC) + if(${CC} MATCHES "^gcc(.*)$") + set(CXX "g++${CMAKE_MATCH_1}") + elseif(${CC} MATCHES "^clang(.*)$") + set(CXX "clang++${CMAKE_MATCH_1}") + else() + set(CXX "${CC}") + endif() + + cmate_msg("using compilers CC=${CC} CXX=${CXX}") + cmate_setg(CMAKE_C_COMPILER "${CC}") + cmate_setg(CMAKE_CXX_COMPILER "${CXX}") + set(ENV{CC} "${CC}") + set(ENV{CXX} "${CXX}") + endif() +endfunction() + ############################################################################## # # Command processing @@ -1397,6 +1488,7 @@ endfunction() if(CMAKE_SCRIPT_MODE_FILE) cmate_set_defaults() cmate_parse_arguments() + cmate_set_compilers() cmate_load_conf("${CMATE_ROOT_DIR}/${CMATE_PRJFILE}") cmate_process_cmd() endif() diff --git a/cpp/deps.txt b/cpp/deps.txt index 268b6aa96..95058ad50 100644 --- a/cpp/deps.txt +++ b/cpp/deps.txt @@ -1,2 +1,2 @@ nlohmann/json@v3.11.3 -DJSON_BuildTests=OFF -cucumber/messages --srcdir=cpp \ No newline at end of file +cucumber/messages --srcdir=cpp diff --git a/cpp/include/gherkin/cucumber/gherkin/regex.hpp b/cpp/include/gherkin/cucumber/gherkin/regex.hpp index 4f0acbc09..4404df329 100644 --- a/cpp/include/gherkin/cucumber/gherkin/regex.hpp +++ b/cpp/include/gherkin/cucumber/gherkin/regex.hpp @@ -108,35 +108,45 @@ extract_submatches(MatchResult&& m, Args&&... args) } template < - typename CharT, + typename CharT, typename Traits, typename MatchResult > void extract_submatches( MatchResult&& m, - std::vector>& vs + std::vector>& vs ) { auto mit = m.begin(); while (++mit != m.end()) { - vs.push_back(std::string_view{mit->first, mit->second}); + vs.push_back( + std::basic_string_view{ + mit->first, + mit->second + } + ); } } } // namespace detail -template +template < + typename CharT, typename Traits, + typename ReTraits, + typename... Args> bool full_match( - std::basic_string_view e, - const std::basic_regex& re, + std::basic_string_view e, + const std::basic_regex& re, Args&&... args ) { - std::cmatch m; + std::match_results m; + auto bit = e.data(); + auto eit = e.data() + e.size(); - bool match = std::regex_match(e.begin(), e.end(), m, re); + bool match = std::regex_match(bit, eit, m, re); if (match) { detail::extract_submatches(m, std::forward(args)...); @@ -145,11 +155,14 @@ full_match( return match; } -template +template < + typename CharT, typename Traits, + typename... Args +> bool full_match( - std::basic_string_view e, - std::basic_string_view pat, + std::basic_string_view e, + std::basic_string_view pat, Args&&... args ) { @@ -158,26 +171,35 @@ full_match( return full_match(e, re, std::forward(args)...); } -template +template < + typename CharT, typename Traits, typename Allocator, + typename... Args +> bool -full_match(const std::basic_string& e, Args&&... args) +full_match( + const std::basic_string& e, + Args&&... args +) { return full_match( - std::string_view{ e.data(), e.size() }, + std::basic_string_view{ e.data(), e.size() }, std::forward(args)... ); } -template +template < + typename CharT, typename Traits, + typename... Args +> bool partial_match( - std::basic_string_view e, - std::basic_string_view pat, + std::basic_string_view e, + std::basic_string_view pat, Args&&... args ) { - std::cmatch m; + std::match_results m; std::regex re(pat.data(), pat.size()); bool match = std::regex_search(e.begin(), e.end(), m, re); diff --git a/cpp/include/gherkin/cucumber/gherkin/utils.hpp b/cpp/include/gherkin/cucumber/gherkin/utils.hpp index 4161b00cf..dcbe54cbe 100644 --- a/cpp/include/gherkin/cucumber/gherkin/utils.hpp +++ b/cpp/include/gherkin/cucumber/gherkin/utils.hpp @@ -1,5 +1,12 @@ #pragma once +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable : 4996) +#pragma warning(disable : 4244) +#endif + +#include #include #include #include @@ -255,3 +262,7 @@ struct reverse }; } + +#ifdef _MSC_VER +#pragma warning(pop) +#endif diff --git a/cpp/src/lib/gherkin/cucumber/gherkin/demangle.cpp b/cpp/src/lib/gherkin/cucumber/gherkin/demangle.cpp index aed508929..c6504cb7b 100644 --- a/cpp/src/lib/gherkin/cucumber/gherkin/demangle.cpp +++ b/cpp/src/lib/gherkin/cucumber/gherkin/demangle.cpp @@ -1,6 +1,13 @@ // https://gist.github.com/bwoods/bbc6bd26b73fa37e94ac +#if defined(_MSC_VER) +#include +#include +#pragma comment(lib, "dbghelp.lib") +#else #include // gcc and clang… +#endif + #include #include @@ -15,11 +22,23 @@ demangle(std::string&& name) { int status = 0; +#if defined(_MSC_VER) + //try to allocate a buffer as __cxa_demangle will do + //assuming symbol name is less than 1024 bytes + char* realname = (char*) malloc(1024 * sizeof(char)); + + if (realname) { + ::UnDecorateSymbolName(name.c_str(), realname, 1024, 0); + } + + return { realname, [] (char * p) { ::free(p); } }; +#else return { abi::__cxa_demangle(name.c_str(), nullptr, nullptr, &status), [] (char * p) { ::free(p); } }; +#endif } } // namespace detail