diff --git a/.gitignore b/.gitignore index c325b311f..9e87b8a36 100644 --- a/.gitignore +++ b/.gitignore @@ -25,6 +25,7 @@ *~ *.bak +*.sw? *.diff *# *.zip diff --git a/CMakeLists.txt b/CMakeLists.txt index a6a663c81..18689984f 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,42 +1,91 @@ cmake_minimum_required(VERSION 3.0) -project(cmark-gfm) -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}) +if(POLICY CMP0063) + cmake_policy(SET CMP0063 NEW) +endif() +if(POLICY CMP0092) + cmake_policy(SET CMP0092 NEW) +endif() -include("FindAsan.cmake") -include("CheckFileOffsetBits.cmake") +project(cmark-gfm + LANGUAGES C CXX) +set(PROJECT_VERSION 0.29.0.gfm.13) 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() -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_FUZZ_QUADRATIC "Build quadratic fuzzing harness" OFF) +set(CMAKE_C_STANDARD 99) +set(CMAKE_C_STANDARD_REQUIRED YES) +set(CMAKE_C_EXTENSIONS NO) +set(CMAKE_C_VISIBILITY_PRESET hidden) +set(CMAKE_INCLUDE_CURRENT_DIR ON) +set(CMAKE_VISIBILITY_INLINES_HIDDEN TRUE) + +if(NOT MSVC OR CMAKE_HOST_SYSTEM_NAME STREQUAL Windows) + set(CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_NO_WARNINGS ON) + include(InstallRequiredSystemLibraries) +endif() + +list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake/modules) + +include(CheckFileOffsetBits) +include(CTest) +include(FindAsan) +include(GenerateExportHeader) +include(GNUInstallDirs) + +check_file_offset_bits() + +# Compiler flags +if(MSVC) + add_compile_options($<$:/W4>) + add_compile_options($<$:/wd4706>) + add_compile_definitions($<$:_CRT_SECURE_NO_WARNINGS>) + # BEGIN cmark-gfm + add_compile_options($<$:/wd4204>) + add_compile_options($<$:/wd4211>) + add_compile_options($<$:/wd4100>) + add_compile_options($<$:/WX>) + # END cmark-gfm +elseif(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES Clang) + add_compile_options($<$:-Wall>) + add_compile_options($<$:-Wextra>) + add_compile_options($<$:-pedantic>) + # BEGIN cmark-gfm + add_compile_options($<$:-Wno-unused-parameter>) + # END cmark-gfm +endif() + +# Check integrity of node structure when compiled as debug +add_compile_definitions($<$:CMARK_DEBUG_NODES>) + +add_compile_options($<$,$>:-pg>) + +if(CMAKE_BUILD_TYPE STREQUAL Ubsan) + add_compile_options($<$:-fsanitize=undefined>) +endif() +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}") + add_compile_options($<$,$>:-fsanitize=fuzzer-no-link,address>) endif() 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) diff --git a/Makefile b/Makefile index be7e46c0e..4ee562cb1 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/api_test/CMakeLists.txt b/api_test/CMakeLists.txt index 55f33e087..f1db2f114 100644 --- a/api_test/CMakeLists.txt +++ b/api_test/CMakeLists.txt @@ -1,30 +1,15 @@ add_executable(api_test cplusplus.cpp harness.c - harness.h - main.c -) -include_directories( - ${PROJECT_SOURCE_DIR}/src - ${PROJECT_BINARY_DIR}/src - ${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() + main.c) +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") +add_test(NAME api_test COMMAND api_test) +if(WIN32) + if(CMARK_SHARED) + set_tests_properties(api_test PROPERTIES + ENVIRONMENT "PATH=$;$;$ENV{PATH}") endif() - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /wd4706 /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") endif() 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 e545b6d6f..f69f6c63a 100644 --- a/extensions/CMakeLists.txt +++ b/extensions/CMakeLists.txt @@ -1,119 +1,30 @@ -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 - ${PROJECT_BINARY_DIR}/src -) - -include_directories(. ${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 "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-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" - DEFINE_SYMBOL "cmark-gfm" - 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) +set_target_properties(libcmark-gfm-extensions PROPERTIES + DEFINE_SYMBOL cmark-gfm + MACOSX_RPATH TRUE + OUTPUT_NAME cmark-gfm-extensions + PDB_NAME libcmark-gfm-extensions + SOVERSION ${PROJECT_VERSION} + VERSION ${PROJECT_VERSION}) +target_link_libraries(libcmark-gfm-extensions PRIVATE + libcmark-gfm) + + +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 - 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(stdbool.h HAVE_STDBOOL_H) -CHECK_C_SOURCE_COMPILES( - "int main() { __builtin_expect(0,0); return 0; }" - HAVE___BUILTIN_EXPECT) -CHECK_C_SOURCE_COMPILES(" - int f(void) __attribute__ (()); - int main() { return 0; } -" HAVE___ATTRIBUTE__) - -# 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 /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() + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) +install(FILES cmark-gfm-core-extensions.h + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) +install(EXPORT cmark-gfm-extensions + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake-gfm-extensions) 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 84dd2a037..58fed2797 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,230 +1,83 @@ -if(${CMAKE_VERSION} VERSION_GREATER "3.3") - cmake_policy(SET CMP0063 NEW) -endif() -include(GNUInstallDirs) +set(PROJECT_VERSION_MAJOR 0) +set(PROJECT_VERSION_MINOR 29) +set(PROJECT_VERSION_PATCH 0) +set(PROJECT_VERSION_GFM 13) -set(LIBRARY "libcmark-gfm") -set(STATICLIBRARY "libcmark-gfm_static") -set(HEADERS - cmark-gfm.h - cmark-gfm-extension_api.h - parser.h - buffer.h - node.h - iterator.h - chunk.h - references.h - footnotes.h - map.h - utf8.h - scanners.h - inlines.h - houdini.h - cmark_ctype.h - render.h - registry.h - syntax_extension.h - plugin.h - ) -set(LIBRARY_SOURCES - cmark.c - node.c - iterator.c +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cmark-gfm_version.h.in + ${CMAKE_CURRENT_BINARY_DIR}/cmark-gfm_version.h) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/libcmark-gfm.pc.in + ${CMAKE_CURRENT_BINARY_DIR}/libcmark-gfm.pc @ONLY) + +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 main.c) - -include_directories(. ${CMAKE_CURRENT_BINARY_DIR}) -include_directories( - ${PROJECT_BINARY_DIR}/extensions -) - -configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cmark-gfm_version.h.in + references.c + registry.c + render.c + scanners.c + scanners.re + syntax_extension.c + utf8.c + xml.c) +target_include_directories(libcmark-gfm PUBLIC + $ + $ + $) +target_sources(libcmark-gfm PRIVATE ${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) - +set_target_properties(libcmark-gfm PROPERTIES + DEFINE_SYMBOL cmark-gfm + MACOSX_RPATH TRUE + OUTPUT_NAME cmark-gfm # 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) + PDB_NAME libcmark-gfm + SOVERSION ${PROJECT_VERSION} + VERSION ${PROJECT_VERSION}) +generate_export_header(libcmark-gfm + BASE_NAME ${PROJECT_NAME}) + +add_executable(cmark-gfm + main.c) +target_link_libraries(cmark-gfm PRIVATE + libcmark-gfm + libcmark-gfm-extensions) +if(MSVC) + target_link_options(cmark-gfm PRIVATE + /INCREMENTAL:NO) endif() -set(libdir lib${LIB_SUFFIX}) -install(TARGETS ${PROGRAM} ${CMARK_INSTALL} +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 - cmark-gfm.h - cmark-gfm-extension_api.h - ${CMAKE_CURRENT_BINARY_DIR}/cmark-gfm_export.h - ${CMAKE_CURRENT_BINARY_DIR}/cmark-gfm_version.h - DESTINATION include - ) - - install(EXPORT cmark-gfm DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake) -endif() - -# Feature tests -include(CheckIncludeFile) -include(CheckCSourceCompiles) -include(CheckCSourceRuns) -include(CheckSymbolExists) -CHECK_INCLUDE_FILE(stdbool.h HAVE_STDBOOL_H) -CHECK_C_SOURCE_COMPILES( - "int main() { __builtin_expect(0,0); return 0; }" - HAVE___BUILTIN_EXPECT) -CHECK_C_SOURCE_COMPILES(" - int f(void) __attribute__ (()); - int main() { return 0; } -" HAVE___ATTRIBUTE__) - -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 /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() + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libcmark-gfm.pc + DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) +install(FILES + cmark-gfm.h + cmark-gfm-extension_api.h + ${CMAKE_CURRENT_BINARY_DIR}/cmark-gfm_export.h + ${CMAKE_CURRENT_BINARY_DIR}/cmark-gfm_version.h + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) +install(EXPORT cmark-gfm + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake) diff --git a/src/blocks.c b/src/blocks.c index 3b5da56bf..96c72db1e 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 "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'); } @@ -189,13 +189,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 c7934e57d..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 "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/buffer.h b/src/buffer.h index b85bb4406..4433981dc 100644 --- a/src/buffer.h +++ b/src/buffer.h @@ -6,7 +6,7 @@ #include #include #include -#include "config.h" + #include "cmark-gfm.h" #ifdef __cplusplus @@ -59,7 +59,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/chunk.h b/src/chunk.h index c411c04a4..bc93a8753 100644 --- a/src/chunk.h +++ b/src/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/commonmark.c b/src/commonmark.c index 987b47318..af60afa9b 100644 --- a/src/commonmark.c +++ b/src/commonmark.c @@ -1,10 +1,10 @@ -#include +#include +#include +#include #include +#include #include -#include -#include -#include "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 && @@ -463,7 +462,7 @@ static int S_render_node(cmark_renderer *renderer, cmark_node *node, if (entering) { LIT("[^"); - char *footnote_label = renderer->mem->calloc(node->parent_footnote_def->as.literal.len + 1, sizeof(char)); + char *footnote_label = (char *)renderer->mem->calloc(node->parent_footnote_def->as.literal.len + 1, sizeof(char)); memmove(footnote_label, node->parent_footnote_def->as.literal.data, node->parent_footnote_def->as.literal.len); OUT(footnote_label, false, LITERAL); @@ -478,7 +477,7 @@ static int S_render_node(cmark_renderer *renderer, cmark_node *node, renderer->footnote_ix += 1; LIT("[^"); - char *footnote_label = renderer->mem->calloc(node->as.literal.len + 1, sizeof(char)); + char *footnote_label = (char *)renderer->mem->calloc(node->as.literal.len + 1, sizeof(char)); memmove(footnote_label, node->as.literal.data, node->as.literal.len); OUT(footnote_label, false, LITERAL); diff --git a/src/config.h.in b/src/config.h.in deleted file mode 100644 index de1a4dd49..000000000 --- a/src/config.h.in +++ /dev/null @@ -1,76 +0,0 @@ -#ifndef CMARK_CONFIG_H -#define CMARK_CONFIG_H - -#ifdef __cplusplus -extern "C" { -#endif - -#cmakedefine HAVE_STDBOOL_H - -#ifdef HAVE_STDBOOL_H - #include -#elif !defined(__cplusplus) - typedef char bool; -#endif - -#cmakedefine HAVE___BUILTIN_EXPECT - -#cmakedefine HAVE___ATTRIBUTE__ - -#ifdef HAVE___ATTRIBUTE__ - #define CMARK_ATTRIBUTE(list) __attribute__ (list) -#else - #define CMARK_ATTRIBUTE(list) -#endif - -#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.h b/src/houdini.h index 7625b045b..632755c7a 100644 --- a/src/houdini.h +++ b/src/houdini.h @@ -6,16 +6,8 @@ extern "C" { #endif #include -#include "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/houdini_href_e.c b/src/houdini_href_e.c index 169389197..272f30622 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(builtin) 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..f53e4ed77 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(builtin) 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..126b3ca5c 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(builtin) 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 22513c939..5a9ac1339 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 "config.h" #include "cmark-gfm.h" #include "houdini.h" #include "scanners.h" diff --git a/src/html.h b/src/html.h index aeba7bcda..3c17f281c 100644 --- a/src/html.h +++ b/src/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/inlines.c b/src/inlines.c index 30f2c1700..5762b189f 100644 --- a/src/inlines.c +++ b/src/inlines.c @@ -1,9 +1,9 @@ +#include +#include #include #include -#include #include "cmark_ctype.h" -#include "config.h" #include "node.h" #include "parser.h" #include "references.h" @@ -68,7 +68,7 @@ typedef struct subject{ // Extensions may populate this. static int8_t SKIP_CHARS[256]; -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'); } @@ -82,9 +82,9 @@ static void subject_from_buf(cmark_mem *mem, int line_number, int block_offset, static bufsize_t subject_find_special_char(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; @@ -97,7 +97,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; @@ -169,9 +169,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(""); @@ -202,32 +202,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); @@ -236,7 +236,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); @@ -250,7 +250,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 13fdb7616..fde2018b8 100644 --- a/src/iterator.c +++ b/src/iterator.c @@ -1,7 +1,6 @@ #include #include -#include "config.h" #include "node.h" #include "cmark-gfm.h" #include "iterator.h" diff --git a/src/latex.c b/src/latex.c index 1a6367a4e..f3b9c941a 100644 --- a/src/latex.c +++ b/src/latex.c @@ -1,9 +1,9 @@ -#include +#include +#include #include +#include #include -#include -#include "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/main.c b/src/main.c index a62c4f2ca..cae7cebe6 100644 --- a/src/main.c +++ b/src/main.c @@ -2,7 +2,7 @@ #include #include #include -#include "config.h" + #include "cmark-gfm.h" #include "node.h" #include "cmark-gfm-extension_api.h" diff --git a/src/man.c b/src/man.c index 634fd9d0f..51ea34807 100644 --- a/src/man.c +++ b/src/man.c @@ -1,9 +1,9 @@ -#include +#include +#include #include +#include #include -#include -#include "config.h" #include "cmark-gfm.h" #include "node.h" #include "buffer.h" diff --git a/src/node.c b/src/node.c index e7a9606d5..fb3d4629f 100644 --- a/src/node.c +++ b/src/node.c @@ -1,7 +1,7 @@ +#include #include #include -#include "config.h" #include "node.h" #include "syntax_extension.h" diff --git a/src/node.h b/src/node.h index 73ca76053..8f7286891 100644 --- a/src/node.h +++ b/src/node.h @@ -5,8 +5,9 @@ extern "C" { #endif -#include +#include #include +#include #include "cmark-gfm.h" #include "cmark-gfm-extension_api.h" @@ -130,24 +131,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/plaintext.c b/src/plaintext.c index 0c7d257b3..32a81f433 100644 --- a/src/plaintext.c +++ b/src/plaintext.c @@ -10,9 +10,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/registry.c b/src/registry.c index f4f2040d6..e6b69b1c8 100644 --- a/src/registry.c +++ b/src/registry.c @@ -2,7 +2,6 @@ #include #include -#include "config.h" #include "cmark-gfm.h" #include "syntax_extension.h" #include "registry.h" diff --git a/src/render.c b/src/render.c index 1a0d2ae8d..70f89f38e 100644 --- a/src/render.c +++ b/src/render.c @@ -7,13 +7,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/render.h b/src/render.h index 4a68d1e07..79af0ccb5 100644 --- a/src/render.h +++ b/src/render.h @@ -5,7 +5,9 @@ extern "C" { #endif +#include #include + #include "buffer.h" #include "chunk.h" diff --git a/src/syntax_extension.h b/src/syntax_extension.h index a5fe11e57..da9e504e4 100644 --- a/src/syntax_extension.h +++ b/src/syntax_extension.h @@ -1,9 +1,10 @@ #ifndef CMARK_SYNTAX_EXTENSION_H #define CMARK_SYNTAX_EXTENSION_H +#include + #include "cmark-gfm.h" #include "cmark-gfm-extension_api.h" -#include "config.h" struct cmark_syntax_extension { cmark_match_block_func last_block_matches; diff --git a/src/xml.c b/src/xml.c index 5753e5ab9..ee561c79c 100644 --- a/src/xml.c +++ b/src/xml.c @@ -1,9 +1,9 @@ -#include +#include +#include #include +#include #include -#include -#include "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..ad053c8a7 100755 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -3,112 +3,101 @@ # 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(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 (PYTHONINTERP_FOUND) +IF (Python3_Interpreter_FOUND) - add_test(html_normalization - ${PYTHON_EXECUTABLE} "-m" "doctest" - "${CMAKE_CURRENT_SOURCE_DIR}/normalize.py" - ) + add_test(NAME html_normalization + COMMAND "$" -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" - ) + 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(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(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 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 + ${CMAKE_LIB_FUZZER_PATH}) + set_target_properties(${FUZZ_HARNESS} PROPERTIES + LINKER_LANGUAGE CXX) +endif()