From ee0a2e7e1965200ec5968ec310bee429db819dde Mon Sep 17 00:00:00 2001 From: Mitya Selivanov Date: Sun, 3 Sep 2023 22:20:31 +0200 Subject: Remove const --- build_and_test.sh | 35 + gen_inl.c | 75 +- include/kit.inl.h | 2870 +++++++++++++++++++++++++++++-- source/kit/array_ref.c | 18 +- source/kit/array_ref.h | 39 +- source/kit/bigint.h | 210 ++- source/kit/condition_variable.h | 2 +- source/kit/dynamic_array.h | 18 +- source/kit/file.c | 84 +- source/kit/input_buffer.c | 37 +- source/kit/input_stream.c | 2 +- source/kit/input_stream.h | 4 +- source/kit/mersenne_twister_64.c | 14 +- source/kit/mersenne_twister_64.h | 2 +- source/kit/mutex.h | 2 +- source/kit/secure_random.c | 24 +- source/kit/secure_random.h | 2 - source/kit/sha256.c | 16 +- source/kit/sha256.h | 2 +- source/kit/sockets.h | 9 - source/kit/string_ref.h | 17 +- source/kit/thread.posix.c | 2 +- source/tests/_static.c | 2 +- source/tests/array_ref.test.c | 6 +- source/tests/cpp.cpp | 13 - source/tests/duration.test.c | 19 + source/tests/input_stream.test.c | 4 +- source/tests/lower_bound.test.c | 78 +- source/tests/main.test.c | 3 +- source/tests/move_back.test.c | 8 +- source/tests/signals.cpp | 29 - source/tests/test_cpp.cpp | 13 + source/tests/test_duration.test.c | 19 - source/tests/test_signals.cpp | 29 + source/tests/test_too_many_assertions.c | 13 + source/tests/test_too_many_tests.c | 14 + source/tests/too_many_assertions.c | 13 - source/tests/too_many_tests.c | 14 - 38 files changed, 3148 insertions(+), 613 deletions(-) delete mode 100644 source/tests/cpp.cpp create mode 100644 source/tests/duration.test.c delete mode 100644 source/tests/signals.cpp create mode 100644 source/tests/test_cpp.cpp delete mode 100644 source/tests/test_duration.test.c create mode 100644 source/tests/test_signals.cpp create mode 100644 source/tests/test_too_many_assertions.c create mode 100644 source/tests/test_too_many_tests.c delete mode 100644 source/tests/too_many_assertions.c delete mode 100644 source/tests/too_many_tests.c diff --git a/build_and_test.sh b/build_and_test.sh index e78ef2d..88f155b 100644 --- a/build_and_test.sh +++ b/build_and_test.sh @@ -9,3 +9,38 @@ gcc -c -o "build/kit_test.o" "source/kit_test/_static.c" ar rcs "build/libkit_test.a" "build/kit_test.o" gcc -o "build/kit_test_suite" "source/tests/_static.c" -Lbuild -lkit -lkit_test +gcc -o "build/test_too_many_assertions" "source/tests/test_too_many_assertions.c" -Lbuild -lkit -lkit_test +gcc -o "build/test_too_many_tests" "source/tests/test_too_many_tests.c" -Lbuild -lkit -lkit_test +g++ -o "build/test_cpp" "source/tests/test_cpp.cpp" -Lbuild -lkit -lkit_test +g++ -o "build/test_signals" "source/tests/test_signals.cpp" -Lbuild -lkit -lkit_test + +./build/kit_test_suite + +./build/test_too_many_assertions >/dev/null +if [ $? -eq 0 ]; then + echo "too many assertions - OK" +else + echo "too many assertions - FAIL" +fi + +./build/test_too_many_tests >/dev/null +if [ $? -eq 0 ]; then + echo "too many tests - OK" +else + echo "too many tests - FAIL" +fi + +./build/test_cpp >/dev/null +if [ $? -eq 0 ]; then + echo "cpp - OK" +else + echo "cpp - FAIL" +fi + +./build/test_signals 2>&1 >/dev/null +if [ $? -eq 0 ]; then + echo "signals - OK" +else + echo "signals - FAIL" +fi + diff --git a/gen_inl.c b/gen_inl.c index 116c5f5..94256ab 100644 --- a/gen_inl.c +++ b/gen_inl.c @@ -8,27 +8,56 @@ exit #include #include -char const *const SOURCES[] = { - "./source/kit/status.h", "./source/kit/allocator.h", - "./source/kit/array_ref.h", "./source/kit/dynamic_array.h", - "./source/kit/string_ref.h", "./source/kit/file.h", - "./source/kit/allocator.c", "./source/kit/array_ref.c", - "./source/kit/dynamic_array.c", "./source/kit/file.c" -}; - -char const *repeat(int n, char c) { +char *HEADERS[] = { "source/kit/types.h", + "source/kit/status.h", + "source/kit/allocator.h", + "source/kit/thread_defs.h", + "source/kit/thread.h", + "source/kit/atomic.h", + "source/kit/mutex.h", + "source/kit/condition_variable.h", + "source/kit/array_ref.h", + "source/kit/string_ref.h", + "source/kit/dynamic_array.h", + "source/kit/lower_bound.h", + "source/kit/move_back.h", + "source/kit/bigint.h", + "source/kit/input_stream.h", + "source/kit/input_buffer.h", + "source/kit/async_function.h", + "source/kit/file.h", + "source/kit/mersenne_twister_64.h", + "source/kit/secure_random.h", + "source/kit/sha256.h", + "source/kit/sockets.h" }; + +char *IMPL[] = { "source/kit/allocator.c", + "source/kit/thread.posix.c", + "source/kit/thread.win32.c", + "source/kit/atomic.win32.c", + "source/kit/mutex.c", + "source/kit/condition_variable.c", + "source/kit/dynamic_array.c", + "source/kit/input_stream.c", + "source/kit/input_buffer.c", + "source/kit/file.c", + "source/kit/mersenne_twister_64.c", + "source/kit/secure_random.c", + "source/kit/sha256.c" }; + +char *repeat(int n, char c) { static char buf[200]; for (int i = 0; i < n && i < 199; i++) buf[i] = c; buf[n] = '\0'; return buf; } -int skip_whitespaces(char const *const line, int i) { +int skip_whitespaces(char *line, int i) { while (line[i] == ' ') i++; return i; } -int skip(char const *const line, int i, char const *const s) { +int skip(char *line, int i, char *s) { int j = 0; while (s[j] != '\0') { if (line[i] != s[j]) @@ -39,7 +68,7 @@ int skip(char const *const line, int i, char const *const s) { return i; } -int is_local_include(char const *const line) { +int is_local_include(char *line) { if (line[0] != '#') return 0; int i = skip_whitespaces(line, 1); @@ -52,12 +81,12 @@ int is_local_include(char const *const line) { return 1; } -int is_empty_line(char const *const line) { +int is_empty_line(char *line) { int i = skip_whitespaces(line, 0); return line[i] == '\0' || line[i] == '\n'; } -int write_file(FILE *out, char const *const source) { +int write_file(FILE *out, char *source) { assert(out != NULL); assert(source != NULL); @@ -99,8 +128,9 @@ int write_file(FILE *out, char const *const source) { } int main(int argc, char **argv) { - char const *const out_file = "./include/kit.inl.h"; - FILE *out = fopen(out_file, "wt"); + char *out_file = "./include/kit.inl.h"; + FILE *out = fopen(out_file, "wt"); + if (out == NULL) { fprintf(stderr, "Can't write: %s\n", out_file); return 1; @@ -109,12 +139,21 @@ int main(int argc, char **argv) { fprintf(out, "#ifndef KIT_INL_H\n"); fprintf(out, "#define KIT_INL_H\n"); - for (int i = 0; i < sizeof SOURCES / sizeof *SOURCES; i++) - if (write_file(out, SOURCES[i]) != 0) { + for (int i = 0; i < sizeof HEADERS / sizeof *HEADERS; i++) + if (write_file(out, HEADERS[i]) != 0) { fclose(out); return 1; } + fprintf(out, "#ifdef KIT_IMPLEMENTATION\n"); + + for (int i = 0; i < sizeof IMPL / sizeof *IMPL; i++) + if (write_file(out, IMPL[i]) != 0) { + fclose(out); + return 1; + } + + fprintf(out, "#endif\n"); fprintf(out, "#endif\n"); fclose(out); diff --git a/include/kit.inl.h b/include/kit.inl.h index 44d22eb..06eaafd 100644 --- a/include/kit.inl.h +++ b/include/kit.inl.h @@ -2,7 +2,25 @@ #define KIT_INL_H /********************************************************************* * * - * File: ./source/kit/status.h * + * File: source/kit/types.h * + * * + *********************************************************************/ +#ifndef KIT_TYPES_H +#define KIT_TYPES_H +typedef signed char i8; +typedef signed short i16; +typedef signed int i32; +typedef signed long long i64; +typedef unsigned char u8; +typedef unsigned short u16; +typedef unsigned int u32; +typedef unsigned long long u64; +typedef float f32; +typedef double f64; +#endif +/********************************************************************* + * * + * File: source/kit/status.h * * * *********************************************************************/ #ifndef KIT_STATUS_H @@ -18,20 +36,25 @@ enum { KIT_ERROR_UNLINK_FAILED, KIT_ERROR_FILE_ALREADY_EXISTS, KIT_ERROR_FILE_DO_NOT_EXIST, - KIT_ERROR_PATH_TOO_LONG + KIT_ERROR_PATH_TOO_LONG, + KIT_ERROR_SOCKETS_STARTUP_FAILED, + KIT_ERROR_SOCKET_CONTROL_FAILED }; -typedef int kit_status_t; +typedef signed int kit_status_t; #ifdef __cplusplus } #endif #endif /********************************************************************* * * - * File: ./source/kit/allocator.h * + * File: source/kit/allocator.h * * * *********************************************************************/ #ifndef KIT_ALLOCATOR_H #define KIT_ALLOCATOR_H +#ifndef _GNU_SOURCE +# define _GNU_SOURCE +#endif #include #ifdef __cplusplus extern "C" { @@ -48,7 +71,7 @@ typedef struct { /* Application should implement this function if custom allocator * dispatch is enabled. * - * See KIT_ENABLE_CUSTOM_ALLOC_DISPATCH + * See KIT_ENABLE_CUSTOM_ALLOC_DISPATCH macro. */ void *kit_alloc_dispatch(kit_allocator_t alloc, int request, ptrdiff_t size, ptrdiff_t previous_size, @@ -60,47 +83,367 @@ kit_allocator_t kit_alloc_default(void); #endif /********************************************************************* * * - * File: ./source/kit/array_ref.h * + * File: source/kit/thread_defs.h * + * * + *********************************************************************/ +#ifndef KIT_THREAD_DEFS_H +#define KIT_THREAD_DEFS_H +#ifdef __cplusplus +extern "C" { +#endif +enum { + thrd_success = 0, + thrd_timedout, + thrd_error, + thrd_busy, + thrd_nomem, + thrd_wrong_stack_size +}; +#ifdef __cplusplus +} +#endif +#endif +/********************************************************************* + * * + * File: source/kit/thread.h * + * * + *********************************************************************/ +#ifndef KIT_THREAD_H +#define KIT_THREAD_H +#ifndef KIT_DISABLE_SYSTEM_THREADS +# ifndef _GNU_SOURCE +# define _GNU_SOURCE +# endif +# include +# include +# if defined(__cplusplus) +# define _Noreturn [[noreturn]] +# elif defined(_MSC_VER) +# define _Noreturn __declspec(noreturn) +# endif +# if !defined(_WIN32) || defined(__CYGWIN__) +# include +# endif +# ifndef _Thread_local +# if defined(__cplusplus) +/* C++11 doesn't need `_Thread_local` keyword or macro */ +# elif !defined(__STDC_NO_THREADS__) +/* threads are optional in C11, _Thread_local present in this + * condition */ +# elif defined(_MSC_VER) +# define _Thread_local __declspec(thread) +# elif defined(__GNUC__) +# define _Thread_local __thread +# else +/* Leave _Thread_local undefined so that use of _Thread_local would + * not promote to a non-thread-local global variable + */ +# endif +# endif +# if !defined(__cplusplus) +/* + * C11 thread_local() macro + * C++11 and above already have thread_local keyword + */ +# ifndef thread_local +# if _MSC_VER +# define thread_local __declspec(thread) +# else +# define thread_local _Thread_local +# endif +# endif +# endif +# ifdef __cplusplus +extern "C" { +# endif +typedef void (*tss_dtor_t)(void *); +typedef int (*thrd_start_t)(void *); +# if defined(_WIN32) && !defined(__CYGWIN__) +typedef struct { + void *handle; +} thrd_t; +typedef unsigned long tss_t; +# else +typedef pthread_t thrd_t; +typedef pthread_key_t tss_t; +# endif +int thrd_create(thrd_t *, thrd_start_t, void *); +int thrd_create_with_stack(thrd_t *, thrd_start_t, void *, + ptrdiff_t stack_size); +thrd_t thrd_current(void); +int thrd_detach(thrd_t); +int thrd_equal(thrd_t, thrd_t); +_Noreturn void thrd_exit(int); +int thrd_join(thrd_t, int *); +int thrd_sleep(const struct timespec *, struct timespec *); +void thrd_yield(void); +# ifdef __cplusplus +} +# endif +#endif +#endif +/********************************************************************* + * * + * File: source/kit/atomic.h * + * * + *********************************************************************/ +#ifndef KIT_ATOMIC_H +#define KIT_ATOMIC_H +#ifndef _GNU_SOURCE +# define _GNU_SOURCE +#endif +#include +#ifndef _MSC_VER +# include +# define KIT_ATOMIC(type_) type_ _Atomic +#else +# include +# define KIT_ATOMIC(type_) type_ volatile +# ifdef __cplusplus +extern "C" { +# endif +enum { + memory_order_relaxed, + memory_order_consume, + memory_order_acquire, + memory_order_release, + memory_order_acq_rel, + memory_order_seq_cst +}; +void kit_atomic_store_explicit_8(uint8_t volatile *var, uint8_t value, + int memory_order); +void kit_atomic_store_explicit_16(uint16_t volatile *var, + uint16_t value, int memory_order); +void kit_atomic_store_explicit_32(uint32_t volatile *var, + uint32_t value, int memory_order); +void kit_atomic_store_explicit_64(uint64_t volatile *var, + uint64_t value, int memory_order); +uint8_t kit_atomic_load_explicit_8(uint8_t volatile *var, + int memory_order); +uint16_t kit_atomic_load_explicit_16(uint16_t volatile *var, + int memory_order); +uint32_t kit_atomic_load_explicit_32(uint32_t volatile *var, + int memory_order); +uint64_t kit_atomic_load_explicit_64(uint64_t volatile *var, + int memory_order); +uint8_t kit_atomic_exchange_explicit_8(uint8_t volatile *var, + uint8_t value, + int memory_order); +uint16_t kit_atomic_exchange_explicit_16(uint16_t volatile *var, + uint16_t value, + int memory_order); +uint32_t kit_atomic_exchange_explicit_32(uint32_t volatile *var, + uint32_t value, + int memory_order); +uint64_t kit_atomic_exchange_explicit_64(uint64_t volatile *var, + uint64_t value, + int memory_order); +uint8_t kit_atomic_fetch_add_explicit_8(uint8_t volatile *var, + uint8_t value, + int memory_order); +uint16_t kit_atomic_fetch_add_explicit_16(uint16_t volatile *var, + uint16_t value, + int memory_order); +uint32_t kit_atomic_fetch_add_explicit_32(uint32_t volatile *var, + uint32_t value, + int memory_order); +uint64_t kit_atomic_fetch_add_explicit_64(uint64_t volatile *var, + uint64_t value, + int memory_order); +# define atomic_store_explicit(var_, value_, memory_order_) \ + do { \ + assert(sizeof *(var_) == 1 || sizeof *(var_) == 2 || \ + sizeof *(var_) == 4 || sizeof *(var_) == 8); \ + if (sizeof *(var_) == 1) \ + kit_atomic_store_explicit_8((uint8_t volatile *) (var_), \ + (uint8_t) (value_), \ + (memory_order_)); \ + if (sizeof *(var_) == 2) \ + kit_atomic_store_explicit_16((uint16_t volatile *) (var_), \ + (uint16_t) (value_), \ + (memory_order_)); \ + if (sizeof *(var_) == 4) \ + kit_atomic_store_explicit_32((uint32_t volatile *) (var_), \ + (uint32_t) (value_), \ + (memory_order_)); \ + if (sizeof *(var_) == 8) \ + kit_atomic_store_explicit_64((uint64_t volatile *) (var_), \ + (uint64_t) (value_), \ + (memory_order_)); \ + } while (0) +# define atomic_load_explicit(var_, memory_order_) \ + (assert(sizeof *(var_) == 1 || sizeof *(var_) == 2 || \ + sizeof *(var_) == 4 || sizeof *(var_) == 8), \ + (sizeof *(var_) == 1 \ + ? kit_atomic_load_explicit_8((uint8_t volatile *) (var_), \ + (memory_order_)) \ + : sizeof *(var_) == 2 \ + ? kit_atomic_load_explicit_16( \ + (uint16_t volatile *) (var_), (memory_order_)) \ + : sizeof *(var_) == 4 \ + ? kit_atomic_load_explicit_32( \ + (uint32_t volatile *) (var_), (memory_order_)) \ + : kit_atomic_load_explicit_64( \ + (uint64_t volatile *) (var_), (memory_order_)))) +# define atomic_exchange_explicit(var_, value_, memory_order_) \ + (assert(sizeof *(var_) == 1 || sizeof *(var_) == 2 || \ + sizeof *(var_) == 4 || sizeof *(var_) == 8), \ + (sizeof *(var_) == 1 ? kit_atomic_exchange_explicit_8( \ + (uint8_t volatile *) (var_), \ + (uint8_t) (value_), (memory_order_)) \ + : sizeof *(var_) == 2 \ + ? kit_atomic_exchange_explicit_16( \ + (uint16_t volatile *) (var_), (uint16_t) (value_), \ + (memory_order_)) \ + : sizeof *(var_) == 4 \ + ? kit_atomic_exchange_explicit_32( \ + (uint32_t volatile *) (var_), (uint32_t) (value_), \ + (memory_order_)) \ + : kit_atomic_exchange_explicit_64( \ + (uint64_t volatile *) (var_), (uint64_t) (value_), \ + (memory_order_)))) +# define atomic_fetch_add_explicit(var_, value_, memory_order_) \ + (assert(sizeof *(var_) == 1 || sizeof *(var_) == 2 || \ + sizeof *(var_) == 4 || sizeof *(var_) == 8), \ + (sizeof *(var_) == 1 ? kit_atomic_fetch_add_explicit_8( \ + (uint8_t volatile *) (var_), \ + (uint8_t) (value_), (memory_order_)) \ + : sizeof *(var_) == 2 \ + ? kit_atomic_fetch_add_explicit_16( \ + (uint16_t volatile *) (var_), (uint16_t) (value_), \ + (memory_order_)) \ + : sizeof *(var_) == 4 \ + ? kit_atomic_fetch_add_explicit_32( \ + (uint32_t volatile *) (var_), (uint32_t) (value_), \ + (memory_order_)) \ + : kit_atomic_fetch_add_explicit_64( \ + (uint64_t volatile *) (var_), (uint64_t) (value_), \ + (memory_order_)))) +#endif +#ifndef KIT_DISABLE_SHORT_NAMES +# define ATOMIC KIT_ATOMIC +#endif +#ifdef __cplusplus +} +#endif +#endif +/********************************************************************* + * * + * File: source/kit/mutex.h * + * * + *********************************************************************/ +#ifndef KIT_MUTEX_H +#define KIT_MUTEX_H +#ifndef KIT_DISABLE_SYSTEM_THREADS +# ifndef _GNU_SOURCE +# define _GNU_SOURCE +# endif +# include +# if !defined(_WIN32) || defined(__CYGWIN__) +# include +# endif +# ifdef __cplusplus +extern "C" { +# endif +# if defined(_WIN32) && !defined(__CYGWIN__) +typedef struct { + void *DebugInfo; + long LockCount; + long RecursionCount; + void *OwningThread; + void *LockSemaphore; + uintptr_t SpinCount; +} mtx_t; +# else +typedef pthread_mutex_t mtx_t; +# endif +enum { + mtx_plain = 0, + mtx_recursive = 1, + mtx_timed = 2, +}; +void mtx_destroy(mtx_t *mtx_); +int mtx_init(mtx_t *mtx_, int); +int mtx_lock(mtx_t *mtx_); +int mtx_timedlock(mtx_t *__restrict mtx_, + struct timespec const *__restrict); +int mtx_trylock(mtx_t *mtx_); +int mtx_unlock(mtx_t *mtx_); +# ifdef __cplusplus +} +# endif +#endif +#endif +/********************************************************************* + * * + * File: source/kit/condition_variable.h * + * * + *********************************************************************/ +#ifndef KIT_CONDITION_VARIABLE_H +#define KIT_CONDITION_VARIABLE_H +#ifndef KIT_DISABLE_SYSTEM_THREADS +# ifdef __cplusplus +extern "C" { +# endif +# if defined(_WIN32) && !defined(__CYGWIN__) +typedef struct { + void *Ptr; +} cnd_t; +typedef struct { + volatile uintptr_t status; +} once_flag; +# else +typedef pthread_cond_t cnd_t; +typedef pthread_once_t once_flag; +# endif +void call_once(once_flag *, void (*)(void)); +int cnd_broadcast(cnd_t *); +void cnd_destroy(cnd_t *); +int cnd_init(cnd_t *); +int cnd_signal(cnd_t *); +int cnd_timedwait(cnd_t *__restrict, mtx_t *__restrict mtx_, + struct timespec const *__restrict); +int cnd_wait(cnd_t *, mtx_t *mtx_); +# ifdef __cplusplus +} +# endif +#endif +#endif +/********************************************************************* + * * + * File: source/kit/array_ref.h * * * *********************************************************************/ #ifndef KIT_ARRAY_REF_H #define KIT_ARRAY_REF_H +#ifndef _GNU_SOURCE +# define _GNU_SOURCE +#endif #include #include #ifdef __cplusplus extern "C" { #endif -typedef int (*kit_ar_compare_fn)(void const *left, void const *right); +typedef int (*kit_ar_compare_fn)(void *left, void *right); int kit_ar_equal_bytes(ptrdiff_t left_element_size, - ptrdiff_t left_size, void const *left_data, + ptrdiff_t left_size, void *left_data, ptrdiff_t right_element_size, - ptrdiff_t right_size, void const *right_data); + ptrdiff_t right_size, void *right_data); int kit_ar_compare(ptrdiff_t left_element_size, ptrdiff_t left_size, - void const *left_data, - ptrdiff_t right_element_size, ptrdiff_t right_size, - void const *right_data, kit_ar_compare_fn compare); -#define KIT_AR_MUT(type_) \ - struct { \ - ptrdiff_t size; \ - type_ *values; \ - } + void *left_data, ptrdiff_t right_element_size, + ptrdiff_t right_size, void *right_data, + kit_ar_compare_fn compare); #define KIT_AR(type_) \ - struct { \ - ptrdiff_t size; \ - type_ const *values; \ + struct { \ + ptrdiff_t size; \ + type_ *values; \ } -#define KIT_AR_MUT_WRAP(name_, element_type_, array_) \ +#define KIT_AR_WRAP(name_, element_type_, array_) \ struct { \ ptrdiff_t size; \ element_type_ *values; \ } name_ = { .size = (sizeof(array_) / sizeof((array_)[0])), \ .values = (array_) } -#define KIT_AR_WRAP(name_, element_type_, array_) \ - struct { \ - ptrdiff_t size; \ - element_type_ const *values; \ - } name_ = { .size = (sizeof(array_) / sizeof((array_)[0])), \ - .values = (array_) } #define KIT_AR_EQUAL(left_, right_) \ kit_ar_equal_bytes(sizeof((left_).values[0]), (left_).size, \ (left_).values, sizeof((right_).values[0]), \ @@ -114,9 +457,7 @@ int kit_ar_compare(ptrdiff_t left_element_size, ptrdiff_t left_size, # define ar_compare_fn kit_ar_compare_fn # define ar_equal_bytes kit_ar_equal_bytes # define ar_compare kit_ar_compare -# define AR_MUT KIT_AR_MUT # define AR KIT_AR -# define AR_MUT_WRAP KIT_AR_MUT_WRAP # define AR_WRAP KIT_AR_WRAP # define AR_EQUAL KIT_AR_EQUAL # define AR_COMPARE KIT_AR_COMPARE @@ -127,7 +468,68 @@ int kit_ar_compare(ptrdiff_t left_element_size, ptrdiff_t left_size, #endif /********************************************************************* * * - * File: ./source/kit/dynamic_array.h * + * File: source/kit/string_ref.h * + * * + *********************************************************************/ +#ifndef KIT_STRING_REF_H +#define KIT_STRING_REF_H +#include +#ifdef __cplusplus +extern "C" { +#endif +typedef KIT_AR(char) kit_string_ref_t; +typedef kit_string_ref_t kit_str_t; +#ifdef __GNUC__ +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wunused-function" +# pragma GCC diagnostic ignored "-Wunknown-pragmas" +# pragma GCC push_options +# pragma GCC optimize("O3") +#endif +static kit_str_t kit_str(ptrdiff_t size, char *static_string) { + kit_str_t s = { .size = size, .values = static_string }; + return s; +} +/* Make a barbarian string for C standard library functions. + * Not thread safe. + * Use with caution. + */ +static char *kit_make_bs(kit_str_t s) { + static char buf[8][4096]; + static int index = 0; + ptrdiff_t n = s.size; + if (n > 4095) + n = 4095; + memcpy(buf[index], s.values, n); + buf[index][n] = '\0'; + char *result = buf[index]; + index = (index + 1) % 8; + return result; +} +#ifdef __GNUC__ +# pragma GCC pop_options +# pragma GCC diagnostic pop +#endif +#define KIT_SZ(static_str_) \ + kit_str(sizeof(static_str_) - 1, (static_str_)) +#define KIT_WRAP_BS(string_) kit_str(strlen(string_), (string_)) +#define KIT_WRAP_STR(string_) \ + kit_str((string_).size, (string_).values) +#ifndef KIT_DISABLE_SHORT_NAMES +# define BS(string_) kit_make_bs(KIT_WRAP_STR(string_)) +# define string_ref_t kit_string_ref_t +# define str_t kit_str_t +# define SZ KIT_SZ +# define WRAP_BS KIT_WRAP_BS +# define WRAP_STR KIT_WRAP_STR +#endif +#ifdef __cplusplus +} +#endif +#endif +/********************************************************************* + * * + * File: source/kit/dynamic_array.h * * * *********************************************************************/ #ifndef KIT_DYNAMIC_ARRAY_H @@ -179,20 +581,20 @@ void kit_da_resize(kit_da_void_t *array, ptrdiff_t element_size, sizeof((array_).values[0]), size_) /* Append a value to dynamic array. */ -#define KIT_DA_APPEND(array_, value_) \ - do { \ - ptrdiff_t const kit_index_back_ = (array_).size; \ - KIT_DA_RESIZE((array_), kit_index_back_ + 1); \ - if (kit_index_back_ < (array_).size) \ - (array_).values[kit_index_back_] = (value_); \ +#define KIT_DA_APPEND(array_, value_) \ + do { \ + ptrdiff_t kit_index_back_ = (array_).size; \ + KIT_DA_RESIZE((array_), kit_index_back_ + 1); \ + if (kit_index_back_ < (array_).size) \ + (array_).values[kit_index_back_] = (value_); \ } while (0) /* Insert a value into dynamic array. */ #define KIT_DA_INSERT(array_, index_, value_) \ do { \ - ptrdiff_t kit_i_; \ - ptrdiff_t const kit_index_back_ = (array_).size; \ - ptrdiff_t const kit_indert_n_ = (index_); \ + ptrdiff_t kit_i_; \ + ptrdiff_t kit_index_back_ = (array_).size; \ + ptrdiff_t kit_indert_n_ = (index_); \ KIT_DA_RESIZE((array_), kit_index_back_ + 1); \ if (kit_index_back_ + 1 == (array_).size) { \ for (kit_i_ = kit_index_back_; kit_i_ > kit_indert_n_; \ @@ -231,19 +633,121 @@ typedef KIT_DA(char) kit_string_t; #endif /********************************************************************* * * - * File: ./source/kit/string_ref.h * + * File: source/kit/lower_bound.h * * * *********************************************************************/ -#ifndef KIT_STRING_REF_H -#define KIT_STRING_REF_H +#ifndef KIT_LOWER_BOUND_H +#define KIT_LOWER_BOUND_H +#ifdef __cplusplus +extern "C" { +#endif +#define KIT_LOWER_BOUND_INL(return_val, size, ...) \ + do { \ + ptrdiff_t position_ = 0; \ + ptrdiff_t count_ = (size); \ + while (count_ > 0) { \ + ptrdiff_t const delta_ = count_ / 2; \ + ptrdiff_t const index_ = position_ + delta_; \ + if (__VA_ARGS__) { \ + position_ += delta_ + 1; \ + count_ -= delta_ + 1; \ + } else \ + count_ = delta_; \ + } \ + (return_val) = position_; \ + } while (0) +#define KIT_LOWER_BOUND(return_val, array, value, op) \ + KIT_LOWER_BOUND_INL(return_val, (array).size, \ + (op) ((array).values[index_], (value))) +#define KIT_LOWER_BOUND_REF(return_val, array, value, op) \ + KIT_LOWER_BOUND_INL(return_val, (array).size, \ + (op) ((array).values + index_, (value))) +#ifndef KIT_DISABLE_SHORT_NAMES +# define LOWER_BOUND_INL KIT_LOWER_BOUND_INL +# define LOWER_BOUND KIT_LOWER_BOUND +# define LOWER_BOUND_REF KIT_LOWER_BOUND_REF +#endif +#ifdef __cplusplus +} +#endif +#endif +/********************************************************************* + * * + * File: source/kit/move_back.h * + * * + *********************************************************************/ +#ifndef KIT_MOVE_BACK_H +#define KIT_MOVE_BACK_H +#ifndef _GNU_SOURCE +# define _GNU_SOURCE +#endif #include #ifdef __cplusplus extern "C" { #endif -typedef KIT_AR_MUT(char) kit_string_mut_t; -typedef KIT_AR(char) kit_string_ref_t; -typedef kit_string_mut_t kit_out_str_t; -typedef kit_string_ref_t kit_str_t; +#define KIT_MOVE_BACK_INL(new_size, array, ...) \ + do { \ + ptrdiff_t index_; \ + ptrdiff_t end_ = (array).size; \ + unsigned char temp_[sizeof *(array).values]; \ + for (index_ = 0; index_ < end_;) { \ + if (__VA_ARGS__) { \ + end_--; \ + if (index_ != end_) { \ + memcpy(temp_, (array).values + end_, \ + sizeof *(array).values); \ + (array).values[end_] = (array).values[index_]; \ + memcpy((array).values + index_, temp_, \ + sizeof *(array).values); \ + } \ + } else \ + index_++; \ + } \ + (new_size) = end_; \ + } while (0) +#define KIT_MOVE_BACK(new_size, array, value, cond) \ + KIT_MOVE_BACK_INL(new_size, array, \ + (cond) ((array).values[index_], (value))) +#define KIT_MOVE_BACK_REF(new_size, array, value, cond) \ + KIT_MOVE_BACK_INL(new_size, array, \ + (cond) ((array).values + index_, (value))) +#ifndef KIT_DISABLE_SHORT_NAMES +# define MOVE_BACK_INL KIT_MOVE_BACK_INL +# define MOVE_BACK KIT_MOVE_BACK +# define MOVE_BACK_REF KIT_MOVE_BACK_REF +#endif +#ifdef __cplusplus +} +#endif +#endif +/********************************************************************* + * * + * File: source/kit/bigint.h * + * * + *********************************************************************/ +#ifndef KIT_BIGINT_H +#define KIT_BIGINT_H +#include +#include +#ifdef __cplusplus +extern "C" { +#endif +#ifndef KIT_BIGINT_SIZE +# define KIT_BIGINT_SIZE 64 +#endif +#if __STDC_VERSION__ >= 199901L +static_assert(sizeof(uint8_t) == 1, "uint8_t size should be 1 byte"); +static_assert(sizeof(uint32_t) == 4, + "uint32_t size should be 4 bytes"); +static_assert(sizeof(uint64_t) == 8, + "uint64_t size should be 8 bytes"); +static_assert(KIT_BIGINT_SIZE > 0 && (KIT_BIGINT_SIZE % 8) == 0, + "Invalid big integer size"); +#endif +typedef struct { + uint32_t v[KIT_BIGINT_SIZE / 4]; +} kit_bigint_t; +typedef uint_fast8_t kit_bit_t; #ifdef __GNUC__ # pragma GCC diagnostic push # pragma GCC diagnostic ignored "-Wunused-function" @@ -251,45 +755,496 @@ typedef kit_string_ref_t kit_str_t; # pragma GCC push_options # pragma GCC optimize("O3") #endif -static kit_str_t kit_str(ptrdiff_t const size, - char const *const static_string) { - kit_str_t const s = { .size = size, .values = static_string }; - return s; +static kit_bigint_t kit_bi_uint32(uint32_t x) { + kit_bigint_t z; + memset(&z, 0, sizeof z); + z.v[0] = x; + return z; } -/* Make a barbarian string for C standard library functions. - * Not thread safe. - * Use with caution. +static kit_bigint_t kit_bi_uint64(uint64_t x) { + kit_bigint_t z; + memset(&z, 0, sizeof z); + z.v[0] = (uint32_t) (x & 0xffffffff); + z.v[1] = (uint32_t) (x >> 32); + return z; +} +static kit_bigint_t kit_bi_int32(int32_t x) { + kit_bigint_t z; + memset(&z, x < 0 ? -1 : 0, sizeof z); + z.v[0] = x; + return z; +} +static kit_bigint_t kit_bi_int64(int64_t x) { + kit_bigint_t z; + memset(&z, x < 0 ? -1 : 0, sizeof z); + z.v[0] = (uint32_t) (((uint64_t) x) & 0xffffffff); + z.v[1] = (uint32_t) (((uint64_t) x) >> 32); + return z; +} +static int kit_bi_is_zero(kit_bigint_t x) { + ptrdiff_t i; + for (i = 0; i < KIT_BIGINT_SIZE / 4; i++) + if (x.v[i] != 0) + return 0; + return 1; +} +static int kit_bi_is_neg(kit_bigint_t x) { + return (x.v[KIT_BIGINT_SIZE / 4 - 1] & 0x80000000) != 0; +} +static int kit_bi_equal(kit_bigint_t x, kit_bigint_t y) { + return kit_ar_equal_bytes(1, KIT_BIGINT_SIZE, x.v, 1, + KIT_BIGINT_SIZE, y.v); +} +static int kit_bi_compare(kit_bigint_t x, kit_bigint_t y) { + ptrdiff_t i; + for (i = KIT_BIGINT_SIZE / 4 - 1; i >= 0; i--) + if (x.v[i] < y.v[i]) + return -1; + else if (x.v[i] > y.v[i]) + return 1; + return 0; +} +static ptrdiff_t kit_bi_significant_bit_count(kit_bigint_t x) { + ptrdiff_t n = KIT_BIGINT_SIZE / 4 - 1; + while (n > 0 && x.v[n] == 0) n--; + uint32_t val = x.v[n]; + if (val == 0) + return 0; + ptrdiff_t bits = (val & 0x80000000u) != 0 ? 32 + : (val & 0x40000000u) != 0 ? 31 + : (val & 0x20000000u) != 0 ? 30 + : (val & 0x10000000u) != 0 ? 29 + : (val & 0x8000000u) != 0 ? 28 + : (val & 0x4000000u) != 0 ? 27 + : (val & 0x2000000u) != 0 ? 26 + : (val & 0x1000000u) != 0 ? 25 + : (val & 0x800000u) != 0 ? 24 + : (val & 0x400000u) != 0 ? 23 + : (val & 0x200000u) != 0 ? 22 + : (val & 0x100000u) != 0 ? 21 + : (val & 0x80000u) != 0 ? 20 + : (val & 0x40000u) != 0 ? 19 + : (val & 0x20000u) != 0 ? 18 + : (val & 0x10000u) != 0 ? 17 + : (val & 0x8000u) != 0 ? 16 + : (val & 0x4000u) != 0 ? 15 + : (val & 0x2000u) != 0 ? 14 + : (val & 0x1000u) != 0 ? 13 + : (val & 0x800u) != 0 ? 12 + : (val & 0x400u) != 0 ? 11 + : (val & 0x200u) != 0 ? 10 + : (val & 0x100u) != 0 ? 9 + : (val & 0x80u) != 0 ? 8 + : (val & 0x40u) != 0 ? 7 + : (val & 0x20u) != 0 ? 6 + : (val & 0x10u) != 0 ? 5 + : (val & 0x08u) != 0 ? 4 + : (val & 0x04u) != 0 ? 3 + : (val & 0x02u) != 0 ? 2 + : 1; + return n * 32 + bits; +} +static kit_bigint_t kit_bi_and(kit_bigint_t x, kit_bigint_t y) { + kit_bigint_t z; + ptrdiff_t i; + for (i = 0; i < KIT_BIGINT_SIZE / 4; i++) z.v[i] = x.v[i] & y.v[i]; + return z; +} +static kit_bigint_t kit_bi_or(kit_bigint_t x, kit_bigint_t y) { + kit_bigint_t z; + ptrdiff_t i; + for (i = 0; i < KIT_BIGINT_SIZE / 4; i++) z.v[i] = x.v[i] | y.v[i]; + return z; +} +static kit_bigint_t kit_bi_xor(kit_bigint_t x, kit_bigint_t y) { + kit_bigint_t z; + ptrdiff_t i; + for (i = 0; i < KIT_BIGINT_SIZE / 4; i++) z.v[i] = x.v[i] ^ y.v[i]; + return z; +} +static kit_bigint_t kit_bi_shl_uint(kit_bigint_t x, uint32_t y) { + kit_bigint_t z; + memset(&z, 0, sizeof z); + ptrdiff_t words = (ptrdiff_t) (y / 32); + ptrdiff_t bits = (ptrdiff_t) (y % 32); + ptrdiff_t i; + for (i = words; i < KIT_BIGINT_SIZE / 4; i++) { + z.v[i] |= x.v[i - words] << bits; + if (bits != 0 && i + 1 < KIT_BIGINT_SIZE / 4) + z.v[i + 1] = x.v[i - words] >> (32 - bits); + } + return z; +} +static kit_bigint_t kit_bi_shr_uint(kit_bigint_t x, uint32_t y) { + kit_bigint_t z; + memset(&z, 0, sizeof z); + ptrdiff_t words = (ptrdiff_t) (y / 32); + ptrdiff_t bits = (ptrdiff_t) (y % 32); + ptrdiff_t i; + for (i = KIT_BIGINT_SIZE / 4 - words - 1; i >= 0; i--) { + z.v[i] |= x.v[i + words] >> bits; + if (bits != 0 && i > 0) + z.v[i - 1] = x.v[i + words] << (32 - bits); + } + return z; +} +static kit_bit_t kit_bi_carry(uint32_t x, uint32_t y, + kit_bit_t carry) { + assert(carry == 0 || carry == 1); + return 0xffffffffu - x < y || 0xffffffffu - x - y < carry ? 1 : 0; +} +/* Increment. */ -static char const *kit_make_bs(kit_str_t const s) { - static char buf[8][4096]; - static int index = 0; - ptrdiff_t n = s.size; - if (n > 4095) - n = 4095; - memcpy(buf[index], s.values, n); - buf[index][n] = '\0'; - char const *result = buf[index]; - index = (index + 1) % 8; - return result; +static kit_bigint_t kit_bi_inc(kit_bigint_t x) { + kit_bigint_t z; + kit_bit_t carry = 1; + ptrdiff_t i; + for (i = 0; i < KIT_BIGINT_SIZE / 4; i++) { + z.v[i] = x.v[i] + carry; + carry = kit_bi_carry(x.v[i], 0, carry); + } + return z; +} +/* Decrement + */ +static kit_bigint_t kit_bi_dec(kit_bigint_t x) { + kit_bigint_t z; + kit_bit_t carry = 0; + ptrdiff_t i; + for (i = 0; i < KIT_BIGINT_SIZE / 4; i++) { + z.v[i] = x.v[i] + 0xffffffff + carry; + carry = kit_bi_carry(x.v[i], 0xffffffff, carry); + } + return z; +} +/* Addition. + */ +static kit_bigint_t kit_bi_add(kit_bigint_t x, kit_bigint_t y) { + kit_bigint_t z; + kit_bit_t carry = 0; + ptrdiff_t i; + for (i = 0; i < KIT_BIGINT_SIZE / 4; i++) { + z.v[i] = x.v[i] + y.v[i] + carry; + carry = kit_bi_carry(x.v[i], y.v[i], carry); + } + return z; +} +/* Negation. + */ +static kit_bigint_t kit_bi_neg(kit_bigint_t x) { + kit_bigint_t y; + kit_bit_t carry = 1; + ptrdiff_t i; + for (i = 0; i < KIT_BIGINT_SIZE / 4; i++) { + y.v[i] = (x.v[i] ^ 0xffffffff) + carry; + carry = kit_bi_carry(x.v[i] ^ 0xffffffff, 0, carry); + } + return y; +} +/* Subtraction. + */ +static kit_bigint_t kit_bi_sub(kit_bigint_t x, kit_bigint_t y) { + kit_bigint_t z; + kit_bit_t carry = 1; + ptrdiff_t i; + for (i = 0; i < KIT_BIGINT_SIZE / 4; i++) { + z.v[i] = x.v[i] + (y.v[i] ^ 0xffffffff) + carry; + carry = kit_bi_carry(x.v[i], (y.v[i] ^ 0xffffffff), carry); + } + return z; +} +static kit_bigint_t kit_bi_mul_uint32(kit_bigint_t x, uint32_t y) { + kit_bigint_t z; + ptrdiff_t i, k; + memset(&z, 0, sizeof z); + if (y != 0) + for (i = 0; i < KIT_BIGINT_SIZE / 4; i++) { + if (x.v[i] == 0) + continue; + uint64_t carry = ((uint64_t) x.v[i]) * ((uint64_t) y); + for (k = i; k < KIT_BIGINT_SIZE / 4 && carry != 0; k++) { + uint64_t sum = ((uint64_t) z.v[k]) + carry; + z.v[k] = ((uint32_t) (sum & 0xffffffffull)); + carry = sum >> 32; + } + } + return z; +} +/* Multiplication. + */ +static kit_bigint_t kit_bi_mul(kit_bigint_t x, kit_bigint_t y) { + kit_bigint_t z; + ptrdiff_t i, j, k; + memset(&z, 0, sizeof z); + for (i = 0; i < KIT_BIGINT_SIZE / 4; i++) { + if (x.v[i] == 0) + continue; + for (j = 0; i + j < KIT_BIGINT_SIZE / 4; j++) { + if (y.v[j] == 0) + continue; + uint64_t carry = ((uint64_t) x.v[i]) * ((uint64_t) y.v[j]); + for (k = i + j; k < KIT_BIGINT_SIZE / 4 && carry != 0; k++) { + uint64_t sum = ((uint64_t) z.v[k]) + carry; + z.v[k] = ((uint32_t) (sum & 0xffffffffull)); + carry = sum >> 32; + } + } + } + return z; +} +typedef struct { + kit_bit_t undefined; + kit_bigint_t quotient; + kit_bigint_t remainder; +} kit_bi_division_t; +/* Unsigned division. + */ +static kit_bi_division_t kit_bi_udiv(kit_bigint_t x, kit_bigint_t y) { + kit_bi_division_t z; + memset(&z, 0, sizeof z); + ptrdiff_t y_bits = kit_bi_significant_bit_count(y); + if (y_bits == 0) { + z.undefined = 1; + return z; + } + ptrdiff_t x_bits = kit_bi_significant_bit_count(x); + ptrdiff_t shift = x_bits - y_bits; + z.remainder = x; + z.quotient = kit_bi_uint32(0); + y = kit_bi_shl_uint(y, (uint32_t) shift); + while (shift >= 0) { + if (kit_bi_compare(z.remainder, y) >= 0) { + z.remainder = kit_bi_sub(z.remainder, y); + z.quotient.v[shift / 32] |= (1u << (shift % 32)); + } + y = kit_bi_shr_uint(y, 1); + shift--; + } + return z; +} +/* Signed division. + * + * Remainder is always a non-negative value less than absolute value + * of y. + */ +static kit_bi_division_t kit_bi_div(kit_bigint_t x, kit_bigint_t y) { + int x_neg = kit_bi_is_neg(x); + int y_neg = kit_bi_is_neg(y); + kit_bigint_t x_abs = x_neg ? kit_bi_neg(x) : x; + kit_bigint_t y_abs = y_neg ? kit_bi_neg(y) : y; + if (x_neg == y_neg) + return kit_bi_udiv(x_abs, y_abs); + kit_bi_division_t z = kit_bi_udiv(x_abs, y_abs); + if (!kit_bi_is_zero(z.remainder) && !y_neg) + z.quotient = kit_bi_dec(kit_bi_neg(z.quotient)); + else + z.quotient = kit_bi_neg(z.quotient); + return z; +} +static void kit_bi_serialize(kit_bigint_t in, uint8_t *out) { + ptrdiff_t i; + assert(out != NULL); + for (i = 0; i < KIT_BIGINT_SIZE / 4; i++) { + out[i * 4] = (uint8_t) (in.v[i] & 0xff); + out[i * 4 + 1] = (uint8_t) ((in.v[i] >> 8) & 0xff); + out[i * 4 + 2] = (uint8_t) ((in.v[i] >> 16) & 0xff); + out[i * 4 + 3] = (uint8_t) ((in.v[i] >> 24) & 0xff); + } +} +static kit_bigint_t kit_bi_deserialize(uint8_t *in) { + ptrdiff_t i; + kit_bigint_t out; + assert(in != NULL); + memset(&out, 0, sizeof out); + for (i = 0; i < KIT_BIGINT_SIZE; i++) + out.v[i / 4] |= ((uint32_t) in[i]) << (8 * (i % 4)); + return out; +} +static uint8_t kit_bin_digit(char hex) { + assert(hex == '0' || hex == '1'); + return hex == '1' ? 1 : 0; +} +static kit_bigint_t kit_bi_from_bin(kit_str_t bin) { + kit_bigint_t z; + ptrdiff_t i; + memset(&z, 0, sizeof z); + for (i = 0; i < bin.size && i / 8 < KIT_BIGINT_SIZE; i++) { + uint8_t digit = kit_bin_digit(bin.values[bin.size - i - 1]); + z.v[i / 32] |= digit << (i % 32); + } + return z; +} +static uint8_t kit_dec_digit(char c) { + assert('c' >= '0' && c <= '9'); + return c >= '0' && c <= '9' ? (uint8_t) (c - '0') : 0; +} +static kit_bigint_t kit_bi_from_dec(kit_str_t dec) { + kit_bigint_t z = kit_bi_uint32(0); + kit_bigint_t factor = kit_bi_uint32(1); + ptrdiff_t i; + for (i = 0; i < dec.size; i++) { + uint32_t digit = kit_dec_digit(dec.values[dec.size - i - 1]); + z = kit_bi_add(z, kit_bi_mul_uint32(factor, digit)); + factor = kit_bi_mul_uint32(factor, 10); + } + return z; +} +static uint8_t kit_hex_digit(char hex) { + assert((hex >= '0' && hex <= '9') || (hex >= 'a' && hex <= 'f') || + (hex >= 'A' && hex <= 'F')); + if (hex >= '0' && hex <= '9') + return hex - '0'; + if (hex >= 'a' && hex <= 'f') + return hex - 'a'; + if (hex >= 'A' && hex <= 'F') + return hex - 'A'; + return 0; +} +static kit_bigint_t kit_bi_from_hex(kit_str_t hex) { + kit_bigint_t z; + ptrdiff_t i; + memset(&z, 0, sizeof z); + for (i = 0; i < hex.size && i / 2 < KIT_BIGINT_SIZE; i++) { + uint8_t digit = kit_hex_digit(hex.values[hex.size - i - 1]); + z.v[i / 8] |= digit << (4 * (i % 8)); + } + return z; +} +static uint8_t KIT_BASE32_DIGITS[] = { + ['1'] = 0, ['2'] = 1, ['3'] = 2, ['4'] = 3, ['5'] = 4, + ['6'] = 5, ['7'] = 6, ['8'] = 7, ['9'] = 8, ['a'] = 9, + ['b'] = 10, ['c'] = 11, ['d'] = 12, ['e'] = 13, ['f'] = 14, + ['g'] = 15, ['h'] = 16, ['j'] = 17, ['k'] = 18, ['m'] = 19, + ['n'] = 20, ['p'] = 21, ['q'] = 22, ['r'] = 23, ['s'] = 24, + ['t'] = 25, ['u'] = 26, ['v'] = 27, ['w'] = 28, ['x'] = 29, + ['y'] = 30, ['z'] = 31 +}; +static uint8_t kit_base32_digit(char c) { + assert(c >= '\0' && c < sizeof KIT_BASE32_DIGITS); + assert(c == '1' || + KIT_BASE32_DIGITS[(size_t) (unsigned char) c] != 0); + return c >= '\0' && c < sizeof KIT_BASE32_DIGITS + ? KIT_BASE32_DIGITS[(size_t) (unsigned char) c] + : 0; +} +static kit_bigint_t kit_bi_from_base32(kit_str_t base32) { + kit_bigint_t z; + ptrdiff_t i; + memset(&z, 0, sizeof z); + for (i = 0; i < base32.size; i++) { + z = kit_bi_shl_uint(z, 5 * i); + z.v[0] |= kit_base32_digit(base32.values[i]); + } + return z; +} +static uint8_t KIT_BASE58_DIGITS[] = { + ['1'] = 0, ['2'] = 1, ['3'] = 2, ['4'] = 3, ['5'] = 4, + ['6'] = 5, ['7'] = 6, ['8'] = 7, ['9'] = 8, ['A'] = 9, + ['B'] = 10, ['C'] = 11, ['D'] = 12, ['E'] = 13, ['F'] = 14, + ['G'] = 15, ['H'] = 16, ['J'] = 17, ['K'] = 18, ['L'] = 19, + ['M'] = 20, ['N'] = 21, ['P'] = 22, ['Q'] = 23, ['R'] = 24, + ['S'] = 25, ['T'] = 26, ['U'] = 27, ['V'] = 28, ['W'] = 29, + ['X'] = 30, ['Y'] = 31, ['Z'] = 32, ['a'] = 33, ['b'] = 34, + ['c'] = 35, ['d'] = 36, ['e'] = 37, ['f'] = 38, ['g'] = 39, + ['h'] = 40, ['i'] = 41, ['j'] = 42, ['k'] = 43, ['m'] = 44, + ['n'] = 45, ['o'] = 46, ['p'] = 47, ['q'] = 48, ['r'] = 49, + ['s'] = 50, ['t'] = 51, ['u'] = 52, ['v'] = 53, ['w'] = 54, + ['x'] = 55, ['y'] = 56, ['z'] = 57 +}; +static uint8_t kit_base58_digit(char c) { + assert(c >= '\0' && c < sizeof KIT_BASE58_DIGITS); + assert(c == '1' || + KIT_BASE58_DIGITS[(size_t) (unsigned char) c] != 0); + return c >= '\0' && c < sizeof KIT_BASE58_DIGITS + ? KIT_BASE58_DIGITS[(size_t) (unsigned char) c] + : 0; +} +static kit_bigint_t kit_bi_from_base58(kit_str_t base58) { + kit_bigint_t z = kit_bi_uint32(0); + kit_bigint_t factor = kit_bi_uint32(1); + ptrdiff_t i; + for (i = 0; i < base58.size; i++) { + uint32_t digit = kit_base58_digit( + base58.values[base58.size - i - 1]); + z = kit_bi_add(z, kit_bi_mul_uint32(factor, digit)); + factor = kit_bi_mul_uint32(factor, 58); + } + return z; } #ifdef __GNUC__ # pragma GCC pop_options # pragma GCC diagnostic pop #endif -#define KIT_SZ(static_str_) \ - kit_str(sizeof(static_str_) - 1, (static_str_)) -#define KIT_WRAP_BS(string_) kit_str(strlen(string_), (string_)) -#define KIT_WRAP_STR(string_) \ - kit_str((string_).size, (string_).values) +#define KIT_BIN(static_str_) \ + kit_bi_from_bin(kit_str(sizeof(static_str_) - 1, (static_str_))) +#define KIT_DEC(static_str_) \ + kit_bi_from_dec(kit_str(sizeof(static_str_) - 1, (static_str_))) +#define KIT_HEX(static_str_) \ + kit_bi_from_hex(kit_str(sizeof(static_str_) - 1, (static_str_))) +#define KIT_BASE32(static_str_) \ + kit_bi_from_base32(kit_str(sizeof(static_str_) - 1, (static_str_))) +#define KIT_BASE58(static_str_) \ + kit_bi_from_base58(kit_str(sizeof(static_str_) - 1, (static_str_))) #ifndef KIT_DISABLE_SHORT_NAMES -# define BS(string_) kit_make_bs(KIT_WRAP_STR(string_)) -# define string_mut_t kit_string_mut_t -# define string_ref_t kit_string_ref_t -# define out_str_t kit_out_str_t -# define str_t kit_str_t -# define SZ KIT_SZ -# define WRAP_BS KIT_WRAP_BS -# define WRAP_STR KIT_WRAP_STR +# define bigint_t kit_bigint_t +# define bi_uint32 kit_bi_uint32 +# define bi_uint64 kit_bi_uint64 +# define bi_int32 kit_bi_int32 +# define bi_int64 kit_bi_int64 +# define bi_is_zero kit_bi_is_zero +# define bi_is_neg kit_bi_is_neg +# define bi_equal kit_bi_equal +# define bi_compare kit_bi_compare +# define bi_carry kit_bi_carry +# define bi_inc kit_bi_inc +# define bi_dec kit_bi_dec +# define bi_add kit_bi_add +# define bi_neg kit_bi_neg +# define bi_sub kit_bi_sub +# define bi_mul kit_bi_mul +# define bi_div kit_bi_div +# define bi_serialize kit_bi_serialize +# define bi_deserialize kit_bi_deserialize +# define BIN KIT_BIN +# define DEC KIT_DEC +# define HEX KIT_HEX +# define BASE32 KIT_BASE32 +# define BASE58 KIT_BASE58 +#endif +#ifdef __cplusplus +} +#endif +#endif +/********************************************************************* + * * + * File: source/kit/input_stream.h * + * * + *********************************************************************/ +#ifndef KIT_INPUT_STREAM_H +#define KIT_INPUT_STREAM_H +#ifdef __cplusplus +extern "C" { +#endif +typedef ptrdiff_t (*kit_is_read_fn)(void *state, + kit_str_t destination); +typedef struct { + void *state; + kit_is_read_fn read; +} kit_is_handle_t; +kit_is_handle_t kit_is_wrap_string(kit_str_t string, + kit_allocator_t alloc); +void kit_is_destroy(kit_is_handle_t in); +#define KIT_IS_WRAP_STRING(string) \ + kit_is_wrap_string((string), kit_alloc_default()) +#define KIT_IS_READ(in, destination) \ + (in).read((in).state, (destination)) +#ifndef KIT_DISABLE_SHORT_NAMES +# define is_read_fn kit_is_read_fn +# define is_handle_t kit_is_handle_t +# define is_wrap_string kit_is_wrap_string +# define is_destroy kit_is_destroy +# define IS_WRAP_STRING KIT_IS_WRAP_STRING +# define IS_READ KIT_IS_READ #endif #ifdef __cplusplus } @@ -297,7 +1252,246 @@ static char const *kit_make_bs(kit_str_t const s) { #endif /********************************************************************* * * - * File: ./source/kit/file.h * + * File: source/kit/input_buffer.h * + * * + *********************************************************************/ +#ifndef KIT_INPUT_BUFFER_H +#define KIT_INPUT_BUFFER_H +#ifdef __cplusplus +extern "C" { +#endif +typedef struct { + kit_status_t status; + ptrdiff_t offset; + void *internal; + kit_string_t data; +} kit_ib_handle_t; +kit_ib_handle_t kit_ib_wrap(kit_is_handle_t upstream, + kit_allocator_t alloc); +kit_ib_handle_t kit_ib_read(kit_ib_handle_t buf, ptrdiff_t size); +typedef int (*kit_ib_read_condition_fn)(kit_str_t data); +kit_ib_handle_t kit_ib_read_while(kit_ib_handle_t buf, + kit_ib_read_condition_fn condition); +void kit_ib_destroy(kit_ib_handle_t buf); +#define KIT_IB_WRAP(upstream) \ + kit_ib_wrap(upstream, kit_alloc_default()) +#ifndef KIT_DISABLE_SHORT_NAMES +# define ib_handle_t kit_ib_handle_t +# define ib_read_condition_fn kit_ib_read_condition_fn +# define ib_wrap kit_ib_wrap +# define ib_read kit_ib_read +# define ib_read_while kit_ib_read_while +# define ib_destroy kit_ib_destroy +# define IB_WRAP KIT_IB_WRAP +#endif +#ifdef __cplusplus +} +#endif +#endif +/********************************************************************* + * * + * File: source/kit/async_function.h * + * * + *********************************************************************/ +#ifndef KIT_ASYNC_FUNCTION_H +#define KIT_ASYNC_FUNCTION_H +#ifndef _GNU_SOURCE +# define _GNU_SOURCE +#endif +#include +#include +#ifdef __cplusplus +extern "C" { +#endif +#ifdef __GNUC__ +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wunused-function" +# pragma GCC diagnostic ignored "-Wunknown-pragmas" +#endif +typedef struct { + int _; +} kit_af_void; +typedef void (*kit_af_state_machine)(void *self_void_); +#define KIT_AF_STATE_DATA \ + struct { \ + int _index; \ + ptrdiff_t _id; \ + kit_af_state_machine _state_machine; \ + } +typedef struct { + KIT_AF_STATE_DATA; +} kit_af_type_void; +#define KIT_AF_INTERNAL(coro_) (*((kit_af_type_void *) (coro_))) +#ifdef KIT_ENABLE_CUSTOM_ASYNC_FUNCTION_DISPATCH +/* Application should implement this function if custom async + * function dispatch is enabled. + * + * See KIT_ENABLE_CUSTOM_ASYNC_FUNCTION_DISPATCH macro. + */ +void kit_async_function_dispatch(void *promise); +#else +static void kit_async_function_dispatch(void *promise) { + /* Dynamic dispatch by default. + */ + KIT_AF_INTERNAL(promise)._state_machine(promise); +} +#endif +#ifdef __GNUC__ +# pragma GCC diagnostic pop +#endif +#define KIT_AF_STATE(ret_type_, name_, ...) \ + struct name_##_coro_state_ { \ + KIT_AF_STATE_DATA; \ + ret_type_ return_value; \ + __VA_ARGS__ \ + } +#define KIT_AF_DECL(name_) void name_(void *self_void_) +#define KIT_CORO_IMPL(name_) \ + KIT_AF_DECL(name_) { \ + struct name_##_coro_state_ *self = \ + (struct name_##_coro_state_ *) self_void_; \ + switch (self->_index) { \ + case 0:; +#define KIT_AF_LINE_() __LINE__ +#define KIT_CORO_END \ + } \ + self->_index = -1; \ + } +#define KIT_CORO_DECL(ret_type_, name_, ...) \ + KIT_AF_STATE(ret_type_, name_, __VA_ARGS__); \ + KIT_AF_DECL(name_) +#define KIT_CORO(ret_type_, name_, ...) \ + KIT_AF_STATE(ret_type_, name_, __VA_ARGS__); \ + KIT_CORO_IMPL(name_) +#define KIT_CORO_DECL_VOID(name_, ...) \ + KIT_CORO_DECL(kit_af_void, name_, __VA_ARGS__) +#define KIT_CORO_VOID(name_, ...) \ + KIT_CORO(kit_af_void, name_, __VA_ARGS__) +#define KIT_STATIC_CORO(ret_type_, name_, ...) \ + KIT_AF_STATE(ret_type_, name_, __VA_ARGS__); \ + static KIT_CORO_IMPL(name_) +#define KIT_STATIC_CORO_VOID(name_, ...) \ + KIT_STATIC_CORO(kit_af_void, name_, __VA_ARGS__) +#define KIT_AF_EXECUTE(promise_) \ + kit_async_function_dispatch(&(promise_)) +#define KIT_AF_NEXT(promise_) \ + (kit_async_function_dispatch(&(promise_)), (promise_).return_value) +#define KIT_AF_YIELD(...) \ + do { \ + self->_index = KIT_AF_LINE_(); \ + self->return_value = __VA_ARGS__; \ + return; \ + case KIT_AF_LINE_():; \ + } while (0) +#define KIT_AF_YIELD_VOID \ + do { \ + self->_index = KIT_AF_LINE_(); \ + return; \ + case KIT_AF_LINE_():; \ + } while (0) +#define KIT_AF_RETURN(...) \ + do { \ + self->_index = -1; \ + self->return_value = __VA_ARGS__; \ + return; \ + } while (0) +#define KIT_AF_RETURN_VOID \ + do { \ + self->_index = -1; \ + return; \ + } while (0) +#define KIT_AF_AWAIT(promise_) \ + do { \ + case KIT_AF_LINE_(): \ + if ((promise_)._index != -1) { \ + self->_index = KIT_AF_LINE_(); \ + kit_async_function_dispatch(&(promise_)); \ + } \ + if ((promise_)._index != -1) \ + return; \ + } while (0) +#define KIT_AF_YIELD_AWAIT(promise_) \ + do { \ + case KIT_AF_LINE_(): \ + if ((promise_)._index != -1) { \ + self->_index = KIT_AF_LINE_(); \ + kit_async_function_dispatch(&(promise_)); \ + self->return_value = (promise_).return_value; \ + return; \ + } \ + } while (0) +#define KIT_AF_TYPE(coro_) struct coro_##_coro_state_ +#define KIT_AF_INITIAL(id_, coro_) \ + ._index = 0, ._id = (id_), ._state_machine = (coro_) +#define KIT_AF_CREATE(promise_, coro_, ...) \ + KIT_AF_TYPE(coro_) \ + promise_ = { KIT_AF_INITIAL(0, coro_), __VA_ARGS__ } +#define KIT_AF_CREATE_ID(promise_, id_, ...) \ + KIT_AF_TYPE(coro_) \ + promise_ = { KIT_AF_INITIAL(id_, NULL), __VA_ARGS__ } +#define KIT_AF_INIT(promise_, coro_, ...) \ + do { \ + KIT_AF_CREATE(kit_af_temp_, coro_, __VA_ARGS__); \ + memcpy(&(promise_), &kit_af_temp_, sizeof kit_af_temp_); \ + } while (0) +#define KIT_AF_INIT_ID(promise_, id_, ...) \ + do { \ + KIT_AF_CREATE_ID(kit_af_temp_, id_, __VA_ARGS__); \ + memcpy(&(promise_), &kit_af_temp_, sizeof kit_af_temp_); \ + } while (0) +#define KIT_AF_FINISHED(promise_) ((promise_)._index == -1) +#define KIT_AF_FINISHED_N(return_, promises_, size_) \ + do { \ + int kit_af_index_; \ + (return_) = 1; \ + for (kit_af_index_ = 0; kit_af_index_ < (size_); \ + kit_af_index_++) \ + if (!KIT_AF_FINISHED((promises_)[kit_af_index_])) { \ + (return_) = 0; \ + break; \ + } \ + } while (0) +#define KIT_AF_FINISHED_ALL(return_, promises_) \ + KIT_AF_FINISHED_N((return_), (promises_), \ + sizeof(promises_) / sizeof((promises_)[0])) +#ifndef KIT_DISABLE_SHORT_NAMES +# define af_void kit_af_void +# define af_state_machine kit_af_state_machine +# define af_type_void kit_af_type_void +# define AF_STATE_DATA KIT_AF_STATE_DATA +# define AF_STATE KIT_AF_STATE +# define AF_DECL KIT_AF_DECL +# define CORO_IMPL KIT_CORO_IMPL +# define CORO_END KIT_CORO_END +# define CORO_DECL KIT_CORO_DECL +# define CORO KIT_CORO +# define CORO_DECL_VOID KIT_CORO_DECL_VOID +# define STATIC_CORO KIT_STATIC_CORO +# define STATIC_CORO_VOID KIT_STATIC_CORO_VOID +# define CORO_VOID KIT_CORO_VOID +# define AF_EXECUTE KIT_AF_EXECUTE +# define AF_NEXT KIT_AF_NEXT +# define AF_YIELD KIT_AF_YIELD +# define AF_YIELD_VOID KIT_AF_YIELD_VOID +# define AF_RETURN KIT_AF_RETURN +# define AF_RETURN_VOID KIT_AF_RETURN_VOID +# define AF_AWAIT KIT_AF_AWAIT +# define AF_YIELD_AWAIT KIT_AF_YIELD_AWAIT +# define AF_TYPE KIT_AF_TYPE +# define AF_INITIAL KIT_AF_INITIAL +# define AF_CREATE KIT_AF_CREATE +# define AF_INIT KIT_AF_INIT +# define AF_FINISHED KIT_AF_FINISHED +# define AF_FINISHED_N KIT_AF_FINISHED_N +# define AF_FINISHED_ALL KIT_AF_FINISHED_ALL +#endif +#ifdef __cplusplus +} +#endif +#endif +/********************************************************************* + * * + * File: source/kit/file.h * * * *********************************************************************/ #ifndef KIT_FILE_H @@ -314,11 +1508,6 @@ extern "C" { # define KIT_PATH_DELIM "/" # define KIT_ENV_HOME "HOME" #endif -typedef enum { - KIT_PATH_NONE, - KIT_PATH_FILE, - KIT_PATH_FOLDER -} kit_path_type_t; kit_string_t kit_path_norm(kit_str_t path, kit_allocator_t alloc); kit_string_t kit_path_join(kit_str_t left, kit_str_t right, kit_allocator_t alloc); @@ -332,6 +1521,11 @@ kit_status_t kit_file_remove(kit_str_t path); kit_status_t kit_file_remove_folder(kit_str_t path); kit_status_t kit_file_remove_recursive(kit_str_t path, kit_allocator_t alloc); +typedef enum { + KIT_PATH_NONE, + KIT_PATH_FILE, + KIT_PATH_FOLDER +} kit_path_type_t; kit_path_type_t kit_path_type(kit_str_t path); typedef struct { kit_status_t status; @@ -360,10 +1554,10 @@ void kit_path_list_destroy(kit_path_list_t list); # define file_remove kit_file_remove # define file_remove_folder kit_file_remove_folder # define file_remove_recursive kit_file_remove_recursive -# define path_type kit_path_type -# define file_size_result_t kit_file_size_result_t -# define file_size kit_file_size # define path_type_t kit_path_type_t +# define path_type kit_path_type +# define file_info_t kit_file_info_t +# define file_info kit_file_info # define path_list_t kit_path_list_t # define file_enum_folder kit_file_enum_folder # define path_list_destroy kit_path_list_destroy @@ -380,7 +1574,195 @@ void kit_path_list_destroy(kit_path_list_t list); #endif /********************************************************************* * * - * File: ./source/kit/allocator.c * + * File: source/kit/mersenne_twister_64.h * + * * + *********************************************************************/ +#ifndef KIT_MERSENNE_TWISTER_64_H +#define KIT_MERSENNE_TWISTER_64_H +#ifndef _GNU_SOURCE +# define _GNU_SOURCE +#endif +#include +#include +#ifdef __cplusplus +extern "C" { +#endif +enum { + KIT_MT64_N = 312, +}; +typedef struct { + uint64_t mt[KIT_MT64_N]; + uint64_t index; +} kit_mt64_state_t; +void kit_mt64_init_array(kit_mt64_state_t *state, ptrdiff_t size, + uint64_t *seed); +void kit_mt64_init(kit_mt64_state_t *state, uint64_t seed); +void kit_mt64_rotate(kit_mt64_state_t *state); +uint64_t kit_mt64_generate(kit_mt64_state_t *state); +#ifndef KIT_DISABLE_SHORT_NAMES +# define mt64_state_t kit_mt64_state_t +# define mt64_init_array kit_mt64_init_array +# define mt64_init kit_mt64_init +# define mt64_rotate kit_mt64_rotate +# define mt64_generate kit_mt64_generate +#endif +#ifdef __cplusplus +} +#endif +#endif +/********************************************************************* + * * + * File: source/kit/secure_random.h * + * * + *********************************************************************/ +#ifndef KIT_SECURE_RANDOM_H +#define KIT_SECURE_RANDOM_H +#ifndef _GNU_SOURCE +# define _GNU_SOURCE +#endif +#include +#include +#ifdef __cplusplus +extern "C" { +#endif +void kit_secure_random(ptrdiff_t size, void *data); +#ifndef KIT_DISABLE_SHORT_NAMES +# define secure_random kit_secure_random +#endif +#ifdef __cplusplus +} +#endif +#endif +/********************************************************************* + * * + * File: source/kit/sha256.h * + * * + *********************************************************************/ +#ifndef KIT_SHA256_H +#define KIT_SHA256_H +#ifndef _GNU_SOURCE +# define _GNU_SOURCE +#endif +#include +#include +#ifdef __cplusplus +extern "C" { +#endif +enum { KIT_SHA256_BLOCK_SIZE = 32 }; +typedef struct { + uint8_t v[KIT_SHA256_BLOCK_SIZE]; +} kit_sha256_hash_t; +kit_sha256_hash_t kit_sha256(ptrdiff_t size, uint8_t *data); +#ifdef __cplusplus +} +#endif +#ifndef KIT_DISABLE_SHORT_NAMES +# define SHA256_BLOCK_SIZE KIT_SHA256_BLOCK_SIZE +# define sha256_hash_t kit_sha256_hash_t +# define sha256 kit_sha256 +#endif +#endif +/********************************************************************* + * * + * File: source/kit/sockets.h * + * * + *********************************************************************/ +#ifndef KIT_SOCKETS_H +#define KIT_SOCKETS_H +#ifndef _GNU_SOURCE +# define _GNU_SOURCE +#endif +#ifndef KIT_DISABLE_SYSTEM_SOCKETS +# ifdef __GNUC__ +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wunused-function" +# pragma GCC diagnostic ignored "-Wunknown-pragmas" +# endif +# if defined(_WIN32) && !defined(__CYGWIN__) +# define WIN32_LEAN_AND_MEAN +# include +# include +# define socket_t SOCKET +# define socklen_t int +# ifdef __cplusplus +extern "C" { +# endif +static kit_status_t kit_sockets_init(void) { + WSADATA data; + memset(&data, 0, sizeof data); + WORD version = MAKEWORD(2, 2); + return WSAStartup(version, &data) == ERROR_SUCCESS + ? KIT_OK + : KIT_ERROR_SOCKETS_STARTUP_FAILED; +} +static kit_status_t kit_sockets_cleanup(void) { + WSACleanup(); + return KIT_OK; +} +static int kit_socket_set_blocking(socket_t s) { + u_long flag = 0; + return ioctlsocket(s, FIONBIO, &flag) == 0 + ? KIT_OK + : KIT_ERROR_SOCKET_CONTROL_FAILED; +} +static int kit_socket_set_nonblocking(socket_t s) { + u_long flag = 1; + return ioctlsocket(s, FIONBIO, &flag) == 0 + ? KIT_OK + : KIT_ERROR_SOCKET_CONTROL_FAILED; +} +# ifdef __cplusplus +} +# endif +# else +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# define socket_t int +# define closesocket close +# define INVALID_SOCKET -1 +# ifdef __cplusplus +extern "C" { +# endif +static kit_status_t kit_sockets_init(void) { + signal(SIGPIPE, SIG_IGN); + return KIT_OK; +} +static kit_status_t kit_sockets_cleanup(void) { + return KIT_OK; +} +static int kit_socket_set_blocking(socket_t s) { + int const flags = fcntl(s, F_GETFL, 0); + return fcntl(s, F_SETFL, flags & ~O_NONBLOCK) == 0 + ? KIT_OK + : KIT_ERROR_SOCKET_CONTROL_FAILED; +} +static int kit_socket_set_nonblocking(socket_t s) { + int const flags = fcntl(s, F_GETFL, 0); + return fcntl(s, F_SETFL, flags | O_NONBLOCK) == 0 + ? KIT_OK + : KIT_ERROR_SOCKET_CONTROL_FAILED; +} +# ifdef __cplusplus +} +# endif +# endif +# ifdef __GNUC__ +# pragma GCC diagnostic pop +# endif +#endif +#endif +#ifdef KIT_IMPLEMENTATION +/********************************************************************* + * * + * File: source/kit/allocator.c * * * *********************************************************************/ #include @@ -430,52 +1812,744 @@ kit_allocator_t kit_alloc_default(void) { } /********************************************************************* * * - * File: ./source/kit/array_ref.c * + * File: source/kit/thread.posix.c * * * *********************************************************************/ -#include -int kit_ar_equal_bytes(ptrdiff_t left_element_size, - ptrdiff_t left_size, void const *left_data, - ptrdiff_t right_element_size, - ptrdiff_t right_size, void const *right_data) { - ptrdiff_t i; - if (left_element_size != right_element_size) - return 0; - if (left_size != right_size) - return 0; - for (i = 0; i < left_size; i++) - if (memcmp((char const *) left_data + i * left_element_size, - (char const *) right_data + i * left_element_size, - left_element_size) != 0) - return 0; - return 1; +#ifndef KIT_DISABLE_SYSTEM_THREADS +# if !defined(_WIN32) || defined(__CYGWIN__) +# include +# include +# include +# include +# include /* intptr_t */ +# include +# include +# ifndef PTHREAD_STACK_MIN +# define PTHREAD_STACK_MIN 16384 +# endif +/* +Configuration macro: + EMULATED_THREADS_USE_NATIVE_TIMEDLOCK + Use pthread_mutex_timedlock() for `mtx_timedlock()' + Otherwise use mtx_trylock() + *busy loop* emulation. +*/ +# if !defined(__CYGWIN__) && !defined(__APPLE__) && \ + !defined(__NetBSD__) +# define EMULATED_THREADS_USE_NATIVE_TIMEDLOCK +# endif +/* +Implementation limits: + - Conditionally emulation for "mutex with timeout" + (see EMULATED_THREADS_USE_NATIVE_TIMEDLOCK macro) +*/ +typedef struct { + thrd_start_t func; + void *arg; + kit_allocator_t alloc; +} impl_thrd_param_t; +static void *impl_thrd_routine(void *p) { + impl_thrd_param_t pack = *((impl_thrd_param_t *) p); + kit_alloc_dispatch(pack.alloc, KIT_DEALLOCATE, 0, 0, p); + return (void *) (intptr_t) pack.func(pack.arg); } -int kit_ar_compare(ptrdiff_t left_element_size, ptrdiff_t left_size, - void const *left_data, - ptrdiff_t right_element_size, ptrdiff_t right_size, - void const *right_data, - kit_ar_compare_fn compare) { - ptrdiff_t i; - if (left_element_size < right_element_size) - return -1; - if (left_element_size > right_element_size) - return 1; - for (i = 0; i < left_size && i < right_size; i++) { - int const c = compare( - (char const *) left_data + i * left_element_size, - (char const *) right_data + i * left_element_size); - if (c != 0) - return c; - } - if (left_size < right_size) - return -1; - if (left_size > right_size) +void call_once(once_flag *flag, void (*func)(void)) { + pthread_once(flag, func); +} +int cnd_broadcast(cnd_t *cond) { + assert(cond != NULL); + return (pthread_cond_broadcast(cond) == 0) ? thrd_success + : thrd_error; +} +void cnd_destroy(cnd_t *cond) { + assert(cond); + pthread_cond_destroy(cond); +} +int cnd_init(cnd_t *cond) { + assert(cond != NULL); + return (pthread_cond_init(cond, NULL) == 0) ? thrd_success + : thrd_error; +} +int cnd_signal(cnd_t *cond) { + assert(cond != NULL); + return (pthread_cond_signal(cond) == 0) ? thrd_success : thrd_error; +} +int cnd_timedwait(cnd_t *cond, mtx_t *mtx, + struct timespec const *abs_time) { + int rt; + assert(mtx != NULL); + assert(cond != NULL); + assert(abs_time != NULL); + rt = pthread_cond_timedwait(cond, mtx, abs_time); + if (rt == ETIMEDOUT) + return thrd_timedout; + return (rt == 0) ? thrd_success : thrd_error; +} +int cnd_wait(cnd_t *cond, mtx_t *mtx) { + assert(mtx != NULL); + assert(cond != NULL); + return (pthread_cond_wait(cond, mtx) == 0) ? thrd_success + : thrd_error; +} +void mtx_destroy(mtx_t *mtx) { + assert(mtx != NULL); + pthread_mutex_destroy(mtx); +} +/* + * XXX: Workaround when building with -O0 and without pthreads link. + * + * In such cases constant folding and dead code elimination won't be + * available, thus the compiler will always add the pthread_mutexattr* + * functions into the binary. As we try to link, we'll fail as the + * symbols are unresolved. + * + * Ideally we'll enable the optimisations locally, yet that does not + * seem to work. + * + * So the alternative workaround is to annotate the symbols as weak. + * Thus the linker will be happy and things don't clash when building + * with -O1 or greater. + */ +# if defined(KIT_HAVE_FUNC_ATTRIBUTE_WEAK) && !defined(__CYGWIN__) +__attribute__((weak)) int pthread_mutexattr_init( + pthread_mutexattr_t *attr); +__attribute__((weak)) int pthread_mutexattr_settype( + pthread_mutexattr_t *attr, int type); +__attribute__((weak)) int pthread_mutexattr_destroy( + pthread_mutexattr_t *attr); +# endif +int mtx_init(mtx_t *mtx, int type) { +# ifdef KIT_HAVE_PTHREAD_MUTEXATTR_SETTYPE + pthread_mutexattr_t attr; +# endif + assert(mtx != NULL); + if (type != mtx_plain && type != mtx_timed && + type != (mtx_plain | mtx_recursive) && + type != (mtx_timed | mtx_recursive)) + return thrd_error; + if ((type & mtx_recursive) == 0) { + pthread_mutex_init(mtx, NULL); + return thrd_success; + } +# ifdef KIT_HAVE_PTHREAD_MUTEXATTR_SETTYPE + pthread_mutexattr_init(&attr); + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_init(mtx, &attr); + pthread_mutexattr_destroy(&attr); + return thrd_success; +# else + return thrd_error; +# endif +} +int mtx_lock(mtx_t *mtx) { + assert(mtx != NULL); + return (pthread_mutex_lock(mtx) == 0) ? thrd_success : thrd_error; +} +int mtx_timedlock(mtx_t *mtx, const struct timespec *ts) { + assert(mtx != NULL); + assert(ts != NULL); + { +# ifdef EMULATED_THREADS_USE_NATIVE_TIMEDLOCK + int rt; + rt = pthread_mutex_timedlock(mtx, ts); + if (rt == 0) + return thrd_success; + return (rt == ETIMEDOUT) ? thrd_timedout : thrd_error; +# else + time_t expire = time(NULL); + expire += ts->tv_sec; + while (mtx_trylock(mtx) != thrd_success) { + time_t now = time(NULL); + if (expire < now) + return thrd_timedout; + // busy loop! + thrd_yield(); + } + return thrd_success; +# endif + } +} +int mtx_trylock(mtx_t *mtx) { + assert(mtx != NULL); + return (pthread_mutex_trylock(mtx) == 0) ? thrd_success : thrd_busy; +} +int mtx_unlock(mtx_t *mtx) { + assert(mtx != NULL); + return (pthread_mutex_unlock(mtx) == 0) ? thrd_success : thrd_error; +} +int thrd_create_with_stack(thrd_t *thr, thrd_start_t func, void *arg, + ptrdiff_t const require_stack_size) { + impl_thrd_param_t *pack; + assert(thr != NULL); + assert(require_stack_size == 0 || + require_stack_size >= PTHREAD_STACK_MIN); + pthread_attr_t attr; + pthread_attr_t *attr_p = NULL; + if (require_stack_size > 0) { + ptrdiff_t const page_size = (ptrdiff_t) sysconf(_SC_PAGESIZE); + ptrdiff_t const delta = require_stack_size % page_size; + ptrdiff_t const stack_size = delta == 0 ? require_stack_size + : require_stack_size + + page_size - delta; + if (pthread_attr_init(&attr) != 0) + return thrd_nomem; + if (pthread_attr_setstacksize(&attr, (size_t) stack_size) != 0) + return thrd_wrong_stack_size; + attr_p = &attr; + } + kit_allocator_t alloc = kit_alloc_default(); + pack = (impl_thrd_param_t *) kit_alloc_dispatch( + alloc, KIT_ALLOCATE, sizeof(impl_thrd_param_t), 0, NULL); + if (!pack) { + if (attr_p) + pthread_attr_destroy(attr_p); + return thrd_nomem; + } + pack->func = func; + pack->arg = arg; + pack->alloc = alloc; + if (pthread_create(thr, attr_p, impl_thrd_routine, pack) != 0) { + kit_alloc_dispatch(alloc, KIT_DEALLOCATE, 0, 0, pack); + if (attr_p) + pthread_attr_destroy(attr_p); + return thrd_error; + } + if (attr_p) + pthread_attr_destroy(attr_p); + return thrd_success; +} +int thrd_create(thrd_t *thr, thrd_start_t func, void *arg) { + return thrd_create_with_stack(thr, func, arg, 0); +} +thrd_t thrd_current(void) { + return pthread_self(); +} +int thrd_detach(thrd_t thr) { + return (pthread_detach(thr) == 0) ? thrd_success : thrd_error; +} +int thrd_equal(thrd_t thr0, thrd_t thr1) { + return pthread_equal(thr0, thr1); +} +_Noreturn void thrd_exit(int res) { + pthread_exit((void *) (intptr_t) res); +} +int thrd_join(thrd_t thr, int *res) { + void *code; + if (pthread_join(thr, &code) != 0) + return thrd_error; + if (res) + *res = (int) (intptr_t) code; + return thrd_success; +} +int thrd_sleep(const struct timespec *time_point, + struct timespec *remaining) { + assert(time_point != NULL); + return nanosleep(time_point, remaining); +} +void thrd_yield(void) { + sched_yield(); +} +# endif +#endif +/********************************************************************* + * * + * File: source/kit/thread.win32.c * + * * + *********************************************************************/ +#ifndef KIT_DISABLE_SYSTEM_THREADS +# if defined(_WIN32) && !defined(__CYGWIN__) +# include +# include +# include +# include +# include +# include +# ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN 1 +# endif +# include +/* +Configuration macro: + EMULATED_THREADS_USE_NATIVE_CALL_ONCE + Use native WindowsAPI one-time initialization function. + (requires WinVista or later) + Otherwise emulate by mtx_trylock() + *busy loop* for WinXP. + EMULATED_THREADS_TSS_DTOR_SLOTNUM + Max registerable TSS dtor number. +*/ +# if _WIN32_WINNT >= 0x0600 +/* Prefer native WindowsAPI on newer environment. */ +# if !defined(__MINGW32__) +# define EMULATED_THREADS_USE_NATIVE_CALL_ONCE +# endif +# endif +# define EMULATED_THREADS_TSS_DTOR_SLOTNUM \ + 64 /* see TLS_MINIMUM_AVAILABLE */ +/* check configuration */ +# if defined(EMULATED_THREADS_USE_NATIVE_CALL_ONCE) && \ + (_WIN32_WINNT < 0x0600) +# error EMULATED_THREADS_USE_NATIVE_CALL_ONCE requires _WIN32_WINNT>=0x0600 +# endif +static_assert(sizeof(cnd_t) == sizeof(CONDITION_VARIABLE), + "The size of cnd_t must equal to CONDITION_VARIABLE"); +static_assert(sizeof(thrd_t) == sizeof(HANDLE), + "The size of thrd_t must equal to HANDLE"); +static_assert(sizeof(tss_t) == sizeof(DWORD), + "The size of tss_t must equal to DWORD"); +static_assert(sizeof(mtx_t) == sizeof(CRITICAL_SECTION), + "The size of mtx_t must equal to CRITICAL_SECTION"); +static_assert(sizeof(once_flag) == sizeof(INIT_ONCE), + "The size of once_flag must equal to INIT_ONCE"); +/* +Implementation limits: + - Conditionally emulation for "Initialization functions" + (see EMULATED_THREADS_USE_NATIVE_CALL_ONCE macro) + - Emulated `mtx_timelock()' with mtx_trylock() + *busy loop* +*/ +typedef struct { + thrd_start_t func; + void *arg; + thrd_t thrd; + kit_allocator_t alloc; +} impl_thrd_param_t; +struct thrd_state { + thrd_t thrd; + bool handle_need_close; +}; +static thread_local struct thrd_state impl_current_thread = { 0 }; +static unsigned __stdcall impl_thrd_routine(void *p) { + impl_thrd_param_t *pack_p = (impl_thrd_param_t *) p; + impl_thrd_param_t pack; + int code; + impl_current_thread.thrd = pack_p->thrd; + impl_current_thread.handle_need_close = false; + memcpy(&pack, pack_p, sizeof(impl_thrd_param_t)); + kit_alloc_dispatch(pack.alloc, KIT_DEALLOCATE, 0, 0, p); + code = pack.func(pack.arg); + return (unsigned) code; +} +static time_t impl_timespec2msec(const struct timespec *ts) { + return (ts->tv_sec * 1000U) + (ts->tv_nsec / 1000000L); +} +static DWORD impl_abs2relmsec(const struct timespec *abs_time) { + const time_t abs_ms = impl_timespec2msec(abs_time); + struct timespec now; + timespec_get(&now, TIME_UTC); + const time_t now_ms = impl_timespec2msec(&now); + const DWORD rel_ms = (abs_ms > now_ms) ? (DWORD) (abs_ms - now_ms) + : 0; + return rel_ms; +} +# ifdef EMULATED_THREADS_USE_NATIVE_CALL_ONCE +struct impl_call_once_param { + void (*func)(void); +}; +static BOOL CALLBACK impl_call_once_callback(PINIT_ONCE InitOnce, + PVOID Parameter, + PVOID *Context) { + struct impl_call_once_param *param = (struct impl_call_once_param *) + Parameter; + (param->func)(); + ((void) InitOnce); + ((void) Context); /* suppress warning */ + return TRUE; +} +# endif /* ifdef EMULATED_THREADS_USE_NATIVE_CALL_ONCE */ +static struct impl_tss_dtor_entry { + tss_t key; + tss_dtor_t dtor; +} impl_tss_dtor_tbl[EMULATED_THREADS_TSS_DTOR_SLOTNUM]; +static int impl_tss_dtor_register(tss_t key, tss_dtor_t dtor) { + int i; + for (i = 0; i < EMULATED_THREADS_TSS_DTOR_SLOTNUM; i++) { + if (!impl_tss_dtor_tbl[i].dtor) + break; + } + if (i == EMULATED_THREADS_TSS_DTOR_SLOTNUM) return 1; + impl_tss_dtor_tbl[i].key = key; + impl_tss_dtor_tbl[i].dtor = dtor; + return 0; +} +static void impl_tss_dtor_invoke(void) { + int i; + for (i = 0; i < EMULATED_THREADS_TSS_DTOR_SLOTNUM; i++) { + if (impl_tss_dtor_tbl[i].dtor) { + void *val = (void *) (size_t) tss_get(impl_tss_dtor_tbl[i].key); + if (val) + (impl_tss_dtor_tbl[i].dtor)(val); + } + } +} +void call_once(once_flag *flag, void (*func)(void)) { + assert(flag && func); +# ifdef EMULATED_THREADS_USE_NATIVE_CALL_ONCE + { + struct impl_call_once_param param; + param.func = func; + InitOnceExecuteOnce((PINIT_ONCE) flag, impl_call_once_callback, + (PVOID) ¶m, NULL); + } +# else + if (InterlockedCompareExchangePointer( + (PVOID volatile *) &flag->status, (PVOID) 1, (PVOID) 0) == + 0) { + (func)(); + InterlockedExchangePointer((PVOID volatile *) &flag->status, + (PVOID) 2); + } else { + while (flag->status == 1) { + // busy loop! + thrd_yield(); + } + } +# endif +} +int cnd_broadcast(cnd_t *cond) { + assert(cond != NULL); + WakeAllConditionVariable((PCONDITION_VARIABLE) cond); + return thrd_success; +} +void cnd_destroy(cnd_t *cond) { + assert(cond != NULL); + /* do nothing */ + (void) cond; +} +int cnd_init(cnd_t *cond) { + assert(cond != NULL); + InitializeConditionVariable((PCONDITION_VARIABLE) cond); + return thrd_success; +} +int cnd_signal(cnd_t *cond) { + assert(cond != NULL); + WakeConditionVariable((PCONDITION_VARIABLE) cond); + return thrd_success; +} +int cnd_timedwait(cnd_t *cond, mtx_t *mtx, + const struct timespec *abs_time) { + assert(cond != NULL); + assert(mtx != NULL); + assert(abs_time != NULL); + const DWORD timeout = impl_abs2relmsec(abs_time); + if (SleepConditionVariableCS((PCONDITION_VARIABLE) cond, + (PCRITICAL_SECTION) mtx, timeout)) + return thrd_success; + return (GetLastError() == ERROR_TIMEOUT) ? thrd_timedout + : thrd_error; +} +int cnd_wait(cnd_t *cond, mtx_t *mtx) { + assert(cond != NULL); + assert(mtx != NULL); + SleepConditionVariableCS((PCONDITION_VARIABLE) cond, + (PCRITICAL_SECTION) mtx, INFINITE); + return thrd_success; +} +void mtx_destroy(mtx_t *mtx) { + assert(mtx); + DeleteCriticalSection((PCRITICAL_SECTION) mtx); +} +int mtx_init(mtx_t *mtx, int type) { + assert(mtx != NULL); + if (type != mtx_plain && type != mtx_timed && + type != (mtx_plain | mtx_recursive) && + type != (mtx_timed | mtx_recursive)) + return thrd_error; + InitializeCriticalSection((PCRITICAL_SECTION) mtx); + return thrd_success; +} +int mtx_lock(mtx_t *mtx) { + assert(mtx != NULL); + EnterCriticalSection((PCRITICAL_SECTION) mtx); + return thrd_success; +} +int mtx_timedlock(mtx_t *mtx, const struct timespec *ts) { + assert(mtx != NULL); + assert(ts != NULL); + while (mtx_trylock(mtx) != thrd_success) { + if (impl_abs2relmsec(ts) == 0) + return thrd_timedout; + /* busy loop! */ + thrd_yield(); + } + return thrd_success; +} +int mtx_trylock(mtx_t *mtx) { + assert(mtx != NULL); + return TryEnterCriticalSection((PCRITICAL_SECTION) mtx) + ? thrd_success + : thrd_busy; +} +int mtx_unlock(mtx_t *mtx) { + assert(mtx != NULL); + LeaveCriticalSection((PCRITICAL_SECTION) mtx); + return thrd_success; +} +int thrd_create_with_stack(thrd_t *thr, thrd_start_t func, void *arg, + ptrdiff_t const stack_size) { + impl_thrd_param_t *pack; + uintptr_t handle; + assert(thr != NULL); + assert(stack_size >= 0 && stack_size < 0x100000000); + kit_allocator_t alloc = kit_alloc_default(); + pack = (impl_thrd_param_t *) kit_alloc_dispatch( + alloc, KIT_ALLOCATE, (sizeof(impl_thrd_param_t)), 0, NULL); + if (!pack) + return thrd_nomem; + pack->func = func; + pack->arg = arg; + pack->alloc = alloc; + handle = _beginthreadex(NULL, (unsigned) stack_size, + impl_thrd_routine, pack, CREATE_SUSPENDED, + NULL); + if (handle == 0) { + kit_alloc_dispatch(alloc, KIT_DEALLOCATE, 0, 0, pack); + if (errno == EAGAIN || errno == EACCES) + return thrd_nomem; + return thrd_error; + } + thr->handle = (void *) handle; + pack->thrd = *thr; + ResumeThread((HANDLE) handle); + return thrd_success; +} +int thrd_create(thrd_t *thr, thrd_start_t func, void *arg) { + return thrd_create_with_stack(thr, func, arg, 0); +} +thrd_t thrd_current(void) { + /* GetCurrentThread() returns a pseudo-handle, which we need + * to pass to DuplicateHandle(). Only the resulting handle can be + * used from other threads. + * + * Note that neither handle can be compared to the one by + * thread_create. Only the thread IDs - as returned by GetThreadId() + * and GetCurrentThreadId() can be compared directly. + * + * Other potential solutions would be: + * - define thrd_t as a thread Ids, but this would mean we'd need to + * OpenThread for many operations + * - use malloc'ed memory for thrd_t. This would imply using TLS for + * current thread. + * + * Neither is particularly nice. + * + * Life would be much easier if C11 threads had different + * abstractions for threads and thread IDs, just like C++11 threads + * does... + */ + struct thrd_state *state = &impl_current_thread; + if (state->thrd.handle == NULL) { + if (!DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), + GetCurrentProcess(), &(state->thrd.handle), + 0, FALSE, DUPLICATE_SAME_ACCESS)) { + abort(); + } + state->handle_need_close = true; + } + return state->thrd; +} +int thrd_detach(thrd_t thr) { + CloseHandle(thr.handle); + return thrd_success; +} +int thrd_equal(thrd_t thr0, thrd_t thr1) { + return GetThreadId(thr0.handle) == GetThreadId(thr1.handle); +} +_Noreturn void thrd_exit(int res) { + _endthreadex((unsigned) res); +} +int thrd_join(thrd_t thr, int *res) { + DWORD w, code; + if (thr.handle == NULL) { + return thrd_error; + } + w = WaitForSingleObject(thr.handle, INFINITE); + if (w != WAIT_OBJECT_0) + return thrd_error; + if (res) { + if (!GetExitCodeThread(thr.handle, &code)) { + CloseHandle(thr.handle); + return thrd_error; + } + *res = (int) code; + } + CloseHandle(thr.handle); + return thrd_success; +} +int thrd_sleep(const struct timespec *time_point, + struct timespec *remaining) { + (void) remaining; + assert(time_point); + assert(!remaining); /* not implemented */ + Sleep((DWORD) impl_timespec2msec(time_point)); return 0; } +void thrd_yield(void) { + SwitchToThread(); +} +# endif +#endif +/********************************************************************* + * * + * File: source/kit/atomic.win32.c * + * * + *********************************************************************/ +#ifdef _MSC_VER +static_assert(sizeof(char) == 1, "Wrong char size"); +static_assert(sizeof(short) == 2, "Wrong short size"); +static_assert(sizeof(int) == 4, "Wrong int size"); +# include +void kit_atomic_store_explicit_8(uint8_t volatile *var, uint8_t value, + int memory_order) { + char volatile *dst = (char volatile *) var; + char src = (char) value; + switch (memory_order) { + case memory_order_relaxed: *dst = src; break; + default: _InterlockedExchange8(dst, src); + } +} +void kit_atomic_store_explicit_16(uint16_t volatile *var, + uint16_t value, int memory_order) { + short volatile *dst = (short volatile *) var; + short src = (short) value; + switch (memory_order) { + case memory_order_relaxed: *dst = src; break; + default: _InterlockedExchange16(dst, src); + } +} +void kit_atomic_store_explicit_32(uint32_t volatile *var, + uint32_t value, int memory_order) { + int volatile *dst = (int volatile *) var; + int src = (int) value; + switch (memory_order) { + case memory_order_relaxed: *dst = src; break; + default: _InterlockedExchange(dst, src); + } +} +void kit_atomic_store_explicit_64(uint64_t volatile *var, + uint64_t value, int memory_order) { + __int64 volatile *dst = (__int64 volatile *) var; + __int64 src = (__int64) value; + switch (memory_order) { + case memory_order_relaxed: *dst = src; break; + default: +# ifdef _WIN64 + _InterlockedExchange64(dst, src); +# else + _InterlockedExchange((int volatile *) dst, (int) src); +# endif + } +} +uint8_t kit_atomic_load_explicit_8(volatile uint8_t *var, + int memory_order) { + char volatile *dst = (char volatile *) var; + if (memory_order == memory_order_relaxed) + return (uint8_t) *dst; + return (uint8_t) _InterlockedOr8(dst, 0); +} +uint16_t kit_atomic_load_explicit_16(uint16_t volatile *var, + int memory_order) { + short volatile *dst = (short volatile *) var; + if (memory_order == memory_order_relaxed) + return (uint16_t) *dst; + return (uint16_t) _InterlockedOr16(dst, 0); +} +uint32_t kit_atomic_load_explicit_32(uint32_t volatile *var, + int memory_order) { + int volatile *dst = (int volatile *) var; + if (memory_order == memory_order_relaxed) + return (uint32_t) *dst; + return (uint32_t) _InterlockedOr(dst, 0); +} +uint64_t kit_atomic_load_explicit_64(uint64_t volatile *var, + int memory_order) { + __int64 volatile *dst = (__int64 volatile *) var; + if (memory_order == memory_order_relaxed) + return (uint64_t) *dst; +# ifdef _WIN64 + return (uint64_t) _InterlockedOr64(dst, 0); +# else + return (uint64_t) _InterlockedOr((int volatile *) dst, 0); +# endif +} +uint8_t kit_atomic_exchange_explicit_8(volatile uint8_t *var, + uint8_t value, + int memory_order) { + char volatile *dst = (char volatile *) var; + char src = (char) value; + return (uint8_t) _InterlockedExchange8(dst, src); +} +uint16_t kit_atomic_exchange_explicit_16(uint16_t volatile *var, + uint16_t value, + int memory_order) { + short volatile *dst = (short volatile *) var; + short src = (short) value; + return (uint16_t) _InterlockedExchange16(dst, src); +} +uint32_t kit_atomic_exchange_explicit_32(uint32_t volatile *var, + uint32_t value, + int memory_order) { + int volatile *dst = (int volatile *) var; + int src = (int) value; + return (uint32_t) _InterlockedExchange(dst, src); +} +uint64_t kit_atomic_exchange_explicit_64(uint64_t volatile *var, + uint64_t value, + int memory_order) { + __int64 volatile *dst = (__int64 volatile *) var; + __int64 src = (__int64) value; +# ifdef _WIN64 + return (uint64_t) _InterlockedExchange64(dst, src); +# else + return (uint64_t) _InterlockedExchange((int volatile *) dst, + (int) src); +# endif +} +uint8_t kit_atomic_fetch_add_explicit_8(volatile uint8_t *var, + uint8_t value, + int memory_order) { + char volatile *dst = (char volatile *) var; + char src = (char) value; + return (uint8_t) _InterlockedExchangeAdd8(dst, src); +} +uint16_t kit_atomic_fetch_add_explicit_16(uint16_t volatile *var, + uint16_t value, + int memory_order) { + short volatile *dst = (short volatile *) var; + short src = (short) value; + return (uint16_t) _InterlockedExchangeAdd16(dst, src); +} +uint32_t kit_atomic_fetch_add_explicit_32(uint32_t volatile *var, + uint32_t value, + int memory_order) { + int volatile *dst = (int volatile *) var; + int src = (int) value; + return (uint32_t) _InterlockedExchangeAdd(dst, src); +} +uint64_t kit_atomic_fetch_add_explicit_64(uint64_t volatile *var, + uint64_t value, + int memory_order) { + __int64 volatile *dst = (__int64 volatile *) var; + __int64 src = (__int64) value; +# ifdef _WIN64 + return (uint64_t) _InterlockedExchangeAdd64(dst, src); +# else + return (uint64_t) _InterlockedExchangeAdd((int volatile *) dst, + (int) src); +# endif +} +#endif +/********************************************************************* + * * + * File: source/kit/mutex.c * + * * + *********************************************************************/ +/********************************************************************* + * * + * File: source/kit/condition_variable.c * + * * + *********************************************************************/ /********************************************************************* * * - * File: ./source/kit/dynamic_array.c * + * File: source/kit/dynamic_array.c * * * *********************************************************************/ #include @@ -485,7 +2559,6 @@ void kit_da_init(kit_da_void_t *array, ptrdiff_t element_size, assert(array != NULL); assert(element_size > 0); assert(size >= 0); - assert(alloc.allocate != NULL); memset(array, 0, sizeof(kit_da_void_t)); if (size > 0) array->values = kit_alloc_dispatch(alloc, KIT_ALLOCATE, @@ -513,7 +2586,6 @@ void kit_da_resize(kit_da_void_t *array, ptrdiff_t element_size, array->size = size; } else { ptrdiff_t capacity = eval_capacity(array->capacity, size); - assert(array->alloc.allocate != NULL); void *bytes = kit_alloc_dispatch( array->alloc, KIT_ALLOCATE, element_size * capacity, 0, NULL); if (bytes != NULL) { @@ -530,7 +2602,194 @@ void kit_da_resize(kit_da_void_t *array, ptrdiff_t element_size, } /********************************************************************* * * - * File: ./source/kit/file.c * + * File: source/kit/input_stream.c * + * * + *********************************************************************/ +#include +enum { input_stream_str }; +typedef struct { + ptrdiff_t type; + kit_allocator_t alloc; +} kit_is_state_basic_t; +typedef struct { + ptrdiff_t type; + kit_allocator_t alloc; + kit_str_t string; +} kit_is_state_str_t; +static int check_type(void *state, ptrdiff_t type) { + kit_is_state_basic_t *basic = (kit_is_state_basic_t *) state; + return basic != NULL && basic->type == type; +} +static ptrdiff_t read_str(void *state, kit_str_t destination) { + if (!check_type(state, input_stream_str)) + return 0; + kit_is_state_str_t *str = (kit_is_state_str_t *) state; + ptrdiff_t size = destination.size < str->string.size + ? destination.size + : str->string.size; + memcpy(destination.values, str->string.values, size); + str->string.values += size; + str->string.size -= size; + return size; +} +kit_is_handle_t kit_is_wrap_string(kit_str_t string, + kit_allocator_t alloc) { + kit_is_handle_t in; + memset(&in, 0, sizeof in); + kit_is_state_str_t *state = (kit_is_state_str_t *) + kit_alloc_dispatch(alloc, KIT_ALLOCATE, + sizeof(kit_is_state_str_t), 0, NULL); + if (state != NULL) { + memset(state, 0, sizeof *state); + state->type = input_stream_str; + state->string = string; + state->alloc = alloc; + in.state = state; + in.read = read_str; + } + return in; +} +void kit_is_destroy(kit_is_handle_t in) { + kit_is_state_basic_t *basic = (kit_is_state_basic_t *) in.state; + if (basic != NULL) + kit_alloc_dispatch(basic->alloc, KIT_DEALLOCATE, 0, 0, in.state); +} +/********************************************************************* + * * + * File: source/kit/input_buffer.c * + * * + *********************************************************************/ +#include +#include +typedef struct { + ptrdiff_t ref_count; + kit_is_handle_t upstream; + kit_allocator_t alloc; + kit_string_t data; +} internal_buffer_t; +static internal_buffer_t *buf_init(kit_is_handle_t upstream, + kit_allocator_t alloc) { + assert(alloc.allocate != NULL); + internal_buffer_t *buf = kit_alloc_dispatch(alloc, KIT_ALLOCATE, + sizeof *buf, 0, NULL); + if (buf != NULL) { + memset(buf, 0, sizeof *buf); + buf->ref_count = 1; + buf->upstream = upstream; + buf->alloc = alloc; + DA_INIT(buf->data, 0, alloc); + } + return buf; +} +static kit_allocator_t buf_alloc(void *p) { + assert(p != NULL); + return ((internal_buffer_t *) p)->alloc; +} +static void buf_acquire(void *p) { + assert(p != NULL); + ((internal_buffer_t *) p)->ref_count++; +} +static void buf_release(void *p) { + assert(p != NULL); + internal_buffer_t *buf = (internal_buffer_t *) p; + if (--buf->ref_count == 0) { + DA_DESTROY(buf->data); + kit_alloc_dispatch(buf->alloc, KIT_DEALLOCATE, 0, 0, buf); + } +} +static void buf_adjust(void *p, ptrdiff_t size) { + assert(p != NULL); + assert(size >= 0); + internal_buffer_t *buf = (internal_buffer_t *) p; + ptrdiff_t offset = buf->data.size; + if (offset < size) { + DA_RESIZE(buf->data, size); + kit_str_t destination = { .size = size - offset, + .values = buf->data.values + offset }; + ptrdiff_t n = KIT_IS_READ(buf->upstream, destination); + DA_RESIZE(buf->data, offset + n); + } +} +static ptrdiff_t buf_read(void *p, ptrdiff_t offset, + kit_str_t destination) { + internal_buffer_t *buf = (internal_buffer_t *) p; + ptrdiff_t n = destination.size < buf->data.size - offset + ? destination.size + : buf->data.size - offset; + memcpy(destination.values, buf->data.values + offset, n); + return n; +} +kit_ib_handle_t kit_ib_wrap(kit_is_handle_t upstream, + kit_allocator_t alloc) { + kit_ib_handle_t buf; + memset(&buf, 0, sizeof buf); + buf.status = KIT_OK; + DA_INIT(buf.data, 0, alloc); + buf.internal = buf_init(upstream, alloc); + if (buf.internal == NULL) + buf.status = KIT_ERROR_BAD_ALLOC; + return buf; +} +kit_ib_handle_t kit_ib_read(kit_ib_handle_t buf, ptrdiff_t size) { + kit_ib_handle_t next; + memset(&next, 0, sizeof next); + if (buf.status != KIT_OK) { + next.status = buf.status; + return next; + } + buf_acquire(buf.internal); + buf_adjust(buf.internal, buf.offset + size); + DA_INIT(next.data, size, buf_alloc(buf.internal)); + if (next.data.size != size) + next.status = KIT_ERROR_BAD_ALLOC; + kit_str_t destination = { .size = next.data.size, + .values = next.data.values }; + ptrdiff_t n = buf_read(buf.internal, buf.offset, destination); + next.offset = buf.offset + n; + next.internal = buf.internal; + DA_RESIZE(next.data, n); + if (next.data.size != n) + next.status = KIT_ERROR_BAD_ALLOC; + return next; +} +kit_ib_handle_t kit_ib_read_while( + kit_ib_handle_t buf, kit_ib_read_condition_fn condition) { + kit_ib_handle_t next; + memset(&next, 0, sizeof next); + if (buf.status != KIT_OK) { + next.status = buf.status; + return next; + } + buf_acquire(buf.internal); + DA_INIT(next.data, 0, buf_alloc(buf.internal)); + ptrdiff_t size = 0; + for (;; ++size) { + buf_adjust(buf.internal, buf.offset + size + 1); + DA_RESIZE(next.data, size + 1); + if (next.data.size != size + 1) + next.status = KIT_ERROR_BAD_ALLOC; + kit_str_t destination = { .size = 1, + .values = next.data.values + size }; + ptrdiff_t n = buf_read(buf.internal, buf.offset + size, + destination); + kit_str_t data = { .size = size + 1, .values = next.data.values }; + if (n != 1 || condition == NULL || condition(data) == 0) + break; + } + next.offset = buf.offset + size; + next.internal = buf.internal; + DA_RESIZE(next.data, size); + if (next.data.size != size) + next.status = KIT_ERROR_BAD_ALLOC; + return next; +} +void kit_ib_destroy(kit_ib_handle_t buf) { + buf_release(buf.internal); + DA_DESTROY(buf.data); +} +/********************************************************************* + * * + * File: source/kit/file.c * * * *********************************************************************/ #include @@ -551,13 +2810,12 @@ enum { PATH_BUF_SIZE = 4096 }; #ifdef __APPLE__ # define st_mtim st_mtimespec #endif -static int is_delim(char const c) { +static int is_delim(char c) { return c == '/' || c == '\\'; } -static kit_string_t kit_get_env_(char *const name, - kit_allocator_t const alloc) { - char *const val = getenv(name); - ptrdiff_t const size = val != NULL ? (ptrdiff_t) strlen(val) : 0; +static kit_string_t kit_get_env_(char *name, kit_allocator_t alloc) { + char *val = getenv(name); + ptrdiff_t size = val != NULL ? (ptrdiff_t) strlen(val) : 0; string_t result; DA_INIT(result, size, alloc); assert(result.size == size); @@ -567,10 +2825,9 @@ static kit_string_t kit_get_env_(char *const name, DA_RESIZE(result, 0); return result; } -kit_string_t kit_path_norm(kit_str_t const path, - kit_allocator_t const alloc) { - str_t const parent = SZ(".."); - ptrdiff_t i, i1, j; +kit_string_t kit_path_norm(kit_str_t path, kit_allocator_t alloc) { + str_t parent = SZ(".."); + ptrdiff_t i, i1, j; string_t norm; DA_INIT(norm, path.size, alloc); assert(norm.size == path.size); @@ -580,8 +2837,7 @@ kit_string_t kit_path_norm(kit_str_t const path, for (i1 = 0, i = 0; i < path.size; i++) { if (!is_delim(path.values[i])) continue; - str_t const s = { .size = i - i1 - 1, - .values = path.values + i1 + 1 }; + str_t s = { .size = i - i1 - 1, .values = path.values + i1 + 1 }; if (AR_EQUAL(s, parent)) { int have_parent = 0; ptrdiff_t i0 = 0; @@ -612,12 +2868,11 @@ kit_string_t kit_path_norm(kit_str_t const path, norm.size = size; return norm; } -kit_string_t kit_path_join(kit_str_t const left, - kit_str_t const right, - kit_allocator_t const alloc) { - ptrdiff_t left_size = left.size; - ptrdiff_t right_size = right.size; - char const *right_values = right.values; +kit_string_t kit_path_join(kit_str_t left, kit_str_t right, + kit_allocator_t alloc) { + ptrdiff_t left_size = left.size; + ptrdiff_t right_size = right.size; + char *right_values = right.values; if (left_size > 0 && is_delim(left.values[left_size - 1])) left_size--; if (right_size > 0 && is_delim(right.values[0])) { @@ -634,7 +2889,7 @@ kit_string_t kit_path_join(kit_str_t const left, memcpy(joined.values + left_size + 1, right_values, right_size); return joined; } -kit_string_t kit_path_user(kit_allocator_t const alloc) { +kit_string_t kit_path_user(kit_allocator_t alloc) { kit_string_t user = kit_get_env_(KIT_ENV_HOME, alloc); if (user.size == 0) { DA_RESIZE(user, 1); @@ -666,8 +2921,7 @@ kit_string_t kit_path_cache(kit_allocator_t alloc) { DA_DESTROY(user); return cache; } -kit_str_t kit_path_index(kit_str_t const path, - ptrdiff_t const index) { +kit_str_t kit_path_index(kit_str_t path, ptrdiff_t index) { str_t s = { .size = 0, .values = NULL }; ptrdiff_t i0 = 0; ptrdiff_t i = 0; @@ -690,7 +2944,7 @@ kit_str_t kit_path_index(kit_str_t const path, } return s; } -kit_str_t kit_path_take(kit_str_t const path, ptrdiff_t const count) { +kit_str_t kit_path_take(kit_str_t path, ptrdiff_t count) { str_t s = { .size = 0, .values = path.values }; ptrdiff_t i0 = 0; ptrdiff_t i = 0; @@ -711,8 +2965,7 @@ kit_str_t kit_path_take(kit_str_t const path, ptrdiff_t const count) { return s; } #if defined(_WIN32) && !defined(__CYGWIN__) -static void win32_prepare_path_(WCHAR *const buf, - kit_str_t const path) { +static void win32_prepare_path_(WCHAR *buf, kit_str_t path) { assert(path.size == 0 || path.values != NULL); assert(path.size + 5 < PATH_BUF_SIZE); memset(buf, 0, PATH_BUF_SIZE); @@ -732,8 +2985,7 @@ static void win32_prepare_path_(WCHAR *const buf, WCHAR buf[PATH_BUF_SIZE]; \ win32_prepare_path_(buf, path) #else -static void unix_prepare_path_(char *const buf, - kit_str_t const path) { +static void unix_prepare_path_(char *buf, kit_str_t path) { assert(path.size == 0 || path.values != NULL); assert(path.size + 1 < PATH_BUF_SIZE); memset(buf, 0, PATH_BUF_SIZE); @@ -744,7 +2996,7 @@ static void unix_prepare_path_(char *const buf, char buf[PATH_BUF_SIZE]; \ unix_prepare_path_(buf, path) #endif -kit_status_t kit_file_create_folder(kit_str_t const path) { +kit_status_t kit_file_create_folder(kit_str_t path) { PREPARE_PATH_BUF_; #if defined(_WIN32) && !defined(__CYGWIN__) return CreateDirectoryW(buf, NULL) ? KIT_OK @@ -753,15 +3005,15 @@ kit_status_t kit_file_create_folder(kit_str_t const path) { return mkdir(buf, 0755) == 0 ? KIT_OK : KIT_ERROR_MKDIR_FAILED; #endif } -kit_status_t kit_file_create_folder_recursive(kit_str_t const path) { +kit_status_t kit_file_create_folder_recursive(kit_str_t path) { ptrdiff_t i; for (i = 0;; i++) { - str_t const part = kit_path_take(path, i); - int const type = kit_path_type(part); + str_t part = kit_path_take(path, i); + int type = kit_path_type(part); if (type == KIT_PATH_FILE) return KIT_ERROR_FILE_ALREADY_EXISTS; if (type == KIT_PATH_NONE) { - kit_status_t const s = kit_file_create_folder(part); + kit_status_t s = kit_file_create_folder(part); if (s != KIT_OK) return s; } @@ -770,7 +3022,7 @@ kit_status_t kit_file_create_folder_recursive(kit_str_t const path) { } return KIT_OK; } -kit_status_t kit_file_remove(kit_str_t const path) { +kit_status_t kit_file_remove(kit_str_t path) { PREPARE_PATH_BUF_; #if defined(_WIN32) && !defined(__CYGWIN__) return DeleteFileW(buf) ? KIT_OK : KIT_ERROR_UNLINK_FAILED; @@ -778,7 +3030,7 @@ kit_status_t kit_file_remove(kit_str_t const path) { return unlink(buf) == 0 ? KIT_OK : KIT_ERROR_UNLINK_FAILED; #endif } -kit_status_t kit_file_remove_folder(kit_str_t const path) { +kit_status_t kit_file_remove_folder(kit_str_t path) { PREPARE_PATH_BUF_; #if defined(_WIN32) && !defined(__CYGWIN__) return RemoveDirectoryW(buf) ? KIT_OK : KIT_ERROR_RMDIR_FAILED; @@ -786,8 +3038,8 @@ kit_status_t kit_file_remove_folder(kit_str_t const path) { return rmdir(buf) == 0 ? KIT_OK : KIT_ERROR_RMDIR_FAILED; #endif } -kit_status_t kit_file_remove_recursive(kit_str_t const path, - kit_allocator_t const alloc) { +kit_status_t kit_file_remove_recursive(kit_str_t path, + kit_allocator_t alloc) { int type = kit_path_type(path); ptrdiff_t i; switch (type) { @@ -799,8 +3051,8 @@ kit_status_t kit_file_remove_recursive(kit_str_t const path, return list.status; } for (i = 0; i < list.files.size; i++) { - str_t const s = { .size = list.files.values[i].size, - .values = list.files.values[i].values }; + str_t s = { .size = list.files.values[i].size, + .values = list.files.values[i].values }; kit_file_remove_recursive(s, alloc); } kit_path_list_destroy(list); @@ -810,7 +3062,7 @@ kit_status_t kit_file_remove_recursive(kit_str_t const path, } return KIT_ERROR_FILE_DO_NOT_EXIST; } -kit_path_type_t kit_path_type(kit_str_t const path) { +kit_path_type_t kit_path_type(kit_str_t path) { PREPARE_PATH_BUF_; #if defined(_WIN32) && !defined(__CYGWIN__) if (PathFileExistsW(buf)) { @@ -830,7 +3082,7 @@ kit_path_type_t kit_path_type(kit_str_t const path) { #endif return KIT_PATH_NONE; } -kit_file_info_t kit_file_info(kit_str_t const path) { +kit_file_info_t kit_file_info(kit_str_t path) { kit_file_info_t result; memset(&result, 0, sizeof result); PREPARE_PATH_BUF_; @@ -840,9 +3092,8 @@ kit_file_info_t kit_file_info(kit_str_t const path) { if (f != INVALID_HANDLE_VALUE) { FILETIME ft; if (GetFileTime(f, NULL, NULL, &ft) != 0) { - uint64_t const nsec100 = (((uint64_t) ft.dwHighDateTime) - << 32) | - (uint64_t) ft.dwLowDateTime; + uint64_t nsec100 = (((uint64_t) ft.dwHighDateTime) << 32) | + (uint64_t) ft.dwLowDateTime; result.time_modified_sec = (int64_t) (nsec100 / 10000000); result.time_modified_nsec = (int32_t) (100 * (nsec100 % 10000000)); @@ -876,8 +3127,8 @@ kit_file_info_t kit_file_info(kit_str_t const path) { result.status = KIT_ERROR_FILE_DO_NOT_EXIST; return result; } -kit_path_list_t kit_file_enum_folder(kit_str_t const path, - kit_allocator_t const alloc) { +kit_path_list_t kit_file_enum_folder(kit_str_t path, + kit_allocator_t alloc) { PREPARE_PATH_BUF_; kit_path_list_t result = { .status = KIT_OK }; DA_INIT(result.files, 0, alloc); @@ -893,7 +3144,7 @@ kit_path_list_t kit_file_enum_folder(kit_str_t const path, if (find == INVALID_HANDLE_VALUE) return result; do { - ptrdiff_t const n = result.files.size; + ptrdiff_t n = result.files.size; DA_RESIZE(result.files, n + 1); if (result.files.size != n + 1) { result.status = KIT_ERROR_BAD_ALLOC; @@ -921,13 +3172,13 @@ kit_path_list_t kit_file_enum_folder(kit_str_t const path, break; if (entry->d_name[0] == '.') continue; - ptrdiff_t const n = result.files.size; + ptrdiff_t n = result.files.size; DA_RESIZE(result.files, n + 1); if (result.files.size != n + 1) { result.status = KIT_ERROR_BAD_ALLOC; break; } - ptrdiff_t const size = (ptrdiff_t) strlen(entry->d_name); + ptrdiff_t size = (ptrdiff_t) strlen(entry->d_name); DA_INIT(result.files.values[n], size, alloc); if (result.files.values[n].size != size) { DA_RESIZE(result.files, n); @@ -947,4 +3198,275 @@ void kit_path_list_destroy(kit_path_list_t list) { DA_DESTROY(list.files.values[i]); DA_DESTROY(list.files); } +/********************************************************************* + * * + * File: source/kit/mersenne_twister_64.c * + * * + *********************************************************************/ +#define MM 156 +#define MATRIX_A 0xb5026f5aa96619e9ull +#define UM 0xffffffff80000000ull +#define LM 0x7fffffffull +void kit_mt64_init_array(kit_mt64_state_t *state, ptrdiff_t size, + uint64_t *seed) { + ptrdiff_t i; + for (i = 0; i < size && i < KIT_MT64_N; i++) state->mt[i] = seed[i]; + for (state->index = size; state->index < KIT_MT64_N; state->index++) + state->mt[state->index] = (6364136223846793005ull * + (state->mt[state->index - 1] ^ + (state->mt[state->index - 1] >> + 62u)) + + state->index); +} +void kit_mt64_init(kit_mt64_state_t *state, uint64_t seed) { + kit_mt64_init_array(state, 1, &seed); +} +void kit_mt64_rotate(kit_mt64_state_t *state) { + static uint64_t mag01[2] = { 0ull, MATRIX_A }; + uint64_t x; + int i; + for (i = 0; i < KIT_MT64_N - MM; i++) { + x = (state->mt[i] & UM) | (state->mt[i + 1] & LM); + state->mt[i] = state->mt[i + MM] ^ (x >> 1u) ^ + mag01[(int) (x & 1ull)]; + } + for (; i < KIT_MT64_N - 1; i++) { + x = (state->mt[i] & UM) | (state->mt[i + 1] & LM); + state->mt[i] = state->mt[i + (MM - KIT_MT64_N)] ^ (x >> 1u) ^ + mag01[(int) (x & 1ull)]; + } + x = (state->mt[KIT_MT64_N - 1] & UM) | (state->mt[0] & LM); + state->mt[KIT_MT64_N - 1] = state->mt[MM - 1] ^ (x >> 1u) ^ + mag01[(int) (x & 1ull)]; + state->index = 0; +} +uint64_t kit_mt64_generate(kit_mt64_state_t *state) { + if (state->index >= KIT_MT64_N) + kit_mt64_rotate(state); + uint64_t x = state->mt[state->index++]; + x ^= (x >> 29u) & 0x5555555555555555ull; + x ^= (x << 17u) & 0x71d67fffeda60000ull; + x ^= (x << 37u) & 0xfff7eee000000000ull; + x ^= (x >> 43u); + return x; +} +/********************************************************************* + * * + * File: source/kit/secure_random.c * + * * + *********************************************************************/ +#include +#include +#if defined(_WIN32) && !defined(__CYGWIN__) +# ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN 1 +# endif +# include +#else +# include +#endif +static uint64_t get_available_memory(void) { +#if defined(_WIN32) && !defined(__CYGWIN__) + MEMORYSTATUSEX status; + status.dwLength = sizeof(status); + GlobalMemoryStatusEx(&status); + return (uint64_t) status.ullTotalPhys; +#else + uint64_t pages = (uint64_t) sysconf(_SC_PHYS_PAGES); + uint64_t page_size = (uint64_t) sysconf(_SC_PAGE_SIZE); + return pages * page_size; +#endif +} +#ifndef KIT_DISABLE_SYSTEM_THREADS +static once_flag kit_secure_random_fallback_flag; +static mtx_t kit_secure_random_fallback_mutex; +static void secure_random_fallback_init(void) { + mtx_init(&kit_secure_random_fallback_mutex, mtx_plain); +} +#endif +static void secure_random_fallback(ptrdiff_t size, void *data) { +#ifndef KIT_DISABLE_SYSTEM_THREADS + call_once(&kit_secure_random_fallback_flag, + secure_random_fallback_init); + mtx_lock(&kit_secure_random_fallback_mutex); +#endif + /* Try to get some unpredictable system properties and use them to + * seed the pseudo random number generator. + */ + static uint64_t n = 0; + static uint64_t time_sec = 0; + static uint64_t time_nsec = 0; + struct timespec t; + ptrdiff_t i; + timespec_get(&t, TIME_UTC); + kit_mt64_state_t state; + if (time_sec == 0 && time_nsec == 0) { + uint64_t seed[] = { n, get_available_memory(), + (uint64_t) t.tv_sec, (uint64_t) t.tv_nsec }; + kit_mt64_init_array(&state, sizeof seed / sizeof *seed, seed); + } else { + uint64_t seed[] = { n, + get_available_memory(), + (uint64_t) t.tv_sec, + (uint64_t) t.tv_nsec, + (uint64_t) t.tv_sec - time_sec, + (uint64_t) t.tv_nsec - time_nsec }; + kit_mt64_init_array(&state, sizeof seed / sizeof *seed, seed); + } + kit_mt64_rotate(&state); + n = kit_mt64_generate(&state); + time_sec = (uint64_t) t.tv_sec; + time_nsec = (uint64_t) t.tv_nsec; + for (i = 0; i < size; i++) + ((uint8_t *) data)[i] = (uint8_t) (kit_mt64_generate(&state) >> + 56); +#ifndef KIT_DISABLE_SYSTEM_THREADS + mtx_unlock(&kit_secure_random_fallback_mutex); +#endif +} +void kit_secure_random(ptrdiff_t size, void *data) { + assert(size > 0); + assert(data != NULL); + if (size <= 0 || data == NULL) + return; +#if defined(_WIN32) && !defined(__CYGWIN__) + secure_random_fallback(size, data); +#else + FILE *f = fopen("/dev/urandom", "rb"); + assert(f != NULL); + if (f == NULL) { + secure_random_fallback(size, data); + return; + } + size_t n = fread(data, 1, size, f); + fclose(f); + assert(n == size); + if (n != size) + secure_random_fallback(size, data); +#endif +} +/********************************************************************* + * * + * File: source/kit/sha256.c * + * * + *********************************************************************/ +#include +#include +#define ROTLEFT(a, b) (((a) << (b)) | ((a) >> (32 - (b)))) +#define ROTRIGHT(a, b) (((a) >> (b)) | ((a) << (32 - (b)))) +#define CH(x, y, z) (((x) & (y)) ^ (~(x) & (z))) +#define MAJ(x, y, z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) +#define EP0(x) (ROTRIGHT(x, 2) ^ ROTRIGHT(x, 13) ^ ROTRIGHT(x, 22)) +#define EP1(x) (ROTRIGHT(x, 6) ^ ROTRIGHT(x, 11) ^ ROTRIGHT(x, 25)) +#define SIG0(x) (ROTRIGHT(x, 7) ^ ROTRIGHT(x, 18) ^ ((x) >> 3)) +#define SIG1(x) (ROTRIGHT(x, 17) ^ ROTRIGHT(x, 19) ^ ((x) >> 10)) +static uint32_t kit_sha256_k[64] = { + 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, + 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, + 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, + 0xc19bf174, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, + 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152, + 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, + 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, + 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, + 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, + 0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116, 0x1e376c08, + 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, + 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, + 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 +}; +static void kit_sha256_transform(uint32_t *state, uint8_t *data) { + assert(state != NULL); + assert(data != NULL); + uint32_t a, b, c, d, e, f, g, h, i, j, t1, t2, m[64]; + for (i = 0, j = 0; i < 16; ++i, j += 4) + m[i] = ((uint32_t) data[j] << 24) | + ((uint32_t) data[j + 1] << 16) | + ((uint32_t) data[j + 2] << 8) | ((uint32_t) data[j + 3]); + for (; i < 64; ++i) + m[i] = SIG1(m[i - 2]) + m[i - 7] + SIG0(m[i - 15]) + m[i - 16]; + a = state[0]; + b = state[1]; + c = state[2]; + d = state[3]; + e = state[4]; + f = state[5]; + g = state[6]; + h = state[7]; + for (i = 0; i < 64; ++i) { + t1 = h + EP1(e) + CH(e, f, g) + kit_sha256_k[i] + m[i]; + t2 = EP0(a) + MAJ(a, b, c); + h = g; + g = f; + f = e; + e = d + t1; + d = c; + c = b; + b = a; + a = t1 + t2; + } + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + state[4] += e; + state[5] += f; + state[6] += g; + state[7] += h; +} +kit_sha256_hash_t kit_sha256(ptrdiff_t in_size, uint8_t *in_data) { + assert(in_size >= 0); + assert(in_data != NULL); + uint32_t state[8] = { 0x6a09e667, 0xbb67ae85, 0x3c6ef372, + 0xa54ff53a, 0x510e527f, 0x9b05688c, + 0x1f83d9ab, 0x5be0cd19 }; + uint8_t data[64]; + ptrdiff_t i; + ptrdiff_t datalen = 0; + uint64_t bitlen = 0; + if (in_data != NULL) + for (i = 0; i < in_size; ++i) { + data[datalen] = in_data[i]; + datalen++; + if (datalen != 64) + continue; + kit_sha256_transform(state, data); + bitlen += 512; + datalen = 0; + } + i = datalen; + if (datalen < 56) { + data[i++] = 0x80; + while (i < 56) data[i++] = 0x00; + } else { + data[i++] = 0x80; + while (i < 64) data[i++] = 0x00; + kit_sha256_transform(state, data); + memset(data, 0, 56); + } + bitlen += datalen * 8; + data[63] = bitlen; + data[62] = bitlen >> 8; + data[61] = bitlen >> 16; + data[60] = bitlen >> 24; + data[59] = bitlen >> 32; + data[58] = bitlen >> 40; + data[57] = bitlen >> 48; + data[56] = bitlen >> 56; + kit_sha256_transform(state, data); + kit_sha256_hash_t hash; + memset(&hash, 0, sizeof hash); + for (i = 0; i < 4; ++i) { + hash.v[i] = (state[0] >> (24 - i * 8)) & 0xff; + hash.v[i + 4] = (state[1] >> (24 - i * 8)) & 0xff; + hash.v[i + 8] = (state[2] >> (24 - i * 8)) & 0xff; + hash.v[i + 12] = (state[3] >> (24 - i * 8)) & 0xff; + hash.v[i + 16] = (state[4] >> (24 - i * 8)) & 0xff; + hash.v[i + 20] = (state[5] >> (24 - i * 8)) & 0xff; + hash.v[i + 24] = (state[6] >> (24 - i * 8)) & 0xff; + hash.v[i + 28] = (state[7] >> (24 - i * 8)) & 0xff; + } + return hash; +} +#endif #endif diff --git a/source/kit/array_ref.c b/source/kit/array_ref.c index dcc4ff5..4c1b1a4 100644 --- a/source/kit/array_ref.c +++ b/source/kit/array_ref.c @@ -3,26 +3,25 @@ #include int kit_ar_equal_bytes(ptrdiff_t left_element_size, - ptrdiff_t left_size, void const *left_data, + ptrdiff_t left_size, void *left_data, ptrdiff_t right_element_size, - ptrdiff_t right_size, void const *right_data) { + ptrdiff_t right_size, void *right_data) { ptrdiff_t i; if (left_element_size != right_element_size) return 0; if (left_size != right_size) return 0; for (i = 0; i < left_size; i++) - if (memcmp((char const *) left_data + i * left_element_size, - (char const *) right_data + i * left_element_size, + if (memcmp((char *) left_data + i * left_element_size, + (char *) right_data + i * left_element_size, left_element_size) != 0) return 0; return 1; } int kit_ar_compare(ptrdiff_t left_element_size, ptrdiff_t left_size, - void const *left_data, - ptrdiff_t right_element_size, ptrdiff_t right_size, - void const *right_data, + void *left_data, ptrdiff_t right_element_size, + ptrdiff_t right_size, void *right_data, kit_ar_compare_fn compare) { ptrdiff_t i; if (left_element_size < right_element_size) @@ -30,9 +29,8 @@ int kit_ar_compare(ptrdiff_t left_element_size, ptrdiff_t left_size, if (left_element_size > right_element_size) return 1; for (i = 0; i < left_size && i < right_size; i++) { - int const c = compare( - (char const *) left_data + i * left_element_size, - (char const *) right_data + i * left_element_size); + int c = compare((char *) left_data + i * left_element_size, + (char *) right_data + i * left_element_size); if (c != 0) return c; } diff --git a/source/kit/array_ref.h b/source/kit/array_ref.h index c893b49..02f7370 100644 --- a/source/kit/array_ref.h +++ b/source/kit/array_ref.h @@ -12,44 +12,31 @@ extern "C" { #endif -typedef int (*kit_ar_compare_fn)(void const *left, void const *right); +typedef int (*kit_ar_compare_fn)(void *left, void *right); int kit_ar_equal_bytes(ptrdiff_t left_element_size, - ptrdiff_t left_size, void const *left_data, + ptrdiff_t left_size, void *left_data, ptrdiff_t right_element_size, - ptrdiff_t right_size, void const *right_data); + ptrdiff_t right_size, void *right_data); int kit_ar_compare(ptrdiff_t left_element_size, ptrdiff_t left_size, - void const *left_data, - ptrdiff_t right_element_size, ptrdiff_t right_size, - void const *right_data, kit_ar_compare_fn compare); - -#define KIT_AR_MUT(type_) \ - struct { \ - ptrdiff_t size; \ - type_ *values; \ - } - -#define KIT_AR(type_) \ - struct { \ - ptrdiff_t size; \ - type_ const *values; \ + void *left_data, ptrdiff_t right_element_size, + ptrdiff_t right_size, void *right_data, + kit_ar_compare_fn compare); + +#define KIT_AR(type_) \ + struct { \ + ptrdiff_t size; \ + type_ *values; \ } -#define KIT_AR_MUT_WRAP(name_, element_type_, array_) \ +#define KIT_AR_WRAP(name_, element_type_, array_) \ struct { \ ptrdiff_t size; \ element_type_ *values; \ } name_ = { .size = (sizeof(array_) / sizeof((array_)[0])), \ .values = (array_) } -#define KIT_AR_WRAP(name_, element_type_, array_) \ - struct { \ - ptrdiff_t size; \ - element_type_ const *values; \ - } name_ = { .size = (sizeof(array_) / sizeof((array_)[0])), \ - .values = (array_) } - #define KIT_AR_EQUAL(left_, right_) \ kit_ar_equal_bytes(sizeof((left_).values[0]), (left_).size, \ (left_).values, sizeof((right_).values[0]), \ @@ -66,9 +53,7 @@ int kit_ar_compare(ptrdiff_t left_element_size, ptrdiff_t left_size, # define ar_equal_bytes kit_ar_equal_bytes # define ar_compare kit_ar_compare -# define AR_MUT KIT_AR_MUT # define AR KIT_AR -# define AR_MUT_WRAP KIT_AR_MUT_WRAP # define AR_WRAP KIT_AR_WRAP # define AR_EQUAL KIT_AR_EQUAL # define AR_COMPARE KIT_AR_COMPARE diff --git a/source/kit/bigint.h b/source/kit/bigint.h index c948b57..7343b56 100644 --- a/source/kit/bigint.h +++ b/source/kit/bigint.h @@ -38,14 +38,14 @@ typedef uint_fast8_t kit_bit_t; # pragma GCC optimize("O3") #endif -static kit_bigint_t kit_bi_uint32(uint32_t const x) { +static kit_bigint_t kit_bi_uint32(uint32_t x) { kit_bigint_t z; memset(&z, 0, sizeof z); z.v[0] = x; return z; } -static kit_bigint_t kit_bi_uint64(uint64_t const x) { +static kit_bigint_t kit_bi_uint64(uint64_t x) { kit_bigint_t z; memset(&z, 0, sizeof z); z.v[0] = (uint32_t) (x & 0xffffffff); @@ -53,14 +53,14 @@ static kit_bigint_t kit_bi_uint64(uint64_t const x) { return z; } -static kit_bigint_t kit_bi_int32(int32_t const x) { +static kit_bigint_t kit_bi_int32(int32_t x) { kit_bigint_t z; memset(&z, x < 0 ? -1 : 0, sizeof z); z.v[0] = x; return z; } -static kit_bigint_t kit_bi_int64(int64_t const x) { +static kit_bigint_t kit_bi_int64(int64_t x) { kit_bigint_t z; memset(&z, x < 0 ? -1 : 0, sizeof z); z.v[0] = (uint32_t) (((uint64_t) x) & 0xffffffff); @@ -68,7 +68,7 @@ static kit_bigint_t kit_bi_int64(int64_t const x) { return z; } -static int kit_bi_is_zero(kit_bigint_t const x) { +static int kit_bi_is_zero(kit_bigint_t x) { ptrdiff_t i; for (i = 0; i < KIT_BIGINT_SIZE / 4; i++) if (x.v[i] != 0) @@ -76,17 +76,16 @@ static int kit_bi_is_zero(kit_bigint_t const x) { return 1; } -static int kit_bi_is_neg(kit_bigint_t const x) { +static int kit_bi_is_neg(kit_bigint_t x) { return (x.v[KIT_BIGINT_SIZE / 4 - 1] & 0x80000000) != 0; } -static int kit_bi_equal(kit_bigint_t const x, kit_bigint_t const y) { +static int kit_bi_equal(kit_bigint_t x, kit_bigint_t y) { return kit_ar_equal_bytes(1, KIT_BIGINT_SIZE, x.v, 1, KIT_BIGINT_SIZE, y.v); } -static int kit_bi_compare(kit_bigint_t const x, - kit_bigint_t const y) { +static int kit_bi_compare(kit_bigint_t x, kit_bigint_t y) { ptrdiff_t i; for (i = KIT_BIGINT_SIZE / 4 - 1; i >= 0; i--) if (x.v[i] < y.v[i]) @@ -96,54 +95,53 @@ static int kit_bi_compare(kit_bigint_t const x, return 0; } -static ptrdiff_t kit_bi_significant_bit_count(kit_bigint_t const x) { +static ptrdiff_t kit_bi_significant_bit_count(kit_bigint_t x) { ptrdiff_t n = KIT_BIGINT_SIZE / 4 - 1; while (n > 0 && x.v[n] == 0) n--; - uint32_t const i32 = x.v[n]; + uint32_t val = x.v[n]; - if (i32 == 0) + if (val == 0) return 0; - ptrdiff_t const bits = (i32 & 0x80000000u) != 0 ? 32 - : (i32 & 0x40000000u) != 0 ? 31 - : (i32 & 0x20000000u) != 0 ? 30 - : (i32 & 0x10000000u) != 0 ? 29 - : (i32 & 0x8000000u) != 0 ? 28 - : (i32 & 0x4000000u) != 0 ? 27 - : (i32 & 0x2000000u) != 0 ? 26 - : (i32 & 0x1000000u) != 0 ? 25 - : (i32 & 0x800000u) != 0 ? 24 - : (i32 & 0x400000u) != 0 ? 23 - : (i32 & 0x200000u) != 0 ? 22 - : (i32 & 0x100000u) != 0 ? 21 - : (i32 & 0x80000u) != 0 ? 20 - : (i32 & 0x40000u) != 0 ? 19 - : (i32 & 0x20000u) != 0 ? 18 - : (i32 & 0x10000u) != 0 ? 17 - : (i32 & 0x8000u) != 0 ? 16 - : (i32 & 0x4000u) != 0 ? 15 - : (i32 & 0x2000u) != 0 ? 14 - : (i32 & 0x1000u) != 0 ? 13 - : (i32 & 0x800u) != 0 ? 12 - : (i32 & 0x400u) != 0 ? 11 - : (i32 & 0x200u) != 0 ? 10 - : (i32 & 0x100u) != 0 ? 9 - : (i32 & 0x80u) != 0 ? 8 - : (i32 & 0x40u) != 0 ? 7 - : (i32 & 0x20u) != 0 ? 6 - : (i32 & 0x10u) != 0 ? 5 - : (i32 & 0x08u) != 0 ? 4 - : (i32 & 0x04u) != 0 ? 3 - : (i32 & 0x02u) != 0 ? 2 - : 1; + ptrdiff_t bits = (val & 0x80000000u) != 0 ? 32 + : (val & 0x40000000u) != 0 ? 31 + : (val & 0x20000000u) != 0 ? 30 + : (val & 0x10000000u) != 0 ? 29 + : (val & 0x8000000u) != 0 ? 28 + : (val & 0x4000000u) != 0 ? 27 + : (val & 0x2000000u) != 0 ? 26 + : (val & 0x1000000u) != 0 ? 25 + : (val & 0x800000u) != 0 ? 24 + : (val & 0x400000u) != 0 ? 23 + : (val & 0x200000u) != 0 ? 22 + : (val & 0x100000u) != 0 ? 21 + : (val & 0x80000u) != 0 ? 20 + : (val & 0x40000u) != 0 ? 19 + : (val & 0x20000u) != 0 ? 18 + : (val & 0x10000u) != 0 ? 17 + : (val & 0x8000u) != 0 ? 16 + : (val & 0x4000u) != 0 ? 15 + : (val & 0x2000u) != 0 ? 14 + : (val & 0x1000u) != 0 ? 13 + : (val & 0x800u) != 0 ? 12 + : (val & 0x400u) != 0 ? 11 + : (val & 0x200u) != 0 ? 10 + : (val & 0x100u) != 0 ? 9 + : (val & 0x80u) != 0 ? 8 + : (val & 0x40u) != 0 ? 7 + : (val & 0x20u) != 0 ? 6 + : (val & 0x10u) != 0 ? 5 + : (val & 0x08u) != 0 ? 4 + : (val & 0x04u) != 0 ? 3 + : (val & 0x02u) != 0 ? 2 + : 1; return n * 32 + bits; } -static kit_bigint_t kit_bi_and(kit_bigint_t const x, - kit_bigint_t const y) { +static kit_bigint_t kit_bi_and(kit_bigint_t x, kit_bigint_t y) { kit_bigint_t z; ptrdiff_t i; @@ -152,8 +150,7 @@ static kit_bigint_t kit_bi_and(kit_bigint_t const x, return z; } -static kit_bigint_t kit_bi_or(kit_bigint_t const x, - kit_bigint_t const y) { +static kit_bigint_t kit_bi_or(kit_bigint_t x, kit_bigint_t y) { kit_bigint_t z; ptrdiff_t i; @@ -162,8 +159,7 @@ static kit_bigint_t kit_bi_or(kit_bigint_t const x, return z; } -static kit_bigint_t kit_bi_xor(kit_bigint_t const x, - kit_bigint_t const y) { +static kit_bigint_t kit_bi_xor(kit_bigint_t x, kit_bigint_t y) { kit_bigint_t z; ptrdiff_t i; @@ -172,14 +168,13 @@ static kit_bigint_t kit_bi_xor(kit_bigint_t const x, return z; } -static kit_bigint_t kit_bi_shl_uint(kit_bigint_t const x, - uint32_t const y) { +static kit_bigint_t kit_bi_shl_uint(kit_bigint_t x, uint32_t y) { kit_bigint_t z; memset(&z, 0, sizeof z); - ptrdiff_t const words = (ptrdiff_t) (y / 32); - ptrdiff_t const bits = (ptrdiff_t) (y % 32); - ptrdiff_t i; + ptrdiff_t words = (ptrdiff_t) (y / 32); + ptrdiff_t bits = (ptrdiff_t) (y % 32); + ptrdiff_t i; for (i = words; i < KIT_BIGINT_SIZE / 4; i++) { z.v[i] |= x.v[i - words] << bits; @@ -190,14 +185,13 @@ static kit_bigint_t kit_bi_shl_uint(kit_bigint_t const x, return z; } -static kit_bigint_t kit_bi_shr_uint(kit_bigint_t const x, - uint32_t const y) { +static kit_bigint_t kit_bi_shr_uint(kit_bigint_t x, uint32_t y) { kit_bigint_t z; memset(&z, 0, sizeof z); - ptrdiff_t const words = (ptrdiff_t) (y / 32); - ptrdiff_t const bits = (ptrdiff_t) (y % 32); - ptrdiff_t i; + ptrdiff_t words = (ptrdiff_t) (y / 32); + ptrdiff_t bits = (ptrdiff_t) (y % 32); + ptrdiff_t i; for (i = KIT_BIGINT_SIZE / 4 - words - 1; i >= 0; i--) { z.v[i] |= x.v[i + words] >> bits; @@ -208,15 +202,15 @@ static kit_bigint_t kit_bi_shr_uint(kit_bigint_t const x, return z; } -static kit_bit_t kit_bi_carry(uint32_t const x, uint32_t const y, - kit_bit_t const carry) { +static kit_bit_t kit_bi_carry(uint32_t x, uint32_t y, + kit_bit_t carry) { assert(carry == 0 || carry == 1); return 0xffffffffu - x < y || 0xffffffffu - x - y < carry ? 1 : 0; } /* Increment. */ -static kit_bigint_t kit_bi_inc(kit_bigint_t const x) { +static kit_bigint_t kit_bi_inc(kit_bigint_t x) { kit_bigint_t z; kit_bit_t carry = 1; ptrdiff_t i; @@ -231,7 +225,7 @@ static kit_bigint_t kit_bi_inc(kit_bigint_t const x) { /* Decrement */ -static kit_bigint_t kit_bi_dec(kit_bigint_t const x) { +static kit_bigint_t kit_bi_dec(kit_bigint_t x) { kit_bigint_t z; kit_bit_t carry = 0; ptrdiff_t i; @@ -246,8 +240,7 @@ static kit_bigint_t kit_bi_dec(kit_bigint_t const x) { /* Addition. */ -static kit_bigint_t kit_bi_add(kit_bigint_t const x, - kit_bigint_t const y) { +static kit_bigint_t kit_bi_add(kit_bigint_t x, kit_bigint_t y) { kit_bigint_t z; kit_bit_t carry = 0; ptrdiff_t i; @@ -262,7 +255,7 @@ static kit_bigint_t kit_bi_add(kit_bigint_t const x, /* Negation. */ -static kit_bigint_t kit_bi_neg(kit_bigint_t const x) { +static kit_bigint_t kit_bi_neg(kit_bigint_t x) { kit_bigint_t y; kit_bit_t carry = 1; ptrdiff_t i; @@ -277,8 +270,7 @@ static kit_bigint_t kit_bi_neg(kit_bigint_t const x) { /* Subtraction. */ -static kit_bigint_t kit_bi_sub(kit_bigint_t const x, - kit_bigint_t const y) { +static kit_bigint_t kit_bi_sub(kit_bigint_t x, kit_bigint_t y) { kit_bigint_t z; kit_bit_t carry = 1; ptrdiff_t i; @@ -291,8 +283,7 @@ static kit_bigint_t kit_bi_sub(kit_bigint_t const x, return z; } -static kit_bigint_t kit_bi_mul_uint32(kit_bigint_t const x, - uint32_t const y) { +static kit_bigint_t kit_bi_mul_uint32(kit_bigint_t x, uint32_t y) { kit_bigint_t z; ptrdiff_t i, k; @@ -306,9 +297,9 @@ static kit_bigint_t kit_bi_mul_uint32(kit_bigint_t const x, uint64_t carry = ((uint64_t) x.v[i]) * ((uint64_t) y); for (k = i; k < KIT_BIGINT_SIZE / 4 && carry != 0; k++) { - uint64_t const sum = ((uint64_t) z.v[k]) + carry; - z.v[k] = ((uint32_t) (sum & 0xffffffffull)); - carry = sum >> 32; + uint64_t sum = ((uint64_t) z.v[k]) + carry; + z.v[k] = ((uint32_t) (sum & 0xffffffffull)); + carry = sum >> 32; } } @@ -317,8 +308,7 @@ static kit_bigint_t kit_bi_mul_uint32(kit_bigint_t const x, /* Multiplication. */ -static kit_bigint_t kit_bi_mul(kit_bigint_t const x, - kit_bigint_t const y) { +static kit_bigint_t kit_bi_mul(kit_bigint_t x, kit_bigint_t y) { kit_bigint_t z; ptrdiff_t i, j, k; @@ -335,9 +325,9 @@ static kit_bigint_t kit_bi_mul(kit_bigint_t const x, uint64_t carry = ((uint64_t) x.v[i]) * ((uint64_t) y.v[j]); for (k = i + j; k < KIT_BIGINT_SIZE / 4 && carry != 0; k++) { - uint64_t const sum = ((uint64_t) z.v[k]) + carry; - z.v[k] = ((uint32_t) (sum & 0xffffffffull)); - carry = sum >> 32; + uint64_t sum = ((uint64_t) z.v[k]) + carry; + z.v[k] = ((uint32_t) (sum & 0xffffffffull)); + carry = sum >> 32; } } } @@ -353,20 +343,19 @@ typedef struct { /* Unsigned division. */ -static kit_bi_division_t kit_bi_udiv(kit_bigint_t const x, - kit_bigint_t y) { +static kit_bi_division_t kit_bi_udiv(kit_bigint_t x, kit_bigint_t y) { kit_bi_division_t z; memset(&z, 0, sizeof z); - ptrdiff_t const y_bits = kit_bi_significant_bit_count(y); + ptrdiff_t y_bits = kit_bi_significant_bit_count(y); if (y_bits == 0) { z.undefined = 1; return z; } - ptrdiff_t const x_bits = kit_bi_significant_bit_count(x); - ptrdiff_t shift = x_bits - y_bits; + ptrdiff_t x_bits = kit_bi_significant_bit_count(x); + ptrdiff_t shift = x_bits - y_bits; z.remainder = x; z.quotient = kit_bi_uint32(0); @@ -391,13 +380,12 @@ static kit_bi_division_t kit_bi_udiv(kit_bigint_t const x, * Remainder is always a non-negative value less than absolute value * of y. */ -static kit_bi_division_t kit_bi_div(kit_bigint_t const x, - kit_bigint_t const y) { - int const x_neg = kit_bi_is_neg(x); - int const y_neg = kit_bi_is_neg(y); +static kit_bi_division_t kit_bi_div(kit_bigint_t x, kit_bigint_t y) { + int x_neg = kit_bi_is_neg(x); + int y_neg = kit_bi_is_neg(y); - kit_bigint_t const x_abs = x_neg ? kit_bi_neg(x) : x; - kit_bigint_t const y_abs = y_neg ? kit_bi_neg(y) : y; + kit_bigint_t x_abs = x_neg ? kit_bi_neg(x) : x; + kit_bigint_t y_abs = y_neg ? kit_bi_neg(y) : y; if (x_neg == y_neg) return kit_bi_udiv(x_abs, y_abs); @@ -412,8 +400,7 @@ static kit_bi_division_t kit_bi_div(kit_bigint_t const x, return z; } -static void kit_bi_serialize(kit_bigint_t const in, - uint8_t *const out) { +static void kit_bi_serialize(kit_bigint_t in, uint8_t *out) { ptrdiff_t i; assert(out != NULL); @@ -426,7 +413,7 @@ static void kit_bi_serialize(kit_bigint_t const in, } } -static kit_bigint_t kit_bi_deserialize(uint8_t const *const in) { +static kit_bigint_t kit_bi_deserialize(uint8_t *in) { ptrdiff_t i; kit_bigint_t out; @@ -440,46 +427,45 @@ static kit_bigint_t kit_bi_deserialize(uint8_t const *const in) { return out; } -static uint8_t kit_bin_digit(char const hex) { +static uint8_t kit_bin_digit(char hex) { assert(hex == '0' || hex == '1'); return hex == '1' ? 1 : 0; } -static kit_bigint_t kit_bi_from_bin(kit_str_t const bin) { +static kit_bigint_t kit_bi_from_bin(kit_str_t bin) { kit_bigint_t z; ptrdiff_t i; memset(&z, 0, sizeof z); for (i = 0; i < bin.size && i / 8 < KIT_BIGINT_SIZE; i++) { - uint8_t const digit = kit_bin_digit(bin.values[bin.size - i - 1]); + uint8_t digit = kit_bin_digit(bin.values[bin.size - i - 1]); z.v[i / 32] |= digit << (i % 32); } return z; } -static uint8_t kit_dec_digit(char const c) { +static uint8_t kit_dec_digit(char c) { assert('c' >= '0' && c <= '9'); return c >= '0' && c <= '9' ? (uint8_t) (c - '0') : 0; } -static kit_bigint_t kit_bi_from_dec(kit_str_t const dec) { +static kit_bigint_t kit_bi_from_dec(kit_str_t dec) { kit_bigint_t z = kit_bi_uint32(0); kit_bigint_t factor = kit_bi_uint32(1); ptrdiff_t i; for (i = 0; i < dec.size; i++) { - uint32_t const digit = kit_dec_digit( - dec.values[dec.size - i - 1]); - z = kit_bi_add(z, kit_bi_mul_uint32(factor, digit)); - factor = kit_bi_mul_uint32(factor, 10); + uint32_t digit = kit_dec_digit(dec.values[dec.size - i - 1]); + z = kit_bi_add(z, kit_bi_mul_uint32(factor, digit)); + factor = kit_bi_mul_uint32(factor, 10); } return z; } -static uint8_t kit_hex_digit(char const hex) { +static uint8_t kit_hex_digit(char hex) { assert((hex >= '0' && hex <= '9') || (hex >= 'a' && hex <= 'f') || (hex >= 'A' && hex <= 'F')); @@ -493,21 +479,21 @@ static uint8_t kit_hex_digit(char const hex) { return 0; } -static kit_bigint_t kit_bi_from_hex(kit_str_t const hex) { +static kit_bigint_t kit_bi_from_hex(kit_str_t hex) { kit_bigint_t z; ptrdiff_t i; memset(&z, 0, sizeof z); for (i = 0; i < hex.size && i / 2 < KIT_BIGINT_SIZE; i++) { - uint8_t const digit = kit_hex_digit(hex.values[hex.size - i - 1]); + uint8_t digit = kit_hex_digit(hex.values[hex.size - i - 1]); z.v[i / 8] |= digit << (4 * (i % 8)); } return z; } -static const uint8_t KIT_BASE32_DIGITS[] = { +static uint8_t KIT_BASE32_DIGITS[] = { ['1'] = 0, ['2'] = 1, ['3'] = 2, ['4'] = 3, ['5'] = 4, ['6'] = 5, ['7'] = 6, ['8'] = 7, ['9'] = 8, ['a'] = 9, ['b'] = 10, ['c'] = 11, ['d'] = 12, ['e'] = 13, ['f'] = 14, @@ -517,7 +503,7 @@ static const uint8_t KIT_BASE32_DIGITS[] = { ['y'] = 30, ['z'] = 31 }; -static uint8_t kit_base32_digit(char const c) { +static uint8_t kit_base32_digit(char c) { assert(c >= '\0' && c < sizeof KIT_BASE32_DIGITS); assert(c == '1' || KIT_BASE32_DIGITS[(size_t) (unsigned char) c] != 0); @@ -527,7 +513,7 @@ static uint8_t kit_base32_digit(char const c) { : 0; } -static kit_bigint_t kit_bi_from_base32(kit_str_t const base32) { +static kit_bigint_t kit_bi_from_base32(kit_str_t base32) { kit_bigint_t z; ptrdiff_t i; @@ -541,7 +527,7 @@ static kit_bigint_t kit_bi_from_base32(kit_str_t const base32) { return z; } -static const uint8_t KIT_BASE58_DIGITS[] = { +static uint8_t KIT_BASE58_DIGITS[] = { ['1'] = 0, ['2'] = 1, ['3'] = 2, ['4'] = 3, ['5'] = 4, ['6'] = 5, ['7'] = 6, ['8'] = 7, ['9'] = 8, ['A'] = 9, ['B'] = 10, ['C'] = 11, ['D'] = 12, ['E'] = 13, ['F'] = 14, @@ -556,7 +542,7 @@ static const uint8_t KIT_BASE58_DIGITS[] = { ['x'] = 55, ['y'] = 56, ['z'] = 57 }; -static uint8_t kit_base58_digit(char const c) { +static uint8_t kit_base58_digit(char c) { assert(c >= '\0' && c < sizeof KIT_BASE58_DIGITS); assert(c == '1' || KIT_BASE58_DIGITS[(size_t) (unsigned char) c] != 0); @@ -566,13 +552,13 @@ static uint8_t kit_base58_digit(char const c) { : 0; } -static kit_bigint_t kit_bi_from_base58(kit_str_t const base58) { +static kit_bigint_t kit_bi_from_base58(kit_str_t base58) { kit_bigint_t z = kit_bi_uint32(0); kit_bigint_t factor = kit_bi_uint32(1); ptrdiff_t i; for (i = 0; i < base58.size; i++) { - uint32_t const digit = kit_base58_digit( + uint32_t digit = kit_base58_digit( base58.values[base58.size - i - 1]); z = kit_bi_add(z, kit_bi_mul_uint32(factor, digit)); factor = kit_bi_mul_uint32(factor, 58); diff --git a/source/kit/condition_variable.h b/source/kit/condition_variable.h index 0e4630d..c27022e 100644 --- a/source/kit/condition_variable.h +++ b/source/kit/condition_variable.h @@ -27,7 +27,7 @@ void cnd_destroy(cnd_t *); int cnd_init(cnd_t *); int cnd_signal(cnd_t *); int cnd_timedwait(cnd_t *__restrict, mtx_t *__restrict mtx_, - const struct timespec *__restrict); + struct timespec const *__restrict); int cnd_wait(cnd_t *, mtx_t *mtx_); # ifdef __cplusplus diff --git a/source/kit/dynamic_array.h b/source/kit/dynamic_array.h index 35dddb3..526fb13 100644 --- a/source/kit/dynamic_array.h +++ b/source/kit/dynamic_array.h @@ -59,21 +59,21 @@ void kit_da_resize(kit_da_void_t *array, ptrdiff_t element_size, /* Append a value to dynamic array. */ -#define KIT_DA_APPEND(array_, value_) \ - do { \ - ptrdiff_t const kit_index_back_ = (array_).size; \ - KIT_DA_RESIZE((array_), kit_index_back_ + 1); \ - if (kit_index_back_ < (array_).size) \ - (array_).values[kit_index_back_] = (value_); \ +#define KIT_DA_APPEND(array_, value_) \ + do { \ + ptrdiff_t kit_index_back_ = (array_).size; \ + KIT_DA_RESIZE((array_), kit_index_back_ + 1); \ + if (kit_index_back_ < (array_).size) \ + (array_).values[kit_index_back_] = (value_); \ } while (0) /* Insert a value into dynamic array. */ #define KIT_DA_INSERT(array_, index_, value_) \ do { \ - ptrdiff_t kit_i_; \ - ptrdiff_t const kit_index_back_ = (array_).size; \ - ptrdiff_t const kit_indert_n_ = (index_); \ + ptrdiff_t kit_i_; \ + ptrdiff_t kit_index_back_ = (array_).size; \ + ptrdiff_t kit_indert_n_ = (index_); \ KIT_DA_RESIZE((array_), kit_index_back_ + 1); \ if (kit_index_back_ + 1 == (array_).size) { \ for (kit_i_ = kit_index_back_; kit_i_ > kit_indert_n_; \ diff --git a/source/kit/file.c b/source/kit/file.c index f767851..2d52e92 100644 --- a/source/kit/file.c +++ b/source/kit/file.c @@ -22,14 +22,13 @@ enum { PATH_BUF_SIZE = 4096 }; # define st_mtim st_mtimespec #endif -static int is_delim(char const c) { +static int is_delim(char c) { return c == '/' || c == '\\'; } -static kit_string_t kit_get_env_(char *const name, - kit_allocator_t const alloc) { - char *const val = getenv(name); - ptrdiff_t const size = val != NULL ? (ptrdiff_t) strlen(val) : 0; +static kit_string_t kit_get_env_(char *name, kit_allocator_t alloc) { + char *val = getenv(name); + ptrdiff_t size = val != NULL ? (ptrdiff_t) strlen(val) : 0; string_t result; DA_INIT(result, size, alloc); @@ -43,10 +42,9 @@ static kit_string_t kit_get_env_(char *const name, return result; } -kit_string_t kit_path_norm(kit_str_t const path, - kit_allocator_t const alloc) { - str_t const parent = SZ(".."); - ptrdiff_t i, i1, j; +kit_string_t kit_path_norm(kit_str_t path, kit_allocator_t alloc) { + str_t parent = SZ(".."); + ptrdiff_t i, i1, j; string_t norm; DA_INIT(norm, path.size, alloc); @@ -61,8 +59,7 @@ kit_string_t kit_path_norm(kit_str_t const path, if (!is_delim(path.values[i])) continue; - str_t const s = { .size = i - i1 - 1, - .values = path.values + i1 + 1 }; + str_t s = { .size = i - i1 - 1, .values = path.values + i1 + 1 }; if (AR_EQUAL(s, parent)) { int have_parent = 0; ptrdiff_t i0 = 0; @@ -101,12 +98,11 @@ kit_string_t kit_path_norm(kit_str_t const path, return norm; } -kit_string_t kit_path_join(kit_str_t const left, - kit_str_t const right, - kit_allocator_t const alloc) { - ptrdiff_t left_size = left.size; - ptrdiff_t right_size = right.size; - char const *right_values = right.values; +kit_string_t kit_path_join(kit_str_t left, kit_str_t right, + kit_allocator_t alloc) { + ptrdiff_t left_size = left.size; + ptrdiff_t right_size = right.size; + char *right_values = right.values; if (left_size > 0 && is_delim(left.values[left_size - 1])) left_size--; @@ -129,7 +125,7 @@ kit_string_t kit_path_join(kit_str_t const left, return joined; } -kit_string_t kit_path_user(kit_allocator_t const alloc) { +kit_string_t kit_path_user(kit_allocator_t alloc) { kit_string_t user = kit_get_env_(KIT_ENV_HOME, alloc); if (user.size == 0) { DA_RESIZE(user, 1); @@ -167,8 +163,7 @@ kit_string_t kit_path_cache(kit_allocator_t alloc) { return cache; } -kit_str_t kit_path_index(kit_str_t const path, - ptrdiff_t const index) { +kit_str_t kit_path_index(kit_str_t path, ptrdiff_t index) { str_t s = { .size = 0, .values = NULL }; ptrdiff_t i0 = 0; @@ -198,7 +193,7 @@ kit_str_t kit_path_index(kit_str_t const path, return s; } -kit_str_t kit_path_take(kit_str_t const path, ptrdiff_t const count) { +kit_str_t kit_path_take(kit_str_t path, ptrdiff_t count) { str_t s = { .size = 0, .values = path.values }; ptrdiff_t i0 = 0; @@ -226,8 +221,7 @@ kit_str_t kit_path_take(kit_str_t const path, ptrdiff_t const count) { } #if defined(_WIN32) && !defined(__CYGWIN__) -static void win32_prepare_path_(WCHAR *const buf, - kit_str_t const path) { +static void win32_prepare_path_(WCHAR *buf, kit_str_t path) { assert(path.size == 0 || path.values != NULL); assert(path.size + 5 < PATH_BUF_SIZE); @@ -248,8 +242,7 @@ static void win32_prepare_path_(WCHAR *const buf, WCHAR buf[PATH_BUF_SIZE]; \ win32_prepare_path_(buf, path) #else -static void unix_prepare_path_(char *const buf, - kit_str_t const path) { +static void unix_prepare_path_(char *buf, kit_str_t path) { assert(path.size == 0 || path.values != NULL); assert(path.size + 1 < PATH_BUF_SIZE); @@ -262,7 +255,7 @@ static void unix_prepare_path_(char *const buf, unix_prepare_path_(buf, path) #endif -kit_status_t kit_file_create_folder(kit_str_t const path) { +kit_status_t kit_file_create_folder(kit_str_t path) { PREPARE_PATH_BUF_; #if defined(_WIN32) && !defined(__CYGWIN__) return CreateDirectoryW(buf, NULL) ? KIT_OK @@ -272,16 +265,16 @@ kit_status_t kit_file_create_folder(kit_str_t const path) { #endif } -kit_status_t kit_file_create_folder_recursive(kit_str_t const path) { +kit_status_t kit_file_create_folder_recursive(kit_str_t path) { ptrdiff_t i; for (i = 0;; i++) { - str_t const part = kit_path_take(path, i); - int const type = kit_path_type(part); + str_t part = kit_path_take(path, i); + int type = kit_path_type(part); if (type == KIT_PATH_FILE) return KIT_ERROR_FILE_ALREADY_EXISTS; if (type == KIT_PATH_NONE) { - kit_status_t const s = kit_file_create_folder(part); + kit_status_t s = kit_file_create_folder(part); if (s != KIT_OK) return s; } @@ -292,7 +285,7 @@ kit_status_t kit_file_create_folder_recursive(kit_str_t const path) { return KIT_OK; } -kit_status_t kit_file_remove(kit_str_t const path) { +kit_status_t kit_file_remove(kit_str_t path) { PREPARE_PATH_BUF_; #if defined(_WIN32) && !defined(__CYGWIN__) return DeleteFileW(buf) ? KIT_OK : KIT_ERROR_UNLINK_FAILED; @@ -301,7 +294,7 @@ kit_status_t kit_file_remove(kit_str_t const path) { #endif } -kit_status_t kit_file_remove_folder(kit_str_t const path) { +kit_status_t kit_file_remove_folder(kit_str_t path) { PREPARE_PATH_BUF_; #if defined(_WIN32) && !defined(__CYGWIN__) return RemoveDirectoryW(buf) ? KIT_OK : KIT_ERROR_RMDIR_FAILED; @@ -310,8 +303,8 @@ kit_status_t kit_file_remove_folder(kit_str_t const path) { #endif } -kit_status_t kit_file_remove_recursive(kit_str_t const path, - kit_allocator_t const alloc) { +kit_status_t kit_file_remove_recursive(kit_str_t path, + kit_allocator_t alloc) { int type = kit_path_type(path); ptrdiff_t i; @@ -325,8 +318,8 @@ kit_status_t kit_file_remove_recursive(kit_str_t const path, return list.status; } for (i = 0; i < list.files.size; i++) { - str_t const s = { .size = list.files.values[i].size, - .values = list.files.values[i].values }; + str_t s = { .size = list.files.values[i].size, + .values = list.files.values[i].values }; kit_file_remove_recursive(s, alloc); } kit_path_list_destroy(list); @@ -339,7 +332,7 @@ kit_status_t kit_file_remove_recursive(kit_str_t const path, return KIT_ERROR_FILE_DO_NOT_EXIST; } -kit_path_type_t kit_path_type(kit_str_t const path) { +kit_path_type_t kit_path_type(kit_str_t path) { PREPARE_PATH_BUF_; #if defined(_WIN32) && !defined(__CYGWIN__) if (PathFileExistsW(buf)) { @@ -360,7 +353,7 @@ kit_path_type_t kit_path_type(kit_str_t const path) { return KIT_PATH_NONE; } -kit_file_info_t kit_file_info(kit_str_t const path) { +kit_file_info_t kit_file_info(kit_str_t path) { kit_file_info_t result; memset(&result, 0, sizeof result); @@ -372,9 +365,8 @@ kit_file_info_t kit_file_info(kit_str_t const path) { if (f != INVALID_HANDLE_VALUE) { FILETIME ft; if (GetFileTime(f, NULL, NULL, &ft) != 0) { - uint64_t const nsec100 = (((uint64_t) ft.dwHighDateTime) - << 32) | - (uint64_t) ft.dwLowDateTime; + uint64_t nsec100 = (((uint64_t) ft.dwHighDateTime) << 32) | + (uint64_t) ft.dwLowDateTime; result.time_modified_sec = (int64_t) (nsec100 / 10000000); result.time_modified_nsec = (int32_t) (100 * (nsec100 % 10000000)); @@ -413,8 +405,8 @@ kit_file_info_t kit_file_info(kit_str_t const path) { return result; } -kit_path_list_t kit_file_enum_folder(kit_str_t const path, - kit_allocator_t const alloc) { +kit_path_list_t kit_file_enum_folder(kit_str_t path, + kit_allocator_t alloc) { PREPARE_PATH_BUF_; kit_path_list_t result = { .status = KIT_OK }; @@ -436,7 +428,7 @@ kit_path_list_t kit_file_enum_folder(kit_str_t const path, return result; do { - ptrdiff_t const n = result.files.size; + ptrdiff_t n = result.files.size; DA_RESIZE(result.files, n + 1); if (result.files.size != n + 1) { result.status = KIT_ERROR_BAD_ALLOC; @@ -472,14 +464,14 @@ kit_path_list_t kit_file_enum_folder(kit_str_t const path, if (entry->d_name[0] == '.') continue; - ptrdiff_t const n = result.files.size; + ptrdiff_t n = result.files.size; DA_RESIZE(result.files, n + 1); if (result.files.size != n + 1) { result.status = KIT_ERROR_BAD_ALLOC; break; } - ptrdiff_t const size = (ptrdiff_t) strlen(entry->d_name); + ptrdiff_t size = (ptrdiff_t) strlen(entry->d_name); DA_INIT(result.files.values[n], size, alloc); if (result.files.values[n].size != size) { DA_RESIZE(result.files, n); diff --git a/source/kit/input_buffer.c b/source/kit/input_buffer.c index c59031f..2ba3f4c 100644 --- a/source/kit/input_buffer.c +++ b/source/kit/input_buffer.c @@ -13,8 +13,8 @@ typedef struct { static internal_buffer_t *buf_init(kit_is_handle_t upstream, kit_allocator_t alloc) { assert(alloc.allocate != NULL); - internal_buffer_t *const buf = kit_alloc_dispatch( - alloc, KIT_ALLOCATE, sizeof *buf, 0, NULL); + internal_buffer_t *buf = kit_alloc_dispatch(alloc, KIT_ALLOCATE, + sizeof *buf, 0, NULL); if (buf != NULL) { memset(buf, 0, sizeof *buf); @@ -42,7 +42,7 @@ static void buf_acquire(void *p) { static void buf_release(void *p) { assert(p != NULL); - internal_buffer_t *const buf = (internal_buffer_t *) p; + internal_buffer_t *buf = (internal_buffer_t *) p; if (--buf->ref_count == 0) { DA_DESTROY(buf->data); @@ -54,21 +54,20 @@ static void buf_adjust(void *p, ptrdiff_t size) { assert(p != NULL); assert(size >= 0); - internal_buffer_t *const buf = (internal_buffer_t *) p; - ptrdiff_t const offset = buf->data.size; + internal_buffer_t *buf = (internal_buffer_t *) p; + ptrdiff_t offset = buf->data.size; if (offset < size) { DA_RESIZE(buf->data, size); - kit_out_str_t destination = { - .size = size - offset, .values = buf->data.values + offset - }; - ptrdiff_t n = KIT_IS_READ(buf->upstream, destination); + kit_str_t destination = { .size = size - offset, + .values = buf->data.values + offset }; + ptrdiff_t n = KIT_IS_READ(buf->upstream, destination); DA_RESIZE(buf->data, offset + n); } } static ptrdiff_t buf_read(void *p, ptrdiff_t offset, - kit_out_str_t destination) { + kit_str_t destination) { internal_buffer_t *buf = (internal_buffer_t *) p; ptrdiff_t n = destination.size < buf->data.size - offset ? destination.size @@ -105,11 +104,11 @@ kit_ib_handle_t kit_ib_read(kit_ib_handle_t buf, ptrdiff_t size) { if (next.data.size != size) next.status = KIT_ERROR_BAD_ALLOC; - kit_out_str_t destination = { .size = next.data.size, - .values = next.data.values }; - ptrdiff_t const n = buf_read(buf.internal, buf.offset, destination); - next.offset = buf.offset + n; - next.internal = buf.internal; + kit_str_t destination = { .size = next.data.size, + .values = next.data.values }; + ptrdiff_t n = buf_read(buf.internal, buf.offset, destination); + next.offset = buf.offset + n; + next.internal = buf.internal; DA_RESIZE(next.data, n); if (next.data.size != n) @@ -141,10 +140,10 @@ kit_ib_handle_t kit_ib_read_while( if (next.data.size != size + 1) next.status = KIT_ERROR_BAD_ALLOC; - kit_out_str_t destination = { .size = 1, - .values = next.data.values + size }; - ptrdiff_t const n = buf_read(buf.internal, buf.offset + size, - destination); + kit_str_t destination = { .size = 1, + .values = next.data.values + size }; + ptrdiff_t n = buf_read(buf.internal, buf.offset + size, + destination); kit_str_t data = { .size = size + 1, .values = next.data.values }; if (n != 1 || condition == NULL || condition(data) == 0) diff --git a/source/kit/input_stream.c b/source/kit/input_stream.c index 7d8476b..0ca2ee0 100644 --- a/source/kit/input_stream.c +++ b/source/kit/input_stream.c @@ -20,7 +20,7 @@ static int check_type(void *state, ptrdiff_t type) { return basic != NULL && basic->type == type; } -static ptrdiff_t read_str(void *state, kit_out_str_t destination) { +static ptrdiff_t read_str(void *state, kit_str_t destination) { if (!check_type(state, input_stream_str)) return 0; kit_is_state_str_t *str = (kit_is_state_str_t *) state; diff --git a/source/kit/input_stream.h b/source/kit/input_stream.h index 213d2ca..b3c3ae6 100644 --- a/source/kit/input_stream.h +++ b/source/kit/input_stream.h @@ -8,8 +8,8 @@ extern "C" { #endif -typedef ptrdiff_t (*kit_is_read_fn)(void *state, - kit_out_str_t destination); +typedef ptrdiff_t (*kit_is_read_fn)(void *state, + kit_str_t destination); typedef struct { void *state; diff --git a/source/kit/mersenne_twister_64.c b/source/kit/mersenne_twister_64.c index c40806e..9bf238f 100644 --- a/source/kit/mersenne_twister_64.c +++ b/source/kit/mersenne_twister_64.c @@ -5,9 +5,8 @@ #define UM 0xffffffff80000000ull #define LM 0x7fffffffull -void kit_mt64_init_array(kit_mt64_state_t *const state, - ptrdiff_t const size, - uint64_t const *const seed) { +void kit_mt64_init_array(kit_mt64_state_t *state, ptrdiff_t size, + uint64_t *seed) { ptrdiff_t i; for (i = 0; i < size && i < KIT_MT64_N; i++) state->mt[i] = seed[i]; for (state->index = size; state->index < KIT_MT64_N; state->index++) @@ -18,13 +17,12 @@ void kit_mt64_init_array(kit_mt64_state_t *const state, state->index); } -void kit_mt64_init(kit_mt64_state_t *const state, - uint64_t const seed) { +void kit_mt64_init(kit_mt64_state_t *state, uint64_t seed) { kit_mt64_init_array(state, 1, &seed); } -void kit_mt64_rotate(kit_mt64_state_t *const state) { - static uint64_t const mag01[2] = { 0ull, MATRIX_A }; +void kit_mt64_rotate(kit_mt64_state_t *state) { + static uint64_t mag01[2] = { 0ull, MATRIX_A }; uint64_t x; int i; @@ -48,7 +46,7 @@ void kit_mt64_rotate(kit_mt64_state_t *const state) { state->index = 0; } -uint64_t kit_mt64_generate(kit_mt64_state_t *const state) { +uint64_t kit_mt64_generate(kit_mt64_state_t *state) { if (state->index >= KIT_MT64_N) kit_mt64_rotate(state); diff --git a/source/kit/mersenne_twister_64.h b/source/kit/mersenne_twister_64.h index 548aea4..452fd73 100644 --- a/source/kit/mersenne_twister_64.h +++ b/source/kit/mersenne_twister_64.h @@ -22,7 +22,7 @@ typedef struct { } kit_mt64_state_t; void kit_mt64_init_array(kit_mt64_state_t *state, ptrdiff_t size, - uint64_t const *seed); + uint64_t *seed); void kit_mt64_init(kit_mt64_state_t *state, uint64_t seed); void kit_mt64_rotate(kit_mt64_state_t *state); uint64_t kit_mt64_generate(kit_mt64_state_t *state); diff --git a/source/kit/mutex.h b/source/kit/mutex.h index 919d92a..ada3a5f 100644 --- a/source/kit/mutex.h +++ b/source/kit/mutex.h @@ -41,7 +41,7 @@ void mtx_destroy(mtx_t *mtx_); int mtx_init(mtx_t *mtx_, int); int mtx_lock(mtx_t *mtx_); int mtx_timedlock(mtx_t *__restrict mtx_, - const struct timespec *__restrict); + struct timespec const *__restrict); int mtx_trylock(mtx_t *mtx_); int mtx_unlock(mtx_t *mtx_); diff --git a/source/kit/secure_random.c b/source/kit/secure_random.c index 022741a..20b3bf8 100644 --- a/source/kit/secure_random.c +++ b/source/kit/secure_random.c @@ -38,8 +38,7 @@ static void secure_random_fallback_init(void) { } #endif -static void secure_random_fallback(ptrdiff_t const size, - void *const data) { +static void secure_random_fallback(ptrdiff_t size, void *data) { #ifndef KIT_DISABLE_SYSTEM_THREADS call_once(&kit_secure_random_fallback_flag, secure_random_fallback_init); @@ -61,17 +60,16 @@ static void secure_random_fallback(ptrdiff_t const size, kit_mt64_state_t state; if (time_sec == 0 && time_nsec == 0) { - uint64_t const seed[] = { n, get_available_memory(), - (uint64_t) t.tv_sec, - (uint64_t) t.tv_nsec }; + uint64_t seed[] = { n, get_available_memory(), + (uint64_t) t.tv_sec, (uint64_t) t.tv_nsec }; kit_mt64_init_array(&state, sizeof seed / sizeof *seed, seed); } else { - uint64_t const seed[] = { n, - get_available_memory(), - (uint64_t) t.tv_sec, - (uint64_t) t.tv_nsec, - (uint64_t) t.tv_sec - time_sec, - (uint64_t) t.tv_nsec - time_nsec }; + uint64_t seed[] = { n, + get_available_memory(), + (uint64_t) t.tv_sec, + (uint64_t) t.tv_nsec, + (uint64_t) t.tv_sec - time_sec, + (uint64_t) t.tv_nsec - time_nsec }; kit_mt64_init_array(&state, sizeof seed / sizeof *seed, seed); } @@ -90,7 +88,7 @@ static void secure_random_fallback(ptrdiff_t const size, #endif } -void kit_secure_random(ptrdiff_t const size, void *const data) { +void kit_secure_random(ptrdiff_t size, void *data) { assert(size > 0); assert(data != NULL); @@ -108,7 +106,7 @@ void kit_secure_random(ptrdiff_t const size, void *const data) { return; } - size_t const n = fread(data, 1, size, f); + size_t n = fread(data, 1, size, f); fclose(f); assert(n == size); diff --git a/source/kit/secure_random.h b/source/kit/secure_random.h index 21399b7..5531a4a 100644 --- a/source/kit/secure_random.h +++ b/source/kit/secure_random.h @@ -5,8 +5,6 @@ # define _GNU_SOURCE #endif -#include "status.h" - #include #include diff --git a/source/kit/sha256.c b/source/kit/sha256.c index 9c99c53..beb1772 100644 --- a/source/kit/sha256.c +++ b/source/kit/sha256.c @@ -13,7 +13,7 @@ #define SIG0(x) (ROTRIGHT(x, 7) ^ ROTRIGHT(x, 18) ^ ((x) >> 3)) #define SIG1(x) (ROTRIGHT(x, 17) ^ ROTRIGHT(x, 19) ^ ((x) >> 10)) -static const uint32_t k[64] = { +static uint32_t kit_sha256_k[64] = { 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, @@ -29,8 +29,7 @@ static const uint32_t k[64] = { 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 }; -static void sha256_transform(uint32_t *const state, - const uint8_t *const data) { +static void kit_sha256_transform(uint32_t *state, uint8_t *data) { assert(state != NULL); assert(data != NULL); @@ -53,7 +52,7 @@ static void sha256_transform(uint32_t *const state, h = state[7]; for (i = 0; i < 64; ++i) { - t1 = h + EP1(e) + CH(e, f, g) + k[i] + m[i]; + t1 = h + EP1(e) + CH(e, f, g) + kit_sha256_k[i] + m[i]; t2 = EP0(a) + MAJ(a, b, c); h = g; g = f; @@ -75,8 +74,7 @@ static void sha256_transform(uint32_t *const state, state[7] += h; } -kit_sha256_hash_t kit_sha256(ptrdiff_t const in_size, - uint8_t const *const in_data) { +kit_sha256_hash_t kit_sha256(ptrdiff_t in_size, uint8_t *in_data) { assert(in_size >= 0); assert(in_data != NULL); @@ -98,7 +96,7 @@ kit_sha256_hash_t kit_sha256(ptrdiff_t const in_size, if (datalen != 64) continue; - sha256_transform(state, data); + kit_sha256_transform(state, data); bitlen += 512; datalen = 0; } @@ -112,7 +110,7 @@ kit_sha256_hash_t kit_sha256(ptrdiff_t const in_size, data[i++] = 0x80; while (i < 64) data[i++] = 0x00; - sha256_transform(state, data); + kit_sha256_transform(state, data); memset(data, 0, 56); } @@ -126,7 +124,7 @@ kit_sha256_hash_t kit_sha256(ptrdiff_t const in_size, data[57] = bitlen >> 48; data[56] = bitlen >> 56; - sha256_transform(state, data); + kit_sha256_transform(state, data); kit_sha256_hash_t hash; memset(&hash, 0, sizeof hash); diff --git a/source/kit/sha256.h b/source/kit/sha256.h index ce74ed9..182ee80 100644 --- a/source/kit/sha256.h +++ b/source/kit/sha256.h @@ -18,7 +18,7 @@ typedef struct { uint8_t v[KIT_SHA256_BLOCK_SIZE]; } kit_sha256_hash_t; -kit_sha256_hash_t kit_sha256(ptrdiff_t size, uint8_t const *data); +kit_sha256_hash_t kit_sha256(ptrdiff_t size, uint8_t *data); #ifdef __cplusplus } diff --git a/source/kit/sockets.h b/source/kit/sockets.h index 87e37e6..2d4af90 100644 --- a/source/kit/sockets.h +++ b/source/kit/sockets.h @@ -23,15 +23,6 @@ # define socket_t SOCKET # define socklen_t int -//# define EINPROGRESS WSAEINPROGRESS -//# define EWOULDBLOCK WSAEWOULDBLOCK -//# define EMSGSIZE WSAEMSGSIZE -//# define EISCONN WSAEISCONN -//# define ECONNRESET WSAECONNRESET -//# define EADDRINUSE WSAEADDRINUSE - -//# define errno ((int) WSAGetLastError()) - # ifdef __cplusplus extern "C" { # endif diff --git a/source/kit/string_ref.h b/source/kit/string_ref.h index 8cf1970..b171840 100644 --- a/source/kit/string_ref.h +++ b/source/kit/string_ref.h @@ -9,10 +9,8 @@ extern "C" { #endif -typedef KIT_AR_MUT(char) kit_string_mut_t; typedef KIT_AR(char) kit_string_ref_t; -typedef kit_string_mut_t kit_out_str_t; typedef kit_string_ref_t kit_str_t; #ifdef __GNUC__ @@ -23,9 +21,8 @@ typedef kit_string_ref_t kit_str_t; # pragma GCC optimize("O3") #endif -static kit_str_t kit_str(ptrdiff_t const size, - char const *const static_string) { - kit_str_t const s = { .size = size, .values = static_string }; +static kit_str_t kit_str(ptrdiff_t size, char *static_string) { + kit_str_t s = { .size = size, .values = static_string }; return s; } @@ -33,16 +30,16 @@ static kit_str_t kit_str(ptrdiff_t const size, * Not thread safe. * Use with caution. */ -static char const *kit_make_bs(kit_str_t const s) { +static char *kit_make_bs(kit_str_t s) { static char buf[8][4096]; static int index = 0; ptrdiff_t n = s.size; if (n > 4095) n = 4095; memcpy(buf[index], s.values, n); - buf[index][n] = '\0'; - char const *result = buf[index]; - index = (index + 1) % 8; + buf[index][n] = '\0'; + char *result = buf[index]; + index = (index + 1) % 8; return result; } @@ -62,9 +59,7 @@ static char const *kit_make_bs(kit_str_t const s) { #ifndef KIT_DISABLE_SHORT_NAMES # define BS(string_) kit_make_bs(KIT_WRAP_STR(string_)) -# define string_mut_t kit_string_mut_t # define string_ref_t kit_string_ref_t -# define out_str_t kit_out_str_t # define str_t kit_str_t # define SZ KIT_SZ diff --git a/source/kit/thread.posix.c b/source/kit/thread.posix.c index ee5d439..79a71e8 100644 --- a/source/kit/thread.posix.c +++ b/source/kit/thread.posix.c @@ -75,7 +75,7 @@ int cnd_signal(cnd_t *cond) { } int cnd_timedwait(cnd_t *cond, mtx_t *mtx, - const struct timespec *abs_time) { + struct timespec const *abs_time) { int rt; assert(mtx != NULL); diff --git a/source/tests/_static.c b/source/tests/_static.c index 4b7543d..54587d3 100644 --- a/source/tests/_static.c +++ b/source/tests/_static.c @@ -43,7 +43,7 @@ #include "string_ref.test.c" #undef KIT_TEST_FILE -#include "test_duration.test.c" +#include "duration.test.c" #undef KIT_TEST_FILE #include "thread.test.c" diff --git a/source/tests/array_ref.test.c b/source/tests/array_ref.test.c index da20aa0..cb19850 100644 --- a/source/tests/array_ref.test.c +++ b/source/tests/array_ref.test.c @@ -3,7 +3,7 @@ #define KIT_TEST_FILE array_ref #include "../kit_test/test.h" -TEST("array ref const wrap") { +TEST("array ref wrap") { int foo[] = { 1, 2, 3 }; AR_WRAP(ref, int, foo); @@ -15,7 +15,7 @@ TEST("array ref const wrap") { TEST("array ref wrap") { int foo[] = { 1, 2, 3 }; - AR_MUT_WRAP(ref, int, foo); + AR_WRAP(ref, int, foo); REQUIRE(ref.size == 3); REQUIRE(ref.values[0] == 1); @@ -36,7 +36,7 @@ TEST("array ref equal") { REQUIRE(AR_EQUAL(foo_ref, bar_ref)); } -static int compare(int const *left, int const *right) { +static int compare(int *left, int *right) { return *left - *right; } diff --git a/source/tests/cpp.cpp b/source/tests/cpp.cpp deleted file mode 100644 index 8b762e4..0000000 --- a/source/tests/cpp.cpp +++ /dev/null @@ -1,13 +0,0 @@ -#include "../kit_test/test.h" - -TEST("foo") { - REQUIRE(20 + 22 == 42); -} - -TEST("bar") { - REQUIRE(true); -} - -int main(int argc, char **argv) { - return run_tests(argc, argv); -} diff --git a/source/tests/duration.test.c b/source/tests/duration.test.c new file mode 100644 index 0000000..56919e4 --- /dev/null +++ b/source/tests/duration.test.c @@ -0,0 +1,19 @@ +#define KIT_TEST_FILE duration +#include "../kit_test/test.h" + +#if defined(_WIN32) && !defined(__CYGWIN__) +__declspec(dllimport) void __stdcall Sleep(unsigned long timeout); +static void kit_sleep(int ms) { + Sleep(ms); +} +#else +# include +# include +static void kit_sleep(int ms) { + usleep(ms * 1000); +} +#endif + +TEST("test duration") { + kit_sleep(100); +} diff --git a/source/tests/input_stream.test.c b/source/tests/input_stream.test.c index 61c2254..46ee0dd 100644 --- a/source/tests/input_stream.test.c +++ b/source/tests/input_stream.test.c @@ -12,8 +12,8 @@ TEST("input stream wrap string") { is_handle_t in = IS_WRAP_STRING(foo_ref); - char buf[4]; - out_str_t buf_ref = { .size = sizeof(buf), .values = buf }; + char buf[4]; + str_t buf_ref = { .size = sizeof(buf), .values = buf }; REQUIRE(IS_READ(in, buf_ref) == buf_ref.size); REQUIRE(AR_EQUAL(foo_ref, bar_ref)); diff --git a/source/tests/lower_bound.test.c b/source/tests/lower_bound.test.c index 3b62325..56ec816 100644 --- a/source/tests/lower_bound.test.c +++ b/source/tests/lower_bound.test.c @@ -8,7 +8,7 @@ static int kit_less_int(int left, int right) { return left < right; } -static int kit_less_int_ref(int const *left, int const *right) { +static int kit_less_int_ref(int *left, int *right) { return *left < *right; } @@ -21,8 +21,8 @@ TEST("lower bound empty") { } TEST("lower bound single left") { - int const v[1] = { 42 }; - AR(int) ref = { .size = 1, .values = v }; + int v[1] = { 42 }; + AR(int) ref = { .size = 1, .values = v }; ptrdiff_t index; LOWER_BOUND(index, ref, 42, kit_less_int); @@ -30,8 +30,8 @@ TEST("lower bound single left") { } TEST("lower bound single right") { - int const v[1] = { 42 }; - AR(int) ref = { .size = 1, .values = v }; + int v[1] = { 42 }; + AR(int) ref = { .size = 1, .values = v }; ptrdiff_t index; LOWER_BOUND(index, ref, 43, kit_less_int); @@ -39,8 +39,8 @@ TEST("lower bound single right") { } TEST("lower bound first of four") { - int const v[4] = { 1, 2, 3, 4 }; - AR(int) ref = { .size = 4, .values = v }; + int v[4] = { 1, 2, 3, 4 }; + AR(int) ref = { .size = 4, .values = v }; ptrdiff_t index; LOWER_BOUND(index, ref, 1, kit_less_int); @@ -48,8 +48,8 @@ TEST("lower bound first of four") { } TEST("lower bound second of four") { - int const v[4] = { 1, 2, 3, 4 }; - AR(int) ref = { .size = 4, .values = v }; + int v[4] = { 1, 2, 3, 4 }; + AR(int) ref = { .size = 4, .values = v }; ptrdiff_t index; LOWER_BOUND(index, ref, 2, kit_less_int); @@ -57,8 +57,8 @@ TEST("lower bound second of four") { } TEST("lower bound third of four") { - int const v[4] = { 1, 2, 3, 4 }; - AR(int) ref = { .size = 4, .values = v }; + int v[4] = { 1, 2, 3, 4 }; + AR(int) ref = { .size = 4, .values = v }; ptrdiff_t index; LOWER_BOUND(index, ref, 3, kit_less_int); @@ -66,8 +66,8 @@ TEST("lower bound third of four") { } TEST("lower bound forth of four") { - int const v[4] = { 1, 2, 3, 4 }; - AR(int) ref = { .size = 4, .values = v }; + int v[4] = { 1, 2, 3, 4 }; + AR(int) ref = { .size = 4, .values = v }; ptrdiff_t index; LOWER_BOUND(index, ref, 4, kit_less_int); @@ -75,8 +75,8 @@ TEST("lower bound forth of four") { } TEST("lower bound fifth of four") { - int const v[4] = { 1, 2, 3, 4 }; - AR(int) ref = { .size = 4, .values = v }; + int v[4] = { 1, 2, 3, 4 }; + AR(int) ref = { .size = 4, .values = v }; ptrdiff_t index; LOWER_BOUND(index, ref, 5, kit_less_int); @@ -84,8 +84,8 @@ TEST("lower bound fifth of four") { } TEST("lower bound first of five") { - int const v[5] = { 1, 2, 3, 4, 5 }; - AR(int) ref = { .size = 5, .values = v }; + int v[5] = { 1, 2, 3, 4, 5 }; + AR(int) ref = { .size = 5, .values = v }; ptrdiff_t index; LOWER_BOUND(index, ref, 1, kit_less_int); @@ -93,8 +93,8 @@ TEST("lower bound first of five") { } TEST("lower bound second of five") { - int const v[5] = { 1, 2, 3, 4, 5 }; - AR(int) ref = { .size = 5, .values = v }; + int v[5] = { 1, 2, 3, 4, 5 }; + AR(int) ref = { .size = 5, .values = v }; ptrdiff_t index; LOWER_BOUND(index, ref, 2, kit_less_int); @@ -102,8 +102,8 @@ TEST("lower bound second of five") { } TEST("lower bound third of five") { - int const v[5] = { 1, 2, 3, 4, 5 }; - AR(int) ref = { .size = 5, .values = v }; + int v[5] = { 1, 2, 3, 4, 5 }; + AR(int) ref = { .size = 5, .values = v }; ptrdiff_t index; LOWER_BOUND(index, ref, 3, kit_less_int); @@ -111,8 +111,8 @@ TEST("lower bound third of five") { } TEST("lower bound forth of five") { - int const v[5] = { 1, 2, 3, 4, 5 }; - AR(int) ref = { .size = 5, .values = v }; + int v[5] = { 1, 2, 3, 4, 5 }; + AR(int) ref = { .size = 5, .values = v }; ptrdiff_t index; LOWER_BOUND(index, ref, 4, kit_less_int); @@ -120,8 +120,8 @@ TEST("lower bound forth of five") { } TEST("lower bound fifth of five") { - int const v[5] = { 1, 2, 3, 4, 5 }; - AR(int) ref = { .size = 5, .values = v }; + int v[5] = { 1, 2, 3, 4, 5 }; + AR(int) ref = { .size = 5, .values = v }; ptrdiff_t index; LOWER_BOUND(index, ref, 5, kit_less_int); @@ -129,8 +129,8 @@ TEST("lower bound fifth of five") { } TEST("lower bound sixth of five") { - int const v[5] = { 1, 2, 3, 4, 5 }; - AR(int) ref = { .size = 5, .values = v }; + int v[5] = { 1, 2, 3, 4, 5 }; + AR(int) ref = { .size = 5, .values = v }; ptrdiff_t index; LOWER_BOUND(index, ref, 6, kit_less_int); @@ -138,9 +138,9 @@ TEST("lower bound sixth of five") { } TEST("lower bound ref first of four") { - int const v[4] = { 1, 2, 3, 4 }; - int const value = 1; - AR(int) ref = { .size = 4, .values = v }; + int v[4] = { 1, 2, 3, 4 }; + int value = 1; + AR(int) ref = { .size = 4, .values = v }; ptrdiff_t index; LOWER_BOUND_REF(index, ref, &value, kit_less_int_ref); @@ -148,9 +148,9 @@ TEST("lower bound ref first of four") { } TEST("lower bound ref second of four") { - int const v[4] = { 1, 2, 3, 4 }; - int const value = 2; - AR(int) ref = { .size = 4, .values = v }; + int v[4] = { 1, 2, 3, 4 }; + int value = 2; + AR(int) ref = { .size = 4, .values = v }; ptrdiff_t index; LOWER_BOUND_REF(index, ref, &value, kit_less_int_ref); @@ -158,9 +158,9 @@ TEST("lower bound ref second of four") { } TEST("lower bound ref fifth of five") { - int const v[5] = { 1, 2, 3, 4, 5 }; - int const value = 5; - AR(int) ref = { .size = 5, .values = v }; + int v[5] = { 1, 2, 3, 4, 5 }; + int value = 5; + AR(int) ref = { .size = 5, .values = v }; ptrdiff_t index; LOWER_BOUND_REF(index, ref, &value, kit_less_int_ref); @@ -168,9 +168,9 @@ TEST("lower bound ref fifth of five") { } TEST("lower bound ref sixth of five") { - int const v[5] = { 1, 2, 3, 4, 5 }; - int const value = 6; - AR(int) ref = { .size = 5, .values = v }; + int v[5] = { 1, 2, 3, 4, 5 }; + int value = 6; + AR(int) ref = { .size = 5, .values = v }; ptrdiff_t index; LOWER_BOUND_REF(index, ref, &value, kit_less_int_ref); diff --git a/source/tests/main.test.c b/source/tests/main.test.c index 2a41d4b..790c8c2 100644 --- a/source/tests/main.test.c +++ b/source/tests/main.test.c @@ -1,9 +1,10 @@ +#include "../kit/status.h" #include "../kit_test/bench.h" #include "../kit_test/test.h" int main(int argc, char **argv) { int status = run_tests(argc, argv); - if (status == 0) + if (status == KIT_OK) status = run_benchmarks(argc, argv); return status; } diff --git a/source/tests/move_back.test.c b/source/tests/move_back.test.c index f08d190..f3f6dc4 100644 --- a/source/tests/move_back.test.c +++ b/source/tests/move_back.test.c @@ -3,19 +3,19 @@ #define KIT_TEST_FILE move_back #include "../kit_test/test.h" -static int is_equal(int const x, int const y) { +static int is_equal(int x, int y) { return x == y; } -static int is_equal_ref(int const *const x, int const y) { +static int is_equal_ref(int *x, int y) { return *x == y; } -static int is_even(int const x, int const _) { +static int is_even(int x, int _) { return (x % 2) == 0; } -static int is_even_ref(int const *const x, int const _) { +static int is_even_ref(int *x, int _) { return (*x % 2) == 0; } diff --git a/source/tests/signals.cpp b/source/tests/signals.cpp deleted file mode 100644 index 0f6d77a..0000000 --- a/source/tests/signals.cpp +++ /dev/null @@ -1,29 +0,0 @@ -#include "../kit_test/test.h" - -#include -#include - -/* FIXME - * MSVC tests fail in GitHub Actions. - */ - -TEST("c++ exception") { - throw std::exception(); -} - -TEST("abort") { - abort(); -} - -TEST("invalid access") { - *(volatile int *) nullptr = 42; -} - -int main(int argc, char **argv) { -#ifndef _MSC_VER - if (run_tests(argc, argv) != 1) - return 1; -#endif - - return 0; -} diff --git a/source/tests/test_cpp.cpp b/source/tests/test_cpp.cpp new file mode 100644 index 0000000..8b762e4 --- /dev/null +++ b/source/tests/test_cpp.cpp @@ -0,0 +1,13 @@ +#include "../kit_test/test.h" + +TEST("foo") { + REQUIRE(20 + 22 == 42); +} + +TEST("bar") { + REQUIRE(true); +} + +int main(int argc, char **argv) { + return run_tests(argc, argv); +} diff --git a/source/tests/test_duration.test.c b/source/tests/test_duration.test.c deleted file mode 100644 index 27384b4..0000000 --- a/source/tests/test_duration.test.c +++ /dev/null @@ -1,19 +0,0 @@ -#define KIT_TEST_FILE test_duration -#include "../kit_test/test.h" - -#if defined(_WIN32) && !defined(__CYGWIN__) -__declspec(dllimport) void __stdcall Sleep(unsigned long timeout); -static void kit_sleep(int ms) { - Sleep(ms); -} -#else -# include -# include -static void kit_sleep(int ms) { - usleep(ms * 1000); -} -#endif - -TEST("test duration") { - kit_sleep(100); -} diff --git a/source/tests/test_signals.cpp b/source/tests/test_signals.cpp new file mode 100644 index 0000000..0f6d77a --- /dev/null +++ b/source/tests/test_signals.cpp @@ -0,0 +1,29 @@ +#include "../kit_test/test.h" + +#include +#include + +/* FIXME + * MSVC tests fail in GitHub Actions. + */ + +TEST("c++ exception") { + throw std::exception(); +} + +TEST("abort") { + abort(); +} + +TEST("invalid access") { + *(volatile int *) nullptr = 42; +} + +int main(int argc, char **argv) { +#ifndef _MSC_VER + if (run_tests(argc, argv) != 1) + return 1; +#endif + + return 0; +} diff --git a/source/tests/test_too_many_assertions.c b/source/tests/test_too_many_assertions.c new file mode 100644 index 0000000..662207d --- /dev/null +++ b/source/tests/test_too_many_assertions.c @@ -0,0 +1,13 @@ +#include "../kit_test/test.h" + +TEST("foo") { + int i; + for (i = 0; i <= KIT_TEST_ASSERTIONS_LIMIT; i++) REQUIRE(1); +} + +int main(int argc, char **argv) { + if (run_tests(argc, argv) != 1) + return 1; + + return 0; +} diff --git a/source/tests/test_too_many_tests.c b/source/tests/test_too_many_tests.c new file mode 100644 index 0000000..d4842e4 --- /dev/null +++ b/source/tests/test_too_many_tests.c @@ -0,0 +1,14 @@ +#include "../kit_test/test.h" + +void bar(int index, kit_test_report_fn report) { } + +int main(int argc, char **argv) { + int i; + for (i = 0; i <= KIT_TESTS_SIZE_LIMIT; i++) + test_register("foo", __FILE__, bar); + + if (run_tests(argc, argv) != 1) + return 1; + + return 0; +} diff --git a/source/tests/too_many_assertions.c b/source/tests/too_many_assertions.c deleted file mode 100644 index 662207d..0000000 --- a/source/tests/too_many_assertions.c +++ /dev/null @@ -1,13 +0,0 @@ -#include "../kit_test/test.h" - -TEST("foo") { - int i; - for (i = 0; i <= KIT_TEST_ASSERTIONS_LIMIT; i++) REQUIRE(1); -} - -int main(int argc, char **argv) { - if (run_tests(argc, argv) != 1) - return 1; - - return 0; -} diff --git a/source/tests/too_many_tests.c b/source/tests/too_many_tests.c deleted file mode 100644 index d4842e4..0000000 --- a/source/tests/too_many_tests.c +++ /dev/null @@ -1,14 +0,0 @@ -#include "../kit_test/test.h" - -void bar(int index, kit_test_report_fn report) { } - -int main(int argc, char **argv) { - int i; - for (i = 0; i <= KIT_TESTS_SIZE_LIMIT; i++) - test_register("foo", __FILE__, bar); - - if (run_tests(argc, argv) != 1) - return 1; - - return 0; -} -- cgit v1.2.3