From 711a548cecd667426836011c05d1a51fe2e52fbb Mon Sep 17 00:00:00 2001 From: tezc Date: Sun, 14 Feb 2021 16:19:26 +0300 Subject: [PATCH 1/5] add version --- array/sc_array.h | 2 ++ buffer/sc_buf.h | 2 ++ condition/sc_cond.h | 2 ++ crc32/sc_crc32.h | 2 ++ heap/sc_heap.h | 2 ++ ini/sc_ini.h | 2 ++ linked-list/sc_list.h | 1 + logger/sc_log.h | 2 ++ map/sc_map.h | 2 ++ memory-map/sc_mmap.h | 2 ++ mutex/sc_mutex.h | 2 ++ option/sc_option.h | 2 ++ perf/sc_perf.h | 2 ++ queue/sc_queue.h | 2 ++ sc/sc.h | 2 ++ signal/sc_signal.h | 2 ++ socket/sc_sock.h | 2 ++ string/sc_str.h | 2 ++ thread/sc_thread.h | 2 ++ time/sc_time.h | 2 ++ timer/sc_timer.h | 2 ++ uri/sc_uri.h | 2 ++ 22 files changed, 43 insertions(+) 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/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.h b/socket/sc_sock.h index 818ec4b..b8d056c 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 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 From 10dc07669a44dfa2d66cee5246d35c2d844d7934 Mon Sep 17 00:00:00 2001 From: tezc Date: Sun, 14 Feb 2021 16:29:50 +0300 Subject: [PATCH 2/5] crc32 hardware, sock startup/cleanup --- crc32/CMakeLists.txt | 10 ++++++++++ crc32/sc_crc32.c | 1 + socket/sc_sock.c | 45 +++++++++++++++++++++++++++++++++++++------- socket/sc_sock.h | 12 ++++++++++++ socket/sock_test.c | 12 ++---------- 5 files changed, 63 insertions(+), 17 deletions(-) diff --git a/crc32/CMakeLists.txt b/crc32/CMakeLists.txt index 2833e5e..dd0bd0c 100644 --- a/crc32/CMakeLists.txt +++ b/crc32/CMakeLists.txt @@ -28,6 +28,16 @@ enable_testing() add_executable(${PROJECT_NAME}_test crc32_test.c sc_crc32.c) +include(CheckCCompilerFlag) + +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/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 b8d056c..1e958f9 100644 --- a/socket/sc_sock.h +++ b/socket/sc_sock.h @@ -92,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); From 22c23afb0638f59b806b98833d02789553fffff1 Mon Sep 17 00:00:00 2001 From: tezc Date: Sun, 14 Feb 2021 17:41:16 +0300 Subject: [PATCH 3/5] readme --- README.md | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 0da6496..da8d4b8 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,8 @@ 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. + ### List | Library | Description | @@ -32,6 +34,17 @@ There is no build, copy .h .c files you want. | **[timer](timer)** | Hashed timing wheel implementation with fast poll / cancel ops | | **[uri](uri)** | A basic uri parser | +### Details +- Most libraries are around a few hundreds lines of code. +- You don't have to build library, you can copy paste pieces you want. + This is good because : + - You don't have to deal with library build process. + - You don't bloat your build, e.g you just want a logger and nothing else, + then you just copy logger. + - As a bonus, compilers generate better code when source is available. +- All libraries report errors back to users (e.g out of memory). +- If a library uses heap memory, you can plug your allocator. + ### Test [![codecov](https://codecov.io/gh/tezc/sc/branch/master/graph/badge.svg?token=O8ZHQ0XZ30)](https://codecov.io/gh/tezc/sc) @@ -58,7 +71,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 From c374a6ef71eb4a7c3fbbc85b8bc63ffdee1cea72 Mon Sep 17 00:00:00 2001 From: tezc Date: Sun, 14 Feb 2021 17:43:45 +0300 Subject: [PATCH 4/5] remove duplicate include --- crc32/CMakeLists.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/crc32/CMakeLists.txt b/crc32/CMakeLists.txt index dd0bd0c..a371a4e 100644 --- a/crc32/CMakeLists.txt +++ b/crc32/CMakeLists.txt @@ -28,8 +28,6 @@ enable_testing() add_executable(${PROJECT_NAME}_test crc32_test.c sc_crc32.c) -include(CheckCCompilerFlag) - if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8") check_c_compiler_flag(-msse4.2 HAVE_CRC32_HARDWARE) if (${HAVE_CRC32_HARDWARE}) From 153aa10f20dc9bd63c7108be39f8090e859b3780 Mon Sep 17 00:00:00 2001 From: tezc Date: Sun, 14 Feb 2021 17:48:32 +0300 Subject: [PATCH 5/5] readme --- README.md | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index da8d4b8..7e2c0e1 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,10 @@ 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. +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 @@ -34,17 +37,6 @@ Libraries are portable, see [test](#test) section for details. | **[timer](timer)** | Hashed timing wheel implementation with fast poll / cancel ops | | **[uri](uri)** | A basic uri parser | -### Details -- Most libraries are around a few hundreds lines of code. -- You don't have to build library, you can copy paste pieces you want. - This is good because : - - You don't have to deal with library build process. - - You don't bloat your build, e.g you just want a logger and nothing else, - then you just copy logger. - - As a bonus, compilers generate better code when source is available. -- All libraries report errors back to users (e.g out of memory). -- If a library uses heap memory, you can plug your allocator. - ### Test [![codecov](https://codecov.io/gh/tezc/sc/branch/master/graph/badge.svg?token=O8ZHQ0XZ30)](https://codecov.io/gh/tezc/sc)