From fe3902c2affbae96b5869fdef3902e0c0d2c62e2 Mon Sep 17 00:00:00 2001 From: Saleem Abdulrasool Date: Wed, 3 Jan 2024 15:02:55 -0800 Subject: [PATCH] assorted fixes to the build system Remove the use of `CMARK_INLINE` (as is being considered upstream) as this workaround is no longer needed. It was to support VS2013 which has been obsoleted for some time now. Restructure the CMake modules to match expectations for CMake. Avoid defining `likely` and `unlikely` in global scope. While doing so, prefer the modern `__has_builtin` for the check (with fallbacks for pre-GCC 4.10, clang 3.4, and MSVC). This largely shouldn't matter in practice as modern branch predictors do well without the hint. Sink the declaration into source files as the macros are not namespaced. Remove the now unnecessary `config.h`. Clean up the builds to only support a single build type which is dependent on the standard `BUILD_SHARED_LIBS`. Simplify and normalise the install rules to use the `GNUInstallDirs` parameters. --- CMakeLists.txt | 49 ++-- api_test/CMakeLists.txt | 17 +- .../modules/CheckFileOffsetBits.c | 0 .../modules/CheckFileOffsetBits.cmake | 0 .../modules/FindAsan.cmake | 0 extensions/CMakeLists.txt | 111 +++------ src/CMakeLists.txt | 229 ++++++------------ src/blocks.c | 11 +- src/buffer.c | 3 +- src/buffer.h | 4 +- src/chunk.h | 31 ++- src/commonmark.c | 10 +- src/config.h.in | 22 -- src/houdini.h | 10 +- src/houdini_href_e.c | 10 + src/houdini_html_e.c | 10 + src/houdini_html_u.c | 11 + src/html.c | 1 - src/html.h | 4 +- src/inlines.c | 33 ++- src/iterator.c | 1 - src/latex.c | 6 +- src/main.c | 2 +- src/man.c | 1 - src/node.c | 1 - src/node.h | 10 +- src/plaintext.c | 5 +- src/registry.c | 1 - src/render.c | 4 +- src/syntax_extension.h | 1 - src/xml.c | 3 +- test/CMakeLists.txt | 9 + 32 files changed, 217 insertions(+), 393 deletions(-) rename CheckFileOffsetBits.c => cmake/modules/CheckFileOffsetBits.c (100%) rename CheckFileOffsetBits.cmake => cmake/modules/CheckFileOffsetBits.cmake (100%) rename FindAsan.cmake => cmake/modules/FindAsan.cmake (100%) delete mode 100644 src/config.h.in diff --git a/CMakeLists.txt b/CMakeLists.txt index 53578ba3d..18689984f 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,36 +7,22 @@ if(POLICY CMP0092) cmake_policy(SET CMP0092 NEW) endif() -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}) - -include("FindAsan.cmake") -include("CheckFileOffsetBits.cmake") -include(CTest) -include(GNUInstallDirs) +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_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) -if(NOT MSVC) - set(CMAKE_C_STANDARD 99) - set(CMAKE_C_STANDARD_REQUIRED YES) - set(CMAKE_C_EXTENSIONS NO) -endif() - -# -fvisibility=hidden +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) @@ -44,13 +30,20 @@ if(NOT MSVC OR CMAKE_HOST_SYSTEM_NAME STREQUAL Windows) 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>) - # Compile as C++ under MSVC older than 12.0 - add_compile_options($<$:/TP>) add_compile_definitions($<$:_CRT_SECURE_NO_WARNINGS>) # BEGIN cmark-gfm add_compile_options($<$:/wd4204>) @@ -80,11 +73,7 @@ if(CMARK_LIB_FUZZER) 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) @@ -96,9 +85,7 @@ if(NOT CMAKE_SYSTEM_NAME STREQUAL Windows) endif() if(BUILD_TESTING) add_subdirectory(test testdir) - if(CMARK_STATIC OR CMARK_SHARED) - add_subdirectory(api_test) - endif() + add_subdirectory(api_test) endif() if(CMARK_FUZZ_QUADRATIC) add_subdirectory(fuzz) diff --git a/api_test/CMakeLists.txt b/api_test/CMakeLists.txt index 0ac3fa203..f1db2f114 100644 --- a/api_test/CMakeLists.txt +++ b/api_test/CMakeLists.txt @@ -1,19 +1,10 @@ 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) add_test(NAME api_test COMMAND api_test) if(WIN32) 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 550199a5a..f69f6c63a 100644 --- a/extensions/CMakeLists.txt +++ b/extensions/CMakeLists.txt @@ -1,85 +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}) - -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}) - target_compile_definitions(${STATICLIBRARY} PUBLIC - CMARK_GFM_STATIC_DEFINE - CMARK_GFM_EXTENSIONS_STATIC_DEFINE) - set_target_properties(${STATICLIBRARY} PROPERTIES - 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() - -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(CheckCSourceCompiles) - -CHECK_C_SOURCE_COMPILES( - "int main() { __builtin_expect(0,0); return 0; }" - HAVE___BUILTIN_EXPECT) + 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/src/CMakeLists.txt b/src/CMakeLists.txt index 56b6cdd62..58fed2797 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,176 +1,83 @@ -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 + +set(PROJECT_VERSION_MAJOR 0) +set(PROJECT_VERSION_MINOR 29) +set(PROJECT_VERSION_PATCH 0) +set(PROJECT_VERSION_GFM 13) + +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() - -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}) - target_compile_definitions(${STATICLIBRARY} PUBLIC - CMARK_GFM_STATIC_DEFINE - CMARK_GFM_EXTENSIONS_STATIC_DEFINE) - set_target_properties(${STATICLIBRARY} PROPERTIES - 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}) + 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() -if (MSVC) - set_property(TARGET ${PROGRAM} - APPEND PROPERTY LINK_FLAGS /INCREMENTAL:NO) -endif(MSVC) - -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(CheckCSourceCompiles) - -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) - -if(CMARK_LIB_FUZZER) - add_executable(cmark-fuzz ../test/cmark-fuzz.c ${LIBRARY_SOURCES}) - target_link_libraries(cmark-fuzz "${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(${FUZZ_HARNESS} PROPERTIES - LINKER_LANGUAGE CXX) -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 2069c772e..96c72db1e 100644 --- a/src/blocks.c +++ b/src/blocks.c @@ -13,7 +13,6 @@ #include "cmark_ctype.h" #include "syntax_extension.h" -#include "config.h" #include "parser.h" #include "cmark-gfm.h" #include "node.h" @@ -50,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; } @@ -65,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'); } @@ -190,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 bb5c0aa74..aeca03d09 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -7,7 +7,6 @@ #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 780173b55..af60afa9b 100644 --- a/src/commonmark.c +++ b/src/commonmark.c @@ -5,7 +5,6 @@ #include #include -#include "config.h" #include "cmark-gfm.h" #include "node.h" #include "buffer.h" @@ -23,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 && @@ -464,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); @@ -479,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 b4de81f13..000000000 --- a/src/config.h.in +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef CMARK_CONFIG_H -#define CMARK_CONFIG_H - -#ifdef __cplusplus -extern "C" { -#endif - -#cmakedefine HAVE___BUILTIN_EXPECT - -#ifndef CMARK_INLINE - #if defined(_MSC_VER) && !defined(__cplusplus) - #define CMARK_INLINE __inline - #else - #define CMARK_INLINE inline - #endif -#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 d6d0d548b..5a9ac1339 100644 --- a/src/html.c +++ b/src/html.c @@ -5,7 +5,6 @@ #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 235461f1e..5762b189f 100644 --- a/src/inlines.c +++ b/src/inlines.c @@ -4,7 +4,6 @@ #include #include "cmark_ctype.h" -#include "config.h" #include "node.h" #include "parser.h" #include "references.h" @@ -69,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'); } @@ -83,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; @@ -98,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; @@ -170,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(""); @@ -203,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); @@ -237,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); @@ -251,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 e39626703..f3b9c941a 100644 --- a/src/latex.c +++ b/src/latex.c @@ -4,7 +4,6 @@ #include #include -#include "config.h" #include "cmark-gfm.h" #include "node.h" #include "buffer.h" @@ -19,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 adfea62c4..51ea34807 100644 --- a/src/man.c +++ b/src/man.c @@ -4,7 +4,6 @@ #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 00df01e77..fb3d4629f 100644 --- a/src/node.c +++ b/src/node.c @@ -2,7 +2,6 @@ #include #include -#include "config.h" #include "node.h" #include "syntax_extension.h" diff --git a/src/node.h b/src/node.h index 6cd4f6f75..8f7286891 100644 --- a/src/node.h +++ b/src/node.h @@ -131,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/syntax_extension.h b/src/syntax_extension.h index a5fe11e57..58509ceb6 100644 --- a/src/syntax_extension.h +++ b/src/syntax_extension.h @@ -3,7 +3,6 @@ #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 1feca55a8..ee561c79c 100644 --- a/src/xml.c +++ b/src/xml.c @@ -4,7 +4,6 @@ #include #include -#include "config.h" #include "cmark-gfm.h" #include "node.h" #include "buffer.h" @@ -26,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 8f23e99aa..ad053c8a7 100755 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -92,3 +92,12 @@ 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()