diff --git a/CMakeLists.txt b/CMakeLists.txt index 15f5c945d..6281d9ca3 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.0) +cmake_minimum_required(VERSION 3.12) project(cmark-gfm) set(PROJECT_VERSION_MAJOR 0) @@ -20,6 +20,17 @@ 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) +# set a required C standard so we can load stdbool.h +if(MSVC) + set(CMAKE_C_STANDARD 11) +else() + set(CMAKE_C_STANDARD 99) +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) + add_subdirectory(src) add_subdirectory(extensions) if(CMARK_TESTS AND (CMARK_SHARED OR CMARK_STATIC)) diff --git a/api_test/CMakeLists.txt b/api_test/CMakeLists.txt index 2ae27d762..151192d8a 100644 --- a/api_test/CMakeLists.txt +++ b/api_test/CMakeLists.txt @@ -6,9 +6,9 @@ add_executable(api_test ) include_directories( ${PROJECT_SOURCE_DIR}/src/include - ${PROJECT_BINARY_DIR}/src/include + ${PROJECT_BINARY_DIR}/src ${PROJECT_SOURCE_DIR}/extensions/include - ${PROJECT_BINARY_DIR}/extensions/include + ${PROJECT_BINARY_DIR}/extensions ) if(CMARK_SHARED) target_link_libraries(api_test libcmark-gfm-extensions libcmark-gfm) @@ -24,7 +24,7 @@ if(MSVC) else() set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /W4") endif() - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /wd4706 /D_CRT_SECURE_NO_WARNINGS") + 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") diff --git a/api_test/main.c b/api_test/main.c index 1051c2904..2e497ce95 100644 --- a/api_test/main.c +++ b/api_test/main.c @@ -1192,7 +1192,7 @@ static void inline_only_opt(test_batch_runner *runner) { cmark_node_free(doc); } -static void check_markdown_plaintext(test_batch_runner *runner, char *markdown) { +static void check_markdown_plaintext(test_batch_runner *runner, const char *markdown) { cmark_node *doc = cmark_parse_document(markdown, strlen(markdown), CMARK_OPT_PRESERVE_WHITESPACE); cmark_node *pg = cmark_node_first_child(doc); INT_EQ(runner, cmark_node_get_type(pg), CMARK_NODE_PARAGRAPH, "markdown '%s' did not produce a paragraph node", markdown); @@ -1228,7 +1228,7 @@ static void preserve_whitespace_opt(test_batch_runner *runner) { check_markdown_plaintext(runner, "\nHello\n"); } -static void check_markdown_attributes_node(test_batch_runner *runner, char *markdown, cmark_node_type expectedType, char *expectedAttributes) { +static void check_markdown_attributes_node(test_batch_runner *runner, const char *markdown, cmark_node_type expectedType, const char *expectedAttributes) { cmark_node *doc = cmark_parse_document(markdown, strlen(markdown), CMARK_OPT_DEFAULT); cmark_node *pg = cmark_node_first_child(doc); INT_EQ(runner, cmark_node_get_type(pg), CMARK_NODE_PARAGRAPH, "markdown '%s' did not produce a paragraph node", markdown); diff --git a/extensions/CMakeLists.txt b/extensions/CMakeLists.txt index 4977c98c3..9bbec1f47 100644 --- a/extensions/CMakeLists.txt +++ b/extensions/CMakeLists.txt @@ -15,7 +15,7 @@ set(LIBRARY_SOURCES include_directories( ${PROJECT_SOURCE_DIR}/src/include - ${PROJECT_BINARY_DIR}/src/include + ${PROJECT_BINARY_DIR}/src ) include (GenerateExportHeader) @@ -86,7 +86,7 @@ install(TARGETS ${CMARK_INSTALL} if (CMARK_SHARED OR CMARK_STATIC) install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/cmark-gfm-core-extensions.h - ${CMAKE_CURRENT_SOURCE_DIR}/include/cmark-gfm-extensions_export.h + ${CMAKE_CURRENT_SOURCE_DIR}/include/extensions-export.h DESTINATION include ) @@ -98,14 +98,10 @@ include(CheckIncludeFile) include(CheckCSourceCompiles) include(CheckCSourceRuns) include(CheckSymbolExists) -CHECK_INCLUDE_FILE(stdbool.h HAVE_STDBOOL_H) +CHECK_INCLUDE_FILE(unistd.h HAVE_UNISTD_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) @@ -115,7 +111,7 @@ if(MSVC) 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") + 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() diff --git a/extensions/include/cmark-gfm-core-extensions.h b/extensions/include/cmark-gfm-core-extensions.h index 51103e616..20da8d6e3 100644 --- a/extensions/include/cmark-gfm-core-extensions.h +++ b/extensions/include/cmark-gfm-core-extensions.h @@ -6,7 +6,7 @@ extern "C" { #endif #include "cmark-gfm-extension_api.h" -#include "cmark-gfm-extensions_export.h" +#include "extensions-export.h" #include "cmark-gfm_config.h" // for bool #include diff --git a/extensions/include/cmark-gfm-extensions_export.h b/extensions/include/cmark-gfm-extensions_export.h deleted file mode 100644 index 69c0bd787..000000000 --- a/extensions/include/cmark-gfm-extensions_export.h +++ /dev/null @@ -1,42 +0,0 @@ - -#ifndef CMARK_GFM_EXTENSIONS_EXPORT_H -#define CMARK_GFM_EXTENSIONS_EXPORT_H - -#ifdef CMARK_GFM_EXTENSIONS_STATIC_DEFINE -# define CMARK_GFM_EXTENSIONS_EXPORT -# define CMARK_GFM_EXTENSIONS_NO_EXPORT -#else -# ifndef CMARK_GFM_EXTENSIONS_EXPORT -# ifdef libcmark_gfm_extensions_EXPORTS - /* We are building this library */ -# define CMARK_GFM_EXTENSIONS_EXPORT __attribute__((visibility("default"))) -# else - /* We are using this library */ -# define CMARK_GFM_EXTENSIONS_EXPORT __attribute__((visibility("default"))) -# endif -# endif - -# ifndef CMARK_GFM_EXTENSIONS_NO_EXPORT -# define CMARK_GFM_EXTENSIONS_NO_EXPORT __attribute__((visibility("hidden"))) -# endif -#endif - -#ifndef CMARK_GFM_EXTENSIONS_DEPRECATED -# define CMARK_GFM_EXTENSIONS_DEPRECATED __attribute__ ((__deprecated__)) -#endif - -#ifndef CMARK_GFM_EXTENSIONS_DEPRECATED_EXPORT -# define CMARK_GFM_EXTENSIONS_DEPRECATED_EXPORT CMARK_GFM_EXTENSIONS_EXPORT CMARK_GFM_EXTENSIONS_DEPRECATED -#endif - -#ifndef CMARK_GFM_EXTENSIONS_DEPRECATED_NO_EXPORT -# define CMARK_GFM_EXTENSIONS_DEPRECATED_NO_EXPORT CMARK_GFM_EXTENSIONS_NO_EXPORT CMARK_GFM_EXTENSIONS_DEPRECATED -#endif - -#if 0 /* DEFINE_NO_DEPRECATED */ -# ifndef CMARK_GFM_EXTENSIONS_NO_DEPRECATED -# define CMARK_GFM_EXTENSIONS_NO_DEPRECATED -# endif -#endif - -#endif /* CMARK_GFM_EXTENSIONS_EXPORT_H */ diff --git a/extensions/include/extensions-export.h b/extensions/include/extensions-export.h new file mode 100644 index 000000000..f91b8564c --- /dev/null +++ b/extensions/include/extensions-export.h @@ -0,0 +1,60 @@ +#ifndef CMARK_GFM_EXTENSIONS_EXPORT_H +#define CMARK_GFM_EXTENSIONS_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_EXTENSIONS_EXPORT_H +#include "cmark-gfm-extensions_export.h" +#else + +#ifdef CMARK_GFM_EXTENSIONS_STATIC_DEFINE +# define CMARK_GFM_EXTENSIONS_EXPORT +# define CMARK_GFM_EXTENSIONS_NO_EXPORT +#else +# if defined(_WIN32) +# ifndef CMARK_GFM_EXTENSIONS_EXPORT +# ifdef libcmark_gfm_extensions_EXPORTS +# define CMARK_GFM_EXTENSIONS_EXPORT __declspec(dllexport) +# else +# define CMARK_GFM_EXTENSIONS_EXPORT __declspec(dllimport) +# endif +# endif + +# ifndef CMARK_GFM_EXTENSIONS_NO_EXPORT +# define CMARK_GFM_EXTENSIONS_NO_EXPORT +# endif +# else +# ifndef CMARK_GFM_EXTENSIONS_EXPORT +# ifdef libcmark_gfm_extensions_EXPORTS +# define CMARK_GFM_EXTENSIONS_EXPORT __attribute__((__visibility__("default"))) +# else +# define CMARK_GFM_EXTENSIONS_EXPORT __attribute__((__visibility__("default"))) +# endif +# endif + +# ifndef CMARK_GFM_EXTENSIONS_NO_EXPORT +# define CMARK_GFM_EXTENSIONS_NO_EXPORT __attribute__((__visibility__("hidden"))) +# endif +# endif +#endif + +#ifndef CMARK_GFM_EXTENSIONS_DEPRECATED +# if defined(_WIN32) +# define CMARK_GFM_EXTENSIONS_DEPRECATED __declspec(deprecated) +# else +# define CMARK_GFM_EXTENSIONS_DEPRECATED __attribute__ ((__deprecated__)) +# endif +#endif + +#ifndef CMARK_GFM_EXTENSIONS_DEPRECATED_EXPORT +# define CMARK_GFM_EXTENSIONS_DEPRECATED_EXPORT CMARK_GFM_EXTENSIONS_EXPORT CMARK_GFM_EXTENSIONS_DEPRECATED +#endif + +#ifndef CMARK_GFM_EXTENSIONS_DEPRECATED_NO_EXPORT +# define CMARK_GFM_EXTENSIONS_DEPRECATED_NO_EXPORT CMARK_GFM_EXTENSIONS_NO_EXPORT CMARK_GFM_EXTENSIONS_DEPRECATED +#endif + +#endif /* CMARK_GFM_EXTENSIONS_EXPORT_H */ + +#endif /* "cmark-gfm-extensions_export.h" */ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index b7018903c..faabffa4a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -45,7 +45,7 @@ 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/include + ${PROJECT_BINARY_DIR}/extensions ) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cmark-gfm_version.h.in @@ -152,12 +152,25 @@ if(CMARK_SHARED OR CMARK_STATIC) ${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/cmark-gfm_export.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) + 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 @@ -165,14 +178,10 @@ include(CheckIncludeFile) include(CheckCSourceCompiles) include(CheckCSourceRuns) include(CheckSymbolExists) -CHECK_INCLUDE_FILE(stdbool.h HAVE_STDBOOL_H) +CHECK_INCLUDE_FILE(unistd.h HAVE_UNISTD_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 @@ -186,7 +195,7 @@ if(MSVC) 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") + 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() diff --git a/src/config.h.in b/src/config.h.in index 65702b2e0..f8f767a8b 100644 --- a/src/config.h.in +++ b/src/config.h.in @@ -5,26 +5,18 @@ extern "C" { #endif -#cmakedefine HAVE_STDBOOL_H - -#ifdef HAVE_STDBOOL_H +#if __STDC_VERSION__ >= 199901l #include #elif !defined(__cplusplus) typedef char bool; #endif -#cmakedefine HAVE___BUILTIN_EXPECT +#cmakedefine HAVE_UNISTD_H -#cmakedefine HAVE___ATTRIBUTE__ +#cmakedefine HAVE___BUILTIN_EXPECT #cmakedefine CMARK_THREADING -#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 diff --git a/src/include/cmark-gfm.h b/src/include/cmark-gfm.h index 14ab95f4a..aee012955 100644 --- a/src/include/cmark-gfm.h +++ b/src/include/cmark-gfm.h @@ -3,7 +3,7 @@ #include #include -#include "cmark-gfm_export.h" +#include "export.h" #include "cmark-gfm_version.h" #ifdef __cplusplus @@ -807,7 +807,7 @@ const char *cmark_version_string(void); * John MacFarlane, Vicent Marti, Kārlis Gaņģis, Nick Wellnhofer. */ -#ifndef CMARK_NO_SHORT_NAMES +#if !defined(CMARK_NO_SHORT_NAMES) #define NODE_DOCUMENT CMARK_NODE_DOCUMENT #define NODE_BLOCK_QUOTE CMARK_NODE_BLOCK_QUOTE #define NODE_LIST CMARK_NODE_LIST diff --git a/src/include/cmark-gfm_config.h b/src/include/cmark-gfm_config.h index 1f96cc558..7d331915b 100644 --- a/src/include/cmark-gfm_config.h +++ b/src/include/cmark-gfm_config.h @@ -1,30 +1,36 @@ #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 -#define HAVE_STDBOOL_H - -#ifdef HAVE_STDBOOL_H +#if __STDC_VERSION__ >= 199901l #include #elif !defined(__cplusplus) typedef char bool; #endif -#define HAVE___BUILTIN_EXPECT +#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___ATTRIBUTE__ +#define HAVE___BUILTIN_EXPECT #define CMARK_THREADING -#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 @@ -75,4 +81,6 @@ CMARK_INLINE int c99_snprintf(char *outBuf, size_t size, const char *format, ... } #endif -#endif +#endif /* not CMARK_USE_CMAKE_HEADERS */ + +#endif /* not CMARK_CONFIG_H */ diff --git a/src/include/cmark_ctype.h b/src/include/cmark_ctype.h index 67c1cb037..4c2457e8c 100644 --- a/src/include/cmark_ctype.h +++ b/src/include/cmark_ctype.h @@ -5,7 +5,7 @@ extern "C" { #endif -#include "cmark-gfm_export.h" +#include "export.h" /** Locale-independent versions of functions from ctype.h. * We want cmark to behave the same no matter what the system locale. diff --git a/src/include/cmark-gfm_export.h b/src/include/export.h similarity index 61% rename from src/include/cmark-gfm_export.h rename to src/include/export.h index 7247214be..c219c6f54 100644 --- a/src/include/cmark-gfm_export.h +++ b/src/include/export.h @@ -1,7 +1,13 @@ - #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 @@ -15,11 +21,7 @@ # define CMARK_GFM_NO_EXPORT # else # if defined(libcmark_gfm_EXPORTS) -# if defined(__linux__) -# define CMARK_GFM_EXPORT __attribute__((__visibility__("protected"))) -# else -# define CMARK_GFM_EXPORT __attribute__((__visibility__("default"))) -# endif +# define CMARK_GFM_EXPORT __attribute__((__visibility__("default"))) # else # define CMARK_GFM_EXPORT __attribute__((__visibility__("default"))) # endif @@ -28,7 +30,11 @@ #endif #ifndef CMARK_GFM_DEPRECATED -# define CMARK_GFM_DEPRECATED __attribute__ ((__deprecated__)) +# if defined(_WIN32) +# define CMARK_GFM_DEPRECATED __declspec(deprecated) +# else +# define CMARK_GFM_DEPRECATED __attribute__ ((__deprecated__)) +# endif #endif #ifndef CMARK_GFM_DEPRECATED_EXPORT @@ -39,10 +45,6 @@ # define CMARK_GFM_DEPRECATED_NO_EXPORT CMARK_GFM_NO_EXPORT CMARK_GFM_DEPRECATED #endif -#if 0 /* DEFINE_NO_DEPRECATED */ -# ifndef CMARK_GFM_NO_DEPRECATED -# define CMARK_GFM_NO_DEPRECATED -# endif -#endif +#endif /* not CMARK_USE_CMAKE_HEADERS */ -#endif /* CMARK_GFM_EXPORT_H */ +#endif /* not CMARK_GFM_EXPORT_H */ diff --git a/src/include/mutex.h b/src/include/mutex.h index 7335d8225..d2ad4787b 100644 --- a/src/include/mutex.h +++ b/src/include/mutex.h @@ -5,7 +5,7 @@ #ifdef CMARK_THREADING -#if __has_include() +#ifdef HAVE_UNISTD_H #include #endif @@ -30,8 +30,9 @@ pthread_mutex_lock(&NAME##_lock); #elif defined(_WIN32) // building for windows -#define _WIN32_WINNT 0x0600 -#include +#define _WIN32_WINNT 0x0600 // minimum target of Windows Vista +#define WIN32_LEAN_AND_MEAN +#include #define CMARK_DEFINE_ONCE(NAME) static INIT_ONCE NAME##_once = INIT_ONCE_STATIC_INIT; diff --git a/src/inlines.c b/src/inlines.c index 7d4a8d451..e97f5e568 100644 --- a/src/inlines.c +++ b/src/inlines.c @@ -1100,7 +1100,7 @@ static bufsize_t manual_scan_attribute_attributes(cmark_chunk *input, bufsize_t static cmark_node *handle_close_bracket_attribute(cmark_parser *parser, subject *subj, bracket *opener) { bufsize_t startattributes, endattributes; - cmark_chunk attributes; + cmark_chunk attributes = CMARK_CHUNK_EMPTY; bufsize_t n; cmark_node *inl; cmark_chunk raw_label;