diff --git a/CMakeLists.txt b/CMakeLists.txt index 75ffe79b8..f653939fd 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,61 +1,114 @@ cmake_minimum_required(VERSION 3.12) + +if(POLICY CMP0063) + cmake_policy(SET CMP0063 NEW) +endif() + +if(POLICY CMP0092) + cmake_policy(SET CMP0092 NEW) +endif() + project(cmark-gfm) +# NOTE: we cannot simply version the project due to the use of an invalid +# version (the infixed `.gfm.`). +set(PROJECT_VERSION 0.29.0.gfm.13) -set(PROJECT_VERSION_MAJOR 0) -set(PROJECT_VERSION_MINOR 29) -set(PROJECT_VERSION_PATCH 0) -set(PROJECT_VERSION_GFM 13) -set(PROJECT_VERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}.gfm.${PROJECT_VERSION_GFM}) +set(CMAKE_C_STANDARD 99) +set(CMAKE_C_STANDARD_REQUIRED YES) +set(CMAKE_C_EXTENSIONS NO) + +set(CMAKE_C_VISIBILITY_PRESET hidden) +set(CMAKE_VISIBILITY_INLINES_HIDDEN TRUE) -include("FindAsan.cmake") -include("CheckFileOffsetBits.cmake") +set(CMAKE_INCLUDE_CURRENT_DIR YES) + +option(CMARK_FUZZ_QUADRATIC "Build quadratic fuzzing harness" OFF) +option(CMARK_LIB_FUZZER "Build libFuzzer fuzzing harness" OFF) +option(CMARK_THREADING "Add locks around static accesses" OFF) if("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_BINARY_DIR}") message(FATAL_ERROR "Do not build in-source.\nPlease remove CMakeCache.txt and the CMakeFiles/ directory.\nThen: mkdir build ; cd build ; cmake .. ; make") endif() +if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE "Release" CACHE STRING + "Choose the type of build, options are: Debug Profile Release Asan Ubsan." FORCE) +endif(NOT CMAKE_BUILD_TYPE) -option(CMARK_TESTS "Build cmark-gfm tests and enable testing" ON) -option(CMARK_STATIC "Build static libcmark-gfm library" ON) -option(CMARK_SHARED "Build shared libcmark-gfm library" ON) -option(CMARK_LIB_FUZZER "Build libFuzzer fuzzing harness" OFF) -option(CMARK_THREADING "Add locks around static accesses" OFF) +list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake/modules) + +include(CheckFileOffsetBits) +include(CTest) +include(FindAsan) +if(CMARK_THREADING) + set(THREADS_PREFER_PTHREAD_FLAG YES) + include(FindThreads) + add_compile_definitions(CMARK_THREADING) +endif() +include(GNUInstallDirs) + +if(NOT MSVC OR CMAKE_HOST_SYSTEM_NAME STREQUAL Windows) + set(CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_NO_WARNINGS ON) + include(InstallRequiredSystemLibraries) +endif() -# set a required C standard so we can load stdbool.h if(MSVC) - set(CMAKE_C_STANDARD 11) -else() - set(CMAKE_C_STANDARD 99) + add_compile_options($<$:/W4>) + add_compile_options($<$:/WX>) + # FIXME(compnerd) why do we diverge from upstream? + add_compile_options($<$:/wd5105>) + add_compile_options($<$:/wd4706>) + add_compile_options($<$:/wd4221>) + add_compile_options($<$:/wd4204>) + add_compile_options($<$:/wd4100>) + add_compile_definitions($<$:_CRT_SECURE_NO_WARNINGS>) +elseif(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES Clang) + add_compile_options($<$:-Wall>) + add_compile_options($<$:-Wextra>) + add_compile_options($<$:-Wno-unused-parameter>) + add_compile_options($<$:-pedantic>) endif() -set(CMAKE_C_STANDARD_REQUIRED YES) -# Use CMake's generated headers instead of the Swift package prebuilt ones -add_compile_definitions(CMARK_USE_CMAKE_HEADERS) +if(CMAKE_BUILD_TYPE STREQUAL "Ubsan") + add_compile_options($<$:-fsanitize=undefined>) +endif() -option(CMARK_FUZZ_QUADRATIC "Build quadratic fuzzing harness" OFF) +# Check integrity of node structure when compiled as debug +add_compile_definitions($<$:CMARK_DEBUG_NODES>) +# FIXME(compnerd) why do we not use `!defined(NDEBUG)`? +add_compile_definitions($<$:DEBUG>) + +add_compile_options($<$,$>:-pg>) + +if(CMARK_LIB_FUZZER) + add_compile_options($<$:-fsanitize-coverage=trace-pc-guard>) +endif() if(CMARK_FUZZ_QUADRATIC) - set(FUZZER_FLAGS "-fsanitize=fuzzer-no-link,address -g") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${FUZZER_FLAGS}") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${FUZZER_FLAGS}") - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${FUZZER_FLAGS}") - set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${FUZZER_FLAGS}") + # FIXME(compnerd) why do we enable debug information? + add_compile_options($<$:-g>) + # FIXME(compnerd) why do we use fuzzer-no-link with a custom variable for the + # runtime rather than `-fsanitize=fuzzer,address`? + add_compile_options($<$:-fsanitize=fuzzer-no-link,address>) + add_link_options($<$:-fsanitize=address>) endif() +check_file_offset_bits() + add_subdirectory(src) add_subdirectory(extensions) -if(CMARK_TESTS AND (CMARK_SHARED OR CMARK_STATIC)) - add_subdirectory(api_test) +# TODO(compnerd) should this be enabled for MinGW, which sets CMAKE_SYSTEM_NAME +# to Windows, but defines `MINGW`. +if(NOT CMAKE_SYSTEM_NAME STREQUAL Windows) + add_subdirectory(man) endif() -add_subdirectory(man) -if(CMARK_TESTS) - enable_testing() +if(BUILD_TESTING) add_subdirectory(test testdir) + add_subdirectory(api_test) endif() if(CMARK_FUZZ_QUADRATIC) add_subdirectory(fuzz) endif() -if(NOT CMAKE_BUILD_TYPE) - set(CMAKE_BUILD_TYPE "Release" CACHE STRING - "Choose the type of build, options are: Debug Profile Release Asan Ubsan." FORCE) -endif(NOT CMAKE_BUILD_TYPE) +export(TARGETS libcmark-gfm libcmark-gfm-extensions + FILE cmark-gfmConfig.cmake) + diff --git a/Makefile b/Makefile index db13e50d0..3ca75ee11 100644 --- a/Makefile +++ b/Makefile @@ -75,7 +75,7 @@ prof: afl: @[ -n "$(AFL_PATH)" ] || { echo '$$AFL_PATH not set'; false; } mkdir -p $(BUILDDIR) - cd $(BUILDDIR) && cmake .. -DCMARK_TESTS=0 -DCMAKE_C_COMPILER=$(AFL_PATH)/afl-clang + cd $(BUILDDIR) && cmake .. -DBUILD_TESTING=NO -DCMAKE_C_COMPILER=$(AFL_PATH)/afl-clang $(MAKE) $(AFL_PATH)/afl-fuzz \ -i test/afl_test_cases \ diff --git a/Package.swift b/Package.swift index ba31d5c16..f1acc5f3a 100644 --- a/Package.swift +++ b/Package.swift @@ -4,28 +4,19 @@ import PackageDescription #if os(Windows) -#if arch(i386) || arch(x86_64) - var cSettings: [CSetting] = [ - .define("_X86_", .when(platforms: [.windows])), - ] -#elseif arch(arm) || arch(arm64) - var cSettings: [CSetting] = [ - .define("_ARM_", .when(platforms: [.windows])), - ] -#else -#error("unsupported architecture") -#endif // When building the library on Windows, we do not have proper control of // whether it is being built statically or dynamically. However, given the // current default of static, we will assume that we are building // statically. More importantly, should this not hold, this will fail at // link time. - cSettings += [ + let cSettings: [CSetting] = [ .define("CMARK_GFM_STATIC_DEFINE", .when(platforms: [.windows])), - .define("CMARK_GFM_EXTENSIONS_STATIC_DEFINE", .when(platforms: [.windows])), + .define("CMARK_THREADING"), ] #else - let cSettings: [CSetting] = [] + let cSettings: [CSetting] = [ + .define("CMARK_THREADING"), + ] #endif let package = Package( @@ -50,9 +41,7 @@ let package = Package( exclude: [ "scanners.re", "libcmark-gfm.pc.in", - "config.h.in", "CMakeLists.txt", - "cmark-gfm_version.h.in", ], cSettings: cSettings ), diff --git a/api_test/CMakeLists.txt b/api_test/CMakeLists.txt index 151192d8a..10e7ca02c 100644 --- a/api_test/CMakeLists.txt +++ b/api_test/CMakeLists.txt @@ -10,22 +10,12 @@ include_directories( ${PROJECT_SOURCE_DIR}/extensions/include ${PROJECT_BINARY_DIR}/extensions ) -if(CMARK_SHARED) - target_link_libraries(api_test libcmark-gfm-extensions libcmark-gfm) -else() - target_link_libraries(api_test libcmark-gfm-extensions_static libcmark-gfm_static) -endif() +target_link_libraries(api_test PRIVATE + libcmark-gfm + libcmark-gfm-extensions) -# Compiler flags -if(MSVC) - # Force to always compile with W4 - if(CMAKE_CXX_FLAGS MATCHES "/W[0-4]") - string(REGEX REPLACE "/W[0-4]" "/W4" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}") - else() - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /W4") - endif() - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /wd4706 /wd5105 /D_CRT_SECURE_NO_WARNINGS") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /TP") -elseif(CMAKE_COMPILER_IS_GNUCC OR "${CMAKE_C_COMPILER_ID}" STREQUAL "Clang") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -std=c99 -pedantic") +add_test(NAME api_test COMMAND api_test) +if(WIN32 AND BUILD_SHARED_LIBS) + set_tests_properties(api_test PROPERTIES + ENVIRONMENT "PATH=$;$;$ENV{PATH}") endif() diff --git a/api_test/main.c b/api_test/main.c index e0fe02968..1824c41f2 100644 --- a/api_test/main.c +++ b/api_test/main.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -1387,7 +1388,7 @@ static void parser_interrupt(test_batch_runner *runner) { cmark_gfm_core_extensions_ensure_registered(); cmark_syntax_extension *my_ext = cmark_syntax_extension_new("interrupt"); - cmark_syntax_extension_set_private(my_ext, run_inner_parser, NULL); + cmark_syntax_extension_set_private(my_ext, (void *)&run_inner_parser, NULL); cmark_syntax_extension_set_match_inline_func(my_ext, reentrant_parse_inline_ext); cmark_parser *parser = cmark_parser_new(CMARK_OPT_DEFAULT); diff --git a/bin/main.c b/bin/main.c index 1c5aae847..0b523596c 100644 --- a/bin/main.c +++ b/bin/main.c @@ -1,8 +1,9 @@ -#include +#include +#include #include +#include #include -#include -#include "cmark-gfm_config.h" + #include "cmark-gfm.h" #include "node.h" #include "cmark-gfm-extension_api.h" diff --git a/CheckFileOffsetBits.c b/cmake/modules/CheckFileOffsetBits.c similarity index 100% rename from CheckFileOffsetBits.c rename to cmake/modules/CheckFileOffsetBits.c diff --git a/CheckFileOffsetBits.cmake b/cmake/modules/CheckFileOffsetBits.cmake similarity index 100% rename from CheckFileOffsetBits.cmake rename to cmake/modules/CheckFileOffsetBits.cmake diff --git a/FindAsan.cmake b/cmake/modules/FindAsan.cmake similarity index 100% rename from FindAsan.cmake rename to cmake/modules/FindAsan.cmake diff --git a/extensions/CMakeLists.txt b/extensions/CMakeLists.txt index 43d4a20f0..3263f26dd 100644 --- a/extensions/CMakeLists.txt +++ b/extensions/CMakeLists.txt @@ -1,114 +1,34 @@ -set(LIBRARY "libcmark-gfm-extensions") -set(STATICLIBRARY "libcmark-gfm-extensions_static") -set(LIBRARY_SOURCES - core-extensions.c - table.c - strikethrough.c - autolink.c - tagfilter.c - ext_scanners.c - ext_scanners.re - ext_scanners.h - tasklist.c - ) - -include_directories( - ${PROJECT_SOURCE_DIR}/src/include - ${PROJECT_BINARY_DIR}/src -) - -include_directories(include ${CMAKE_CURRENT_BINARY_DIR}) - -set(CMAKE_C_FLAGS_PROFILE "${CMAKE_C_FLAGS_RELEASE} -pg") -set(CMAKE_LINKER_PROFILE "${CMAKE_LINKER_FLAGS_RELEASE} -pg") - -if (CMARK_SHARED) - add_library(${LIBRARY} SHARED ${LIBRARY_SOURCES}) - - set_target_properties(${LIBRARY} PROPERTIES - OUTPUT_NAME "cmark-gfm-extensions" - DEFINE_SYMBOL "libcmark_gfm_EXPORTS" - SOVERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}.gfm.${PROJECT_VERSION_GFM} - VERSION ${PROJECT_VERSION}) - - set_property(TARGET ${LIBRARY} - APPEND PROPERTY MACOSX_RPATH true) - - # Avoid name clash between PROGRAM and LIBRARY pdb files. - set_target_properties(${LIBRARY} PROPERTIES PDB_NAME cmark-gfm-extensions_dll) - - list(APPEND CMARK_INSTALL ${LIBRARY}) - target_link_libraries(${LIBRARY} libcmark-gfm) - -endif() - -if (CMARK_STATIC) - add_library(${STATICLIBRARY} STATIC ${LIBRARY_SOURCES}) - - set_target_properties(${STATICLIBRARY} PROPERTIES - COMPILE_FLAGS "-DCMARK_GFM_STATIC_DEFINE -DCMARK_GFM_EXTENSIONS_STATIC_DEFINE" - POSITION_INDEPENDENT_CODE ON) - - if (MSVC) - set_target_properties(${STATICLIBRARY} PROPERTIES - OUTPUT_NAME "cmark-gfm-extensions_static" - VERSION ${PROJECT_VERSION}) - else() - set_target_properties(${STATICLIBRARY} PROPERTIES - OUTPUT_NAME "cmark-gfm-extensions" - VERSION ${PROJECT_VERSION}) - endif(MSVC) - - list(APPEND CMARK_INSTALL ${STATICLIBRARY}) -endif() - -set(CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_NO_WARNINGS ON) - -include (InstallRequiredSystemLibraries) -install(TARGETS ${CMARK_INSTALL} +add_library(libcmark-gfm-extensions + autolink.c + core-extensions.c + ext_scanners.c + ext_scanners.h + ext_scanners.re + strikethrough.c + table.c + tagfilter.c + tasklist.c) +target_compile_definitions(libcmark-gfm-extensions PUBLIC + $<$>:CMARK_GFM_STATIC_DEFINE>) +target_link_libraries(libcmark-gfm-extensions PRIVATE + libcmark-gfm) +set_target_properties(libcmark-gfm-extensions PROPERTIES + DEFINE_SYMBOL libcmark_gfm_EXPORTS + MACOSX_RPATH TRUE + OUTPUT_NAME cmark-gfm-extensions + PDB_NAME libcmark-gfm-extensions + SOVERSION ${PROJECT_VERSION} + VERSION ${PROJECT_VERSION}) + + +install(TARGETS libcmark-gfm-extensions EXPORT cmark-gfm-extensions - RUNTIME DESTINATION bin - LIBRARY DESTINATION lib${LIB_SUFFIX} - ARCHIVE DESTINATION lib${LIB_SUFFIX} - ) - -if (CMARK_SHARED OR CMARK_STATIC) - install(FILES - ${CMAKE_CURRENT_SOURCE_DIR}/include/cmark-gfm-core-extensions.h - DESTINATION include - ) - - install(EXPORT cmark-gfm-extensions DESTINATION lib${LIB_SUFFIX}/cmake-gfm-extensions) -endif() - -# Feature tests -include(CheckIncludeFile) -include(CheckCSourceCompiles) -include(CheckCSourceRuns) -include(CheckSymbolExists) -CHECK_INCLUDE_FILE(unistd.h HAVE_UNISTD_H) -CHECK_C_SOURCE_COMPILES( - "int main() { __builtin_expect(0,0); return 0; }" - HAVE___BUILTIN_EXPECT) - -# Always compile with warnings -if(MSVC) - # Force to always compile with W4 - if(CMAKE_CXX_FLAGS MATCHES "/W[0-4]") - string(REGEX REPLACE "/W[0-4]" "/W4" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}") - else() - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /W4") - endif() - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /WX /wd4706 /wd4204 /wd4221 /wd4100 /wd5105 /D_CRT_SECURE_NO_WARNINGS") -elseif(CMAKE_COMPILER_IS_GNUCC OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wno-unused-parameter -std=c99 -pedantic") -endif() - -# Compile as C++ under MSVC older than 12.0 -if(MSVC AND MSVC_VERSION LESS 1800) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /TP") -endif() - -if(CMAKE_BUILD_TYPE STREQUAL "Ubsan") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=undefined") -endif() + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) +install(FILES + include/cmark-gfm-core-extensions.h + include/module.modulemap + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/cmark_gfm_extensions) +install(EXPORT cmark-gfm-extensions + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake-gfm-extensions) diff --git a/extensions/autolink.c b/extensions/autolink.c index d898cd2d4..bba666b9d 100644 --- a/extensions/autolink.c +++ b/extensions/autolink.c @@ -1,8 +1,10 @@ +#include +#include +#include + #include "autolink.h" #include -#include #include -#include #if defined(_WIN32) #define strncasecmp _strnicmp diff --git a/extensions/include/cmark-gfm-core-extensions.h b/extensions/include/cmark-gfm-core-extensions.h index 6f7aada65..de652feb9 100644 --- a/extensions/include/cmark-gfm-core-extensions.h +++ b/extensions/include/cmark-gfm-core-extensions.h @@ -7,6 +7,7 @@ extern "C" { #include "cmark-gfm-extension_api.h" #include "export.h" + #include #include diff --git a/extensions/include/module.modulemap b/extensions/include/module.modulemap new file mode 100644 index 000000000..7bb1bd79a --- /dev/null +++ b/extensions/include/module.modulemap @@ -0,0 +1,5 @@ + +module cmark_gfm_extensions { + header "cmark-gfm-core-extensions.h" +} + diff --git a/extensions/strikethrough.c b/extensions/strikethrough.c index e08842242..436e515f0 100644 --- a/extensions/strikethrough.c +++ b/extensions/strikethrough.c @@ -1,3 +1,5 @@ +#include + #include "strikethrough.h" #include #include diff --git a/extensions/table.c b/extensions/table.c index 6c7a2bbae..c84f863e7 100644 --- a/extensions/table.c +++ b/extensions/table.c @@ -1,3 +1,5 @@ +#include + #include #include #include diff --git a/extensions/tasklist.c b/extensions/tasklist.c index 954edf147..d6d9fe664 100644 --- a/extensions/tasklist.c +++ b/extensions/tasklist.c @@ -1,3 +1,5 @@ +#include + #include "tasklist.h" #include #include diff --git a/fuzz/CMakeLists.txt b/fuzz/CMakeLists.txt index a9ed57aa5..e4e7b5185 100644 --- a/fuzz/CMakeLists.txt +++ b/fuzz/CMakeLists.txt @@ -1,22 +1,11 @@ -include_directories( - ${PROJECT_BINARY_DIR}/extensions - ${PROJECT_BINARY_DIR}/src - ../extensions - ../src -) - -macro(fuzzer name) - add_executable(${name} ${name}.c) - set_target_properties(${name} - PROPERTIES - COMPILE_FLAGS "-fsanitize=fuzzer" - LINK_FLAGS "-fsanitize=fuzzer") - if(CMARK_SHARED) - target_link_libraries(${name} libcmark-gfm-extensions libcmark-gfm) - elseif(CMARK_STATIC) - target_link_libraries(${name} libcmark-gfm-extensions_static libcmark-gfm_static) - endif() -endmacro() - -fuzzer(fuzz_quadratic) -fuzzer(fuzz_quadratic_brackets) +foreach(fuzzer fuzz_quadratic fuzz_quadratic_brackets) + add_executable(${fuzzer} + ${fuzzer}.c) + target_compile_options(${fuzzer} PRIVATE + -fsanitize=fuzzer) + target_link_options(${fuzzer} PRIVATE + -fsanitize=fuzzer) + target_link_libraries(${fuzzer} PRIVATE + libcmark-gfm + libcmark-gfm-extensions) +endforeach() diff --git a/man/CMakeLists.txt b/man/CMakeLists.txt index d0c5b6066..e47c63583 100644 --- a/man/CMakeLists.txt +++ b/man/CMakeLists.txt @@ -1,10 +1,4 @@ -if (NOT MSVC) - -include(GNUInstallDirs) - - install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/man1/cmark-gfm.1 - DESTINATION ${CMAKE_INSTALL_MANDIR}/man1) - - install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/man3/cmark-gfm.3 - DESTINATION ${CMAKE_INSTALL_MANDIR}/man3) -endif(NOT MSVC) +install(FILES man1/cmark-gfm.1 + DESTINATION ${CMAKE_INSTALL_MANDIR}/man1) +install(FILES man3/cmark-gfm.3 + DESTINATION ${CMAKE_INSTALL_MANDIR}/man3) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 65e23cccd..76e16b88a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,221 +1,95 @@ -if(${CMAKE_VERSION} VERSION_GREATER "3.3") - cmake_policy(SET CMP0063 NEW) -endif() - -include(GNUInstallDirs) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/libcmark-gfm.pc.in + ${CMAKE_CURRENT_BINARY_DIR}/libcmark-gfm.pc @ONLY) -set(LIBRARY "libcmark-gfm") -set(STATICLIBRARY "libcmark-gfm_static") -file(GLOB HEADERS include/*.h) -set(LIBRARY_SOURCES - cmark.c - node.c - iterator.c +add_library(libcmark-gfm + arena.c blocks.c - inlines.c - scanners.c - scanners.re - utf8.c buffer.c - references.c - footnotes.c - map.c - render.c - man.c - xml.c - html.c + cmark.c + cmark_ctype.c commonmark.c - plaintext.c - latex.c + footnotes.c houdini_href_e.c houdini_html_e.c houdini_html_u.c - cmark_ctype.c - arena.c + html.c + inlines.c + iterator.c + latex.c linked_list.c - syntax_extension.c - registry.c + man.c + map.c + node.c + plaintext.c plugin.c - ${HEADERS} - ) - -set(PROGRAM "cmark-gfm") -set(PROGRAM_SOURCES "${PROJECT_SOURCE_DIR}/bin/main.c") - -include_directories(include ${CMAKE_CURRENT_BINARY_DIR}) -include_directories( - ${PROJECT_SOURCE_DIR}/extensions/include - ${PROJECT_BINARY_DIR}/extensions -) - -configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cmark-gfm_version.h.in - ${CMAKE_CURRENT_BINARY_DIR}/cmark-gfm_version.h) - -include (GenerateExportHeader) - -include("../CheckFileOffsetBits.cmake") -CHECK_FILE_OFFSET_BITS() - -add_executable(${PROGRAM} ${PROGRAM_SOURCES}) - -if(CMARK_SHARED) - target_link_libraries(${PROGRAM} libcmark-gfm-extensions libcmark-gfm) -elseif(CMARK_STATIC) - target_link_libraries(${PROGRAM} libcmark-gfm-extensions_static libcmark-gfm_static) -endif() - -# Disable the PUBLIC declarations when compiling the executable: -set_target_properties(${PROGRAM} PROPERTIES - COMPILE_FLAGS "-DCMARK_GFM_STATIC_DEFINE -DCMARK_GFM_EXTENSIONS_STATIC_DEFINE") - -# Check integrity of node structure when compiled as debug: -set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DCMARK_DEBUG_NODES -DDEBUG") -set(CMAKE_LINKER_DEBUG "${CMAKE_LINKER_FLAGS_DEBUG}") - -set(CMAKE_C_FLAGS_PROFILE "${CMAKE_C_FLAGS_RELEASE} -pg") -set(CMAKE_LINKER_PROFILE "${CMAKE_LINKER_FLAGS_RELEASE} -pg") - -# -fvisibility=hidden -set(CMAKE_C_VISIBILITY_PRESET hidden) -set(CMAKE_VISIBILITY_INLINES_HIDDEN 1) - -if (CMARK_SHARED) - add_library(${LIBRARY} SHARED ${LIBRARY_SOURCES}) - # Include minor version and patch level in soname for now. - set_target_properties(${LIBRARY} PROPERTIES - OUTPUT_NAME "cmark-gfm" - SOVERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}.gfm.${PROJECT_VERSION_GFM} - VERSION ${PROJECT_VERSION}) - - set_property(TARGET ${LIBRARY} - APPEND PROPERTY MACOSX_RPATH true) - - # Avoid name clash between PROGRAM and LIBRARY pdb files. - set_target_properties(${LIBRARY} PROPERTIES PDB_NAME cmark-gfm_dll) - - generate_export_header(${LIBRARY} - BASE_NAME ${PROJECT_NAME}) - - list(APPEND CMARK_INSTALL ${LIBRARY}) -endif() - -if (CMARK_STATIC) - add_library(${STATICLIBRARY} STATIC ${LIBRARY_SOURCES}) - set_target_properties(${STATICLIBRARY} PROPERTIES - COMPILE_FLAGS -DCMARK_GFM_STATIC_DEFINE - POSITION_INDEPENDENT_CODE ON) - - if (MSVC) - set_target_properties(${STATICLIBRARY} PROPERTIES - OUTPUT_NAME "cmark-gfm_static" - VERSION ${PROJECT_VERSION}) - else() - set_target_properties(${STATICLIBRARY} PROPERTIES - OUTPUT_NAME "cmark-gfm" - VERSION ${PROJECT_VERSION}) - endif(MSVC) - - if (NOT CMARK_SHARED) - generate_export_header(${STATICLIBRARY} - BASE_NAME ${PROJECT_NAME}) - endif() - - list(APPEND CMARK_INSTALL ${STATICLIBRARY}) -endif() - -if (MSVC) - set_property(TARGET ${PROGRAM} - APPEND PROPERTY LINK_FLAGS /INCREMENTAL:NO) -endif(MSVC) - -if(NOT MSVC OR CMAKE_HOST_SYSTEM_NAME STREQUAL Windows) - set(CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_NO_WARNINGS ON) - include(InstallRequiredSystemLibraries) + references.c + registry.c + render.c + scanners.c + scanners.re + syntax_extension.c + utf8.c + xml.c) +if(NOT BUILD_SHARED_LIBS) + target_compile_definitions(libcmark-gfm PUBLIC + CMARK_GFM_STATIC_DEFINE) + target_compile_options(libcmark-gfm PUBLIC + $<$:-Xcc -DCMARK_GFM_STATIC_DEFINE>) endif() - -set(libdir lib${LIB_SUFFIX}) - -install(TARGETS ${PROGRAM} ${CMARK_INSTALL} +target_include_directories(libcmark-gfm PUBLIC + $ + $ + $) + target_link_libraries(libcmark-gfm PRIVATE + $<$:Threads::Threads>) +set_target_properties(libcmark-gfm PROPERTIES + MACOSX_RPATH TRUE + OUTPUT_NAME cmark-gfm + PDB_NAME libcmark-gfm + SOVERSION ${PROJECT_VERSION} + VERSION ${PROJECT_VERSION}) + +add_executable(cmark-gfm + ${PROJECT_SOURCE_DIR}/bin/main.c) +target_link_libraries(cmark-gfm + libcmark-gfm + libcmark-gfm-extensions) + + +install(TARGETS cmark-gfm libcmark-gfm EXPORT cmark-gfm - RUNTIME DESTINATION bin - LIBRARY DESTINATION ${libdir} - ARCHIVE DESTINATION ${libdir} - ) - -if(CMARK_SHARED OR CMARK_STATIC) - configure_file(${CMAKE_CURRENT_SOURCE_DIR}/libcmark-gfm.pc.in - ${CMAKE_CURRENT_BINARY_DIR}/libcmark-gfm.pc @ONLY) - install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libcmark-gfm.pc - DESTINATION ${libdir}/pkgconfig) - - install(FILES - ${CMAKE_CURRENT_SOURCE_DIR}/include/cmark-gfm.h - ${CMAKE_CURRENT_SOURCE_DIR}/include/cmark-gfm_config.h - ${CMAKE_CURRENT_SOURCE_DIR}/include/cmark-gfm-extension_api.h - ${CMAKE_CURRENT_SOURCE_DIR}/include/export.h - ${CMAKE_CURRENT_SOURCE_DIR}/include/cmark-gfm_version.h - DESTINATION include - ) - - install(EXPORT cmark-gfm DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake) - - set(CMARK_TARGETS_FILE ${CMAKE_CURRENT_BINARY_DIR}/cmarkTargets.cmake) - export(TARGETS ${CMARK_INSTALL} FILE ${CMARK_TARGETS_FILE}) - - if(CMARK_THREADING AND NOT APPLE AND NOT MSVC AND NOT ANDROID) - if(CMARK_SHARED) - target_link_libraries(${LIBRARY} pthread) - endif(CMARK_SHARED) - - if(CMARK_STATIC) - target_link_libraries(${STATICLIBRARY} pthread) - endif(CMARK_STATIC) - endif() -endif() - -# Feature tests -include(CheckIncludeFile) -include(CheckCSourceCompiles) -include(CheckCSourceRuns) -include(CheckSymbolExists) -CHECK_INCLUDE_FILE(unistd.h HAVE_UNISTD_H) -CHECK_C_SOURCE_COMPILES( - "int main() { __builtin_expect(0,0); return 0; }" - HAVE___BUILTIN_EXPECT) - -CONFIGURE_FILE( - ${CMAKE_CURRENT_SOURCE_DIR}/config.h.in - ${CMAKE_CURRENT_BINARY_DIR}/config.h) - -# Always compile with warnings -if(MSVC) - # Force to always compile with W4 - if(CMAKE_CXX_FLAGS MATCHES "/W[0-4]") - string(REGEX REPLACE "/W[0-4]" "/W4" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}") - else() - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /W4") - endif() - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /WX /wd4706 /wd4204 /wd4221 /wd4100 /wd5105 /D_CRT_SECURE_NO_WARNINGS") -elseif(CMAKE_COMPILER_IS_GNUCC OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wno-unused-parameter -std=c99 -pedantic") -endif() - -# Compile as C++ under MSVC older than 12.0 -if(MSVC AND MSVC_VERSION LESS 1800) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /TP") -endif() - -if(CMAKE_BUILD_TYPE STREQUAL "Ubsan") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=undefined") -endif() - -if(CMARK_LIB_FUZZER) - set(FUZZ_HARNESS "cmark-fuzz") - add_executable(${FUZZ_HARNESS} ../test/cmark-fuzz.c ${LIBRARY_SOURCES}) - target_link_libraries(${FUZZ_HARNESS} "${CMAKE_LIB_FUZZER_PATH}") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize-coverage=trace-pc-guard") - - # cmark is written in C but the libFuzzer runtime is written in C++ which - # needs to link against the C++ runtime. Explicitly link it into cmark-fuzz - set_target_properties(${FUZZ_HARNESS} PROPERTIES LINK_FLAGS "-lstdc++") -endif() + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) +install(FILES + include/buffer.h + include/chunk.h + include/cmark_ctype.h + include/cmark-gfm.h + include/cmark-gfm-extension_api.h + include/cmark-gfm_version.h + include/export.h + include/footnotes.h + include/houdini.h + include/html.h + include/inlines.h + include/iterator.h + include/map.h + include/node.h + include/parser.h + include/plugin.h + include/references.h + include/registry.h + include/render.h + include/scanners.h + include/syntax_extension.h + include/utf8.h + include/module.modulemap + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/cmark_gfm) +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libcmark-gfm.pc + DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) +install(EXPORT cmark-gfm + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake) + +export(TARGETS libcmark-gfm + FILE ${CMAKE_CURRENT_BINARY_DIR}/cmarkTargets.cmake) diff --git a/src/blocks.c b/src/blocks.c index f3b20580e..6467a3a59 100644 --- a/src/blocks.c +++ b/src/blocks.c @@ -5,14 +5,14 @@ * see http://spec.commonmark.org/0.24/#phase-1-block-structure */ -#include #include -#include #include +#include +#include +#include #include "cmark_ctype.h" #include "syntax_extension.h" -#include "cmark-gfm_config.h" #include "parser.h" #include "cmark-gfm.h" #include "node.h" @@ -49,7 +49,7 @@ static bool S_last_line_checked(const cmark_node *node) { return (node->flags & CMARK_NODE__LAST_LINE_CHECKED) != 0; } -static CMARK_INLINE cmark_node_type S_type(const cmark_node *node) { +static inline cmark_node_type S_type(const cmark_node *node) { return (cmark_node_type)node->type; } @@ -64,11 +64,11 @@ static void S_set_last_line_checked(cmark_node *node) { node->flags |= CMARK_NODE__LAST_LINE_CHECKED; } -static CMARK_INLINE bool S_is_line_end_char(char c) { +static inline bool S_is_line_end_char(char c) { return (c == '\n' || c == '\r'); } -static CMARK_INLINE bool S_is_space_or_tab(char c) { +static inline bool S_is_space_or_tab(char c) { return (c == ' ' || c == '\t'); } @@ -213,13 +213,13 @@ static bool is_blank(cmark_strbuf *s, bufsize_t offset) { return true; } -static CMARK_INLINE bool accepts_lines(cmark_node_type block_type) { +static inline bool accepts_lines(cmark_node_type block_type) { return (block_type == CMARK_NODE_PARAGRAPH || block_type == CMARK_NODE_HEADING || block_type == CMARK_NODE_CODE_BLOCK); } -static CMARK_INLINE bool contains_inlines(cmark_node *node) { +static inline bool contains_inlines(cmark_node *node) { if (node->extension && node->extension->contains_inlines_func) { return node->extension->contains_inlines_func(node->extension, node) != 0; } diff --git a/src/buffer.c b/src/buffer.c index df6873731..aeca03d09 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -1,13 +1,12 @@ -#include -#include #include -#include +#include +#include +#include +#include #include #include -#include -#include +#include -#include "cmark-gfm_config.h" #include "cmark_ctype.h" #include "buffer.h" @@ -31,7 +30,7 @@ void cmark_strbuf_init(cmark_mem *mem, cmark_strbuf *buf, cmark_strbuf_grow(buf, initial_size); } -static CMARK_INLINE void S_strbuf_grow_by(cmark_strbuf *buf, bufsize_t add) { +static inline void S_strbuf_grow_by(cmark_strbuf *buf, bufsize_t add) { cmark_strbuf_grow(buf, buf->size + add); } diff --git a/src/cmark-gfm_version.h.in b/src/cmark-gfm_version.h.in deleted file mode 100644 index 0847d0095..000000000 --- a/src/cmark-gfm_version.h.in +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef CMARK_GFM_VERSION_H -#define CMARK_GFM_VERSION_H - -#define CMARK_GFM_VERSION ((@PROJECT_VERSION_MAJOR@ << 24) | (@PROJECT_VERSION_MINOR@ << 16) | (@PROJECT_VERSION_PATCH@ << 8) | @PROJECT_VERSION_GFM@) -#define CMARK_GFM_VERSION_STRING "@PROJECT_VERSION_MAJOR@.@PROJECT_VERSION_MINOR@.@PROJECT_VERSION_PATCH@.gfm.@PROJECT_VERSION_GFM@" - -#endif diff --git a/src/commonmark.c b/src/commonmark.c index f1698687f..a5aa74728 100644 --- a/src/commonmark.c +++ b/src/commonmark.c @@ -1,10 +1,10 @@ -#include +#include +#include +#include #include +#include #include -#include -#include -#include "cmark-gfm_config.h" #include "cmark-gfm.h" #include "node.h" #include "buffer.h" @@ -22,9 +22,8 @@ // Functions to convert cmark_nodes to commonmark strings. -static CMARK_INLINE void outc(cmark_renderer *renderer, cmark_node *node, - cmark_escaping escape, - int32_t c, unsigned char nextc) { +static inline void outc(cmark_renderer *renderer, cmark_node *node, + cmark_escaping escape, int32_t c, unsigned char nextc) { bool needs_escaping = false; bool follows_digit = renderer->buffer->size > 0 && diff --git a/src/config.h.in b/src/config.h.in deleted file mode 100644 index f8f767a8b..000000000 --- a/src/config.h.in +++ /dev/null @@ -1,70 +0,0 @@ -#ifndef CMARK_CONFIG_H -#define CMARK_CONFIG_H - -#ifdef __cplusplus -extern "C" { -#endif - -#if __STDC_VERSION__ >= 199901l - #include -#elif !defined(__cplusplus) - typedef char bool; -#endif - -#cmakedefine HAVE_UNISTD_H - -#cmakedefine HAVE___BUILTIN_EXPECT - -#cmakedefine CMARK_THREADING - -#ifndef CMARK_INLINE - #if defined(_MSC_VER) && !defined(__cplusplus) - #define CMARK_INLINE __inline - #else - #define CMARK_INLINE inline - #endif -#endif - -/* snprintf and vsnprintf fallbacks for MSVC before 2015, - due to Valentin Milea http://stackoverflow.com/questions/2915672/ -*/ - -#if defined(_MSC_VER) && _MSC_VER < 1900 - -#include -#include - -#define snprintf c99_snprintf -#define vsnprintf c99_vsnprintf - -CMARK_INLINE int c99_vsnprintf(char *outBuf, size_t size, const char *format, va_list ap) -{ - int count = -1; - - if (size != 0) - count = _vsnprintf_s(outBuf, size, _TRUNCATE, format, ap); - if (count == -1) - count = _vscprintf(format, ap); - - return count; -} - -CMARK_INLINE int c99_snprintf(char *outBuf, size_t size, const char *format, ...) -{ - int count; - va_list ap; - - va_start(ap, format); - count = c99_vsnprintf(outBuf, size, format, ap); - va_end(ap); - - return count; -} - -#endif - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/houdini_href_e.c b/src/houdini_href_e.c index 169389197..bff3c612f 100644 --- a/src/houdini_href_e.c +++ b/src/houdini_href_e.c @@ -4,6 +4,16 @@ #include "houdini.h" +#if !defined(__has_builtin) +# define __has_builtin(b) 0 +#endif + +#if !__has_builtin(__builtin_expect) +# define __builtin_expect(e, v) (e) +#endif + +#define likely(e) __builtin_expect((e), 1) + /* * The following characters will not be escaped: * diff --git a/src/houdini_html_e.c b/src/houdini_html_e.c index da0b15c53..bda1efcd2 100644 --- a/src/houdini_html_e.c +++ b/src/houdini_html_e.c @@ -4,6 +4,16 @@ #include "houdini.h" +#if !defined(__has_builtin) +# define __has_builtin(b) 0 +#endif + +#if !__has_builtin(__builtin_expect) +# define __builtin_expect(e, v) (e) +#endif + +#define unlikely(e) __builtin_expect((e), 0) + /** * According to the OWASP rules: * diff --git a/src/houdini_html_u.c b/src/houdini_html_u.c index 30d08aa4a..0657493ce 100644 --- a/src/houdini_html_u.c +++ b/src/houdini_html_u.c @@ -7,6 +7,17 @@ #include "utf8.h" #include "entities.inc" +#if !defined(__has_builtin) +# define __has_builtin(b) 0 +#endif + +#if !__has_builtin(__builtin_expect) +# define __builtin_expect(e, v) (e) +#endif + +#define likely(e) __builtin_expect((e), 1) +#define unlikely(e) __builtin_expect((e), 0) + /* Binary tree lookup code for entities added by JGM */ static const unsigned char *S_lookup(int i, int low, int hi, diff --git a/src/html.c b/src/html.c index f1f2ff774..4d5624ae7 100644 --- a/src/html.c +++ b/src/html.c @@ -1,9 +1,10 @@ -#include +#include +#include #include +#include #include -#include + #include "cmark_ctype.h" -#include "cmark-gfm_config.h" #include "cmark-gfm.h" #include "houdini.h" #include "scanners.h" diff --git a/src/include/buffer.h b/src/include/buffer.h index 96a8ba2fa..56a28feb5 100644 --- a/src/include/buffer.h +++ b/src/include/buffer.h @@ -6,7 +6,6 @@ #include #include #include -#include "cmark-gfm_config.h" #include "cmark-gfm.h" #ifdef __cplusplus @@ -59,7 +58,7 @@ CMARK_GFM_EXPORT void cmark_strbuf_copy_cstr(char *data, bufsize_t datasize, const cmark_strbuf *buf); -static CMARK_INLINE const char *cmark_strbuf_cstr(const cmark_strbuf *buf) { +static inline const char *cmark_strbuf_cstr(const cmark_strbuf *buf) { return (char *)buf->ptr; } diff --git a/src/include/chunk.h b/src/include/chunk.h index c411c04a4..bc93a8753 100644 --- a/src/include/chunk.h +++ b/src/include/chunk.h @@ -17,7 +17,7 @@ typedef struct cmark_chunk { bufsize_t alloc; // also implies a NULL-terminated string } cmark_chunk; -static CMARK_INLINE void cmark_chunk_free(cmark_mem *mem, cmark_chunk *c) { +static inline void cmark_chunk_free(cmark_mem *mem, cmark_chunk *c) { if (c->alloc) mem->free(c->data); @@ -26,7 +26,7 @@ static CMARK_INLINE void cmark_chunk_free(cmark_mem *mem, cmark_chunk *c) { c->len = 0; } -static CMARK_INLINE void cmark_chunk_ltrim(cmark_chunk *c) { +static inline void cmark_chunk_ltrim(cmark_chunk *c) { assert(!c->alloc); while (c->len && cmark_isspace(c->data[0])) { @@ -35,7 +35,7 @@ static CMARK_INLINE void cmark_chunk_ltrim(cmark_chunk *c) { } } -static CMARK_INLINE void cmark_chunk_rtrim(cmark_chunk *c) { +static inline void cmark_chunk_rtrim(cmark_chunk *c) { assert(!c->alloc); while (c->len > 0) { @@ -46,20 +46,19 @@ static CMARK_INLINE void cmark_chunk_rtrim(cmark_chunk *c) { } } -static CMARK_INLINE void cmark_chunk_trim(cmark_chunk *c) { +static inline void cmark_chunk_trim(cmark_chunk *c) { cmark_chunk_ltrim(c); cmark_chunk_rtrim(c); } -static CMARK_INLINE bufsize_t cmark_chunk_strchr(cmark_chunk *ch, int c, - bufsize_t offset) { +static inline bufsize_t cmark_chunk_strchr(cmark_chunk *ch, int c, + bufsize_t offset) { const unsigned char *p = (unsigned char *)memchr(ch->data + offset, c, ch->len - offset); return p ? (bufsize_t)(p - ch->data) : ch->len; } -static CMARK_INLINE const char *cmark_chunk_to_cstr(cmark_mem *mem, - cmark_chunk *c) { +static inline const char *cmark_chunk_to_cstr(cmark_mem *mem, cmark_chunk *c) { unsigned char *str; if (c->alloc) { @@ -76,8 +75,8 @@ static CMARK_INLINE const char *cmark_chunk_to_cstr(cmark_mem *mem, return (char *)str; } -static CMARK_INLINE void cmark_chunk_set_cstr(cmark_mem *mem, cmark_chunk *c, - const char *str) { +static inline void cmark_chunk_set_cstr(cmark_mem *mem, cmark_chunk *c, + const char *str) { unsigned char *old = c->alloc ? c->data : NULL; if (str == NULL) { c->len = 0; @@ -94,19 +93,19 @@ static CMARK_INLINE void cmark_chunk_set_cstr(cmark_mem *mem, cmark_chunk *c, } } -static CMARK_INLINE cmark_chunk cmark_chunk_literal(const char *data) { +static inline cmark_chunk cmark_chunk_literal(const char *data) { bufsize_t len = data ? (bufsize_t)strlen(data) : 0; cmark_chunk c = {(unsigned char *)data, len, 0}; return c; } -static CMARK_INLINE cmark_chunk cmark_chunk_dup(const cmark_chunk *ch, - bufsize_t pos, bufsize_t len) { +static inline cmark_chunk cmark_chunk_dup(const cmark_chunk *ch, bufsize_t pos, + bufsize_t len) { cmark_chunk c = {ch->data + pos, len, 0}; return c; } -static CMARK_INLINE cmark_chunk cmark_chunk_buf_detach(cmark_strbuf *buf) { +static inline cmark_chunk cmark_chunk_buf_detach(cmark_strbuf *buf) { cmark_chunk c; c.len = buf->size; @@ -118,14 +117,14 @@ static CMARK_INLINE cmark_chunk cmark_chunk_buf_detach(cmark_strbuf *buf) { /* trim_new variants are to be used when the source chunk may or may not be * allocated; forces a newly allocated chunk. */ -static CMARK_INLINE cmark_chunk cmark_chunk_ltrim_new(cmark_mem *mem, cmark_chunk *c) { +static inline cmark_chunk cmark_chunk_ltrim_new(cmark_mem *mem, cmark_chunk *c) { cmark_chunk r = cmark_chunk_dup(c, 0, c->len); cmark_chunk_ltrim(&r); cmark_chunk_to_cstr(mem, &r); return r; } -static CMARK_INLINE cmark_chunk cmark_chunk_rtrim_new(cmark_mem *mem, cmark_chunk *c) { +static inline cmark_chunk cmark_chunk_rtrim_new(cmark_mem *mem, cmark_chunk *c) { cmark_chunk r = cmark_chunk_dup(c, 0, c->len); cmark_chunk_rtrim(&r); cmark_chunk_to_cstr(mem, &r); diff --git a/src/include/cmark-gfm-extension_api.h b/src/include/cmark-gfm-extension_api.h index 49e9fa20f..7c6a2ab84 100644 --- a/src/include/cmark-gfm-extension_api.h +++ b/src/include/cmark-gfm-extension_api.h @@ -7,6 +7,8 @@ extern "C" { #include "cmark-gfm.h" +#include + struct cmark_renderer; struct cmark_html_renderer; struct cmark_chunk; diff --git a/src/include/cmark-gfm_config.h b/src/include/cmark-gfm_config.h deleted file mode 100644 index 7d331915b..000000000 --- a/src/include/cmark-gfm_config.h +++ /dev/null @@ -1,86 +0,0 @@ -#ifndef CMARK_CONFIG_H -#define CMARK_CONFIG_H - -#ifdef CMARK_USE_CMAKE_HEADERS -// if the CMake config header exists, use that instead of this Swift package prebuilt one -// we need to undefine the header guard, since config.h uses the same one -#undef CMARK_CONFIG_H -#include "config.h" -#else - -#ifdef __cplusplus -extern "C" { -#endif - -#if __STDC_VERSION__ >= 199901l - #include -#elif !defined(__cplusplus) - typedef char bool; -#endif - -#if defined(__has_include) -# if __has_include() -# define HAVE_UNISTD_H -# endif -#elif defined(unix) || defined(__unix__) || defined(__unix) || defined(__APPLE__) - // Apple Clang does not define any of the unix symbols, even though it provides unistd.h -# define HAVE_UNISTD_H -#endif - -#define HAVE___BUILTIN_EXPECT - -#define CMARK_THREADING - -#ifndef CMARK_INLINE - #if defined(_MSC_VER) && !defined(__cplusplus) - #define CMARK_INLINE __inline - #else - #define CMARK_INLINE inline - #endif -#endif - -/* snprintf and vsnprintf fallbacks for MSVC before 2015, - due to Valentin Milea http://stackoverflow.com/questions/2915672/ -*/ - -#if defined(_MSC_VER) && _MSC_VER < 1900 - -#include -#include - -#define snprintf c99_snprintf -#define vsnprintf c99_vsnprintf - -CMARK_INLINE int c99_vsnprintf(char *outBuf, size_t size, const char *format, va_list ap) -{ - int count = -1; - - if (size != 0) - count = _vsnprintf_s(outBuf, size, _TRUNCATE, format, ap); - if (count == -1) - count = _vscprintf(format, ap); - - return count; -} - -CMARK_INLINE int c99_snprintf(char *outBuf, size_t size, const char *format, ...) -{ - int count; - va_list ap; - - va_start(ap, format); - count = c99_vsnprintf(outBuf, size, format, ap); - va_end(ap); - - return count; -} - -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* not CMARK_USE_CMAKE_HEADERS */ - -#endif /* not CMARK_CONFIG_H */ diff --git a/src/include/cmark-gfm_version.h b/src/include/cmark-gfm_version.h index 7e7bd823d..cf4dfee03 100644 --- a/src/include/cmark-gfm_version.h +++ b/src/include/cmark-gfm_version.h @@ -1,7 +1,7 @@ #ifndef CMARK_GFM_VERSION_H #define CMARK_GFM_VERSION_H -#define CMARK_GFM_VERSION ((0 << 24) | (29 << 16) | (0 << 8) | 0) -#define CMARK_GFM_VERSION_STRING "0.29.0.gfm.0" +#define CMARK_GFM_VERSION ((0 << 24) | (29 << 16) | (0 << 8) | 13) +#define CMARK_GFM_VERSION_STRING "0.29.0.gfm.13" #endif diff --git a/src/include/export.h b/src/include/export.h index c219c6f54..61ea28cdb 100644 --- a/src/include/export.h +++ b/src/include/export.h @@ -1,13 +1,6 @@ #ifndef CMARK_GFM_EXPORT_H #define CMARK_GFM_EXPORT_H -#ifdef CMARK_USE_CMAKE_HEADERS -// if the CMake config header exists, use that instead of this Swift package prebuilt one -// we need to undefine the header guard, since export.h uses the same one -#undef CMARK_GFM_EXPORT_H -#include "cmark-gfm_export.h" -#else - #ifdef CMARK_GFM_STATIC_DEFINE # define CMARK_GFM_EXPORT # define CMARK_GFM_NO_EXPORT @@ -45,6 +38,4 @@ # define CMARK_GFM_DEPRECATED_NO_EXPORT CMARK_GFM_NO_EXPORT CMARK_GFM_DEPRECATED #endif -#endif /* not CMARK_USE_CMAKE_HEADERS */ - #endif /* not CMARK_GFM_EXPORT_H */ diff --git a/src/include/houdini.h b/src/include/houdini.h index ff3c0887a..632755c7a 100644 --- a/src/include/houdini.h +++ b/src/include/houdini.h @@ -6,16 +6,8 @@ extern "C" { #endif #include -#include "cmark-gfm_config.h" -#include "buffer.h" -#ifdef HAVE___BUILTIN_EXPECT -#define likely(x) __builtin_expect((x), 1) -#define unlikely(x) __builtin_expect((x), 0) -#else -#define likely(x) (x) -#define unlikely(x) (x) -#endif +#include "buffer.h" #ifdef HOUDINI_USE_LOCALE #define _isxdigit(c) isxdigit(c) diff --git a/src/include/html.h b/src/include/html.h index aeba7bcda..fea9c67bf 100644 --- a/src/include/html.h +++ b/src/include/html.h @@ -4,7 +4,7 @@ #include "buffer.h" #include "node.h" -CMARK_INLINE +inline static void cmark_html_render_cr(cmark_strbuf *html) { if (html->size && html->ptr[html->size - 1] != '\n') cmark_strbuf_putc(html, '\n'); @@ -12,7 +12,7 @@ static void cmark_html_render_cr(cmark_strbuf *html) { #define BUFFER_SIZE 100 -CMARK_INLINE +inline static void cmark_html_render_sourcepos(cmark_node *node, cmark_strbuf *html, int options) { char buffer[BUFFER_SIZE]; if (CMARK_OPT_SOURCEPOS & options) { diff --git a/src/include/inlines.h b/src/include/inlines.h index d323af994..235282a13 100644 --- a/src/include/inlines.h +++ b/src/include/inlines.h @@ -5,8 +5,9 @@ extern "C" { #endif +#include #include -#include "cmark-gfm_config.h" + #include "references.h" cmark_chunk cmark_clean_url(cmark_mem *mem, cmark_chunk *url); diff --git a/src/include/module.modulemap b/src/include/module.modulemap index 1fc033abb..16c65818f 100644 --- a/src/include/module.modulemap +++ b/src/include/module.modulemap @@ -1,6 +1,5 @@ module cmark_gfm { - umbrella header "cmark-gfm.h" - header "cmark-gfm_config.h" + header "cmark-gfm.h" header "cmark-gfm-extension_api.h" header "buffer.h" header "chunk.h" @@ -11,7 +10,6 @@ module cmark_gfm { header "inlines.h" header "iterator.h" header "map.h" - header "mutex.h" header "node.h" header "parser.h" header "plugin.h" diff --git a/src/include/mutex.h b/src/include/mutex.h index d2ad4787b..59427f345 100644 --- a/src/include/mutex.h +++ b/src/include/mutex.h @@ -1,11 +1,11 @@ #ifndef CMARK_MUTEX_H #define CMARK_MUTEX_H -#include "cmark-gfm_config.h" +#include #ifdef CMARK_THREADING -#ifdef HAVE_UNISTD_H +#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) #include #endif @@ -54,7 +54,7 @@ pthread_mutex_lock(&NAME##_lock); #else // no threading support -static CMARK_INLINE bool check_latch(int *latch) { +static inline bool check_latch(int *latch) { if (!*latch) { *latch = 1; return true; diff --git a/src/include/node.h b/src/include/node.h index 76c5b7992..6491b2d46 100644 --- a/src/include/node.h +++ b/src/include/node.h @@ -5,8 +5,9 @@ extern "C" { #endif -#include +#include #include +#include #include "cmark-gfm.h" #include "cmark-gfm-extension_api.h" @@ -135,24 +136,24 @@ void cmark_register_node_flag(cmark_node_internal_flags *flags); CMARK_GFM_EXPORT void cmark_init_standard_node_flags(void); -static CMARK_INLINE cmark_mem *cmark_node_mem(cmark_node *node) { +static inline cmark_mem *cmark_node_mem(cmark_node *node) { return node->content.mem; } CMARK_GFM_EXPORT int cmark_node_check(cmark_node *node, FILE *out); -static CMARK_INLINE bool CMARK_NODE_TYPE_BLOCK_P(cmark_node_type node_type) { +static inline bool CMARK_NODE_TYPE_BLOCK_P(cmark_node_type node_type) { return (node_type & CMARK_NODE_TYPE_MASK) == CMARK_NODE_TYPE_BLOCK; } -static CMARK_INLINE bool CMARK_NODE_BLOCK_P(cmark_node *node) { +static inline bool CMARK_NODE_BLOCK_P(cmark_node *node) { return node != NULL && CMARK_NODE_TYPE_BLOCK_P((cmark_node_type) node->type); } -static CMARK_INLINE bool CMARK_NODE_TYPE_INLINE_P(cmark_node_type node_type) { +static inline bool CMARK_NODE_TYPE_INLINE_P(cmark_node_type node_type) { return (node_type & CMARK_NODE_TYPE_MASK) == CMARK_NODE_TYPE_INLINE; } -static CMARK_INLINE bool CMARK_NODE_INLINE_P(cmark_node *node) { +static inline bool CMARK_NODE_INLINE_P(cmark_node *node) { return node != NULL && CMARK_NODE_TYPE_INLINE_P((cmark_node_type) node->type); } diff --git a/src/include/parser.h b/src/include/parser.h index 95aab9ec9..e524bf73e 100644 --- a/src/include/parser.h +++ b/src/include/parser.h @@ -1,8 +1,10 @@ #ifndef CMARK_PARSER_H #define CMARK_PARSER_H +#include #include #include + #include "references.h" #include "node.h" #include "buffer.h" diff --git a/src/include/references.h b/src/include/references.h index 81330ae7a..03d985f82 100644 --- a/src/include/references.h +++ b/src/include/references.h @@ -1,6 +1,8 @@ #ifndef CMARK_REFERENCES_H #define CMARK_REFERENCES_H +#include + #include "map.h" #ifdef __cplusplus diff --git a/src/include/render.h b/src/include/render.h index 4a68d1e07..79af0ccb5 100644 --- a/src/include/render.h +++ b/src/include/render.h @@ -5,7 +5,9 @@ extern "C" { #endif +#include #include + #include "buffer.h" #include "chunk.h" diff --git a/src/include/syntax_extension.h b/src/include/syntax_extension.h index 081a54c9a..de8d3d62a 100644 --- a/src/include/syntax_extension.h +++ b/src/include/syntax_extension.h @@ -3,7 +3,8 @@ #include "cmark-gfm.h" #include "cmark-gfm-extension_api.h" -#include "cmark-gfm_config.h" + +#include struct cmark_syntax_extension { cmark_match_block_func last_block_matches; diff --git a/src/inlines.c b/src/inlines.c index a8dea13ce..6e51feb0c 100644 --- a/src/inlines.c +++ b/src/inlines.c @@ -1,9 +1,9 @@ +#include +#include #include #include -#include #include "cmark_ctype.h" -#include "cmark-gfm_config.h" #include "node.h" #include "parser.h" #include "references.h" @@ -79,7 +79,7 @@ void cmark_set_default_skip_chars(int8_t **skip_chars, bool use_memcpy) { *skip_chars = default_skip_chars; } -static CMARK_INLINE bool S_is_line_end_char(char c) { +static inline bool S_is_line_end_char(char c) { return (c == '\n' || c == '\r'); } @@ -93,9 +93,9 @@ static void subject_from_buf(cmark_mem *mem, int line_number, int block_offset, static bufsize_t subject_find_special_char(cmark_parser *parser, subject *subj, int options); // Create an inline with a literal string value. -static CMARK_INLINE cmark_node *make_literal(subject *subj, cmark_node_type t, - int start_column, int end_column, - cmark_chunk s) { +static inline cmark_node *make_literal(subject *subj, cmark_node_type t, + int start_column, int end_column, + cmark_chunk s) { cmark_node *e = (cmark_node *)subj->mem->calloc(1, sizeof(*e)); cmark_strbuf_init(subj->mem, &e->content, 0); e->type = (uint16_t)t; @@ -108,7 +108,7 @@ static CMARK_INLINE cmark_node *make_literal(subject *subj, cmark_node_type t, } // Create an inline with no value. -static CMARK_INLINE cmark_node *make_simple(cmark_mem *mem, cmark_node_type t) { +static inline cmark_node *make_simple(cmark_mem *mem, cmark_node_type t) { cmark_node *e = (cmark_node *)mem->calloc(1, sizeof(*e)); cmark_strbuf_init(mem, &e->content, 0); e->type = (uint16_t)t; @@ -180,9 +180,9 @@ static cmark_chunk cmark_clean_autolink(cmark_mem *mem, cmark_chunk *url, return cmark_chunk_buf_detach(&buf); } -static CMARK_INLINE cmark_node *make_autolink(subject *subj, - int start_column, int end_column, - cmark_chunk url, int is_email) { +static inline cmark_node *make_autolink(subject *subj, int start_column, + int end_column, cmark_chunk url, + int is_email) { cmark_node *link = make_simple(subj->mem, CMARK_NODE_LINK); link->as.link.url = cmark_clean_autolink(subj->mem, &url, is_email); link->as.link.title = cmark_chunk_literal(""); @@ -213,32 +213,32 @@ static void subject_from_buf(cmark_mem *mem, int line_number, int block_offset, e->no_link_openers = true; } -static CMARK_INLINE int isbacktick(int c) { return (c == '`'); } +static inline int isbacktick(int c) { return (c == '`'); } -static CMARK_INLINE unsigned char peek_char_n(subject *subj, bufsize_t n) { +static inline unsigned char peek_char_n(subject *subj, bufsize_t n) { // NULL bytes should have been stripped out by now. If they're // present, it's a programming error: assert(!(subj->pos + n < subj->input.len && subj->input.data[subj->pos + n] == 0)); return (subj->pos + n < subj->input.len) ? subj->input.data[subj->pos + n] : 0; } -static CMARK_INLINE unsigned char peek_char(subject *subj) { +static inline unsigned char peek_char(subject *subj) { return peek_char_n(subj, 0); } -static CMARK_INLINE unsigned char peek_at(subject *subj, bufsize_t pos) { +static inline unsigned char peek_at(subject *subj, bufsize_t pos) { return subj->input.data[pos]; } // Return true if there are more characters in the subject. -static CMARK_INLINE int is_eof(subject *subj) { +static inline int is_eof(subject *subj) { return (subj->pos >= subj->input.len); } // Advance the subject. Doesn't check for eof. #define advance(subj) (subj)->pos += 1 -static CMARK_INLINE bool skip_spaces(subject *subj) { +static inline bool skip_spaces(subject *subj) { bool skipped = false; while (peek_char(subj) == ' ' || peek_char(subj) == '\t') { advance(subj); @@ -247,7 +247,7 @@ static CMARK_INLINE bool skip_spaces(subject *subj) { return skipped; } -static CMARK_INLINE bool skip_line_end(subject *subj) { +static inline bool skip_line_end(subject *subj) { bool seen_line_end_char = false; if (peek_char(subj) == '\r') { advance(subj); @@ -261,7 +261,7 @@ static CMARK_INLINE bool skip_line_end(subject *subj) { } // Take characters while a predicate holds, and return a string. -static CMARK_INLINE cmark_chunk take_while(subject *subj, int (*f)(int)) { +static inline cmark_chunk take_while(subject *subj, int (*f)(int)) { unsigned char c; bufsize_t startpos = subj->pos; bufsize_t len = 0; diff --git a/src/iterator.c b/src/iterator.c index f107454df..e7cc64582 100644 --- a/src/iterator.c +++ b/src/iterator.c @@ -1,7 +1,7 @@ #include +#include #include -#include "cmark-gfm_config.h" #include "node.h" #include "cmark-gfm.h" #include "iterator.h" diff --git a/src/latex.c b/src/latex.c index 87e7dd32b..0fc607975 100644 --- a/src/latex.c +++ b/src/latex.c @@ -1,9 +1,9 @@ -#include +#include +#include #include +#include #include -#include -#include "cmark-gfm_config.h" #include "cmark-gfm.h" #include "node.h" #include "buffer.h" @@ -18,9 +18,8 @@ #define BLANKLINE() renderer->blankline(renderer) #define LIST_NUMBER_STRING_SIZE 20 -static CMARK_INLINE void outc(cmark_renderer *renderer, cmark_node *node, - cmark_escaping escape, - int32_t c, unsigned char nextc) { +static inline void outc(cmark_renderer *renderer, cmark_node *node, + cmark_escaping escape, int32_t c, unsigned char nextc) { if (escape == LITERAL) { cmark_render_code_point(renderer, c); return; diff --git a/src/man.c b/src/man.c index b92cbd803..1baceb4c5 100644 --- a/src/man.c +++ b/src/man.c @@ -1,9 +1,9 @@ -#include +#include +#include #include +#include #include -#include -#include "cmark-gfm_config.h" #include "cmark-gfm.h" #include "node.h" #include "buffer.h" diff --git a/src/node.c b/src/node.c index 49c371ff2..8088e681a 100644 --- a/src/node.c +++ b/src/node.c @@ -1,7 +1,7 @@ +#include #include #include -#include "cmark-gfm_config.h" #include "mutex.h" #include "node.h" #include "syntax_extension.h" diff --git a/src/plaintext.c b/src/plaintext.c index c9aa0fd6e..f464ac333 100644 --- a/src/plaintext.c +++ b/src/plaintext.c @@ -1,3 +1,5 @@ +#include + #include "node.h" #include "syntax_extension.h" #include "render.h" @@ -10,9 +12,8 @@ // Functions to convert cmark_nodes to plain text strings. -static CMARK_INLINE void outc(cmark_renderer *renderer, cmark_node *node, - cmark_escaping escape, - int32_t c, unsigned char nextc) { +static inline void outc(cmark_renderer *renderer, cmark_node *node, + cmark_escaping escape, int32_t c, unsigned char nextc) { cmark_render_code_point(renderer, c); } diff --git a/src/references.c b/src/references.c index 44eca1058..6dec0637a 100644 --- a/src/references.c +++ b/src/references.c @@ -1,3 +1,5 @@ +#include + #include "cmark-gfm.h" #include "parser.h" #include "references.h" diff --git a/src/registry.c b/src/registry.c index 91f79530a..090a01c31 100644 --- a/src/registry.c +++ b/src/registry.c @@ -2,7 +2,6 @@ #include #include -#include "cmark-gfm_config.h" #include "cmark-gfm.h" #include "mutex.h" #include "syntax_extension.h" diff --git a/src/render.c b/src/render.c index 1a0d2ae8d..cdcb17e28 100644 --- a/src/render.c +++ b/src/render.c @@ -1,4 +1,6 @@ +#include #include + #include "buffer.h" #include "chunk.h" #include "cmark-gfm.h" @@ -7,13 +9,13 @@ #include "node.h" #include "syntax_extension.h" -static CMARK_INLINE void S_cr(cmark_renderer *renderer) { +static inline void S_cr(cmark_renderer *renderer) { if (renderer->need_cr < 1) { renderer->need_cr = 1; } } -static CMARK_INLINE void S_blankline(cmark_renderer *renderer) { +static inline void S_blankline(cmark_renderer *renderer) { if (renderer->need_cr < 2) { renderer->need_cr = 2; } diff --git a/src/syntax_extension.c b/src/syntax_extension.c index 393752c0e..361c99333 100644 --- a/src/syntax_extension.c +++ b/src/syntax_extension.c @@ -1,5 +1,6 @@ -#include #include +#include +#include #include "cmark-gfm.h" #include "syntax_extension.h" diff --git a/src/xml.c b/src/xml.c index 184bff486..ad46af723 100644 --- a/src/xml.c +++ b/src/xml.c @@ -1,9 +1,9 @@ -#include +#include +#include #include +#include #include -#include -#include "cmark-gfm_config.h" #include "cmark-gfm.h" #include "node.h" #include "buffer.h" @@ -25,7 +25,7 @@ struct render_state { int indent; }; -static CMARK_INLINE void indent(struct render_state *state) { +static inline void indent(struct render_state *state) { int i; for (i = 0; i < state->indent && i < MAX_INDENT; i++) { cmark_strbuf_putc(state->xml, ' '); diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 2b5c99bc5..2fbbd4d71 100755 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -3,112 +3,104 @@ # By default, we run the spec tests only if python3 is available. # To require the spec tests, compile with -DSPEC_TESTS=1 -if (SPEC_TESTS) - find_package(PythonInterp 3 REQUIRED) -else(SPEC_TESTS) - find_package(PythonInterp 3) -endif(SPEC_TESTS) - -if (CMARK_SHARED OR CMARK_STATIC) - add_test(NAME api_test COMMAND api_test) +if(SPEC_TESTS) + set(PYTHON_REQUIRED REQUIRED) +else() + set(PYTHON_REQUIRED) endif() -if (WIN32) - file(TO_NATIVE_PATH ${CMAKE_BINARY_DIR}/src WIN_SRC_DLL_DIR) - file(TO_NATIVE_PATH ${CMAKE_BINARY_DIR}/extensions WIN_EXTENSIONS_DLL_DIR) - set(NEWPATH "${WIN_SRC_DLL_DIR};${WIN_EXTENSIONS_DLL_DIR};$ENV{PATH}") - string(REPLACE ";" "\\;" NEWPATH "${NEWPATH}") - set_tests_properties(api_test PROPERTIES ENVIRONMENT "PATH=${NEWPATH}") - set(ROUNDTRIP "${CMAKE_CURRENT_SOURCE_DIR}/roundtrip.bat") -else(WIN32) - set(ROUNDTRIP "${CMAKE_CURRENT_SOURCE_DIR}/roundtrip.sh") -endif(WIN32) - -IF (PYTHONINTERP_FOUND) - - add_test(html_normalization - ${PYTHON_EXECUTABLE} "-m" "doctest" - "${CMAKE_CURRENT_SOURCE_DIR}/normalize.py" - ) - - if (CMARK_SHARED) - add_test(spectest_library - ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/spec_tests.py" "--no-normalize" "--spec" - "${CMAKE_CURRENT_SOURCE_DIR}/spec.txt" "--library-dir" "${CMAKE_CURRENT_BINARY_DIR}/../src" - ) - - add_test(pathological_tests_library - ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/pathological_tests.py" - "--library-dir" "${CMAKE_CURRENT_BINARY_DIR}/../src" - ) - - add_test(roundtriptest_library - ${PYTHON_EXECUTABLE} - "${CMAKE_CURRENT_SOURCE_DIR}/roundtrip_tests.py" - "--spec" "${CMAKE_CURRENT_SOURCE_DIR}/spec.txt" - "--library-dir" "${CMAKE_CURRENT_BINARY_DIR}/../src" - ) - - add_test(entity_library - ${PYTHON_EXECUTABLE} - "${CMAKE_CURRENT_SOURCE_DIR}/entity_tests.py" - "--library-dir" "${CMAKE_CURRENT_BINARY_DIR}/../src" - ) - endif() +if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.12) + find_package(Python3 ${PYTHON_REQUIRED} COMPONENTS Interpreter) +else() + find_package(PythonInterp 3 ${PYTHON_REQUIRED}) + set(Python3_Interpreter_FOUND ${PYTHONINTERP_FOUND}) + add_executable(Python3::Interpreter IMPORTED) + set_target_properties(Python3::Interpreter PROPERTIES + IMPORTED_LOCATION ${PYTHON_EXECUTABLE}) +endif() + +if(Python3_Interpreter_FOUND) + + add_test(NAME html_normalization + COMMAND "$" "-m" "doctest" "${CMAKE_CURRENT_SOURCE_DIR}/normalize.py") + + if(BUILD_SHARED_LIBS) + add_test(NAME spectest_library + COMMAND "$" "${CMAKE_CURRENT_SOURCE_DIR}/spec_tests.py" + --no-normalize + --spec "${CMAKE_CURRENT_SOURCE_DIR}/spec.txt" + --library-dir "$") - add_test(spectest_executable - ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/spec_tests.py" "--no-normalize" "--spec" "${CMAKE_CURRENT_SOURCE_DIR}/spec.txt" "--program" "${CMAKE_CURRENT_BINARY_DIR}/../src/cmark-gfm" - ) - - add_test(smartpuncttest_executable - ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/spec_tests.py" "--no-normalize" "--spec" "${CMAKE_CURRENT_SOURCE_DIR}/smart_punct.txt" "--program" "${CMAKE_CURRENT_BINARY_DIR}/../src/cmark-gfm --smart" - ) - - add_test(extensions_executable - ${PYTHON_EXECUTABLE} - "${CMAKE_CURRENT_SOURCE_DIR}/spec_tests.py" - "--no-normalize" - "--spec" "${CMAKE_CURRENT_SOURCE_DIR}/extensions.txt" - "--program" "${CMAKE_CURRENT_BINARY_DIR}/../src/cmark-gfm" - "--extensions" "table strikethrough autolink tagfilter footnotes tasklist" - ) - - add_test(roundtrip_extensions_executable - ${PYTHON_EXECUTABLE} - "${CMAKE_CURRENT_SOURCE_DIR}/roundtrip_tests.py" - "--spec" "${CMAKE_CURRENT_SOURCE_DIR}/extensions.txt" - "--program" "${CMAKE_CURRENT_BINARY_DIR}/../src/cmark-gfm" - "--extensions" "table strikethrough autolink tagfilter footnotes tasklist" - ) - - add_test(option_table_prefer_style_attributes - ${PYTHON_EXECUTABLE} - "${CMAKE_CURRENT_SOURCE_DIR}/roundtrip_tests.py" - "--spec" "${CMAKE_CURRENT_SOURCE_DIR}/extensions-table-prefer-style-attributes.txt" - "--program" "${CMAKE_CURRENT_BINARY_DIR}/../src/cmark-gfm --table-prefer-style-attributes" - "--extensions" "table strikethrough autolink tagfilter footnotes tasklist" - ) - - add_test(option_full_info_string - ${PYTHON_EXECUTABLE} - "${CMAKE_CURRENT_SOURCE_DIR}/roundtrip_tests.py" - "--spec" "${CMAKE_CURRENT_SOURCE_DIR}/extensions-full-info-string.txt" - "--program" "${CMAKE_CURRENT_BINARY_DIR}/../src/cmark-gfm --full-info-string" - ) - - add_test(regressiontest_executable - ${PYTHON_EXECUTABLE} - "${CMAKE_CURRENT_SOURCE_DIR}/spec_tests.py" "--no-normalize" "--spec" - "${CMAKE_CURRENT_SOURCE_DIR}/regression.txt" "--program" - "${CMAKE_CURRENT_BINARY_DIR}/../src/cmark-gfm" - ) - - -ELSE(PYTHONINTERP_FOUND) - - message("\n*** A python 3 interpreter is required to run the spec tests.\n") - add_test(skipping_spectests - echo "Skipping spec tests, because no python 3 interpreter is available.") - -ENDIF(PYTHONINTERP_FOUND) + add_test(NAME pathological_tests_library + COMMAND "$" "${CMAKE_CURRENT_SOURCE_DIR}/pathological_tests.py" + --library-dir "$") + add_test(NAME roundtriptest_library + COMMAND "$" "${CMAKE_CURRENT_SOURCE_DIR}/roundtrip_tests.py" + --spec "${CMAKE_CURRENT_SOURCE_DIR}/spec.txt" + --library-dir "$") + + add_test(NAME entity_library + COMMAND "$" "${CMAKE_CURRENT_SOURCE_DIR}/entity_tests.py" + --library-dir "$") + endif() + + add_test(NAME spectest_executable + COMMAND "$" "${CMAKE_CURRENT_SOURCE_DIR}/spec_tests.py" + --no-normalize + --spec "${CMAKE_CURRENT_SOURCE_DIR}/spec.txt" + --program "$") + + add_test(NAME smartpuncttest_executable + COMMAND "$" "${CMAKE_CURRENT_SOURCE_DIR}/spec_tests.py" + --no-normalize + --spec "${CMAKE_CURRENT_SOURCE_DIR}/smart_punct.txt" + --program "$ --smart") + + add_test(NAME extensions_executable + COMMAND "$" "${CMAKE_CURRENT_SOURCE_DIR}/spec_tests.py" + --no-normalize + --spec "${CMAKE_CURRENT_SOURCE_DIR}/extensions.txt" + --program "$" + --extensions "table strikethrough autolink tagfilter footnotes tasklist") + + add_test(NAME roundtrip_extensions_executable + COMMAND "$" "${CMAKE_CURRENT_SOURCE_DIR}/roundtrip_tests.py" + --spec "${CMAKE_CURRENT_SOURCE_DIR}/extensions.txt" + --program "$" + --extensions "table strikethrough autolink tagfilter footnotes tasklist") + + add_test(NAME option_table_prefer_style_attributes + COMMAND "$" "${CMAKE_CURRENT_SOURCE_DIR}/roundtrip_tests.py" + --spec "${CMAKE_CURRENT_SOURCE_DIR}/extensions-table-prefer-style-attributes.txt" + --program "$ --table-prefer-style-attributes" + --extensions "table strikethrough autolink tagfilter footnotes tasklist") + + add_test(NAME option_full_info_string + COMMAND "$" "${CMAKE_CURRENT_SOURCE_DIR}/roundtrip_tests.py" + --spec "${CMAKE_CURRENT_SOURCE_DIR}/extensions-full-info-string.txt" + --program "$ --full-info-string") + + add_test(NAME regressiontest_executable + COMMAND "$" "${CMAKE_CURRENT_SOURCE_DIR}/spec_tests.py" + --no-normalize + --spec "${CMAKE_CURRENT_SOURCE_DIR}/regression.txt" + --program "$") + +else(Python3_Interpreter_FOUND) + + message(WARNING "A python 3 interpreter is required to run the spec tests") + +endif(Python3_Interpreter_FOUND) + + +if(CMARK_LIB_FUZZER) + add_executable(cmark-fuzz cmark-fuzz.c) + target_link_libraries(cmark-fuzz PRIVATE + libcmark-gfm_static + "${CMAKE_LIB_FUZZER_PATH}") + # cmark is written in C but the libFuzzer runtime is written in C++ which + # needs to link against the C++ runtime. + set_target_properties(cmark-fuzz PROPERTIES + LINKER_LANGUAGE CXX) +endif()