diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/ccmake.h | 1 | ||||
-rw-r--r-- | include/container.h | 426 | ||||
-rw-r--r-- | include/dynstring.h | 1 | ||||
-rw-r--r-- | include/embed.h | 1 | ||||
-rw-r--r-- | include/log.h | 3 | ||||
-rw-r--r-- | include/rstypes.h | 1 | ||||
-rw-r--r-- | include/ttycolor.h | 1 |
7 files changed, 235 insertions, 199 deletions
diff --git a/include/ccmake.h b/include/ccmake.h index e69de29..b3b23a0 100644 --- a/include/ccmake.h +++ b/include/ccmake.h @@ -0,0 +1 @@ +/* vim: set ts=8 noet: */ diff --git a/include/container.h b/include/container.h index 9491477..1401162 100644 --- a/include/container.h +++ b/include/container.h @@ -17,7 +17,7 @@ #define struct_member_size(type, member) sizeof(( (type*)0 )->member) typedef unsigned char byte; -/// Find closest powers of 2 +/* Find closest powers of 2 */ #ifdef __GNUC__ # define upper_2_power_32(number) (32 - __builtin_clz(number)) # define upper_2_power_64(number) (64 - __builtin_clzl(number)) @@ -30,25 +30,34 @@ typedef unsigned char byte; unsigned long __bit_scan_64(int64_t number); #endif -/// define FALLTHROUGH macro +/* define FALLTHROUGH macro */ #if defined(__clang__) || defined(__GNUC__) # define FALLTHROUGH __attribute__((fallthrough)) #elif defined(_MSC_VER) # define FALLTHROUGH __fallthrough() #else # define FALLTHROUGH ((void)0) -#endif +#endif /* FALLTHROUGH */ + +/* define UNREACHABLE macro */ +#if defined(__GNUC__) /* GCC, Clang, ICC */ +# define UNREACHABLE (__builtin_unreachable()) +#elif defined(_MSC_VER) /* MSVC */ +# define UNREACHABLE (__assume(false)) +#else +# define UNREACHABLE ((void)*(volatile char*)0) +#endif /* UNREACHABLE */ -/// define TODO macro +/* define TODO macro */ #define TODO (void)(*(volatile char*)0) -/// typedefs for array qsort +/* typedefs for array qsort */ typedef int(*qsort_cmp_t)(const void*, const void*); #define get_qsort_cmp(type) __qsort_cmps[sizeof(type)] extern const qsort_cmp_t __qsort_cmps[64]; typedef void*(*memcpy_t)(void* restrict, const void*, size_t); -/// default qsort_cmp_t functions to be used with integral types. +/* default qsort_cmp_t functions to be used with integral types. */ #ifdef CONTAINER_EXPOSE_HELPERS # define _CONTAINER_STATIC int __default_char_cmp(const void* a, const void* b); @@ -58,7 +67,7 @@ typedef void*(*memcpy_t)(void* restrict, const void*, size_t); int __default_long_long_cmp(const void* a, const void* b); #else # define _CONTAINER_STATIC static -#endif // CONTAINER_EXPOSE_HELPERS +#endif /* CONTAINER_EXPOSE_HELPERS */ /* ----------------------------------------------------------------- */ @@ -75,24 +84,28 @@ typedef void*(*memcpy_t)(void* restrict, const void*, size_t); * to all of the macros in this library. */ -/// size of the array header. Should not be used directly, unless you know what you are doing +/* TODO: implement in operations that change the array size */ +/* #define SHINK_RESIZING_ARRAY */ + + +/* size of the array header. Should not be used directly, unless you know what you are doing */ #define DYNARRAY_HEADER_SIZE sizeof(struct _dynarray_header) -/// allocate new array of <size> elements of type <type>. +/* allocate new array of <size> elements of type <type>. */ #define array_new(type, size) _alloc_dynarray(sizeof(type), size) -/// get amount of elements in the array +/* get amount of elements in the array */ #define array_size(array) (((struct _dynarray_header *)((byte *)(array)-DYNARRAY_HEADER_SIZE))->size) -/// get array capacity (it's maximum size until reallocation) +/* get array capacity (it's maximum size until reallocation) */ #define array_capacity(array) (((struct _dynarray_header *)((byte *)(array)-DYNARRAY_HEADER_SIZE))->capacity) -/// get element size of an array (same as sizeof(array[0]), except not constant-expression) +/* get element size of an array (same as sizeof(array[0]), except not constant-expression) */ #define array_element_size(array) (((struct _dynarray_header *)((byte *)(array)-DYNARRAY_HEADER_SIZE))->memb_size) -/// free a dynamic array +/* free a dynamic array */ #define array_free(array) free(array_header(array)) -/// get dynamic array header. should not be used directly, unless you know what you are doing. +/* get dynamic array header. should not be used directly, unless you know what you are doing. */ #define array_header(array) ((struct _dynarray_header *)(((byte *)array) - DYNARRAY_HEADER_SIZE)) -/// allocate new array of <size> element of type <type> and initialize it from buffer +/* allocate new array of <size> element of type <type> and initialize it from buffer */ #define array_new_buffer_copy(type, buffer, size) _alloc_dynarray_buffer(sizeof(type), size, buffer, sizeof(type) * size) -/// add one new element to the end of the array. May invalidate previous pointer if size+1 > capacity. +/* add one new element to the end of the array. May invalidate previous pointer if size+1 > capacity. */ #define array_push(array, element) \ do { \ struct _dynarray_header *_ahdr = array_header(array); \ @@ -100,39 +113,43 @@ typedef void*(*memcpy_t)(void* restrict, const void*, size_t); array = _memreserve_dynarray(array, 1L << upper_2_power_64(_ahdr->size + 1)); \ _ahdr = array_header(array); \ } \ + /* Not sure this should be done like this tho... Maybe memcpy? */ \ + /* memcpy(array + _ahdr->size, &element, sizeof element); */ \ array[_ahdr->size] = (element); \ ++_ahdr->size; \ } while (0) #define array_extend(array, buffer, len) do {array = _array_extend(array, buffer, len); } while(0) -/// inserts element at given index element is evaluated once. -/// Note: `element` HAS to be of same type as the array during initialization. The expression has to be of the same type. -/// That means calling `array_insert(arr, 0, 5)`, where array is of type `long`, WILL lead to errors. because typeof(0) is -/// int, and it will put it in an `int` variable and copy 8 bytes from there, which will be some random stack garbage. +/* inserts element at given index element is evaluated once. + * Note: `element` HAS to be of same type as the array during initialization. The expression has to be of the same type. + * That means calling `array_insert(arr, 0, 5)`, where array is of type `long`, WILL lead to errors. because typeof(0) is + * int, and it will put it in an `int` variable and copy 8 bytes from there, which will be some random stack garbage. */ #define array_insert(array, element, idx) \ do { \ typeof(element) __tmp_el_var = (element); \ array = _insert_to_index_dynarray(array, &__tmp_el_var, sizeof(__tmp_el_var), idx); \ } while(0) -/// removes last element from the array +/* Removes last element from the array */ #define array_pop(array) --array_header(array)->size -/// reserve length elements so that subsequent (length - current_size) pushes require no reallocation +/* Reserve length elements so that subsequent (length - current_size) pushes require no reallocation */ #define array_reserve(array, length) do { array = _memreserve_dynarray(array, length); } while (0) -/// change size of an array. the capacity is set to lowest power of 2 that is greater than length +/* Change size of an array. the capacity is set to lowest power of 2 that is greater than length */ #define array_resize(array, length) do { array = _force_resize_dynarray(array, length); } while(0) -/// set capacity to minimum possible value +/* Set capacity to minimum possible value */ #define array_shrink(array) do { array = _memshrink_array(array); } while(0) -/// bound-checks and returns a pointer to that element. on error returns NULL +/* Bound-checks and returns a pointer to that element. on error returns NULL */ #define array_at(array, idx) (idx < array_size(array) ? (void*)((byte*)array + idx*array_element_size(array)) : NULL) -/// sorts the array using compare_func for comparison +/* Sorts the array using compare_func for comparison */ #define array_qsort(array, compare_func) qsort(array, array_size(array), array_element_size(array), compare_func) -/// sorts the array using pre-defined comparison functions for signed integers based on size (1, 2, 4, 8) +/* Sorts the array using pre-defined comparison functions for signed integers based on size (1, 2, 4, 8) */ #define array_qsort_integral(array) array_qsort(array, __qsort_cmps[array_element_size(array)]) -/// Placed here because is not a macro. compares 2 arrays and returns the same way as `strcmp` +/* Removes an element at the index */ +#define array_pop_at(array, idx) do { array = _array_pop_at(array, idx); } while (0) +/* Placed here because is not a macro. compares 2 arrays and returns the same way as `strcmp` */ int array_compare(const void *const a1, const void *const a2, qsort_cmp_t comp); -/// Exact copy of the array. you have to free the pointer as well. +/* Exact copy of the array. you have to free the pointer as well. */ void* array_copy(void* old); -/// Search for element `element` in array `array` using comparator `cmp`. -/// Returns bool. Assumes that the array is sorted. +/* Search for element `element` in array `array` using comparator `cmp`. */ +/* Returns bool. Assumes that the array is sorted. */ char array_binary_search(void* array, void* element, qsort_cmp_t cmp); struct linked_list array_to_ll(void* array); @@ -150,128 +167,128 @@ struct linked_list_node { void* data; struct linked_list_node *next; }; -/// holds meta about list and first element. you should not use it's members. +/* holds meta about list and first element. you should not use it's members. */ struct linked_list { struct __linked_list_meta meta; struct linked_list_node *first; struct linked_list_node *last; }; -/// creates an empty linked list. `memb_size` should usually be sizeof(element type), -/// O(1) +/* creates an empty linked list. `memb_size` should usually be sizeof(element type), */ +/* O(1) */ struct linked_list ll_create(size_t memb_size); -/// Created linked list with elements as in buf. Copies the memory with `memcpy`. -/// Assumes buffer size is >= buff_len * memb_size -/// O(buff_len) +/* Created linked list with elements as in buf. Copies the memory with `memcpy`. */ +/* Assumes buffer size is >= buff_len * memb_size */ +/* O(buff_len) */ struct linked_list ll_create_from_buffer(size_t memb_size, const void* buf, size_t buff_len); -/// iteratively frees a linked list -/// O(n) +/* iteratively frees a linked list */ +/* O(n) */ void ll_free(struct linked_list* list); -/// searches an `element` in the list using `cmp`. Returns whether it found it or not. -/// O(n) +/* searches an `element` in the list using `cmp`. Returns whether it found it or not. */ +/* O(n) */ char ll_search(const struct linked_list* list, const void* element, qsort_cmp_t cmp); -/// searches for `element` in the list using `cmp`. Returns the node if it was found, else returns NULL -/// O(n) +/* searches for `element` in the list using `cmp`. Returns the node if it was found, else returns NULL */ +/* O(n) */ struct linked_list_node* ll_find(const struct linked_list* list, const void* element, qsort_cmp_t cmp); -/// get a pointer to node at index i. DO NOT FREE THIS POINTER. Returns NULL if -/// list is not long enough. -/// O(i) +/* get a pointer to node at index i. DO NOT FREE THIS POINTER. Returns NULL if */ +/* list is not long enough. */ +/* O(i) */ struct linked_list_node* ll_at(const struct linked_list* list, const size_t i); -/// truncate a list starting from index i. if i==0, frees the list and you have to initialize a new one. -/// O(n) +/* truncate a list starting from index i. if i==0, frees the list and you have to initialize a new one. */ +/* O(n) */ void ll_truncate(struct linked_list* list, const size_t i); -/// returns a size of a list as stored in metadata. -/// Should be same as `ll_definite_size` unless user modifies nodes directly. Which you should not do. -/// O(1) +/* returns a size of a list as stored in metadata. */ +/* Should be same as `ll_definite_size` unless user modifies nodes directly. Which you should not do. */ +/* O(1) */ size_t ll_probably_size(const struct linked_list* list); -/// Counts elements in linked list, updating size in metadata if necessary. -/// if `ll_probably_size` is greater than `ll_definite_size`, there was a memory leak. -// if it is equal, everything is fine -/// else, the creator of the library is dumb. -/// O(n) +/* Counts elements in linked list, updating size in metadata if necessary. */ +/* if `ll_probably_size` is greater than `ll_definite_size`, there was a memory leak. */ +/* if it is equal, everything is fine */ +/* else, the creator of the library is dumb. */ +/* O(n) */ size_t ll_definite_size(struct linked_list *list); -/// creates a new node at the end of list and copies memory from element to new node. -/// The amount of memory copied is `memb_size` that was passed in `ll_create*` function. -/// If list->last->next == NULL, O(1) (which is guaranteed if you don't touch the nodes). +/* creates a new node at the end of list and copies memory from element to new node. */ +/* The amount of memory copied is `memb_size` that was passed in `ll_create*` function. */ +/* If list->last->next == NULL, O(1) (which is guaranteed if you don't touch the nodes). */ void ll_append(struct linked_list *list, const void* restrict element); -/// same as `ll_append`, except it does not perform memcpy and directly assigns pointer to node. -/// the only reqirement to this function is that `pointer` must be freeable with `free` function. -/// ONLY USE THIS IF YOU ARE 100% SURE THAT POINTER CAME UNMODIFIED FROM MALLOC, -/// OTHERWISE THE `ll_free` FUNCTION MAY DOUBLE-FREE, LEAK MEMORY AND OTHER TERRIBLE THINGS. -/// Complexity same as `ll_append`, usually O(1) +/* same as `ll_append`, except it does not perform memcpy and directly assigns pointer to node. */ +/* the only reqirement to this function is that `pointer` must be freeable with `free` function. */ +/* ONLY USE THIS IF YOU ARE 100% SURE THAT POINTER CAME UNMODIFIED FROM MALLOC, */ +/* OTHERWISE THE `ll_free` FUNCTION MAY DOUBLE-FREE, LEAK MEMORY AND OTHER TERRIBLE THINGS. */ +/* Complexity same as `ll_append`, usually O(1) */ void ll_append_mallocated_pointer(struct linked_list *list, void* pointer); -/// inserts an element to the front of the list. -/// O(1) +/* inserts an element to the front of the list. */ +/* O(1) */ void ll_insert_front(struct linked_list *list, const void* restrict element); -/// This to `ll_insert_front` is same as `ll_append_mallocated_pointer` to `ll_append`. -/// Copies `pointer` into newly created node. Same security considerations -/// as in `ll_append_mallocated_pointer`. -/// O(1) +/* This to `ll_insert_front` is same as `ll_append_mallocated_pointer` to `ll_append`. */ +/* Copies `pointer` into newly created node. Same security considerations */ +/* as in `ll_append_mallocated_pointer`. */ +/* O(1) */ void ll_insert_front_mallocated_pointer(struct linked_list *list, void* pointer); -/// inserts an element at index I if it exists. Returns 1 if insertion was successfull, -/// 0 if list is not long enough. -/// O(i) +/* inserts an element at index I if it exists. Returns 1 if insertion was successfull, */ +/* 0 if list is not long enough. */ +/* O(i) */ char ll_insert_at(struct linked_list *list, const void* restrict element, size_t i); -/// copies a pointer directly into newly created node. see `ll_insert_at` -/// and `ll_append_mallocated_pointer` for more details. -/// O(i) +/* copies a pointer directly into newly created node. see `ll_insert_at` */ +/* and `ll_append_mallocated_pointer` for more details. */ +/* O(i) */ char ll_insert_at_mallocated_pointer(struct linked_list *list, void* pointer, size_t i); -/// removes the element from the front, or, if the list is empty, does nothing -/// O(1) +/* removes the element from the front, or, if the list is empty, does nothing */ +/* O(1) */ void ll_remove_front(struct linked_list* list); -/// removes the element from the back, or, if the list is empty, does nothing -/// O(n) +/* removes the element from the back, or, if the list is empty, does nothing */ +/* O(n) */ void ll_remove_back(struct linked_list* list); -/// Removes element at index i. if there is no such index, does nothing. -/// O(n) +/* Removes element at index i. if there is no such index, does nothing. */ +/* O(n) */ char ll_remove_at(struct linked_list *list, size_t i); -/// removes first occurrence of element `elem` from list. +/* removes first occurrence of element `elem` from list. */ void ll_remove_elem(struct linked_list* list, const void* elem, qsort_cmp_t cmp); -/// Removes ALL occurrences of element "elem" in a list -/// WARNING: SOMETHING IS WRONG WITH THIS FUNCTION AND IT SHOULD NOT BE USED EVER -/// UNLESS I FIX IT -/// FOR NOW I WILL ADD TODO MARK THERE -/// O(n) +/* Removes ALL occurrences of element "elem" in a list */ +/* WARNING: SOMETHING IS WRONG WITH THIS FUNCTION AND IT SHOULD NOT BE USED EVER */ +/* UNLESS I FIX IT */ +/* FOR NOW I WILL ADD TODO MARK THERE */ +/* O(n) */ void ll_remove_all(struct linked_list* list, const void* elem, qsort_cmp_t cmp); -/// splits a linked list into two, the second one starting from element at index `i`. -/// List that you passed stays valid, only it's size changes. return value is the second list. -/// O(n) +/* splits a linked list into two, the second one starting from element at index `i`. */ +/* List that you passed stays valid, only it's size changes. return value is the second list. */ +/* O(n) */ struct linked_list ll_split_at(struct linked_list *list, size_t i); -/// merges 2 lists into one, with elements of second list appearing at the end of first list -/// invalidates second list, leaving only first one valid. -/// O(1) +/* merges 2 lists into one, with elements of second list appearing at the end of first list */ +/* invalidates second list, leaving only first one valid. */ +/* O(1) */ void ll_merge(struct linked_list* fst, struct linked_list* snd); -/// splits linked list into N linked lists at indexes given in varargs. -/// varargs type: size_t -/// INDEXES MUST BE IN ASCENDING ORDER, OR ELSE ARE IGNORED. -/// Returns array (as defined in array implementation above). -/// O(n) +/* splits linked list into N linked lists at indexes given in varargs. */ +/* varargs type: size_t */ +/* INDEXES MUST BE IN ASCENDING ORDER, OR ELSE ARE IGNORED. */ +/* Returns array (as defined in array implementation above). */ +/* O(n) */ struct linked_list* ll_split_n(struct linked_list* list, size_t splits, ...); -/// merges N linked lists into one. -/// varargs type: struct linked_list* -/// Leaves `result` list valid, all other ones are invalidated. -/// Lists are appended in the order they are given in varargs. -/// O(`merges`) +/* merges N linked lists into one. */ +/* varargs type: struct linked_list* */ +/* Leaves `result` list valid, all other ones are invalidated. */ +/* Lists are appended in the order they are given in varargs. */ +/* O(`merges`) */ void ll_merge_n(struct linked_list* result, size_t merges, ...); -/// creates array (not an array of pointers, array of elements! it uses memcpy to copy elements) -/// Leaves linked list unchanged +/* creates array (not an array of pointers, array of elements! it uses memcpy to copy elements) */ +/* Leaves linked list unchanged */ void* ll_to_array(const struct linked_list* list); -/// Same as `ll_to_array`, except it accepts function used for copying. Use if you think -/// that your data should not be `memcpy`'d +/* Same as `ll_to_array`, except it accepts function used for copying. Use if you think */ +/* that your data should not be `memcpy`'d */ void* ll_to_array_custom_cpy(const struct linked_list* list, memcpy_t cpy); -/// literally does: -/// 1. linked list to array -/// 2. sort the array using qsort -/// 3. array to linked list -/// since linked list in not random-access, i think this is literally more efficient. -/// Also, I am not in a mood to write sorting algorithms today +/* literally does: */ +/* 1. linked list to array */ +/* 2. sort the array using qsort */ +/* 3. array to linked list */ +/* since linked list in not random-access, i think this is literally more efficient. */ +/* Also, I am not in a mood to write sorting algorithms today */ void ll_sort(struct linked_list *list, qsort_cmp_t cmp); -/// Deallocates a node and returns next one; +/* Deallocates a node and returns next one; */ struct linked_list_node* ll_free_node(struct linked_list* list, struct linked_list_node* node) ; -/// Sets a custom free function for the data of the list +/* Sets a custom free function for the data of the list */ void ll_set_free(struct linked_list* list, free_t new_free); -/// Creates a deep copy of the list, meaning that it must be free'd as any other list -/// Uses `cpy` function to copy data to new location. If NULL, memcpy is used. +/* Creates a deep copy of the list, meaning that it must be free'd as any other list */ +/* Uses `cpy` function to copy data to new location. If NULL, memcpy is used. */ struct linked_list ll_deep_copy(const struct linked_list* list, memcpy_t cpy); /* ----------------------------------------------------------------- */ @@ -284,9 +301,9 @@ struct linked_list ll_deep_copy(const struct linked_list* list, memcpy_t cpy); #ifndef HMAP_INIT_SIZE # define HMAP_INIT_SIZE 32 #endif -/// should return `0` only if first argument is equal to second, -/// otherwise should return `1` or any other integer -/// OPERATES ON `struct hmap_pair*` !!!!!!!!!! NOT ON KEYS! +/* should return `0` only if first argument is equal to second, */ +/* otherwise should return `1` or any other integer */ +/* OPERATES ON `struct hmap_pair*` !!!!!!!!!! NOT ON KEYS! */ typedef int(*hmap_equal_fn)(const void*, const void*); typedef size_t(*hmap_hash_fn)(const void*); struct hmap_pair { @@ -313,51 +330,51 @@ struct hash_map_iter { }; typedef struct hash_map_iter hmap_iter; struct hash_map hmap_new(const size_t key_size, const size_t val_size, hmap_equal_fn eq, hmap_hash_fn hash); -/// copies data from pointers +/* copies data from pointers */ struct hash_map hmap_new_from_buffer(size_t key_size, size_t val_size, hmap_equal_fn eq, hmap_hash_fn hash, const struct hmap_pair* buf, size_t buf_len); void hmap_free(struct hash_map* map); -/// copy the contents of the pair into hash map (using `memcpy`). -/// The element is left unchanged, the memory pointed to by `element` may be anything, from stack to FFI allocator +/* copy the contents of the pair into hash map (using `memcpy`). */ +/* The element is left unchanged, the memory pointed to by `element` may be anything, from stack to FFI allocator */ void hmap_insert_copy(struct hash_map* map, const struct hmap_pair element); -/// returns 1 if an object was inserted, 0 if it was not. This is done to be able to free uninserted pointer. +/* returns 1 if an object was inserted, 0 if it was not. This is done to be able to free uninserted pointer. */ char hmap_insert_mallocated(struct hash_map* map, struct hmap_pair element); -/// pair is a pointer +/* pair is a pointer */ #define hmap_insert_pair(map, pair) hmap_insert_range(map, pair, 1); -/// copies data from pointers +/* copies data from pointers */ void hmap_insert_range(struct hash_map* map, const struct hmap_pair* elements, size_t elements_len); void* hmap_get(struct hash_map* map, void* key); -/// returns 1 if value was updates successfully, otherwise 0 (if key does not exist) +/* returns 1 if value was updates successfully, otherwise 0 (if key does not exist) */ char hmap_update(struct hash_map* map, void* key, void* new_val); void hmap_remove(struct hash_map* map, void* key); -/// double the size of a hash map +/* double the size of a hash map */ void hmap_rehash(struct hash_map* map); void hmap_rehash_to_size(struct hash_map* map, size_t new_size); -/// initialize iterator `iter`. +/* initialize iterator `iter`. */ void hmapi_begin(const struct hash_map* map, struct hash_map_iter* iter); -/// set iter to next element. If there is no next element, `hash_map_iter.current_node` is set to NULL +/* set iter to next element. If there is no next element, `hash_map_iter.current_node` is set to NULL */ void hmapi_next(struct hash_map_iter* iter); -/// Get a key-value pair at the iterator iter. -/// If iter is pointing beyond hash map (after the last element), `(struct hmap_pair){NULL, NULL}` is returned +/* Get a key-value pair at the iterator iter. */ +/* If iter is pointing beyond hash map (after the last element), `(struct hmap_pair){NULL, NULL}` is returned */ struct hmap_pair hmapi_get_data(const struct hash_map_iter* iter); void* hmapi_get_key(const struct hash_map_iter* iter); void* hmapi_get_val(const struct hash_map_iter* iter); -/// the function does comparison the same way `qsort_cmp_t` might do it, except this is wrapped in an enum. -/// This is done because 2 iterators might be incomparable (come from different hash maps), in this case `hampi_no` is returned. +/* the function does comparison the same way `qsort_cmp_t` might do it, except this is wrapped in an enum. */ +/* This is done because 2 iterators might be incomparable (come from different hash maps), in this case `hampi_no` is returned. */ enum hmapi_cmp_res hmapi_cmp(const struct hash_map_iter *a, const struct hash_map_iter* b); -/// 1 if a > b, 0 otherwise. +/* 1 if a > b, 0 otherwise. */ char hmapi_gt(const struct hash_map_iter *a, const struct hash_map_iter* b); -/// 1 if a = b, 0 otherwise +/* 1 if a = b, 0 otherwise */ char hmapi_eq(const struct hash_map_iter *a, const struct hash_map_iter* b); -/// 1 if a < b, 0 otherwise +/* 1 if a < b, 0 otherwise */ char hmapi_lt(const struct hash_map_iter *a, const struct hash_map_iter* b); -/// 1 if a >= b, 0 otherwise +/* 1 if a >= b, 0 otherwise */ char hmapi_ge(const struct hash_map_iter *a, const struct hash_map_iter* b); -/// 1 if a <= b, 0 otherwise +/* 1 if a <= b, 0 otherwise */ char hmapi_le(const struct hash_map_iter *a, const struct hash_map_iter* b); -/// 1 if a != b, otherwise 0 +/* 1 if a != b, otherwise 0 */ char hmapi_ne(const struct hash_map_iter *a, const struct hash_map_iter* b); -/// 1 if `iter` is an end iterator, 0 otherwise +/* 1 if `iter` is an end iterator, 0 otherwise */ char hmapi_end(const struct hash_map_iter* iter); /* ----------------------------------------------------------------- */ @@ -370,9 +387,9 @@ char hmapi_end(const struct hash_map_iter* iter); #ifndef HSET_INIT_SIZE # define HSET_INIT_SIZE 32 #endif -/// should return `0` only if first argument is equal to second, -/// otherwise should return `1` or any other integer -/// unlike hmap, operates on data structures directly +/* should return `0` only if first argument is equal to second, */ +/* otherwise should return `1` or any other integer */ +/* unlike hmap, operates on data structures directly */ typedef int(*hset_equal_fn)(const void*, const void*); typedef size_t(*hset_hash_fn)(const void*); struct hash_set { @@ -394,46 +411,46 @@ struct hash_set_iter { }; typedef struct hash_set_iter hset_iter; struct hash_set hset_new(const size_t el_size, hset_equal_fn eq, hset_hash_fn hash); -/// copies data from pointers +/* copies data from pointers */ struct hash_set hset_new_from_buffer(size_t el_size, hset_equal_fn eq, hset_hash_fn hash, const void* buf, size_t buf_len); char hset_ok(struct hash_set set); void hset_free(struct hash_set* set); -/// copy the contents of the pair into hash map (using `memcpy`). -/// The element is left unchanged, the memory pointed to by `element` may be anything, from stack to FFI allocator +/* copy the contents of the pair into hash map (using `memcpy`). */ +/* The element is left unchanged, the memory pointed to by `element` may be anything, from stack to FFI allocator */ void hset_insert_copy(struct hash_set* set, const void* element); -/// returns 1 if an object was inserted, 0 if it was not. This is done to be able to free uninserted pointer. +/* returns 1 if an object was inserted, 0 if it was not. This is done to be able to free uninserted pointer. */ char hset_insert_mallocated(struct hash_set* set, void* element); -/// get a pointer to an element with same hash and modify it directly +/* get a pointer to an element with same hash and modify it directly */ void* hset_at(struct hash_set* set, void* element); -/// returns 1 if value was updated successfully, otherwise 0 (if key does not exist) +/* returns 1 if value was updated successfully, otherwise 0 (if key does not exist) */ void hset_remove(struct hash_set* set, void* elem); -/// double the size of a hash set +/* double the size of a hash set */ void hset_rehash(struct hash_set* set); void hset_rehash_to_size(struct hash_set* set, size_t new_size); size_t hset_count(struct hash_set* set); -/// initialize iterator `iter`. +/* initialize iterator `iter`. */ void hseti_begin(const struct hash_set* map, struct hash_set_iter* iter); -/// set iter to next element. If there is no next element, `hash_set_iter.current_node` is set to NULL +/* set iter to next element. If there is no next element, `hash_set_iter.current_node` is set to NULL */ void hseti_next(struct hash_set_iter* iter); -/// If iter is pointing beyond hash set (after the last element), NULL is returned +/* If iter is pointing beyond hash set (after the last element), NULL is returned */ void* hseti_get(const struct hash_set_iter* iter); -/// the function does comparison the same way `qsort_cmp_t` might do it, except this is wrapped in an enum. -/// This is done because 2 iterators might be incomparable (come from different hash maps), in this case `hampi_no` is returned. +/* the function does comparison the same way `qsort_cmp_t` might do it, except this is wrapped in an enum. */ +/* This is done because 2 iterators might be incomparable (come from different hash maps), in this case `hampi_no` is returned. */ enum hseti_cmp_res hseti_cmp(const struct hash_set_iter *a, const struct hash_set_iter* b); -/// 1 if a > b, 0 otherwise. +/* 1 if a > b, 0 otherwise. */ char hseti_gt(const struct hash_set_iter *a, const struct hash_set_iter* b); -/// 1 if a = b, 0 otherwise +/* 1 if a = b, 0 otherwise */ char hseti_eq(const struct hash_set_iter *a, const struct hash_set_iter* b); -/// 1 if a < b, 0 otherwise +/* 1 if a < b, 0 otherwise */ char hseti_lt(const struct hash_set_iter *a, const struct hash_set_iter* b); -/// 1 if a >= b, 0 otherwise +/* 1 if a >= b, 0 otherwise */ char hseti_ge(const struct hash_set_iter *a, const struct hash_set_iter* b); -/// 1 if a <= b, 0 otherwise +/* 1 if a <= b, 0 otherwise */ char hseti_le(const struct hash_set_iter *a, const struct hash_set_iter* b); -/// 1 if a != b, otherwise 0 +/* 1 if a != b, otherwise 0 */ char hseti_ne(const struct hash_set_iter *a, const struct hash_set_iter* b); -/// 1 if `iter` is an end iterator, 0 otherwise +/* 1 if `iter` is an end iterator, 0 otherwise */ char hseti_end(const struct hash_set_iter* iter); /* ------------------------------------------------------------------------- */ @@ -454,15 +471,16 @@ struct _dynarray_header { void *_alloc_dynarray(size_t el_size, size_t len); void *_alloc_dynarray_buffer(size_t el_size, size_t alen, void *buffer, size_t blen); -/// Forcibly change size AND capacity of the array to new value -/// ignores the power-of-2-capacity rule +/* Forcibly change size AND capacity of the array to new value */ +/* ignores the power-of-2-capacity rule */ void *_force_resize_dynarray(void *dynarray, size_t new_size); void *_memreserve_dynarray(void *dynarray, size_t reserved); void *_memshrink_array(void *dynarray); void *_insert_to_index_dynarray(void *const dynarray, const void *const element, size_t el_size, size_t index); void* _array_extend(void* array, void* buffer, size_t len); +void* _array_pop_at(void* array, size_t idx); -// uncomment in dev mode so that LSP highlights the code +/* uncomment in dev mode so that LSP highlights the code */ /* #define CONTAINER_IMPLEMENTATION */ #ifdef CONTAINER_IMPLEMENTATION @@ -479,11 +497,11 @@ unsigned long __bit_scan_32(int32_t number) { } else { return 1; } -# else // _MSC_VER +# else /* _MSC_VER */ unsigned long count; for (count = 0; number; number >>= 1) { ++count; } return count; -# endif // _MSC_VER +# endif /* _MSC_VER */ } unsigned long __bit_scan_64(int64_t number) { # ifdef _MSC_VER @@ -493,13 +511,13 @@ unsigned long __bit_scan_64(int64_t number) { } else { return 1; } -# else // _MSC_VER +# else /* _MSC_VER */ unsigned long count; for (count = 0; number; number >>= 1) { ++count; } return count; -# endif // _MSC_VER +# endif /* _MSC_VER */ } -#endif // __GNUC__ +#endif /* __GNUC__ */ _CONTAINER_STATIC int __default_char_cmp(const void* a, const void* b) { @@ -534,8 +552,8 @@ _CONTAINER_STATIC int __default_long_cmp(const void* a, const void* b) { } #ifdef __GNUC__ -// cope -#pragma GCC diagnostic ignored "-Woverride-init" // Is is meant to override it on different platforms +/* cope */ +#pragma GCC diagnostic ignored "-Woverride-init" /* Is is meant to override it on different platforms */ const qsort_cmp_t __qsort_cmps[64] = { [sizeof(char)] = __default_char_cmp, [sizeof(short)] = __default_short_cmp, @@ -545,13 +563,13 @@ const qsort_cmp_t __qsort_cmps[64] = { [63] = 0, }; #pragma GCC diagnostic warning "-Woverride-init" -#else // not __GNUC__ +#else /* not __GNUC__ */ const qsort_cmp_t __qsort_cmps[64] = { 0, __default_char_cmp, __default_short_cmp, 0, __default_int_cmp, 0, 0, 0, __default_long_long_cmp, }; -#endif // __GNUC__ +#endif /* __GNUC__ */ /* ----------------------------------------------------------------- */ @@ -568,10 +586,10 @@ void *_alloc_dynarray(size_t el_size, size_t len) header->memb_size = el_size; return data + DYNARRAY_HEADER_SIZE; } -/// assumes that element size in the buffer is the same as element size in the array +/* assumes that element size in the buffer is the same as element size in the array */ void *_alloc_dynarray_buffer(size_t el_size, size_t alen, void *buffer, size_t blen) { void *array = _alloc_dynarray(el_size, alen); - memcpy(array, buffer, el_size * blen); + memcpy(array, buffer, blen); return array; } void *_memreserve_dynarray(void * const dynarray, size_t reserved) @@ -615,11 +633,11 @@ void *_force_resize_dynarray(void * const dynarray, size_t new_size) } void *_insert_to_index_dynarray(void *const dynarray, const void *const element, size_t el_size, size_t index) { struct _dynarray_header* hdr = array_header(dynarray); + if (el_size != hdr->memb_size) { return NULL; } byte* array = (byte*) _memreserve_dynarray(dynarray, 1 << upper_2_power_64(hdr->size + 1)); hdr = array_header(array); ++hdr->size; memmove(array + hdr->memb_size * (index+1), array + hdr->memb_size * (index), hdr->memb_size * (hdr->size - 1 - index)); - if (el_size != hdr->memb_size) { /* TODO: warning? */ } memcpy(array + hdr->memb_size * index, element, el_size); return array; } @@ -629,6 +647,21 @@ void* _array_extend(void* array, void* buffer, size_t len) { memcpy((byte*)array + header->size*header->memb_size, buffer, len * header->memb_size); return array; } +void* _array_pop_at(void* array, size_t idx) { + struct _dynarray_header* header = array_header(array); + size_t offdest = idx * header->memb_size, offsrc = offdest + header->memb_size, + len = header->memb_size * (header->size - idx - 1); + memmove((byte*)array + offdest, (byte*)array + offsrc, len); + --header->size; /* I may or may not have spent 1 hour to realize this line should be after memmove */ +#ifdef SHINK_RESIZING_ARRAY + if ((header->size << 2) < header->capacity) { + header->array_capacity >>= 1; + header = realloc(header, DYNARRAY_HEADER_SIZE + header->size * header->capacity); + array = ((byte*)header) + DYNARRAY_HEADER_SIZE; + } +#endif + return array; +} int array_compare(const void *const a1, const void *const a2, qsort_cmp_t comp) { struct _dynarray_header *hdr = array_header(a1); struct _dynarray_header *hdr2 = array_header(a2); @@ -642,8 +675,7 @@ int array_compare(const void *const a1, const void *const a2, qsort_cmp_t comp) if (s1 == s2) return 0; if (i == s1) return -1; if (i == s2) return 1; - TODO; - __builtin_unreachable(); + TODO; UNREACHABLE; } void* array_copy(void* old) { return _alloc_dynarray_buffer(array_element_size(old), array_size(old), old, array_size(old) * array_element_size(old)); @@ -701,7 +733,7 @@ struct linked_list ll_create_from_buffer(size_t memb_size, const void* buf, size ret.last = current_node; return ret; } -/// An older, more ugly implementation +/* An older, more ugly implementation */ void ll_free_(struct linked_list* list) { struct linked_list_node *to_dealloc = NULL; for (struct linked_list_node *current = list->first; current != NULL; current = current->next) { @@ -1122,7 +1154,7 @@ void hmap_remove(struct hash_map* map, void* key) { void hmap_rehash(struct hash_map* map) { hmap_rehash_to_size(map, array_size(map->buckets) << 1); } -/// double the size of a hash map +/* double the size of a hash map */ void hmap_rehash_to_size(struct hash_map* map, size_t new_size) { struct linked_list* new_buckets = array_new(struct linked_list, new_size); for (size_t i = 0; i < new_size; ++i) { @@ -1259,8 +1291,9 @@ void hset_free(struct hash_set* set) { } void hset_insert_copy(struct hash_set* set, const void* element) { size_t index = set->hash(element) % array_size(set->buckets); - if (ll_search(set->buckets + index, element, set->eq)) { - void* target = ll_find(set->buckets + index, element, set->eq)->data; + struct linked_list_node *node; + if (( node = ll_find(set->buckets + index, element, set->eq) ) /* != NULL */) { + void* target = node->data; memcpy(target, element, set->elem_size); return; } @@ -1269,8 +1302,9 @@ void hset_insert_copy(struct hash_set* set, const void* element) { } char hset_insert_mallocated(struct hash_set* set, void* element) { size_t index = set->hash(element) % array_size(set->buckets); - if (ll_search(set->buckets + index, element, set->eq)) { - void* target = ll_find(set->buckets + index, element, set->eq)->data; + struct linked_list_node *node; + if (( node = ll_find(set->buckets + index, element, set->eq)) /* != NULL */) { + void* target = node->data; free(target); target = element; return 0; @@ -1362,15 +1396,9 @@ enum hseti_cmp_res hseti_cmp(const struct hash_set_iter *a, const struct hash_se } return hset_gt; } -char hseti_gt(const struct hash_set_iter *a, const struct hash_set_iter* b) { - return hseti_cmp(a, b) == hset_gt; -} -char hseti_eq(const struct hash_set_iter *a, const struct hash_set_iter* b) { - return hseti_cmp(a, b) == hset_eq; -} -char hseti_lt(const struct hash_set_iter *a, const struct hash_set_iter* b) { - return hseti_cmp(a, b) == hset_lt; -} +char hseti_gt(const struct hash_set_iter *a, const struct hash_set_iter* b) { return hseti_cmp(a, b) == hset_gt; } +char hseti_eq(const struct hash_set_iter *a, const struct hash_set_iter* b) { return hseti_cmp(a, b) == hset_eq; } +char hseti_lt(const struct hash_set_iter *a, const struct hash_set_iter* b) { return hseti_cmp(a, b) == hset_lt; } char hseti_ge(const struct hash_set_iter *a, const struct hash_set_iter* b) { enum hseti_cmp_res cmp = hseti_cmp(a, b); return cmp == hset_gt || cmp == hset_eq; @@ -1386,6 +1414,8 @@ char hseti_ne(const struct hash_set_iter *a, const struct hash_set_iter* b) { char hseti_end(const struct hash_set_iter* iter) { return iter->current_node == NULL || iter->bucket_pos == SIZE_MAX; } -#endif // CONTAINER_IMPLEMENTATION +#endif /* CONTAINER_IMPLEMENTATION */ + +#endif /* JUSTANOTHERCATGIRL_HEADERS_CONTAINER */ -#endif // JUSTANOTHERCATGIRL_HEADERS_CONTAINER +/* vim: set ts=8 noet: */ diff --git a/include/dynstring.h b/include/dynstring.h index e69de29..b3b23a0 100644 --- a/include/dynstring.h +++ b/include/dynstring.h @@ -0,0 +1 @@ +/* vim: set ts=8 noet: */ diff --git a/include/embed.h b/include/embed.h index e69de29..b3b23a0 100644 --- a/include/embed.h +++ b/include/embed.h @@ -0,0 +1 @@ +/* vim: set ts=8 noet: */ diff --git a/include/log.h b/include/log.h index 59d2ed3..489d6c2 100644 --- a/include/log.h +++ b/include/log.h @@ -34,7 +34,7 @@ // F stands for format: needed to have printf-style formatting // P stands for perror -#ifdef LOG_DEBUG +#if defined(LOG_DEBUG) || defined(DEBUG) || defined(DBG) || defined(Debug) || defined(debug) // Log debug # define LDEBUG(msg) fputs("[DEBUG] " msg NL, stderr) # define LDEBUGV(msg) fprintf(stderr, "[DEBUG %s:%i@%s] " msg NL, __FILE__, __LINE__, __func__) @@ -82,3 +82,4 @@ #define LFAILV(msg) do { fprintf(stderr, RED "[CRITICAL %s:%i@%s] ", __FILE__, __LINE__, __func__); perror(msg); fputs(NLRST, stderr); exit(EXIT_FAILURE); } while(0) +/* vim: set ts=8 noet: */ diff --git a/include/rstypes.h b/include/rstypes.h index 57bfb63..f9f9723 100644 --- a/include/rstypes.h +++ b/include/rstypes.h @@ -40,3 +40,4 @@ typedef long double f128; #endif // RS_TYPES_USE_128 #endif // JUSTANOTHERCATGITL_RSTYPES_H +/* vim: set ts=8 noet: */ diff --git a/include/ttycolor.h b/include/ttycolor.h index d3f6f85..8aa10f0 100644 --- a/include/ttycolor.h +++ b/include/ttycolor.h @@ -82,3 +82,4 @@ #endif //JUSTANOTHERCATGIRL_HEADERS_TTYCOLOR +/* vim: set ts=8 noet: */ |