Skip to content

Commit abef559

Browse files
committed
Conform to C89—and my own quality standards—for MSVC (2005,2022,2026), DOS (OpenWatcom), gcc, and clang. Use the same CI as my other C projects. Add header-only option.
1 parent b6d73d2 commit abef559

10 files changed

Lines changed: 387 additions & 186 deletions

File tree

.github/workflows/ci.yml

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [ "main", "master" ]
6+
pull_request:
7+
branches: [ "main", "master" ]
8+
9+
jobs:
10+
build:
11+
uses: SamuelMarks/c-ci/.github/workflows/c-cmake-ci.yml@master
12+
with:
13+
cmake_configure_flags: '-DC89STRINGUTILS_BUILD_AMALGAMATION=ON'
14+
project_name: 'c89stringutils'
15+
16+
test-amalg:
17+
name: Test Amalgamation
18+
runs-on: ubuntu-latest
19+
steps:
20+
- uses: actions/checkout@v4
21+
22+
- name: Generate amalgamation
23+
run: |
24+
cmake -B build -DC89STRINGUTILS_BUILD_AMALGAMATION=ON
25+
cmake --build build
26+
27+
- name: Create Test File
28+
run: |
29+
cat << 'EOF' > test_amalg.c
30+
#define C89STRINGUTILS_IMPLEMENTATION
31+
#include "build/c89stringutils/c89stringutils_amalgamation.h"
32+
#include <stdio.h>
33+
#include <stdlib.h>
34+
35+
int main(void) {
36+
char* x = NULL;
37+
int len = asprintf(&x, "hello %s", "world");
38+
if (len > 0 && x != NULL) {
39+
printf("%s\n", x);
40+
free(x);
41+
return 0;
42+
}
43+
return 1;
44+
}
45+
EOF
46+
47+
- name: Compile Test Amalgamation
48+
run: gcc -Wall -Wextra -Werror -o test_amalg test_amalg.c
49+
50+
- name: Run Test Amalgamation
51+
run: ./test_amalg

.github/workflows/linux-Windows-macOS-sunOS.yml

Lines changed: 0 additions & 45 deletions
This file was deleted.

.gitignore

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1-
.idea
2-
*build*
3-
*_export.h
1+
.idea
2+
*build*
3+
*_export.h
4+
5+
test_amalg.c
6+
cmake/scripts/

CMakeLists.txt

Lines changed: 126 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -1,111 +1,126 @@
1-
cmake_minimum_required(VERSION 3.11)
2-
project(c89stringutils VERSION 0.0.2 LANGUAGES C)
3-
4-
set(CMAKE_C_VISIBILITY_PRESET hidden)
5-
set(CMAKE_VISIBILITY_INLINES_HIDDEN YES)
6-
set(CMAKE_C_STANDARD 90)
7-
8-
add_library("${PROJECT_NAME}_compiler_flags" INTERFACE)
9-
if (NOT DEFINED MSVC_VERSION
10-
OR MSVC_VERSION STRGREATER "1900" # 2015
11-
OR NOT (CMAKE_C_COMPILER_ID STREQUAL "OpenWatcom"))
12-
target_compile_features("${PROJECT_NAME}_compiler_flags" INTERFACE "c_std_${CMAKE_C_STANDARD}")
13-
elseif ((MSVC_VERSION STRLESS_EQUAL "1900"
14-
OR CMAKE_C_COMPILER_ID STREQUAL "OpenWatcom"
15-
OR CYGWIN)
16-
AND NOT EXISTS "${CMAKE_BINARY_DIR}/c89stringutils_export.h")
17-
file(COPY "${CMAKE_SOURCE_DIR}/c89stringutils/c89stringutils_export_pregen.h"
18-
DESTINATION "${CMAKE_BINARY_DIR}")
19-
file(RENAME "${CMAKE_BINARY_DIR}/c89stringutils_export_pregen.h"
20-
"${CMAKE_BINARY_DIR}/c89stringutils_export.h")
21-
endif ()
22-
if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.15")
23-
set(gcc_like "$<COMPILE_LANG_AND_ID:C,CXX,ARMClang,AppleClang,Clang,GNU,LCC>")
24-
set(msvc "$<COMPILE_LANG_AND_ID:C,CXX,MSVC>")
25-
target_compile_options(
26-
"${PROJECT_NAME}_compiler_flags"
27-
INTERFACE
28-
"$<$<AND:${gcc_like},$<CONFIG:Debug>>:$<BUILD_INTERFACE:-Wshadow;-Wformat=2;-Wall;-Wno-missing-braces;-Wno-long-long;-pedantic;-fprofile-arcs;-ftest-coverage>>"
29-
"$<${msvc}:$<BUILD_INTERFACE:-W3;-WX;-Zi;-permissive->>"
30-
)
31-
target_link_options(
32-
"${PROJECT_NAME}_compiler_flags"
33-
INTERFACE
34-
"$<$<AND:${gcc_like},$<CONFIG:Debug>>:$<BUILD_INTERFACE:--coverage>>"
35-
)
36-
endif (CMAKE_VERSION VERSION_GREATER_EQUAL "3.15")
37-
# Set the build directories
38-
if (CMAKE_SYSTEM_NAME STREQUAL "Windows"
39-
OR CMAKE_SYSTEM_NAME STREQUAL "CYGWIN"
40-
OR CMAKE_SYSTEM_NAME MATCHES "MINGW.*")
41-
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}")
42-
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}")
43-
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}")
44-
else ()
45-
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib")
46-
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin")
47-
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib")
48-
endif ()
49-
50-
# configure a header file to pass the version number only
51-
configure_file(
52-
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/config.h.in"
53-
"${PROJECT_NAME}Config.h"
54-
)
55-
56-
add_subdirectory("${PROJECT_NAME}")
57-
58-
include(CTest)
59-
option(BUILD_TESTING "Build the tests" OFF)
60-
option(C89STRINGUTILS_BUILD_TESTING "Build the tests" OFF)
61-
if (BUILD_TESTING AND C89STRINGUTILS_BUILD_TESTING)
62-
add_subdirectory("${PROJECT_NAME}/tests")
63-
endif (BUILD_TESTING AND C89STRINGUTILS_BUILD_TESTING)
64-
65-
###########
66-
# Install #
67-
###########
68-
69-
include(GNUInstallDirs)
70-
71-
install(
72-
FILES "${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.h"
73-
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
74-
)
75-
include(InstallRequiredSystemLibraries)
76-
set(CPACK_BUNDLE_NAME "${PROJECT_NAME}")
77-
set(CPACK_PACKAGE_VENDOR "Samuel Marks")
78-
set(CPACK_PACKAGE_DESCRIPTION "string functions from newer standards / common non-standards for C89")
79-
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "${CPACK_PACKAGE_DESCRIPTION}")
80-
if (APPLE)
81-
set(CPACK_BUNDLE_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Info.plist")
82-
set(CPACK_BUNDLE_ICON "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Info.plist")
83-
set(CPACK_PACKAGE_ICON "${CMAKE_CURRENT_SOURCE_DIR}/cmake/CustomVolumeIcon.icns")
84-
endif (APPLE)
85-
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/cmake/LICENSE.txt")
86-
set(CPACK_PACKAGE_VERSION_MAJOR "${${PROJECT_NAME}_VERSION_MAJOR}")
87-
set(CPACK_PACKAGE_VERSION_MINOR "${${PROJECT_NAME}_VERSION_MINOR}")
88-
set(CPACK_RESOURCE_FILE_README "${CMAKE_CURRENT_SOURCE_DIR}/cmake/README.txt")
89-
set(CPACK_RESOURCE_FILE_WELCOME "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Welcome.txt")
90-
set(CPACK_PACKAGE_CONTACT "https://github.com/offscale/${PROJECT_NAME}")
91-
92-
include(CPack)
93-
include(CMakePackageConfigHelpers)
94-
95-
# generate the config file that is includes the exports
96-
configure_package_config_file(
97-
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/Config.cmake.in"
98-
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
99-
INSTALL_DESTINATION "${CMAKE_INSTALL_DATADIR}/${PROJECT_NAME}"
100-
NO_SET_AND_CHECK_MACRO
101-
NO_CHECK_REQUIRED_COMPONENTS_MACRO
102-
)
103-
104-
# generate the version file for the config file
105-
write_basic_package_version_file(
106-
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake"
107-
VERSION "${${PROJECT_NAME}_VERSION_MAJOR}.${${PROJECT_NAME}_VERSION_MINOR}"
108-
COMPATIBILITY AnyNewerVersion
109-
)
110-
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
111-
DESTINATION "${CMAKE_INSTALL_DATADIR}/${PROJECT_NAME}")
1+
cmake_minimum_required(VERSION 3.11)
2+
project(c89stringutils VERSION 0.0.2 LANGUAGES C)
3+
4+
set(CMAKE_C_VISIBILITY_PRESET hidden)
5+
set(CMAKE_VISIBILITY_INLINES_HIDDEN YES)
6+
set(CMAKE_C_STANDARD 90)
7+
8+
add_library("${PROJECT_NAME}_compiler_flags" INTERFACE)
9+
if (NOT DEFINED MSVC_VERSION
10+
OR MSVC_VERSION STRGREATER "1900" # 2015
11+
OR NOT (CMAKE_C_COMPILER_ID STREQUAL "OpenWatcom"))
12+
target_compile_features("${PROJECT_NAME}_compiler_flags" INTERFACE "c_std_${CMAKE_C_STANDARD}")
13+
elseif ((MSVC_VERSION STRLESS_EQUAL "1900"
14+
OR CMAKE_C_COMPILER_ID STREQUAL "OpenWatcom"
15+
OR CYGWIN)
16+
AND NOT EXISTS "${CMAKE_BINARY_DIR}/c89stringutils_export.h")
17+
file(COPY "${CMAKE_SOURCE_DIR}/c89stringutils/c89stringutils_export_pregen.h"
18+
DESTINATION "${CMAKE_BINARY_DIR}")
19+
file(RENAME "${CMAKE_BINARY_DIR}/c89stringutils_export_pregen.h"
20+
"${CMAKE_BINARY_DIR}/c89stringutils_export.h")
21+
endif ()
22+
if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.15")
23+
set(gcc_like "$<COMPILE_LANG_AND_ID:C,CXX,ARMClang,AppleClang,Clang,GNU,LCC>")
24+
set(msvc "$<COMPILE_LANG_AND_ID:C,CXX,MSVC>")
25+
target_compile_options(
26+
"${PROJECT_NAME}_compiler_flags"
27+
INTERFACE
28+
"$<$<AND:${gcc_like},$<CONFIG:Debug>>:$<BUILD_INTERFACE:-Wshadow;-Wformat=2;-Wall;-Wno-missing-braces;-Wno-long-long;-pedantic;-fprofile-arcs;-ftest-coverage>>"
29+
"$<${msvc}:$<BUILD_INTERFACE:-W3;-WX;-Zi;-permissive->>"
30+
)
31+
target_link_options(
32+
"${PROJECT_NAME}_compiler_flags"
33+
INTERFACE
34+
"$<$<AND:${gcc_like},$<CONFIG:Debug>>:$<BUILD_INTERFACE:--coverage>>"
35+
)
36+
endif (CMAKE_VERSION VERSION_GREATER_EQUAL "3.15")
37+
# Set the build directories
38+
if (CMAKE_SYSTEM_NAME STREQUAL "Windows"
39+
OR CMAKE_SYSTEM_NAME STREQUAL "CYGWIN"
40+
OR CMAKE_SYSTEM_NAME MATCHES "MINGW.*")
41+
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}")
42+
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}")
43+
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}")
44+
else ()
45+
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib")
46+
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin")
47+
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib")
48+
endif ()
49+
50+
# configure a header file to pass the version number only
51+
configure_file(
52+
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/config.h.in"
53+
"${PROJECT_NAME}Config.h"
54+
)
55+
56+
add_subdirectory("${PROJECT_NAME}")
57+
58+
include(CTest)
59+
option(BUILD_TESTING "Build the tests" ON)
60+
option(C89STRINGUTILS_BUILD_TESTING "Build the tests" ON)
61+
62+
if (CDD_CHARSET STREQUAL "Unicode")
63+
add_compile_definitions(UNICODE _UNICODE)
64+
endif()
65+
if (MSVC AND CDD_MSVC_RTC)
66+
add_compile_options("/${CDD_MSVC_RTC}")
67+
endif()
68+
if (CDD_LTO)
69+
include(CheckIPOSupported)
70+
check_ipo_supported(RESULT ipo_supported)
71+
if(ipo_supported)
72+
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)
73+
endif()
74+
endif()
75+
76+
if (BUILD_TESTING AND C89STRINGUTILS_BUILD_TESTING)
77+
add_subdirectory("${PROJECT_NAME}/tests")
78+
endif (BUILD_TESTING AND C89STRINGUTILS_BUILD_TESTING)
79+
80+
###########
81+
# Install #
82+
###########
83+
84+
include(GNUInstallDirs)
85+
86+
install(
87+
FILES "${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.h"
88+
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
89+
)
90+
include(InstallRequiredSystemLibraries)
91+
set(CPACK_BUNDLE_NAME "${PROJECT_NAME}")
92+
set(CPACK_PACKAGE_VENDOR "Samuel Marks")
93+
set(CPACK_PACKAGE_DESCRIPTION "string functions from newer standards / common non-standards for C89")
94+
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "${CPACK_PACKAGE_DESCRIPTION}")
95+
if (APPLE)
96+
set(CPACK_BUNDLE_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Info.plist")
97+
set(CPACK_BUNDLE_ICON "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Info.plist")
98+
set(CPACK_PACKAGE_ICON "${CMAKE_CURRENT_SOURCE_DIR}/cmake/CustomVolumeIcon.icns")
99+
endif (APPLE)
100+
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/cmake/LICENSE.txt")
101+
set(CPACK_PACKAGE_VERSION_MAJOR "${${PROJECT_NAME}_VERSION_MAJOR}")
102+
set(CPACK_PACKAGE_VERSION_MINOR "${${PROJECT_NAME}_VERSION_MINOR}")
103+
set(CPACK_RESOURCE_FILE_README "${CMAKE_CURRENT_SOURCE_DIR}/cmake/README.txt")
104+
set(CPACK_RESOURCE_FILE_WELCOME "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Welcome.txt")
105+
set(CPACK_PACKAGE_CONTACT "https://github.com/offscale/${PROJECT_NAME}")
106+
107+
include(CPack)
108+
include(CMakePackageConfigHelpers)
109+
110+
# generate the config file that is includes the exports
111+
configure_package_config_file(
112+
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/Config.cmake.in"
113+
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
114+
INSTALL_DESTINATION "${CMAKE_INSTALL_DATADIR}/${PROJECT_NAME}"
115+
NO_SET_AND_CHECK_MACRO
116+
NO_CHECK_REQUIRED_COMPONENTS_MACRO
117+
)
118+
119+
# generate the version file for the config file
120+
write_basic_package_version_file(
121+
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake"
122+
VERSION "${${PROJECT_NAME}_VERSION_MAJOR}.${${PROJECT_NAME}_VERSION_MINOR}"
123+
COMPATIBILITY AnyNewerVersion
124+
)
125+
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
126+
DESTINATION "${CMAKE_INSTALL_DATADIR}/${PROJECT_NAME}")

0 commit comments

Comments
 (0)