Skip to content

2020/01/03 Merge #14

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 20 commits into from
Jan 3, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/FUNDING.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
github: [jgm]
44 changes: 43 additions & 1 deletion CMakeLists.txt
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ cmake_minimum_required(VERSION 3.0)
project(cmark VERSION 0.29.0)

include("FindAsan.cmake")
include(GNUInstallDirs)

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")
Expand All @@ -12,18 +13,59 @@ option(CMARK_STATIC "Build static libcmark library" ON)
option(CMARK_SHARED "Build shared libcmark library" ON)
option(CMARK_LIB_FUZZER "Build libFuzzer 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_VISIBILITY_PRESET hidden)
set(CMAKE_VISIBILITY_INLINES_HIDDEN 1)

set(CMAKE_INCLUDE_CURRENT_DIR ON)

# The Linux modules distributed with CMake add "-rdynamic" to the build flags
# which is incompatible with static linking under certain configurations.
# Unsetting CMAKE_SHARED_LIBRARY_LINK_C_FLAGS ensures this does not happen.
if(CMARK_STATIC AND "${CMAKE_SYSTEM_NAME}" STREQUAL "Linux")
SET(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS)
endif()

# Compiler flags
if(MSVC)
# Force to always compile with W4
add_compile_options($<$<COMPILE_LANGUAGE:C>:/W4>)
add_compile_options($<$<COMPILE_LANGUAGE:C>:/wd4706>)
add_compile_options($<$<COMPILE_LANGUAGE:C>:/TP>)
add_compile_options($<$<COMPILE_LANGUAGE:C>:/D_CRT_SECURE_NO_WARNINGS>)
elseif(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES Clang)
add_compile_options($<$<COMPILE_LANGUAGE:C>:-Wall>)
add_compile_options($<$<COMPILE_LANGUAGE:C>:-Wextra>)
add_compile_options($<$<COMPILE_LANGUAGE:C>:-pedantic>)
endif()

# Check integrity of node structure when compiled as debug
add_compile_options($<$<CONFIG:Debug>:-DCMARK_DEBUG_NODES>)

add_compile_options($<$<AND:$<CONFIG:PROFILE>,$<COMPILE_LANGUAGE:C>>:-pg>)

if(CMAKE_BUILD_TYPE STREQUAL Ubsan)
add_compile_options($<$<COMPILE_LANGUAGE:C>:-fsanitize=undefined>)
endif()
if(CMARK_LIB_FUZZER)
add_compile_options($<$<COMPILE_LANGUAGE:C>:-fsanitize-coverage=trace-pc-guard>)
endif()

add_subdirectory(src)
if(CMARK_TESTS AND (CMARK_SHARED OR CMARK_STATIC))
add_subdirectory(api_test)
endif()
add_subdirectory(man)
# 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()
if(CMARK_TESTS)
enable_testing()
add_subdirectory(test testdir)
Expand Down
18 changes: 0 additions & 18 deletions api_test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,8 @@ add_executable(api_test
harness.h
main.c
)
include_directories(
${PROJECT_SOURCE_DIR}/src
${PROJECT_BINARY_DIR}/src
)
if(CMARK_SHARED)
target_link_libraries(api_test libcmark)
else()
target_link_libraries(api_test libcmark_static)
endif()

# Compiler flags
if(MSVC)
# Force to always compile with W4
if(CMAKE_CXX_FLAGS MATCHES "/W[0-4]")
string(REGEX REPLACE "/W[0-4]" "/W4" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
else()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /W4")
endif()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /wd4706 /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()
6 changes: 3 additions & 3 deletions api_test/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -837,11 +837,11 @@ static void numeric_entities(test_batch_runner *runner) {
"Valid numeric entity 0x10FFFF");
test_md_to_html(runner, "&#x110000;", "<p>" UTF8_REPL "</p>\n",
"Invalid numeric entity 0x110000");
test_md_to_html(runner, "&#x80000000;", "<p>" UTF8_REPL "</p>\n",
test_md_to_html(runner, "&#x80000000;", "<p>&amp;#x80000000;</p>\n",
"Invalid numeric entity 0x80000000");
test_md_to_html(runner, "&#xFFFFFFFF;", "<p>" UTF8_REPL "</p>\n",
test_md_to_html(runner, "&#xFFFFFFFF;", "<p>&amp;#xFFFFFFFF;</p>\n",
"Invalid numeric entity 0xFFFFFFFF");
test_md_to_html(runner, "&#99999999;", "<p>" UTF8_REPL "</p>\n",
test_md_to_html(runner, "&#99999999;", "<p>&amp;#99999999;</p>\n",
"Invalid numeric entity 99999999");

test_md_to_html(runner, "&#;", "<p>&amp;#;</p>\n",
Expand Down
14 changes: 4 additions & 10 deletions man/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,10 +1,4 @@
if (NOT MSVC)

include(GNUInstallDirs)

install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/man1/cmark.1
DESTINATION ${CMAKE_INSTALL_MANDIR}/man1)

install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/man3/cmark.3
DESTINATION ${CMAKE_INSTALL_MANDIR}/man3)
endif(NOT MSVC)
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/man1/cmark.1
DESTINATION ${CMAKE_INSTALL_MANDIR}/man1)
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/man3/cmark.3
DESTINATION ${CMAKE_INSTALL_MANDIR}/man3)
87 changes: 24 additions & 63 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ if(${CMAKE_VERSION} VERSION_GREATER "3.3")
cmake_policy(SET CMP0063 NEW)
endif()

include(GNUInstallDirs)

set(LIBRARY "libcmark")
set(STATICLIBRARY "libcmark_static")
set(HEADERS
Expand Down Expand Up @@ -48,8 +46,6 @@ set(LIBRARY_SOURCES
set(PROGRAM "cmark")
set(PROGRAM_SOURCES main.c)

include_directories(. ${CMAKE_CURRENT_BINARY_DIR})

configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cmark_version.h.in
${CMAKE_CURRENT_BINARY_DIR}/cmark_version.h)

Expand All @@ -66,30 +62,20 @@ elseif (CMARK_SHARED)
target_link_libraries(${PROGRAM} ${LIBRARY})
endif()

# Check integrity of node structure when compiled as debug:
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DCMARK_DEBUG_NODES")
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
MACOSX_RPATH TRUE
OUTPUT_NAME "cmark"
# Avoid name clash between PROGRAM and LIBRARY pdb files.
PDB_NAME cmark_dll
# Include minor version and patch level in soname for now.
SOVERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}
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_dll)
target_include_directories(${LIBRARY} INTERFACE
$<INSTALL_INTERFACE:include>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>)

generate_export_header(${LIBRARY}
BASE_NAME ${PROJECT_NAME})
Expand All @@ -101,17 +87,13 @@ if (CMARK_STATIC)
add_library(${STATICLIBRARY} STATIC ${LIBRARY_SOURCES})
set_target_properties(${STATICLIBRARY} PROPERTIES
COMPILE_FLAGS -DCMARK_STATIC_DEFINE
POSITION_INDEPENDENT_CODE ON)

if (MSVC)
set_target_properties(${STATICLIBRARY} PROPERTIES
OUTPUT_NAME "cmark_static"
VERSION ${PROJECT_VERSION})
else()
set_target_properties(${STATICLIBRARY} PROPERTIES
OUTPUT_NAME "cmark"
VERSION ${PROJECT_VERSION})
endif(MSVC)
OUTPUT_NAME "cmark$<$<BOOL:MSVC>:_static>"
POSITION_INDEPENDENT_CODE ON
VERSION ${PROJECT_VERSION})
target_include_directories(${STATICLIBRARY} INTERFACE
$<INSTALL_INTERFACE:include>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>)

if (NOT CMARK_SHARED)
generate_export_header(${STATICLIBRARY}
Expand Down Expand Up @@ -154,6 +136,10 @@ if(CMARK_SHARED OR CMARK_STATIC)
)

install(EXPORT cmark DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake)

configure_file(cmarkConfig.cmake.in
${CMAKE_CURRENT_BINARY_DIR}/cmarkConfig.cmake)
export(TARGETS ${CMARK_INSTALL} FILE cmarkTargets.cmake)
endif()

export(TARGETS ${PROGRAM} ${LIBRARY} ${STATICLIBRARY}
Expand All @@ -162,8 +148,6 @@ export(TARGETS ${PROGRAM} ${LIBRARY} ${STATICLIBRARY}
# 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; }"
Expand All @@ -177,35 +161,12 @@ 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} /wd4706 /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 -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")
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. Explicitly link it into cmark-fuzz
set_target_properties(${FUZZ_HARNESS} PROPERTIES LINK_FLAGS "-lstdc++")
# needs to link against the C++ runtime.
set_target_properties(cmark-fuzz PROPERTIES
LINKER_LANGUAGE CXX)
endif()
7 changes: 7 additions & 0 deletions src/cmarkConfig.cmake.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
set(HAVE_LIBCMARK_STATIC @CMARK_STATIC@)
set(HAVE_LIBCMARK_SHARED @CMARK_SHARED@)

if((HAVE_LIBCMARK_STATIC AND NOT TARGET libcmark_static) OR
(HAVE_LIBCMARK_SHARED AND NOT TARGET libcmark))
include(cmarkTargets.cmake)
endif()
57 changes: 27 additions & 30 deletions src/commonmark.c
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ static int S_render_node(cmark_renderer *renderer, cmark_node *node,
char *emph_delim;
bool first_in_list_item;
bufsize_t marker_width;
bool has_nonspace;
bool allow_wrap = renderer->width > 0 && !(CMARK_OPT_NOBREAKS & options) &&
!(CMARK_OPT_HARDBREAKS & options);

Expand Down Expand Up @@ -214,8 +215,7 @@ static int S_render_node(cmark_renderer *renderer, cmark_node *node,
break;

case CMARK_NODE_LIST:
if (!entering && node->next && (node->next->type == CMARK_NODE_CODE_BLOCK ||
node->next->type == CMARK_NODE_LIST)) {
if (!entering && node->next && (node->next->type == CMARK_NODE_LIST)) {
// this ensures that a following indented code block or list will be
// inteprereted correctly.
CR();
Expand Down Expand Up @@ -276,6 +276,7 @@ static int S_render_node(cmark_renderer *renderer, cmark_node *node,
break;

case CMARK_NODE_CODE_BLOCK:

first_in_list_item = node->prev == NULL && node->parent &&
node->parent->type == CMARK_NODE_ITEM;

Expand All @@ -287,34 +288,23 @@ static int S_render_node(cmark_renderer *renderer, cmark_node *node,
fencechar[0] = strchr(info, '`') == NULL ? '`' : '~';
code = cmark_node_get_literal(node);
code_len = strlen(code);
// use indented form if no info, and code doesn't
// begin or end with a blank line, and code isn't
// first thing in a list item
if (info_len == 0 && (code_len > 2 && !cmark_isspace(code[0]) &&
!(cmark_isspace(code[code_len - 1]) &&
cmark_isspace(code[code_len - 2]))) &&
!first_in_list_item) {
LIT(" ");
cmark_strbuf_puts(renderer->prefix, " ");
OUT(cmark_node_get_literal(node), false, LITERAL);
cmark_strbuf_truncate(renderer->prefix, renderer->prefix->size - 4);
} else {
numticks = longest_backtick_sequence(code) + 1;
if (numticks < 3) {
numticks = 3;
}
for (i = 0; i < numticks; i++) {
LIT(fencechar);
}
LIT(" ");
OUT(info, false, LITERAL);
CR();
OUT(cmark_node_get_literal(node), false, LITERAL);
CR();
for (i = 0; i < numticks; i++) {
LIT(fencechar);
}

numticks = longest_backtick_sequence(code) + 1;
if (numticks < 3) {
numticks = 3;
}
for (i = 0; i < numticks; i++) {
LIT(fencechar);
}
LIT(" ");
OUT(info, false, LITERAL);
CR();
OUT(cmark_node_get_literal(node), false, LITERAL);
CR();
for (i = 0; i < numticks; i++) {
LIT(fencechar);
}

BLANKLINE();
break;

Expand Down Expand Up @@ -371,9 +361,16 @@ static int S_render_node(cmark_renderer *renderer, cmark_node *node,
code = cmark_node_get_literal(node);
code_len = strlen(code);
numticks = shortest_unused_backtick_sequence(code);
has_nonspace = false;
for (i=0; i < code_len; i++) {
if (code[i] != ' ') {
has_nonspace = true;
break;
}
}
extra_spaces = code_len == 0 ||
code[0] == '`' || code[code_len - 1] == '`' ||
code[0] == ' ' || code[code_len - 1] == ' ';
(has_nonspace && code[0] == ' ' && code[code_len - 1] == ' ');
for (i = 0; i < numticks; i++) {
LIT("`");
}
Expand Down
Loading