diff options
| -rw-r--r-- | Makefile | 3 | ||||
| -rw-r--r-- | README.md | 3 | ||||
| -rw-r--r-- | include/moslib/ds/array.h | 100 | ||||
| -rw-r--r-- | include/moslib/ds/hashmap.h | 64 | ||||
| -rw-r--r-- | include/moslib/string.h | 30 | ||||
| -rw-r--r-- | include/moslib/tester.h | 36 | ||||
| -rw-r--r-- | src/ds/array.c | 27 | ||||
| -rw-r--r-- | src/ds/hashmap.c | 11 | ||||
| -rw-r--r-- | src/tester.c | 8 | ||||
| -rw-r--r-- | tests/ds/array_tests.c | 37 | ||||
| -rw-r--r-- | tests/ds/hashmap_tests.c | 21 | ||||
| -rw-r--r-- | tests/string_tests.c | 96 |
12 files changed, 282 insertions, 154 deletions
@@ -7,7 +7,8 @@ RUN_TESTS=./run_tests ifneq ($(shell uname -s),Darwin) CFLAGS+= -s else - RUN_TESTS=DYLD_FALLBACK_LIBRARY_PATH="/usr/local/lib:$DYLD_FALLBACK_LIBRARY_PATH" ./run_tests; rm -rf run_tests.dSYM/ + RUN_TESTS=DYLD_FALLBACK_LIBRARY_PATH="/usr/local/lib:$DYLD_FALLBACK_LIBRARY_PATH" + RUN_TESTS+= ./run_tests; rm -rf run_tests.dSYM/ endif both: shared static clean @@ -1,6 +1,7 @@ # Personal library for a bunch of useful stuff -Just a bunch of useful code for me, put into a single lib, so I don't have to reimplement it every single time. +Just a bunch of useful code for me, put into a single lib, +so I don't have to reimplement it every single time. Defnitely not the best implementations ever made, but they're mine, so idc. ## Contains: diff --git a/include/moslib/ds/array.h b/include/moslib/ds/array.h index 36acc03..cc0c174 100644 --- a/include/moslib/ds/array.h +++ b/include/moslib/ds/array.h @@ -1,8 +1,8 @@ // moslib/ds/array.h // Implementation of dynamic array -// ======================================== QUICK USAGE GUIDE ========================================= -// ---------------------------------------------------------------------------------------------------- +// ======================================= QUICK USAGE GUIDE ======================================= +// ------------------------------------------------------------------------------------------------- // // Define the dynamic array of type T as: // @@ -14,7 +14,7 @@ // // #define MOS_ARR_INIT_CAP <desired_init_cap> // -// ---------------------------------------------------------------------------------------------------- +// ------------------------------------------------------------------------------------------------- // // You can access the items simply by array indexing: // @@ -29,7 +29,7 @@ // It will provide bounds checking - arr_get returning NULL when index is out of bounds // - both arr_first and arr_last returning NULL when array is empty // -// ---------------------------------------------------------------------------------------------------- +// ------------------------------------------------------------------------------------------------- // // To append/push to the array use: // @@ -46,15 +46,15 @@ // size_t index = arr_insert(array, i, item); // // It returns the index of the newly inserted item -// If index is greater or equal to array length then it functions identically to arr_append/arr_push. +// If index >= array length then it functions identically to arr_append/arr_push. // // To put into specific index (and update if value exists) use: // // size_t index = arr_put(array, i, item); // // It returns the index of the newly put item -// If index is greater or equal to array length it will extend the length to the put item and it will -// zero all items between previously last item to the new item. +// If index >= array length it will extend the length to the put item and it will zero all items +// between previously last item to the new item. // // If you want to add more items than 1 at once, you can use these: // @@ -65,7 +65,7 @@ // // They work the same way as their counterparts without n, but accept an array of items instead. // -// ---------------------------------------------------------------------------------------------------- +// ------------------------------------------------------------------------------------------------- // // To concatenate two dynamic arrays of the same type use: // @@ -75,7 +75,7 @@ // Returns index of the first item of array2 in array1. // If array 2 is NULL or has length 0 - returns (size_t)-1. // -// ---------------------------------------------------------------------------------------------------- +// ------------------------------------------------------------------------------------------------- // // To delete and retrieve the last item from an array use: // @@ -102,7 +102,7 @@ // // They work like arr_del_n without needing to specify the indices. // -// ---------------------------------------------------------------------------------------------------- +// ------------------------------------------------------------------------------------------------- // // You can use these to get a pointer to the previous or next item in array: // @@ -112,7 +112,7 @@ // When p_item is NULL it will return pointer to the last/first item. // When there's no prev/next item - it will return NULL. // -// ---------------------------------------------------------------------------------------------------- +// ------------------------------------------------------------------------------------------------- // // To get array's current length use: // @@ -126,7 +126,7 @@ // If it's smaller than current length - it will delete items. // Returns amount of items deleted in this way. // -// ---------------------------------------------------------------------------------------------------- +// ------------------------------------------------------------------------------------------------- // // To get array's current capacity use: // @@ -139,14 +139,14 @@ // When target_cap is lower than array length it will set capacity to array length. // Returns the new capacity. // -// ---------------------------------------------------------------------------------------------------- +// ------------------------------------------------------------------------------------------------- // // To free the array from memory use: // // arr_free(array); // -// ---------------------------------------------------------------------------------------------------- -// ===================================== END OF QUICK USAGE GUIDE ===================================== +// ------------------------------------------------------------------------------------------------- +// ===================================== END OF QUICK USAGE GUIDE ================================== #include "moslib/safe.h" @@ -220,8 +220,6 @@ // pointer to the last item or NULL if array is empty #define mos_arr_last(arr) (mos_arr_len(arr) == 0 ? NULL : (arr) + mos_arr_len(arr) - 1) -// clang-format off - // Append a given item to the array // // Arguments: @@ -235,11 +233,10 @@ // Returns: // index of the appended item #define mos_arr_push mos_arr_append -#define mos_arr_append(arr, ...) ( \ - mos_arr_append_fn(&(arr), sizeof(*(arr)), MOS_ARR_INIT_CAP), \ - (arr)[mos_arr_len(arr) - 1] = __VA_ARGS__, \ - mos_arr_len(arr) - 1 \ -) +#define mos_arr_append(arr, ...) \ + (mos_arr_append_fn(&(arr), sizeof(*(arr)), MOS_ARR_INIT_CAP), \ + (arr)[mos_arr_len(arr) - 1] = __VA_ARGS__, \ + mos_arr_len(arr) - 1) // Insert a given item at the specific position in the array // Move everything after it to the right @@ -258,15 +255,12 @@ // // Returns: // index of the inserted item -#define mos_arr_insert(arr, i, ...) ( \ - (size_t)(i) >= mos_arr_len(arr) ? ( \ - mos_arr_append(arr, __VA_ARGS__) \ - ) : ( \ - mos_arr_insert_fn(&(arr), i, sizeof(*(arr)), MOS_ARR_INIT_CAP), \ - (arr)[(size_t)(i)] = __VA_ARGS__, \ - (size_t)(i) \ - ) \ -) +#define mos_arr_insert(arr, i, ...) \ + ((size_t)(i) >= mos_arr_len(arr) \ + ? (mos_arr_append(arr, __VA_ARGS__)) \ + : (mos_arr_insert_fn(&(arr), i, sizeof(*(arr)), MOS_ARR_INIT_CAP), \ + (arr)[(size_t)(i)] = __VA_ARGS__, \ + (size_t)(i))) // Put a given item at the specific position in the array // If index is within array bounds - it overwrites the item at given spot @@ -286,13 +280,10 @@ // // Returns: // index of the put item -#define mos_arr_put(arr, i, ...) ( \ - mos_arr_put_fn(&(arr), i, sizeof(*(arr)), MOS_ARR_INIT_CAP), \ - (arr)[(size_t)(i)] = __VA_ARGS__, \ - (size_t)(i) \ -) - -// clang-format on +#define mos_arr_put(arr, i, ...) \ + (mos_arr_put_fn(&(arr), i, sizeof(*(arr)), MOS_ARR_INIT_CAP), \ + (arr)[(size_t)(i)] = __VA_ARGS__, \ + (size_t)(i)) // Append n given items to the array // @@ -309,7 +300,8 @@ // Returns: // index of the first appended item #define mos_arr_push_n mos_arr_append_n -#define mos_arr_append_n(arr, items, n) mos_arr_append_n_fn(&(arr), items, n, sizeof(*(arr)), MOS_ARR_INIT_CAP) +#define mos_arr_append_n(arr, items, n) \ + mos_arr_append_n_fn(&(arr), items, n, sizeof(*(arr)), MOS_ARR_INIT_CAP) // Insert n given items at the specific position in the array // Move everything after them to the right @@ -330,7 +322,8 @@ // // Returns: // index of the first inserted item -#define mos_arr_insert_n(arr, i, items, n) mos_arr_insert_n_fn(&(arr), i, items, n, sizeof(*(arr)), MOS_ARR_INIT_CAP) +#define mos_arr_insert_n(arr, i, items, n) \ + mos_arr_insert_n_fn(&(arr), i, items, n, sizeof(*(arr)), MOS_ARR_INIT_CAP) // Put n given items at the specific position in the array // If index is within array bounds - it overwrites the items at given spots @@ -352,7 +345,8 @@ // // Returns: // index of the first put item -#define mos_arr_put_n(arr, i, items, n) mos_arr_put_n_fn(&(arr), i, items, n, sizeof(*(arr)), MOS_ARR_INIT_CAP) +#define mos_arr_put_n(arr, i, items, n) \ + mos_arr_put_n_fn(&(arr), i, items, n, sizeof(*(arr)), MOS_ARR_INIT_CAP) // Concatenate two dynamic arrays of the same type // @@ -365,7 +359,8 @@ // // Returns: // index of the first new item in arr1 or (size_t)-1 if arr2 is NULL or has length 0 -#define mos_arr_concat(arr1, arr2) mos_arr_concat_fn(&(arr1), arr2, sizeof(*(arr1)), MOS_ARR_INIT_CAP) +#define mos_arr_concat(arr1, arr2) \ + mos_arr_concat_fn(&(arr1), arr2, sizeof(*(arr1)), MOS_ARR_INIT_CAP) // Delete and retrieve the last item from the array // No bounds checking @@ -448,7 +443,10 @@ // // Returns: // pointer to the previous item or NULL if there's no more items -#define mos_arr_prev(arr, curr) ((!(arr) || !(curr)) ? mos_arr_last(arr) : ((curr) == mos_arr_first(arr) ? NULL : (arr) + mos_arr_p_diff(curr, arr) - 1)) +#define mos_arr_prev(arr, curr) \ + ((!(arr) || !(curr)) \ + ? mos_arr_last(arr) \ + : ((curr) == mos_arr_first(arr) ? NULL : (arr) + mos_arr_p_diff(curr, arr) - 1)) // Get the pointer to the next item in the array from the pointer to the current one // If pointer is NULL - gets the first item from the array @@ -462,7 +460,10 @@ // // Returns: // pointer to the next item or NULL if there's no more items -#define mos_arr_next(arr, curr) ((!(arr) || !(curr)) ? mos_arr_first(arr) : ((curr) == mos_arr_last(arr) ? NULL : (arr) + mos_arr_p_diff(curr, arr) + 1)) +#define mos_arr_next(arr, curr) \ + ((!(arr) || !(curr)) \ + ? mos_arr_first(arr) \ + : ((curr) == mos_arr_last(arr) ? NULL : (arr) + mos_arr_p_diff(curr, arr) + 1)) // Get the length of the array // @@ -526,9 +527,14 @@ extern void mos_arr_free(void *arr); extern void mos_arr_append_fn(void *p_arr, size_t el_size, size_t init_cap); extern void mos_arr_insert_fn(void *p_arr, size_t i, size_t el_size, size_t init_cap); extern void mos_arr_put_fn(void *p_arr, size_t i, size_t el_size, size_t init_cap); -extern size_t mos_arr_append_n_fn(void *p_arr, const void *items, size_t n, size_t el_size, size_t init_cap); -extern size_t mos_arr_insert_n_fn(void *p_arr, size_t i, const void *items, size_t n, size_t el_size, size_t init_cap); -extern size_t mos_arr_put_n_fn(void *p_arr, size_t i, const void *items, size_t n, size_t el_size, size_t init_cap); +extern size_t +mos_arr_append_n_fn(void *p_arr, const void *items, size_t n, size_t el_size, size_t init_cap); +extern size_t mos_arr_insert_n_fn( + void *p_arr, size_t i, const void *items, size_t n, size_t el_size, size_t init_cap +); +extern size_t mos_arr_put_n_fn( + void *p_arr, size_t i, const void *items, size_t n, size_t el_size, size_t init_cap +); extern size_t mos_arr_concat_fn(void *p_arr, const void *arr2, size_t el_size, size_t init_cap); extern size_t mos_arr_del_fn(void *arr, size_t i, size_t el_size); extern size_t mos_arr_del_n_fn(void *arr, size_t i, size_t n, size_t el_size); diff --git a/include/moslib/ds/hashmap.h b/include/moslib/ds/hashmap.h index cd17d0f..09a27e2 100644 --- a/include/moslib/ds/hashmap.h +++ b/include/moslib/ds/hashmap.h @@ -1,8 +1,8 @@ // moslib/ds/hashmap.h // Implementation of hashmap -// ======================================== QUICK USAGE GUIDE ========================================= -// ---------------------------------------------------------------------------------------------------- +// ======================================= QUICK USAGE GUIDE ======================================= +// ------------------------------------------------------------------------------------------------- // // Start by defining an Entry struct: // @@ -36,8 +36,6 @@ // // .hash and .eq will overwrite the functions set by .key. // -// It's better to assign NULL than to call hm_new with no arguments when you don't redefine anything. -// // Examples: // // HM_DEF(str_int, char *, int); @@ -52,13 +50,13 @@ // HM_DEF(int_int, int, int); // int_int *hm3 = hm_new(.hash = hash_int); // -// ---------------------------------------------------------------------------------------------------- +// ------------------------------------------------------------------------------------------------- // // To set the hashmap load factor, define (before including the header): // // #define MOS_HM_LOAD_FACTOR <desired_load_factor_in_%> // -// ---------------------------------------------------------------------------------------------------- +// ------------------------------------------------------------------------------------------------- // // To put a key/value pair or an entry into a hashmap use: // @@ -67,7 +65,7 @@ // // If an entry with the same key already exists - it will be overwritten. // -// ---------------------------------------------------------------------------------------------------- +// ------------------------------------------------------------------------------------------------- // // To get a value from a hashmap use: // @@ -80,9 +78,9 @@ // struct Entry *entry = hm_get_e(hm, key); // // If an entry of given key is not in the hashmap it will return NULL. -// Note that hm_put, hm_put_e and hm_del might cause a rehash which will leave that pointer dangling. +// Note: hm_put, hm_put_e and hm_del might cause a rehash which will leave that pointer dangling. // -// ---------------------------------------------------------------------------------------------------- +// ------------------------------------------------------------------------------------------------- // // To delete an an entry from a hashmap use: // @@ -97,7 +95,7 @@ // It works the same as hm_del - it just ensures no reallocation. // Useful when you want to delete entries while looping over them. // -// ---------------------------------------------------------------------------------------------------- +// ------------------------------------------------------------------------------------------------- // // You can loop over the hashmap using these functions: // @@ -106,28 +104,28 @@ // // hm_first will return the pointer to the "first entry" (with the lowest hash) in the hashmap. // If hashmap is empty - it will return NULL. -// Note that hm_put, hm_put_e and hm_del might cause a rehash which will leave that pointer dangling. +// Note: hm_put, hm_put_e and hm_del might cause a rehash which will leave that pointer dangling. // // hm_next returns the pointer to the next entry in the hashmap from the pointer to the current one. // If hashmap is empty - it will return NULL. // If curr is NULL - same as hm_first. // If curr is the last entry - it will return NULL. -// Note that hm_put, hm_put_e and hm_del might cause a rehash which will leave that pointer dangling. +// Note: hm_put, hm_put_e and hm_del might cause a rehash which will leave that pointer dangling. // -// ---------------------------------------------------------------------------------------------------- +// ------------------------------------------------------------------------------------------------- // // To get the count of entries in the hashmap, use: // // hm_size(hm); // -// ---------------------------------------------------------------------------------------------------- +// ------------------------------------------------------------------------------------------------- // // Free the hashmap with: // // hm_free(hm); // -// ---------------------------------------------------------------------------------------------------- -// ===================================== END OF QUICK USAGE GUIDE ===================================== +// ------------------------------------------------------------------------------------------------- +// =================================== END OF QUICK USAGE GUIDE ==================================== #include <stddef.h> #include <stdint.h> @@ -166,10 +164,12 @@ typedef struct { int (*eq)(const void *key1, const void *key2); } MosHmNewArgs; -// clang-format off // Macro to define Entry struct easier -#define MOS_HM_DEF(name, key_t, val_t) typedef struct {key_t key; val_t val;} name -// clang-format on +#define MOS_HM_DEF(name, key_t, val_t) \ + typedef struct { \ + key_t key; \ + val_t val; \ + } name // Create a new hashmap // @@ -204,7 +204,11 @@ typedef struct { // ... // value of the entry to put // variadic to make things like (struct Val){1,1} work properly -#define mos_hm_put(hm, k, ...) (mos_hm_ini(hm), (hm)->val = __VA_ARGS__, (hm)->key = k, mos_hm_put_fn(&(hm), mos_hm_fn_args(hm), MOS_HM_LOAD_FACTOR)) +#define mos_hm_put(hm, k, ...) \ + (mos_hm_ini(hm), \ + (hm)->val = __VA_ARGS__, \ + (hm)->key = k, \ + mos_hm_put_fn(&(hm), mos_hm_fn_args(hm), MOS_HM_LOAD_FACTOR)) // Put a given entry in the hashmap // If entry of the same key exists - overwrites it @@ -216,7 +220,10 @@ typedef struct { // ... // entry to put into hashmap // variadic to make things like (struct Entry){"key","val"} work properly -#define mos_hm_put_e(hm, ...) (mos_hm_ini(hm), (hm)[0] = __VA_ARGS__, mos_hm_put_fn(&(hm), mos_hm_fn_args(hm), MOS_HM_LOAD_FACTOR)) +#define mos_hm_put_e(hm, ...) \ + (mos_hm_ini(hm), \ + (hm)[0] = __VA_ARGS__, \ + mos_hm_put_fn(&(hm), mos_hm_fn_args(hm), MOS_HM_LOAD_FACTOR)) // Get the value of entry with specific key // @@ -229,7 +236,8 @@ typedef struct { // // Returns: // value of the entry with given key or 0 if no such entry exist -#define mos_hm_get(hm, k) (mos_hm_ini(hm), (hm)->key = k, (hm)[mos_hm_get_fn(hm, mos_hm_fn_args(hm))].val) +#define mos_hm_get(hm, k) \ + (mos_hm_ini(hm), (hm)->key = k, (hm)[mos_hm_get_fn(hm, mos_hm_fn_args(hm))].val) // Get a pointer to an entry with specific key in hashmap // @@ -314,14 +322,20 @@ extern void mos_hm_init(void *p_hm, size_t entry_size); #define mos_hm_fn_args(hm) &(hm)->key, sizeof(*(hm)), sizeof((hm)->key) -#define mos_hm_del_(hm, k, reh) (mos_hm_ini(hm), (hm)->key = k, mos_hm_del_fn(&(hm), mos_hm_fn_args(hm), MOS_HM_LOAD_FACTOR, reh)) +#define mos_hm_del_(hm, k, reh) \ + (mos_hm_ini(hm), \ + (hm)->key = k, \ + mos_hm_del_fn(&(hm), mos_hm_fn_args(hm), MOS_HM_LOAD_FACTOR, reh)) // Function prototypes for macros extern void *mos_hm_new_fn(MosHmNewArgs args); -extern void mos_hm_put_fn(void *p_hm, void *key, size_t entry_size, size_t key_size, uint8_t load_factor); +extern void +mos_hm_put_fn(void *p_hm, void *key, size_t entry_size, size_t key_size, uint8_t load_factor); extern size_t mos_hm_get_fn(void *hm, void *key, size_t entry_size, size_t key_size); extern void *mos_hm_get_e_fn(void *hm, void *key, size_t entry_size, size_t key_size); -extern int mos_hm_del_fn(void *p_hm, void *key, size_t entry_size, size_t key_size, uint8_t load_factor, int reh); +extern int mos_hm_del_fn( + void *p_hm, void *key, size_t entry_size, size_t key_size, uint8_t load_factor, int reh +); extern void *mos_hm_first_fn(const void *hm, size_t entry_size); extern void *mos_hm_next_fn(const void *hm, const void *curr, size_t entry_size); diff --git a/include/moslib/string.h b/include/moslib/string.h index 165bdf7..65a38c5 100644 --- a/include/moslib/string.h +++ b/include/moslib/string.h @@ -1,8 +1,8 @@ // moslib/string.h // Length aware string slices -// ======================================== QUICK USAGE GUIDE ========================================= -// ---------------------------------------------------------------------------------------------------- +// ======================================= QUICK USAGE GUIDE ======================================= +// ------------------------------------------------------------------------------------------------- // // StringSlice is defined as a struct which contains a pointer to the beginning of a string and its // length: @@ -12,7 +12,7 @@ // size_t len; // } StringSlice; // -// ---------------------------------------------------------------------------------------------------- +// ------------------------------------------------------------------------------------------------- // // To get a string slice from a C string you can use: // @@ -45,7 +45,7 @@ // // StringSlice ss = ss_from_vars("[in][out]", 4); // -// ---------------------------------------------------------------------------------------------------- +// ------------------------------------------------------------------------------------------------- // // To print a slice you can either use: // @@ -57,14 +57,14 @@ // // printf("Slice: " SS_FMT "\n", SS_ARGS(ss)); // -// ---------------------------------------------------------------------------------------------------- +// ------------------------------------------------------------------------------------------------- // // To check if two slices / slice and string are equal, use: // // int are_eq = ss_eq(ss1, ss2); // int are_eq = ss_eq_str(ss1, "string"); // -// ---------------------------------------------------------------------------------------------------- +// ------------------------------------------------------------------------------------------------- // // You can trim a slice from whitespace using: // @@ -72,7 +72,7 @@ // StringSlice trimmed_l = ss_trim_left(ss); // StringSlice trimmed_r = ss_trim_right(ss); // -// ---------------------------------------------------------------------------------------------------- +// ------------------------------------------------------------------------------------------------- // // To check whether a slice starts or ends with a slice / string, you can use: // @@ -81,7 +81,7 @@ // int flag = ss_starts_with_str(ss, str_prefix); // int flag = ss_ends_with_str(ss, str_suffix); // -// ---------------------------------------------------------------------------------------------------- +// ------------------------------------------------------------------------------------------------- // // To delete from the left or the right, use: // @@ -100,7 +100,7 @@ // It will return whether or not the slice started / ended with the prefix / suffix and delete it if // it did. // -// ---------------------------------------------------------------------------------------------------- +// ------------------------------------------------------------------------------------------------- // // You can split a slice by a delimiter using ss_split functions: // @@ -123,27 +123,27 @@ // // It will return the "split" part and leave the remainder in the argument slice. // -// ---------------------------------------------------------------------------------------------------- +// ------------------------------------------------------------------------------------------------- // // To find within a slice a part which begins with given target, use: // // StringSlice target1 = ss_find(ss, ss_target); // StringSlice target2 = ss_find_str(ss, str_target); // -// The return value is a slice that begins at the beginning of the specified target and ends at the end -// of the original slice. +// The return value is a slice that begins at the beginning of the specified target and ends +// at the end of the original slice. // If the target was an emptry slice / string - returns the entire slice. // If the target was not found - returns empty slice. // -// ---------------------------------------------------------------------------------------------------- +// ------------------------------------------------------------------------------------------------- // // If you want to get length of a slice then you can simply use the len field of the struct. // However, if you want to know the length which respects utf-8 encoding, use: // // size_t utf8_len = ss_utf8_len(ss); // -// ---------------------------------------------------------------------------------------------------- -// ===================================== END OF QUICK USAGE GUIDE ===================================== +// ------------------------------------------------------------------------------------------------- +// =================================== END OF QUICK USAGE GUIDE ==================================== #include <stddef.h> diff --git a/include/moslib/tester.h b/include/moslib/tester.h index f8cc8b1..9f3b482 100644 --- a/include/moslib/tester.h +++ b/include/moslib/tester.h @@ -1,8 +1,8 @@ // moslib/tester.h // Helper functions for writing and running tests -// ======================================== QUICK USAGE GUIDE ========================================= -// ---------------------------------------------------------------------------------------------------- +// ======================================= QUICK USAGE GUIDE ======================================= +// ------------------------------------------------------------------------------------------------- // // Define the tester: // @@ -14,13 +14,13 @@ // // Tester *tester = new_tester(); // -// ---------------------------------------------------------------------------------------------------- +// ------------------------------------------------------------------------------------------------- // // Add test groups: // // TestGroup *test_group = add_test_group(tester, group_name); // -// ---------------------------------------------------------------------------------------------------- +// ------------------------------------------------------------------------------------------------- // // Create tests. // They should use test_assert functions to check correctness. @@ -67,26 +67,26 @@ // test_assert(code == 0, "function didn't fail"); // } // -// ---------------------------------------------------------------------------------------------------- +// ------------------------------------------------------------------------------------------------- // // Add tests to test group: // // add_test(test_group, test_fn); // -// ---------------------------------------------------------------------------------------------------- +// ------------------------------------------------------------------------------------------------- // // Run tests: // // int all_passed = run_tests(tester); // -// ---------------------------------------------------------------------------------------------------- +// ------------------------------------------------------------------------------------------------- // // Free tester: // // free_tester(tester); // -// ---------------------------------------------------------------------------------------------------- -// ===================================== END OF QUICK USAGE GUIDE ===================================== +// ------------------------------------------------------------------------------------------------- +// =================================== END OF QUICK USAGE GUIDE ==================================== #include <stdio.h> @@ -137,7 +137,8 @@ extern MosTester *mos_new_tester(void); // // Returns: // pointer to the added group -#define mos_add_test_group(tester, group_name) ((!(tester) ? (tester) = mos_new_tester() : 0), mos_add_test_group_fn(tester, group_name)) +#define mos_add_test_group(tester, group_name) \ + ((!(tester) ? (tester) = mos_new_tester() : 0), mos_add_test_group_fn(tester, group_name)) // Assert that an expression is true // Use in test functions to test correctness @@ -159,7 +160,7 @@ extern void mos_test_assert(int expression, const char *fail_message); // // code // expected exit code -#define mos_test_assert_exit(function, code) mos_test_assert_exit_fn(function, code, #function); +#define mos_test_assert_exit(function, code) mos_test_assert_exit_fn(function, code, #function) // Assert that function writes correct output to specified stream // @@ -172,7 +173,8 @@ extern void mos_test_assert(int expression, const char *fail_message); // // output // expected output of the function -#define mos_test_assert_out(function, stream, output) mos_test_assert_out_fn(function, stream, output, #function, #stream); +#define mos_test_assert_out(function, stream, output) \ + mos_test_assert_out_fn(function, stream, output, #function, #stream) // Suppress given output // @@ -193,7 +195,7 @@ extern void mos_unsuppress_outputs(void); // // test // test to add to the group -#define mos_add_test(group, test) mos_add_test_fn(group, test, #test); +#define mos_add_test(group, test) mos_add_test_fn(group, test, #test) // Run defined tests // @@ -215,7 +217,13 @@ extern void mos_free_tester(MosTester *tester); // Function prototypes for macros extern MosTestGroup *mos_add_test_group_fn(MosTester *tester, const char *group_name); extern void mos_test_assert_exit_fn(MosTestFn function, int code, const char *name); -extern void mos_test_assert_out_fn(MosTestFn function, FILE *stream, const char *output, const char *fn_name, const char *stream_name); +extern void mos_test_assert_out_fn( + MosTestFn function, + FILE *stream, + const char *output, + const char *fn_name, + const char *stream_name +); extern void mos_add_test_fn(MosTestGroup *group, MosTestFn test, const char *name); #endif // MOSLIB_TESTER_H diff --git a/src/ds/array.c b/src/ds/array.c index 3d0baa3..21d8be5 100644 --- a/src/ds/array.c +++ b/src/ds/array.c @@ -41,15 +41,13 @@ static void *expand(void *arr, size_t min_cap, size_t el_size) { return hdr2arr(hdr); } -// clang-format off // init array if it's not, define arr, hdr vars and expand to fit min_cap -#define ini(min_cap) \ - !*(void**)p_arr ? *(void **)p_arr = init(init_cap, el_size) : 0; \ - Header *hdr = arr2hdr(*(void**)p_arr); \ - *(void **)p_arr = expand(*(void**)p_arr, min_cap, el_size); \ - void *arr = *(void **)p_arr; \ +#define ini(min_cap) \ + !*(void **)p_arr ? *(void **)p_arr = init(init_cap, el_size) : 0; \ + Header *hdr = arr2hdr(*(void **)p_arr); \ + *(void **)p_arr = expand(*(void **)p_arr, min_cap, el_size); \ + void *arr = *(void **)p_arr; \ hdr = arr2hdr(arr) -// clang-format on void mos_arr_append_fn(void *p_arr, size_t el_size, size_t init_cap) { ini(hdr->len + 1); @@ -70,7 +68,8 @@ void mos_arr_put_fn(void *p_arr, size_t i, size_t el_size, size_t init_cap) { } } -size_t mos_arr_append_n_fn(void *p_arr, const void *items, size_t n, size_t el_size, size_t init_cap) { +size_t +mos_arr_append_n_fn(void *p_arr, const void *items, size_t n, size_t el_size, size_t init_cap) { ini(hdr->len + n); size_t i = hdr->len; @@ -79,7 +78,9 @@ size_t mos_arr_append_n_fn(void *p_arr, const void *items, size_t n, size_t el_s return i; } -size_t mos_arr_insert_n_fn(void *p_arr, size_t i, const void *items, size_t n, size_t el_size, size_t init_cap) { +size_t mos_arr_insert_n_fn( + void *p_arr, size_t i, const void *items, size_t n, size_t el_size, size_t init_cap +) { ini(hdr->len + n); if (i >= hdr->len) return mos_arr_append_n_fn(p_arr, items, n, el_size, init_cap); @@ -90,7 +91,9 @@ size_t mos_arr_insert_n_fn(void *p_arr, size_t i, const void *items, size_t n, s return i; } -size_t mos_arr_put_n_fn(void *p_arr, size_t i, const void *items, size_t n, size_t el_size, size_t init_cap) { +size_t mos_arr_put_n_fn( + void *p_arr, size_t i, const void *items, size_t n, size_t el_size, size_t init_cap +) { ini(i + n + 1); if (i > hdr->len) { memset((char *)arr + hdr->len * el_size, 0, (i - hdr->len) * el_size); @@ -123,7 +126,9 @@ size_t mos_arr_del_n_fn(void *arr, size_t i, size_t n, size_t el_size) { return 0; size_t new_n = n > hdr->len - i ? hdr->len - i : n; - memmove((char *)arr + i * el_size, (char *)arr + (i + new_n) * el_size, (hdr->len - i) * el_size); + memmove( + (char *)arr + i * el_size, (char *)arr + (i + new_n) * el_size, (hdr->len - i) * el_size + ); hdr->len -= new_n; return new_n; } diff --git a/src/ds/hashmap.c b/src/ds/hashmap.c index 2b74b35..a983fc2 100644 --- a/src/ds/hashmap.c +++ b/src/ds/hashmap.c @@ -139,7 +139,9 @@ void *mos_hm_new_fn(MosHmNewArgs args) { return hdr2hm(hdr); } -static size_t probe(const void *hm, const void *key, size_t entry_size, size_t key_size, size_t key_off, int put) { +static size_t probe( + const void *hm, const void *key, size_t entry_size, size_t key_size, size_t key_off, int put +) { Header *hdr = hm2hdr(hm); uint32_t hash = hdr->hash ? hdr->hash(key) : default_hash(key, key_size); size_t i = hash % hdr->cap; @@ -161,7 +163,8 @@ static size_t probe(const void *hm, const void *key, size_t entry_size, size_t k exit(EXIT_FAILURE); } -static void rehash(void *p_hm, size_t entry_size, size_t key_size, size_t key_off, uint8_t load_factor) { +static void +rehash(void *p_hm, size_t entry_size, size_t key_size, size_t key_off, uint8_t load_factor) { void *hm = *(void **)p_hm; Header *hdr = hm2hdr(hm); size_t size = mos_hm_size(hm); @@ -243,7 +246,9 @@ void *mos_hm_get_e_fn(void *hm, void *key, size_t entry_size, size_t key_size) { return (char *)hm + (i + 1) * entry_size; } -int mos_hm_del_fn(void *p_hm, void *key, size_t entry_size, size_t key_size, uint8_t load_factor, int reh) { +int mos_hm_del_fn( + void *p_hm, void *key, size_t entry_size, size_t key_size, uint8_t load_factor, int reh +) { void *hm = *(void **)p_hm; Header *hdr = hm2hdr(hm); size_t key_off = (char *)key - (char *)hm; diff --git a/src/tester.c b/src/tester.c index b36a4d2..42f0486 100644 --- a/src/tester.c +++ b/src/tester.c @@ -130,7 +130,13 @@ void mos_test_assert_exit_fn(MosTestFn function, int code, const char *name) { } } -void mos_test_assert_out_fn(MosTestFn function, FILE *stream, const char *output, const char *fn_name, const char *stream_name) { +void mos_test_assert_out_fn( + MosTestFn function, + FILE *stream, + const char *output, + const char *fn_name, + const char *stream_name +) { size_t n = strlen(output); char *out = mos_safe_calloc(n + 2, 1); diff --git a/tests/ds/array_tests.c b/tests/ds/array_tests.c index c5d7c4d..975443c 100644 --- a/tests/ds/array_tests.c +++ b/tests/ds/array_tests.c @@ -16,10 +16,16 @@ TEST(cap_test) { test_assert(arr_cap(arr) == 2 * MOS_ARR_INIT_CAP, "capacity didn't increase 2 times"); size_t new_cap = arr_set_cap(arr, 3 * MOS_ARR_INIT_CAP); - test_assert(new_cap == arr_cap(arr) && new_cap == 3 * MOS_ARR_INIT_CAP, "set cap didn't set correct capacity (cap >= len)"); + test_assert( + new_cap == arr_cap(arr) && new_cap == 3 * MOS_ARR_INIT_CAP, + "set cap didn't set correct capacity (cap >= len)" + ); new_cap = arr_set_cap(arr, 0); - test_assert(new_cap == arr_cap(arr) && new_cap == MOS_ARR_INIT_CAP + 1, "set cap didn't set correct capacity (cap < len)"); + test_assert( + new_cap == arr_cap(arr) && new_cap == MOS_ARR_INIT_CAP + 1, + "set cap didn't set correct capacity (cap < len)" + ); arr_free(arr); } @@ -95,10 +101,14 @@ TEST(getting_items) { test_assert(arr_last(arr) == NULL, "last of empty array isn't null"); arr_append(arr, (struct test){0}); - test_assert(arr_first(arr) == arr_last(arr), "first and last are different for array of length 1"); + test_assert( + arr_first(arr) == arr_last(arr), "first and last are different for array of length 1" + ); arr_append(arr, (struct test){1, 1}); - test_assert(arr_first(arr) != arr_last(arr), "first and last are the same for array of length >1"); + test_assert( + arr_first(arr) != arr_last(arr), "first and last are the same for array of length >1" + ); struct test *next_first = arr_next(arr, NULL); struct test *next_last = arr_next(arr, next_first); @@ -108,15 +118,24 @@ TEST(getting_items) { struct test *prev_null = arr_prev(arr, prev_first); test_assert(next_first && next_last, "next gave NULL when it shouldn't have"); test_assert(prev_first && prev_last, "prev gave NULL when it shouldn't have"); - test_assert(next_first == prev_first && next_last == prev_last, "next and prev gave different values for the same element"); + test_assert( + next_first == prev_first && next_last == prev_last, + "next and prev gave different values for the same element" + ); test_assert(!next_null, "next didn't give NULL after running out of items"); test_assert(!prev_null, "prev didn't give NULL after running out of items"); - test_assert(arr_get(arr, -1) == NULL && arr_get(arr, 2) == NULL, "arr_get didn't give NULL when out of bounds"); + test_assert( + arr_get(arr, -1) == NULL && arr_get(arr, 2) == NULL, + "arr_get didn't give NULL when out of bounds" + ); struct test i0 = *arr_get(arr, 0); struct test i1 = *arr_get(arr, 1); - test_assert(!memcmp(&i0, &arr[0], sizeof(struct test)) && !memcmp(&i1, &arr[1], sizeof(struct test)), "arr_get(arr, i) gives different result than arr[i]"); + test_assert( + !memcmp(&i0, &arr[0], sizeof(struct test)) && !memcmp(&i1, &arr[1], sizeof(struct test)), + "arr_get(arr, i) gives different result than arr[i]" + ); arr_free(arr); } @@ -176,7 +195,9 @@ TEST(arr_concat_test) { test_assert(index == 2, "arr_concat returned wrong index"); unsigned long expected[] = {4, 5, 1, 2, 3, 4, 5}; test_assert(arr_len(arr2) == 7, "arr_concat produced array of wrong length"); - test_assert(!memcmp(arr2, expected, 7 * sizeof(unsigned long)), "arr_concat produced wrong array"); + test_assert( + !memcmp(arr2, expected, 7 * sizeof(unsigned long)), "arr_concat produced wrong array" + ); arr_free(arr1); arr_free(arr2); diff --git a/tests/ds/hashmap_tests.c b/tests/ds/hashmap_tests.c index 4c615a7..268bc29 100644 --- a/tests/ds/hashmap_tests.c +++ b/tests/ds/hashmap_tests.c @@ -45,13 +45,19 @@ TEST(put_e_get_e) { hm_put_e(hm, (E){0.0f, 69}); hm_put_e(hm, (E){1.0f, 420}); E e = {0.0f, 69}; - test_assert(memcmp(&e, hm_get_e(hm, 0.0f), sizeof(E)) == 0, "hm_get_e got entry not from hm_put_e"); + test_assert( + memcmp(&e, hm_get_e(hm, 0.0f), sizeof(E)) == 0, "hm_get_e got entry not from hm_put_e" + ); e = (E){1.0f, 420}; - test_assert(memcmp(&e, hm_get_e(hm, 1.0f), sizeof(E)) == 0, "hm_get_e got entry not from hm_put_e"); + test_assert( + memcmp(&e, hm_get_e(hm, 1.0f), sizeof(E)) == 0, "hm_get_e got entry not from hm_put_e" + ); e = (E){1.0f, 2137}; hm_put_e(hm, e); - test_assert(memcmp(&e, hm_get_e(hm, 1.0f), sizeof(E)) == 0, "hm_put_e didn't update entry properly"); + test_assert( + memcmp(&e, hm_get_e(hm, 1.0f), sizeof(E)) == 0, "hm_put_e didn't update entry properly" + ); hm_free(hm); } @@ -137,7 +143,9 @@ TEST(looping) { E items[] = {{1, 10}, {2, 20}, {3, 30}}; arr_append_n(allowed, items, 3); - test_assert(memcmp(hm_first(hm), hm_next(hm, NULL), sizeof(E)) == 0, "hm_next(hm, NULL) != hm_first(hm)"); + test_assert( + memcmp(hm_first(hm), hm_next(hm, NULL), sizeof(E)) == 0, "hm_next(hm, NULL) != hm_first(hm)" + ); E *e = NULL; while ((e = hm_next(hm, e))) { int flag = 0; @@ -150,7 +158,10 @@ TEST(looping) { } test_assert(flag, "hm_next produced an entry that wasn't put in the hashmap"); } - test_assert(arr_len(allowed) == 0, "hm_next didn't produce every entry from hashmap when it looped over it"); + test_assert( + arr_len(allowed) == 0, + "hm_next didn't produce every entry from hashmap when it looped over it" + ); arr_free(allowed); hm_free(hm); diff --git a/tests/string_tests.c b/tests/string_tests.c index 0d0d7e2..f600400 100644 --- a/tests/string_tests.c +++ b/tests/string_tests.c @@ -26,7 +26,9 @@ TEST(creating) { test_assert(ss3.data == str && ss3.len == str_len, "ss_from_vars created wrong slice"); StringSlice ss4 = SS_LIT(HELLO_WORLD_LIT); - test_assert(ss4.data == str && ss4.len == sizeof(HELLO_WORLD_LIT) - 1, "SS_LIT created wrong slice"); + test_assert( + ss4.data == str && ss4.len == sizeof(HELLO_WORLD_LIT) - 1, "SS_LIT created wrong slice" + ); StringSlice ss5 = ss_copy(ss1); test_assert(ss5.data == ss1.data && ss5.len == ss1.len, "ss_from_arr created wrong slice"); @@ -58,11 +60,15 @@ TEST(comparing) { free(hw); StringSlice ss3 = ss_from_vars(ss.data, ss.len - 1); - test_assert(ss_eq(ss, ss3) == 0, "slice is equal when the pointer is the same but length differs"); + test_assert( + ss_eq(ss, ss3) == 0, "slice is equal when the pointer is the same but length differs" + ); StringSlice ss4 = ss_from_str("hello"); StringSlice ss5 = ss_from_str("world"); - test_assert(ss_eq(ss4, ss5) == 0, "slice is equal when the length is the same but pointer differs"); + test_assert( + ss_eq(ss4, ss5) == 0, "slice is equal when the length is the same but pointer differs" + ); test_assert(ss_eq_str(ss4, "world") == 0, "slice is equal to different string"); } @@ -86,7 +92,9 @@ TEST(trimming) { TEST(prefix_suffix) { StringSlice ss = ss_from_str("pre mid suf"); - test_assert(ss_starts_with(ss, ss_from_str("pre")), "slice doesn't start with its slice prefix"); + test_assert( + ss_starts_with(ss, ss_from_str("pre")), "slice doesn't start with its slice prefix" + ); test_assert(ss_starts_with(ss, ss_from_str("suf")) == 0, "slice starts with not slice prefix"); test_assert(ss_ends_with(ss, ss_from_str("suf")), "slice doesn't end with its slice suffix"); @@ -99,7 +107,9 @@ TEST(prefix_suffix) { test_assert(ss_ends_with_str(ss, "pre") == 0, "slice ends with not string suffix"); StringSlice ss2 = ss_from_str(""); - test_assert(ss_starts_with(ss2, ss_from_str("")), "starts_with breaks for empty slice and prefix"); + test_assert( + ss_starts_with(ss2, ss_from_str("")), "starts_with breaks for empty slice and prefix" + ); test_assert(ss_ends_with(ss2, ss_from_str("")), "ends_with breaks for empty slice and suffix"); } @@ -151,7 +161,9 @@ TEST(splitting) { StringSlice ss1 = ss_from_str("Hello, World!"); StringSlice ss2 = ss_split(&ss1, ','); - test_assert(ss_eq_str(ss2, "Hello") && ss_eq_str(ss1, " World!"), "ss_split didn't split proprely"); + test_assert( + ss_eq_str(ss2, "Hello") && ss_eq_str(ss1, " World!"), "ss_split didn't split proprely" + ); StringSlice ss3 = ss_split_str(&ss2, "ll"); test_assert(ss_eq_str(ss3, "He") && ss_eq_str(ss2, "o"), "ss_split_str didn't split proprely"); @@ -162,47 +174,85 @@ TEST(splitting) { ss1 = ss_from_str("hiii"); ss2 = ss_split_str(&ss1, ""); - test_assert(ss_eq_str(ss2, "") && ss_eq_str(ss1, "hiii"), "ss_split_str fails empty str edge case"); + test_assert( + ss_eq_str(ss2, "") && ss_eq_str(ss1, "hiii"), "ss_split_str fails empty str edge case" + ); ss2 = ss_split_ss(&ss1, SS_LIT("")); - test_assert(ss_eq_str(ss2, "") && ss_eq_str(ss1, "hiii"), "ss_split_ss fails empty ss edge case"); + test_assert( + ss_eq_str(ss2, "") && ss_eq_str(ss1, "hiii"), "ss_split_ss fails empty ss edge case" + ); ss2 = ss_split(&ss1, '.'); - test_assert(ss_eq_str(ss2, "hiii") && ss_eq_str(ss1, ""), "ss_split fails not found delim edge case"); + test_assert( + ss_eq_str(ss2, "hiii") && ss_eq_str(ss1, ""), "ss_split fails not found delim edge case" + ); ss1 = ss_split_str(&ss2, ".."); - test_assert(ss_eq_str(ss1, "hiii") && ss_eq_str(ss2, ""), "ss_split_str fails not found delim edge case"); + test_assert( + ss_eq_str(ss1, "hiii") && ss_eq_str(ss2, ""), "ss_split_str fails not found delim edge case" + ); ss2 = ss_split_ss(&ss1, SS_LIT("...")); - test_assert(ss_eq_str(ss2, "hiii") && ss_eq_str(ss1, ""), "ss_split_ss fails not found delim edge case"); + test_assert( + ss_eq_str(ss2, "hiii") && ss_eq_str(ss1, ""), "ss_split_ss fails not found delim edge case" + ); StringSlice ss_middle = ss_from_str("[left][middle][right]"); StringSlice ss_left = ss_split_left(&ss_middle, 6); - test_assert(ss_eq_str(ss_left, "[left]") && ss_eq_str(ss_middle, "[middle][right]"), "ss_split_left didn't split properly"); + test_assert( + ss_eq_str(ss_left, "[left]") && ss_eq_str(ss_middle, "[middle][right]"), + "ss_split_left didn't split properly" + ); StringSlice ss_right = ss_split_right(&ss_middle, 7); - test_assert(ss_eq_str(ss_right, "[right]") && ss_eq_str(ss_middle, "[middle]"), "ss_split_right didn't split properly"); + test_assert( + ss_eq_str(ss_right, "[right]") && ss_eq_str(ss_middle, "[middle]"), + "ss_split_right didn't split properly" + ); ss_left = ss_split_left(&ss_middle, 20); - test_assert(ss_eq_str(ss_left, "[middle]") && ss_eq_str(ss_middle, ""), "ss_split_left didn't split properly (n > len)"); + test_assert( + ss_eq_str(ss_left, "[middle]") && ss_eq_str(ss_middle, ""), + "ss_split_left didn't split properly (n > len)" + ); ss_right = ss_split_right(&ss_middle, 500); - test_assert(ss_eq_str(ss_right, "") && ss_eq_str(ss_middle, ""), "ss_split_right didn't split properly (n > len)"); + test_assert( + ss_eq_str(ss_right, "") && ss_eq_str(ss_middle, ""), + "ss_split_right didn't split properly (n > len)" + ); } TEST(finding) { char *txt = "a slice of FINDME text"; StringSlice ss = ss_from_str(txt); - test_assert(ss_eq_str(ss_find(ss, ss_from_str("FINDME")), "FINDME text"), "find didn't find a part of the slice"); - test_assert(ss_eq_str(ss_find_str(ss, "FINDME"), "FINDME text"), "find_str didn't find a part of the slice"); - - test_assert(ss_eq(ss_find(ss, ss_from_str("")), ss), "find didn't return whole slice for empty target"); - test_assert(ss_eq(ss_find_str(ss, ""), ss), "find_str didn't return whole slice for empty target"); - - test_assert(ss_eq_str(ss_find(ss, ss_from_str("abcd")), ""), "find didn't return empty slice for not found target"); - test_assert(ss_eq_str(ss_find_str(ss, "abcd"), ""), "find_str didn't return empty slice for not found target"); + test_assert( + ss_eq_str(ss_find(ss, ss_from_str("FINDME")), "FINDME text"), + "find didn't find a part of the slice" + ); + test_assert( + ss_eq_str(ss_find_str(ss, "FINDME"), "FINDME text"), + "find_str didn't find a part of the slice" + ); + + test_assert( + ss_eq(ss_find(ss, ss_from_str("")), ss), "find didn't return whole slice for empty target" + ); + test_assert( + ss_eq(ss_find_str(ss, ""), ss), "find_str didn't return whole slice for empty target" + ); + + test_assert( + ss_eq_str(ss_find(ss, ss_from_str("abcd")), ""), + "find didn't return empty slice for not found target" + ); + test_assert( + ss_eq_str(ss_find_str(ss, "abcd"), ""), + "find_str didn't return empty slice for not found target" + ); } TEST(utf8_len_test) { |
