diff --git a/README.md b/README.md index 0da6496..7e2c0e1 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,11 @@ Common C libraries and data structures. (C99) Each folder is stand-alone and contains a single .h .c pair. There is no build, copy .h .c files you want. +Libraries are portable, see [test](#test) section for details. + +As a general rule, all libraries report errors back to users (e.g out of memory). +If a library uses heap memory, you can plug your allocator. + ### List | Library | Description | @@ -58,7 +63,7 @@ cmake .. -DSANITIZER=address && make && make check mkdir build; cd build; cmake .. -DSANITIZER=undefined && make && make check -#coverage, requires GCC. +#coverage, requires GCC and lcov mkdir build; cd build; cmake .. -DCMAKE_BUILD_TYPE=Coverage; make; make coverage diff --git a/array/sc_array.h b/array/sc_array.h index 48b0127..2332722 100644 --- a/array/sc_array.h +++ b/array/sc_array.h @@ -32,6 +32,8 @@ #include #include +#define SC_ARRAY_VERSION "1.0.0" + #ifdef SC_HAVE_CONFIG_H #include "config.h" #else diff --git a/buffer/sc_buf.h b/buffer/sc_buf.h index 2b8d2f9..a4a69ff 100644 --- a/buffer/sc_buf.h +++ b/buffer/sc_buf.h @@ -31,6 +31,8 @@ #include #include +#define SC_BUF_VERSION "1.0.0" + #ifdef SC_HAVE_CONFIG_H #include "config.h" #else diff --git a/condition/sc_cond.h b/condition/sc_cond.h index 422d85e..ef610ef 100644 --- a/condition/sc_cond.h +++ b/condition/sc_cond.h @@ -27,6 +27,8 @@ #include +#define SC_COND_VERSION "1.0.0" + #if defined(_WIN32) || defined(_WIN64) #include #else diff --git a/crc32/CMakeLists.txt b/crc32/CMakeLists.txt index 2833e5e..a371a4e 100644 --- a/crc32/CMakeLists.txt +++ b/crc32/CMakeLists.txt @@ -28,6 +28,14 @@ enable_testing() add_executable(${PROJECT_NAME}_test crc32_test.c sc_crc32.c) +if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8") + check_c_compiler_flag(-msse4.2 HAVE_CRC32_HARDWARE) + if (${HAVE_CRC32_HARDWARE}) + target_compile_options(${PROJECT_NAME}_test PRIVATE -msse4.2) + target_compile_definitions(${PROJECT_NAME}_test PRIVATE -DHAVE_CRC32C) + endif () +endif() + if ("${CMAKE_C_COMPILER_ID}" STREQUAL "Clang" OR "${CMAKE_C_COMPILER_ID}" STREQUAL "AppleClang" OR "${CMAKE_C_COMPILER_ID}" STREQUAL "GNU") diff --git a/crc32/sc_crc32.c b/crc32/sc_crc32.c index dfeb62d..9c5e879 100644 --- a/crc32/sc_crc32.c +++ b/crc32/sc_crc32.c @@ -42,6 +42,7 @@ #define CRC32_POLY 0x82f63b78 #ifdef HAVE_CRC32C +#include #include /* Multiply a matrix times a vector over the Galois field of two elements, diff --git a/crc32/sc_crc32.h b/crc32/sc_crc32.h index 484af3d..6b7b920 100644 --- a/crc32/sc_crc32.h +++ b/crc32/sc_crc32.h @@ -27,6 +27,8 @@ #include +#define SC_CRC32_VERSION "1.0.0" + /** * Call once globally. */ diff --git a/heap/sc_heap.h b/heap/sc_heap.h index 9b76371..8c27763 100644 --- a/heap/sc_heap.h +++ b/heap/sc_heap.h @@ -29,6 +29,8 @@ #include #include +#define SC_HEAP_VERSION "1.0.0" + #ifdef SC_HAVE_CONFIG_H #include "config.h" #else diff --git a/ini/sc_ini.h b/ini/sc_ini.h index 52d2ed7..2390d4a 100644 --- a/ini/sc_ini.h +++ b/ini/sc_ini.h @@ -29,6 +29,8 @@ #include #include +#define SC_INI_VERSION "1.0.0" + // Set max line length. If a line is longer, it will be truncated silently. #define SC_INI_MAX_LINE_LEN 1024 diff --git a/linked-list/sc_list.h b/linked-list/sc_list.h index 7b5c89f..f0858b3 100644 --- a/linked-list/sc_list.h +++ b/linked-list/sc_list.h @@ -28,6 +28,7 @@ #include #include +#define SC_LIST_VERSION "1.0.0" struct sc_list { diff --git a/logger/sc_log.h b/logger/sc_log.h index d4083a5..0a51757 100644 --- a/logger/sc_log.h +++ b/logger/sc_log.h @@ -31,6 +31,8 @@ #include #include +#define SC_LOG_VERSION "1.0.0" + enum sc_log_level { SC_LOG_DEBUG, diff --git a/map/sc_map.h b/map/sc_map.h index ca80f75..2321637 100644 --- a/map/sc_map.h +++ b/map/sc_map.h @@ -31,6 +31,8 @@ #include #include +#define SC_MAP_VERSION "1.0.0" + #ifdef SC_HAVE_CONFIG_H #include "config.h" #else diff --git a/memory-map/sc_mmap.h b/memory-map/sc_mmap.h index e32b02f..544ee05 100644 --- a/memory-map/sc_mmap.h +++ b/memory-map/sc_mmap.h @@ -29,6 +29,8 @@ #include #include +#define SC_MMAP_VERSION "1.0.0" + #if defined(_WIN32) #include diff --git a/mutex/sc_mutex.h b/mutex/sc_mutex.h index de300df..6f51197 100644 --- a/mutex/sc_mutex.h +++ b/mutex/sc_mutex.h @@ -25,6 +25,8 @@ #ifndef SC_MUTEX_H #define SC_MUTEX_H +#define SC_MUTEX_VERSION "1.0.0" + #if defined(_WIN32) || defined(_WIN64) #include #else diff --git a/option/sc_option.h b/option/sc_option.h index 17da2bb..0823e74 100644 --- a/option/sc_option.h +++ b/option/sc_option.h @@ -28,6 +28,8 @@ #include #include +#define SC_OPTION_VERSION "1.0.0" + struct sc_option_item { const char letter; diff --git a/perf/sc_perf.h b/perf/sc_perf.h index aacb71e..06db9a8 100644 --- a/perf/sc_perf.h +++ b/perf/sc_perf.h @@ -28,6 +28,8 @@ #include #include +#define SC_PERF_VERSION "1.0.0" + #define SC_PERF_HW_CACHE(CACHE, OP, RESULT) \ ((PERF_COUNT_HW_CACHE_##CACHE) | (PERF_COUNT_HW_CACHE_OP_##OP << 8u) | \ (PERF_COUNT_HW_CACHE_RESULT_##RESULT << 16u)) diff --git a/queue/sc_queue.h b/queue/sc_queue.h index e754b15..c9c1096 100644 --- a/queue/sc_queue.h +++ b/queue/sc_queue.h @@ -32,6 +32,8 @@ #include #include +#define SC_QUEUE_VERSION "1.0.0" + #ifdef SC_HAVE_CONFIG_H #include "config.h" #else diff --git a/sc/sc.h b/sc/sc.h index 6d75bc3..dcd5f5e 100644 --- a/sc/sc.h +++ b/sc/sc.h @@ -28,6 +28,8 @@ #include #include +#define SC_VERSION "1.0.0" + #define sc_max(a, b) (((a) > (b)) ? (a) : (b)) #define sc_min(a, b) (((a) > (b)) ? (b) : (a)) diff --git a/signal/sc_signal.h b/signal/sc_signal.h index 0e4e716..66ad7af 100644 --- a/signal/sc_signal.h +++ b/signal/sc_signal.h @@ -29,6 +29,8 @@ #include #include +#define SC_SIGNAL_VERSION "1.0.0" + /** * Set shutdown fd here. When shutdown signal is received e.g SIGINT, SIGTERM. * Signal handler will write 1 byte to shutdown fd. So, your app can detect diff --git a/socket/sc_sock.c b/socket/sc_sock.c index 0ba5fc5..9569aa5 100644 --- a/socket/sc_sock.c +++ b/socket/sc_sock.c @@ -83,15 +83,36 @@ int sc_sock_set_blocking(struct sc_sock *sock, bool blocking) return rc == 0 ? 0 : -1; } +int sc_sock_startup() +{ + int rc; + WSADATA data; + + rc = WSAStartup(MAKEWORD(2, 2), &data); + if (rc != 0 || (LOBYTE(data.wVersion) != 2 || HIBYTE(data.wVersion) != 2)) { + return -1; + } + + return 0; +} + +int sc_sock_cleanup() +{ + int rc; + + rc = WSACleanup(); + return rc != 0 ? -1 : 0; +} + #else #include #include #include #include + #include #include #include - #include #define sc_close(n) close(n) #define sc_unlink(n) unlink(n) @@ -101,6 +122,16 @@ int sc_sock_set_blocking(struct sc_sock *sock, bool blocking) #define SC_EINPROGRESS EINPROGRESS #define SC_EINTR EINTR +int sc_sock_startup() +{ + return 0; +} + +int sc_sock_cleanup() +{ + return 0; +} + static int sc_sock_err() { return errno; @@ -1336,11 +1367,11 @@ int sc_sock_poll_term(struct sc_sock_poll *p) return 0; } -static int sc_sock_poll_expand(struct sc_sock_poll* p) +static int sc_sock_poll_expand(struct sc_sock_poll *p) { int cap, rc = 0; - void** data = NULL; - struct pollfd* ev = NULL; + void **data = NULL; + struct pollfd *ev = NULL; if (p->count == p->cap) { if (p->cap >= SC_SIZE_MAX / 2) { @@ -1362,7 +1393,7 @@ static int sc_sock_poll_expand(struct sc_sock_poll* p) p->data = data; for (int i = p->cap; i < cap; i++) { - p->events[i].fd = SC_INVALID; + p->events[i].fd = SC_INVALID; } p->cap = cap; @@ -1483,14 +1514,14 @@ uint32_t sc_sock_poll_event(struct sc_sock_poll *p, int i) return events; } -int sc_sock_poll_wait(struct sc_sock_poll* p, int timeout) +int sc_sock_poll_wait(struct sc_sock_poll *p, int timeout) { int n, rc = p->cap; timeout = (timeout == -1) ? 16 : timeout; do { - n = WSAPoll(p->events, (ULONG)p->cap, timeout); + n = WSAPoll(p->events, (ULONG) p->cap, timeout); } while (n < 0 && errno == EINTR); if (n == SC_INVALID) { diff --git a/socket/sc_sock.h b/socket/sc_sock.h index 818ec4b..1e958f9 100644 --- a/socket/sc_sock.h +++ b/socket/sc_sock.h @@ -28,6 +28,8 @@ #include #include +#define SC_SOCK_VERSION "1.0.0" + #ifdef SC_HAVE_CONFIG_H #include "config.h" #else @@ -90,6 +92,18 @@ struct sc_sock char err[128]; }; +/** + * Call once when your application starts. + * @return 0 on success, negative on failure. + */ +int sc_sock_startup(); + +/** + * Call once before your application terminates + * @return 0 on success, negative on failure. + */ +int sc_sock_cleanup(); + /** * Initialize sock * diff --git a/socket/sock_test.c b/socket/sock_test.c index 5f2e023..5cb6d47 100644 --- a/socket/sock_test.c +++ b/socket/sock_test.c @@ -1471,13 +1471,8 @@ int main() assert(sc_mutex_init(&mutex) == 0); #endif -#if defined(_WIN32) || defined(_WIN64) - WSADATA data; + assert(sc_sock_startup() == 0); - int rc = WSAStartup(MAKEWORD(2, 2), &data); - assert(rc == 0); - assert(LOBYTE(data.wVersion) == 2 && HIBYTE(data.wVersion) == 2); -#endif test1(); test_ip4(); @@ -1498,10 +1493,7 @@ int main() test_err(); test_poll_mass(); -#if defined(_WIN32) || defined(_WIN64) - rc = WSACleanup(); - assert(rc == 0); -#endif + assert(sc_sock_cleanup() == 0); #ifdef SC_HAVE_WRAP assert(sc_mutex_term(&mutex) == 0); diff --git a/string/sc_str.h b/string/sc_str.h index 5b8b65b..c8441fd 100644 --- a/string/sc_str.h +++ b/string/sc_str.h @@ -29,6 +29,8 @@ #include #include +#define SC_STR_VERSION "1.0.0" + #ifdef SC_HAVE_CONFIG_H #include "config.h" #else diff --git a/thread/sc_thread.h b/thread/sc_thread.h index f54ced9..b0d843e 100644 --- a/thread/sc_thread.h +++ b/thread/sc_thread.h @@ -24,6 +24,8 @@ #ifndef SC_THREAD_H #define SC_THREAD_H +#define SC_THREAD_VERSION "1.0.0" + #if defined(_WIN32) || defined(_WIN64) #include diff --git a/time/sc_time.h b/time/sc_time.h index c596835..5f0b1d9 100644 --- a/time/sc_time.h +++ b/time/sc_time.h @@ -24,6 +24,8 @@ #ifndef SC_TIME_H #define SC_TIME_H +#define SC_TIME_VERSION "1.0.0" + #include /** diff --git a/timer/sc_timer.h b/timer/sc_timer.h index 0b7d738..4ae757e 100644 --- a/timer/sc_timer.h +++ b/timer/sc_timer.h @@ -25,6 +25,8 @@ #ifndef SC_TIMER_H #define SC_TIMER_H +#define SC_TIMER_VERSION "1.0.0" + #include #include #include diff --git a/uri/sc_uri.h b/uri/sc_uri.h index 461967d..eefd76c 100644 --- a/uri/sc_uri.h +++ b/uri/sc_uri.h @@ -24,6 +24,8 @@ #ifndef SC_URI_H #define SC_URI_H +#define SC_URI_VERSION "1.0.0" + #ifdef SC_HAVE_CONFIG_H #include "config.h" #else