changed bool_t to bool to be drop-in replacement in C89, added memqswap which usually gets optimized better but may fail allocation, changed some linked list functions to be polymorphic, added some tests, fixed bugs in linked list
Minclude/cutils/byte_array.h
| @@ -24,12 +24,12 @@ void* bytearray_at(const Bytearray* bytearray, size_t index); | |||
|---|---|---|---|
| 24 | 24 | void* bytearray_pop_at(Bytearray* bytearray, size_t index, void* retptr); | |
| 25 | 25 | ||
| 26 | 26 | #define bytearray_push(bytearray, item) bytearray_insert(bytearray, bytearray->length, item) | |
| 27 | - | bool_t bytearray_insert(Bytearray* bytearray, size_t index, const void* item); | |
| 27 | + | bool bytearray_insert(Bytearray* bytearray, size_t index, const void* item); | |
| 28 | 28 | ||
| 29 | 29 | void bytearray_remove(Bytearray* bytearray, size_t index, void (*rmv)(void*)); | |
| 30 | 30 | ||
| 31 | - | bool_t bytearray_adjust_size(Bytearray* bytearray, size_t size); | |
| 32 | - | bool_t bytearray_shrink(Bytearray* bytearray); | |
| 31 | + | bool bytearray_adjust_size(Bytearray* bytearray, size_t size); | |
| 32 | + | bool bytearray_shrink(Bytearray* bytearray); | |
| 33 | 33 | HEDLEY_NON_NULL(3) | |
| 34 | 34 | size_t* bytearray_find(const Bytearray* haystack, const void* needle, int (*cmp)(const void*, const void*)); | |
| 35 | 35 | ||
Minclude/cutils/common.h
| @@ -6,7 +6,14 @@ | |||
|---|---|---|---|
| 6 | 6 | #ifndef SIZE_MAX | |
| 7 | 7 | #define SIZE_MAX (size_t)-1; | |
| 8 | 8 | #endif | |
| 9 | - | typedef enum {b_false, b_true} bool_t; | |
| 9 | + | ||
| 10 | + | #if __STDC_VERSION__ >= 199901L | |
| 11 | + | #include <stdbool.h> | |
| 12 | + | #else | |
| 13 | + | #ifndef CUTILS_NO_BOOL | |
| 14 | + | typedef enum {false = 0, true = 1} bool; | |
| 15 | + | #endif | |
| 16 | + | #endif | |
| 10 | 17 | ||
| 11 | 18 | ||
| 12 | 19 | #endif /* CUTILS_COMMON_H */ | |
Minclude/cutils/dyn_string.h
| @@ -22,17 +22,17 @@ char string_at(const String* string, size_t index); | |||
|---|---|---|---|
| 22 | 22 | #define string_pop(string) string_pop_at(string, string->length-1) | |
| 23 | 23 | char string_pop_at(String* string, size_t index); | |
| 24 | 24 | ||
| 25 | - | bool_t string_insert(String* string, size_t index, char character); | |
| 25 | + | bool string_insert(String* string, size_t index, char character); | |
| 26 | 26 | #define string_push(string, character) string_insert(string, string->length, character) | |
| 27 | 27 | ||
| 28 | 28 | void string_remove(String* string, size_t index); | |
| 29 | 29 | void string_remove_range(String* string, size_t index, size_t length); | |
| 30 | 30 | ||
| 31 | - | bool_t string_adjust_size(String* string, size_t size); | |
| 31 | + | bool string_adjust_size(String* string, size_t size); | |
| 32 | 32 | size_t* string_find_char(const String* haystack, const char needle); | |
| 33 | 33 | size_t* string_find_str(const String* haystack, const String* needle); | |
| 34 | 34 | ||
| 35 | - | bool_t string_concat(String* string, const String* other); | |
| 35 | + | bool string_concat(String* string, const String* other); | |
| 36 | 36 | ||
| 37 | 37 | String* from_cstring(const char* cstring); | |
| 38 | 38 | String* from_cstring_del(char* cstring); | |
Minclude/cutils/linked-list.h
| @@ -7,13 +7,12 @@ | |||
|---|---|---|---|
| 7 | 7 | typedef struct SLnode | |
| 8 | 8 | { | |
| 9 | 9 | void* item; | |
| 10 | - | struct SLnode* next; | |
| 10 | + | void* next; /*has to be void* so the next field is compatible between the structs*/ | |
| 11 | 11 | } SLnode; | |
| 12 | 12 | ||
| 13 | 13 | typedef struct DLnode | |
| 14 | 14 | { | |
| 15 | - | void* item; | |
| 16 | - | struct DLnode* next; | |
| 15 | + | struct SLnode sl; | |
| 17 | 16 | struct DLnode* prev; | |
| 18 | 17 | } DLnode; | |
| 19 | 18 | ||
| @@ -22,67 +21,43 @@ typedef struct LinkedList | |||
|---|---|---|---|
| 22 | 21 | void* head; /*SLnode if doubly_linked is false, otherwise DLnode*/ | |
| 23 | 22 | void* tail; | |
| 24 | 23 | size_t length; | |
| 25 | - | bool_t doubly_linked; | |
| 26 | - | bool_t circularly_linked; | |
| 24 | + | bool doubly_linked; | |
| 25 | + | bool circularly_linked; | |
| 27 | 26 | } LinkedList; | |
| 28 | 27 | ||
| 29 | - | LinkedList* new_ll(bool_t doubly_linked, bool_t circularly_linked); | |
| 28 | + | LinkedList* new_ll(bool doubly_linked, bool circularly_linked); | |
| 29 | + | void delete_ll(LinkedList* ll, void(*rmv) (void*)); | |
| 30 | 30 | ||
| 31 | - | void delete_sll(LinkedList* ll, void(*rmv) (void*)); | |
| 32 | - | void delete_dll(LinkedList* ll, void(*rmv) (void*)); | |
| 33 | - | HEDLEY_INLINE | |
| 34 | - | static void delete_ll(LinkedList* ll, void(*rmv) (void*)) | |
| 35 | - | { | |
| 36 | - | if(ll->doubly_linked) | |
| 37 | - | delete_dll(ll, rmv); | |
| 38 | - | else | |
| 39 | - | delete_sll(ll, rmv); | |
| 40 | - | } | |
| 41 | - | ||
| 42 | - | void* sll_at(const LinkedList* ll, size_t index); | |
| 43 | - | void* dll_at(const LinkedList* ll, size_t index); | |
| 31 | + | void* llnode_at(const LinkedList* ll, size_t index); | |
| 44 | 32 | HEDLEY_INLINE | |
| 45 | 33 | static void* ll_at(const LinkedList* ll, size_t index) | |
| 46 | 34 | { | |
| 47 | - | if(ll->doubly_linked) | |
| 48 | - | return sll_at(ll, index); | |
| 49 | - | else | |
| 50 | - | return dll_at(ll, index); | |
| 35 | + | return ((SLnode*)llnode_at(ll, index))->item; | |
| 51 | 36 | } | |
| 52 | 37 | #define ll_pop(ll) ll_pop_at(ll, ll->length-1) | |
| 53 | - | void* sll_pop_at(LinkedList* ll, size_t index); | |
| 54 | - | void* dll_pop_at(LinkedList* ll, size_t index); | |
| 55 | - | HEDLEY_INLINE | |
| 56 | - | static void* ll_pop_at(LinkedList* ll, size_t index) | |
| 57 | - | { | |
| 58 | - | if(ll->doubly_linked) | |
| 59 | - | return sll_pop_at(ll, index); | |
| 60 | - | else | |
| 61 | - | return dll_pop_at(ll, index); | |
| 62 | - | } | |
| 38 | + | void* ll_pop_at(LinkedList* ll, size_t index); | |
| 63 | 39 | ||
| 64 | 40 | #define ll_push(ll, item) ll_insert(ll, ll->length, item) | |
| 65 | - | bool_t sll_insert(LinkedList* ll, size_t index, void* item); | |
| 66 | - | bool_t dll_insert(LinkedList* ll, size_t index, void* item); | |
| 41 | + | bool sll_insert(LinkedList* ll, size_t index, void* item); | |
| 42 | + | bool dll_insert(LinkedList* ll, size_t index, void* item); | |
| 67 | 43 | HEDLEY_INLINE | |
| 68 | - | static bool_t ll_insert(LinkedList* ll, size_t index, void* item) | |
| 44 | + | static bool ll_insert(LinkedList* ll, size_t index, void* item) | |
| 69 | 45 | { | |
| 70 | 46 | if(ll->doubly_linked) | |
| 71 | - | return sll_insert(ll, index, item); | |
| 72 | - | else | |
| 73 | 47 | return dll_insert(ll, index, item); | |
| 48 | + | else | |
| 49 | + | return sll_insert(ll, index, item); | |
| 74 | 50 | } | |
| 75 | 51 | ||
| 76 | - | ||
| 77 | 52 | void sll_remove(LinkedList* ll, size_t index, void (*rmv)(void*)); | |
| 78 | 53 | void dll_remove(LinkedList* ll, size_t index, void (*rmv)(void*)); | |
| 79 | 54 | HEDLEY_INLINE | |
| 80 | 55 | static void ll_remove(LinkedList* ll, size_t index, void (*rmv)(void*)) | |
| 81 | 56 | { | |
| 82 | 57 | if(ll->doubly_linked) | |
| 83 | - | sll_remove(ll, index, rmv); | |
| 84 | - | else | |
| 85 | 58 | dll_remove(ll, index, rmv); | |
| 59 | + | else | |
| 60 | + | sll_remove(ll, index, rmv); | |
| 86 | 61 | } | |
| 87 | 62 | void sll_remove_range(LinkedList* ll, size_t index, size_t length, void (*rmv)(void*)); | |
| 88 | 63 | void dll_remove_range(LinkedList* ll, size_t index, size_t length, void (*rmv)(void*)); | |
| @@ -90,30 +65,22 @@ HEDLEY_INLINE | |||
|---|---|---|---|
| 90 | 65 | static void ll_remove_range(LinkedList* ll, size_t index, size_t length, void (*rmv)(void*)) | |
| 91 | 66 | { | |
| 92 | 67 | if(ll->doubly_linked) | |
| 93 | - | sll_remove_range(ll, index, length, rmv); | |
| 94 | - | else | |
| 95 | 68 | dll_remove_range(ll, index, length, rmv); | |
| 96 | - | } | |
| 97 | - | ||
| 98 | - | size_t* sll_find(const LinkedList* haystack, const void* needle, int (*cmp)(const void*, const void*)); | |
| 99 | - | size_t* dll_find(const LinkedList* haystack, const void* needle, int (*cmp)(const void*, const void*)); | |
| 100 | - | HEDLEY_INLINE | |
| 101 | - | static size_t* ll_find(const LinkedList* haystack, const void* needle, int (*cmp)(const void*, const void*)) | |
| 102 | - | { | |
| 103 | - | if(haystack->doubly_linked) | |
| 104 | - | return sll_find(haystack, needle, cmp); | |
| 105 | 69 | else | |
| 106 | - | return dll_find(haystack, needle, cmp); | |
| 70 | + | sll_remove_range(ll, index, length, rmv); | |
| 107 | 71 | } | |
| 72 | + | ||
| 73 | + | size_t* ll_find(const LinkedList* haystack, const void* needle, int (*cmp)(const void*, const void*)); | |
| 74 | + | ||
| 108 | 75 | void sll_swap(LinkedList* ll, size_t item1, size_t item2); | |
| 109 | 76 | void dll_swap(LinkedList* ll, size_t item1, size_t item2); | |
| 110 | 77 | HEDLEY_INLINE | |
| 111 | 78 | static void ll_swap(LinkedList* ll, size_t item1, size_t item2) | |
| 112 | 79 | { | |
| 113 | 80 | if(ll->doubly_linked) | |
| 114 | - | sll_swap(ll, item1, item2); | |
| 115 | - | else | |
| 116 | 81 | dll_swap(ll, item1, item2); | |
| 82 | + | else | |
| 83 | + | sll_swap(ll, item1, item2); | |
| 117 | 84 | } | |
| 118 | 85 | ||
| 119 | 86 | ||
Minclude/cutils/misc.h
| @@ -15,6 +15,7 @@ | |||
|---|---|---|---|
| 15 | 15 | #endif | |
| 16 | 16 | ||
| 17 | 17 | #include <string.h> | |
| 18 | + | #include <stdlib.h> | |
| 18 | 19 | #include <cutils/common.h> | |
| 19 | 20 | ||
| 20 | 21 | #if __STDC_VERSION__ >= 199901L | |
| @@ -38,12 +39,25 @@ static void memswap(void* item1, void* item2, size_t length) | |||
|---|---|---|---|
| 38 | 39 | ||
| 39 | 40 | while(length--) | |
| 40 | 41 | { | |
| 41 | - | tmp = *item1_tmp; | |
| 42 | - | *item1_tmp = *item2_tmp; | |
| 43 | - | *item2_tmp = tmp; | |
| 42 | + | tmp = item1_tmp[length]; | |
| 43 | + | item1_tmp[length] = item2_tmp[length]; | |
| 44 | + | item2_tmp[length] = tmp; | |
| 44 | 45 | } | |
| 45 | 46 | } | |
| 46 | 47 | ||
| 48 | + | HEDLEY_INLINE | |
| 49 | + | static bool memqswap(void* item1, void* item2, size_t length) | |
| 50 | + | { | |
| 51 | + | void* tmp = malloc(length); | |
| 52 | + | if(!tmp) | |
| 53 | + | return false; | |
| 54 | + | memcpy(tmp, item1, length); | |
| 55 | + | memcpy(item1, item2, length); | |
| 56 | + | memcpy(item2, tmp, length); | |
| 57 | + | free(tmp); | |
| 58 | + | return true; | |
| 59 | + | } | |
| 60 | + | ||
| 47 | 61 | #if __STDC_VERSION__ >= 201112L | |
| 48 | 62 | #include <time.h> | |
| 49 | 63 | #endif | |
Minclude/cutils/vector.h
| @@ -22,14 +22,14 @@ void* vector_at(const Vector* vector, size_t index); | |||
|---|---|---|---|
| 22 | 22 | #define vector_pop(vector) vector_pop_at(vector, vector->length-1) | |
| 23 | 23 | void* vector_pop_at(Vector* vector, size_t index); | |
| 24 | 24 | ||
| 25 | - | bool_t vector_insert(Vector* vector, size_t index, void* item); | |
| 25 | + | bool vector_insert(Vector* vector, size_t index, void* item); | |
| 26 | 26 | #define vector_push(vector, item) vector_insert(vector, vector->length, item) | |
| 27 | 27 | ||
| 28 | 28 | void vector_remove(Vector* vector, size_t index, void (*rmv)(void*)); | |
| 29 | 29 | void vector_remove_range(Vector* vector, size_t index, size_t length, void (*rmv)(void*)); | |
| 30 | 30 | ||
| 31 | - | bool_t vector_adjust_size(Vector* vector, size_t size); | |
| 32 | - | bool_t vector_shrink(Vector* vector); | |
| 31 | + | bool vector_adjust_size(Vector* vector, size_t size); | |
| 32 | + | bool vector_shrink(Vector* vector); | |
| 33 | 33 | HEDLEY_NON_NULL(3) | |
| 34 | 34 | size_t* vector_find(const Vector* haystack, const void* needle, int (*cmp)(const void*, const void*)); | |
| 35 | 35 | ||
Msrc/byte_array.c
| @@ -63,18 +63,18 @@ void* bytearray_pop_at(Bytearray* bytearray, size_t index, void* retptr) | |||
|---|---|---|---|
| 63 | 63 | return retptr; | |
| 64 | 64 | } | |
| 65 | 65 | ||
| 66 | - | bool_t bytearray_insert(Bytearray* bytearray, size_t index, const void* item) | |
| 66 | + | bool bytearray_insert(Bytearray* bytearray, size_t index, const void* item) | |
| 67 | 67 | { | |
| 68 | 68 | size_t length = bytearray->length; | |
| 69 | 69 | size_t size = bytearray->element_size; | |
| 70 | 70 | ||
| 71 | 71 | if(index > length || !bytearray_adjust_size(bytearray, length+1)) | |
| 72 | - | return b_false; | |
| 72 | + | return false; | |
| 73 | 73 | ||
| 74 | 74 | memmove(bytearray->items+index*size+1*size, bytearray->items+index*size, (length*size-index*size)*sizeof(*bytearray->items)); | |
| 75 | 75 | memcpy(bytearray->items+index*size, item, bytearray->element_size); | |
| 76 | 76 | bytearray->length++; | |
| 77 | - | return b_true; | |
| 77 | + | return true; | |
| 78 | 78 | } | |
| 79 | 79 | ||
| 80 | 80 | void bytearray_remove(Bytearray* bytearray, size_t index, void (*rmv)(void*)) | |
| @@ -91,7 +91,7 @@ void bytearray_remove(Bytearray* bytearray, size_t index, void (*rmv)(void*)) | |||
|---|---|---|---|
| 91 | 91 | } | |
| 92 | 92 | } | |
| 93 | 93 | ||
| 94 | - | bool_t bytearray_adjust_size(Bytearray* bytearray, size_t size) | |
| 94 | + | bool bytearray_adjust_size(Bytearray* bytearray, size_t size) | |
| 95 | 95 | { | |
| 96 | 96 | while(bytearray->capacity < size) | |
| 97 | 97 | { | |
| @@ -102,14 +102,14 @@ bool_t bytearray_adjust_size(Bytearray* bytearray, size_t size) | |||
|---|---|---|---|
| 102 | 102 | if(!bytearray->items) | |
| 103 | 103 | { | |
| 104 | 104 | bytearray->items = tmp; | |
| 105 | - | return b_false; | |
| 105 | + | return false; | |
| 106 | 106 | } | |
| 107 | 107 | bytearray->capacity *= 2; | |
| 108 | 108 | } | |
| 109 | - | return b_true; | |
| 109 | + | return true; | |
| 110 | 110 | } | |
| 111 | 111 | ||
| 112 | - | bool_t bytearray_shrink(Bytearray* bytearray) | |
| 112 | + | bool bytearray_shrink(Bytearray* bytearray) | |
| 113 | 113 | { | |
| 114 | 114 | while(bytearray->capacity > bytearray->length*2) | |
| 115 | 115 | { | |
| @@ -120,11 +120,11 @@ bool_t bytearray_shrink(Bytearray* bytearray) | |||
|---|---|---|---|
| 120 | 120 | if(!bytearray->items) | |
| 121 | 121 | { | |
| 122 | 122 | bytearray->items = tmp; | |
| 123 | - | return b_false; | |
| 123 | + | return false; | |
| 124 | 124 | } | |
| 125 | 125 | bytearray->capacity /= 2; | |
| 126 | 126 | } | |
| 127 | - | return b_true; | |
| 127 | + | return true; | |
| 128 | 128 | } | |
| 129 | 129 | ||
| 130 | 130 | size_t* bytearray_find(const Bytearray* haystack, const void* needle, int (*cmp)(const void*, const void*)) | |
Msrc/dyn_string.c
| @@ -25,7 +25,7 @@ void string_remove(String* string, size_t index) | |||
|---|---|---|---|
| 25 | 25 | string->length--; | |
| 26 | 26 | } | |
| 27 | 27 | } | |
| 28 | - | ||
| 28 | + | /* TODO: optimize */ | |
| 29 | 29 | void string_remove_range(String* string, size_t index, size_t length) | |
| 30 | 30 | { | |
| 31 | 31 | size_t i; | |
| @@ -35,15 +35,15 @@ void string_remove_range(String* string, size_t index, size_t length) | |||
|---|---|---|---|
| 35 | 35 | } | |
| 36 | 36 | } | |
| 37 | 37 | ||
| 38 | - | bool_t string_insert(String* string, size_t index, char character) | |
| 38 | + | bool string_insert(String* string, size_t index, char character) | |
| 39 | 39 | { | |
| 40 | 40 | if(index > string->length || !string_adjust_size(string, string->length)) | |
| 41 | - | return b_false; | |
| 41 | + | return false; | |
| 42 | 42 | ||
| 43 | 43 | memmove(string->chars+index+1, string->chars+index, (string->length-index)*sizeof(*string->chars)); | |
| 44 | 44 | string->chars[index] = character; | |
| 45 | 45 | string->length++; | |
| 46 | - | return b_true; | |
| 46 | + | return true; | |
| 47 | 47 | } | |
| 48 | 48 | ||
| 49 | 49 | char string_at(const String* string, size_t index) | |
| @@ -66,13 +66,13 @@ char string_pop_at(String* string, size_t index) | |||
|---|---|---|---|
| 66 | 66 | } | |
| 67 | 67 | } | |
| 68 | 68 | ||
| 69 | - | bool_t string_concat(String* string, const String* other) | |
| 69 | + | bool string_concat(String* string, const String* other) | |
| 70 | 70 | { | |
| 71 | 71 | if(!string_adjust_size(string,string->length+other->length-1)) | |
| 72 | - | return b_false; | |
| 72 | + | return false; | |
| 73 | 73 | memcpy(string->chars+string->length,other->chars,other->length); | |
| 74 | 74 | string->length += other->length; | |
| 75 | - | return b_true; | |
| 75 | + | return true; | |
| 76 | 76 | } | |
| 77 | 77 | ||
| 78 | 78 | size_t* string_find_char(const String* haystack, const char needle) | |
| @@ -112,7 +112,7 @@ size_t* string_find_str(const String* haystack, const String* needle) | |||
|---|---|---|---|
| 112 | 112 | return NULL; | |
| 113 | 113 | } | |
| 114 | 114 | ||
| 115 | - | bool_t string_adjust_size(String* string, size_t size) | |
| 115 | + | bool string_adjust_size(String* string, size_t size) | |
| 116 | 116 | { | |
| 117 | 117 | while(string->capacity < size) | |
| 118 | 118 | { | |
| @@ -121,11 +121,11 @@ bool_t string_adjust_size(String* string, size_t size) | |||
|---|---|---|---|
| 121 | 121 | if(!string->chars) | |
| 122 | 122 | { | |
| 123 | 123 | string->chars = tmp; | |
| 124 | - | return b_false; | |
| 124 | + | return false; | |
| 125 | 125 | } | |
| 126 | 126 | string->capacity *= 2; | |
| 127 | 127 | } | |
| 128 | - | return b_true; | |
| 128 | + | return true; | |
| 129 | 129 | } | |
| 130 | 130 | ||
| 131 | 131 | ||
Msrc/linked-list.c
| @@ -1,7 +1,7 @@ | |||
|---|---|---|---|
| 1 | 1 | #include <cutils/linked-list.h> | |
| 2 | 2 | #include <cutils/misc.h> | |
| 3 | 3 | ||
| 4 | - | LinkedList* new_ll(bool_t doubly_linked, bool_t circularly_linked) | |
| 4 | + | LinkedList* new_ll(bool doubly_linked, bool circularly_linked) | |
| 5 | 5 | { | |
| 6 | 6 | LinkedList* ret = malloc(sizeof(*ret)); | |
| 7 | 7 | ret->head = NULL; | |
| @@ -12,7 +12,7 @@ LinkedList* new_ll(bool_t doubly_linked, bool_t circularly_linked) | |||
|---|---|---|---|
| 12 | 12 | return ret; | |
| 13 | 13 | } | |
| 14 | 14 | ||
| 15 | - | void delete_sll(LinkedList* ll, void(*rmv) (void*)) | |
| 15 | + | void delete_ll(LinkedList* ll, void(*rmv) (void*)) | |
| 16 | 16 | { | |
| 17 | 17 | size_t i; | |
| 18 | 18 | SLnode *current, *tmp; | |
| @@ -27,30 +27,11 @@ void delete_sll(LinkedList* ll, void(*rmv) (void*)) | |||
|---|---|---|---|
| 27 | 27 | tmp = current; | |
| 28 | 28 | current = current->next; | |
| 29 | 29 | free(tmp); | |
| 30 | - | ||
| 31 | - | } | |
| 32 | - | } | |
| 33 | - | ||
| 34 | - | void delete_dll(LinkedList* ll, void(*rmv) (void*)) | |
| 35 | - | { | |
| 36 | - | size_t i; | |
| 37 | - | DLnode *current, *tmp; | |
| 38 | - | ||
| 39 | - | current = ll->head; | |
| 40 | - | ||
| 41 | - | for(i = 0; i < ll->length; i++) | |
| 42 | - | { | |
| 43 | - | ||
| 44 | - | if(rmv) | |
| 45 | - | rmv(current->item); | |
| 46 | - | tmp = current; | |
| 47 | - | current = current->next; | |
| 48 | - | free(tmp); | |
| 49 | - | ||
| 50 | 30 | } | |
| 31 | + | free(ll); | |
| 51 | 32 | } | |
| 52 | 33 | ||
| 53 | - | void* sll_at(const LinkedList* ll, size_t index) | |
| 34 | + | void* llnode_at(const LinkedList* ll, size_t index) | |
| 54 | 35 | { | |
| 55 | 36 | size_t i; | |
| 56 | 37 | SLnode* current; | |
| @@ -62,67 +43,31 @@ void* sll_at(const LinkedList* ll, size_t index) | |||
|---|---|---|---|
| 62 | 43 | current = current->next; | |
| 63 | 44 | } | |
| 64 | 45 | ||
| 65 | - | return current->item; | |
| 46 | + | return current; | |
| 66 | 47 | } | |
| 67 | 48 | ||
| 68 | - | void* dll_at(const LinkedList* ll, size_t index) | |
| 69 | - | { | |
| 70 | - | size_t i; | |
| 71 | - | DLnode* current; | |
| 72 | - | ||
| 73 | - | current = ll->head; | |
| 74 | 49 | ||
| 75 | - | for(i = 0; i < index; i++) | |
| 76 | - | { | |
| 77 | - | current = current->next; | |
| 78 | - | } | |
| 79 | - | ||
| 80 | - | return current->item; | |
| 81 | - | } | |
| 82 | - | ||
| 83 | - | void* sll_pop_at(LinkedList* ll, size_t index) | |
| 50 | + | void* ll_pop_at(LinkedList* ll, size_t index) | |
| 84 | 51 | { | |
| 85 | - | size_t i; | |
| 86 | - | SLnode* current; | |
| 52 | + | SLnode* node; | |
| 87 | 53 | void* tmp; | |
| 88 | 54 | ||
| 89 | - | current = ll->head; | |
| 90 | - | ||
| 91 | - | for(i = 0; i < index; i++) | |
| 92 | - | { | |
| 93 | - | current = current->next; | |
| 94 | - | } | |
| 55 | + | node = llnode_at(ll ,index); | |
| 95 | 56 | ||
| 96 | - | tmp = current->item; | |
| 57 | + | tmp = node->item; | |
| 97 | 58 | ll_remove(ll, index, NULL); | |
| 98 | 59 | return tmp; | |
| 99 | 60 | } | |
| 100 | 61 | ||
| 101 | - | void* dll_pop_at(LinkedList* ll, size_t index) | |
| 102 | - | { | |
| 103 | - | size_t i; | |
| 104 | - | DLnode* current; | |
| 105 | - | void* tmp; | |
| 106 | - | ||
| 107 | - | current = ll->head; | |
| 108 | - | ||
| 109 | - | for(i = 0; i < index; i++) | |
| 110 | - | { | |
| 111 | - | current = current->next; | |
| 112 | - | } | |
| 113 | 62 | ||
| 114 | - | tmp = current->item; | |
| 115 | - | ll_remove(ll, index, NULL); | |
| 116 | - | return tmp; | |
| 117 | - | } | |
| 118 | 63 | ||
| 119 | - | bool_t sll_insert(LinkedList* ll, size_t index, void* item) | |
| 64 | + | bool sll_insert(LinkedList* ll, size_t index, void* item) | |
| 120 | 65 | { | |
| 121 | 66 | size_t i; | |
| 122 | 67 | SLnode *current, *prev, *newnode = malloc(sizeof(*newnode)); | |
| 123 | 68 | ||
| 124 | 69 | if(!newnode) | |
| 125 | - | return b_false; | |
| 70 | + | return false; | |
| 126 | 71 | ||
| 127 | 72 | newnode->item =item; | |
| 128 | 73 | prev = NULL; | |
| @@ -137,60 +82,75 @@ bool_t sll_insert(LinkedList* ll, size_t index, void* item) | |||
|---|---|---|---|
| 137 | 82 | if(current) | |
| 138 | 83 | { | |
| 139 | 84 | newnode->next = current; | |
| 140 | - | if(prev) | |
| 141 | - | prev->next = newnode; | |
| 142 | - | else | |
| 85 | + | if(index == 0) | |
| 143 | 86 | ll->head = newnode; | |
| 87 | + | else | |
| 88 | + | prev->next = newnode; | |
| 144 | 89 | } else { | |
| 145 | 90 | ll->tail = newnode; | |
| 91 | + | newnode->next = NULL; | |
| 146 | 92 | if(index == 0) | |
| 147 | 93 | ll->head = newnode; | |
| 148 | - | newnode->next = NULL; | |
| 94 | + | if(prev) | |
| 95 | + | prev->next = newnode; | |
| 149 | 96 | } | |
| 150 | 97 | ||
| 151 | 98 | ll->length++; | |
| 152 | - | return b_true; | |
| 99 | + | return true; | |
| 153 | 100 | } | |
| 154 | 101 | ||
| 155 | - | bool_t dll_insert(LinkedList* ll, size_t index, void* item) | |
| 102 | + | bool dll_insert(LinkedList* ll, size_t index, void* item) | |
| 156 | 103 | { | |
| 157 | 104 | size_t i; | |
| 158 | - | DLnode *current, *newnode = malloc(sizeof(*newnode)); | |
| 105 | + | DLnode *current, *prev, *newnode = malloc(sizeof(*newnode)); | |
| 159 | 106 | ||
| 160 | 107 | if(!newnode) | |
| 161 | - | return b_false; | |
| 108 | + | return false; | |
| 162 | 109 | ||
| 163 | - | newnode->item =item; | |
| 110 | + | newnode->sl.item = item; | |
| 111 | + | prev = NULL; | |
| 164 | 112 | current = ll->head; | |
| 165 | 113 | ||
| 166 | 114 | for(i = 0; i < index; i++) | |
| 167 | 115 | { | |
| 168 | - | current = current->next; | |
| 116 | + | prev = current; | |
| 117 | + | current = current->sl.next; | |
| 169 | 118 | } | |
| 170 | 119 | ||
| 171 | 120 | if(current) | |
| 172 | 121 | { | |
| 173 | - | newnode->next = current; | |
| 174 | - | if(current->prev) | |
| 122 | + | newnode->sl.next = current; | |
| 123 | + | if(index == 0) | |
| 175 | 124 | { | |
| 176 | - | current->prev->next = newnode; | |
| 177 | - | newnode->prev =current; | |
| 178 | - | } else { | |
| 179 | 125 | ll->head = newnode; | |
| 180 | 126 | newnode->prev = NULL; | |
| 127 | + | } else { | |
| 128 | + | prev->sl.next = newnode; | |
| 129 | + | newnode->prev = prev; | |
| 181 | 130 | } | |
| 131 | + | current->prev = newnode; | |
| 182 | 132 | } else { | |
| 183 | 133 | ll->tail = newnode; | |
| 134 | + | newnode->sl.next = NULL; | |
| 184 | 135 | if(index == 0) | |
| 136 | + | { | |
| 185 | 137 | ll->head = newnode; | |
| 186 | - | newnode->next = NULL; | |
| 187 | - | newnode->prev = NULL; | |
| 138 | + | newnode->prev = NULL; | |
| 139 | + | } | |
| 140 | + | if(prev) | |
| 141 | + | { | |
| 142 | + | prev->sl.next = newnode; | |
| 143 | + | newnode->prev = prev; | |
| 144 | + | } | |
| 145 | + | ||
| 188 | 146 | } | |
| 189 | 147 | ||
| 190 | 148 | ll->length++; | |
| 191 | - | return b_true; | |
| 149 | + | return true; | |
| 192 | 150 | } | |
| 193 | 151 | ||
| 152 | + | ||
| 153 | + | ||
| 194 | 154 | void sll_remove(LinkedList* ll, size_t index, void (*rmv)(void*)) | |
| 195 | 155 | { | |
| 196 | 156 | size_t i; | |
| @@ -208,30 +168,50 @@ void sll_remove(LinkedList* ll, size_t index, void (*rmv)(void*)) | |||
|---|---|---|---|
| 208 | 168 | if(rmv) | |
| 209 | 169 | rmv(current->item); | |
| 210 | 170 | ||
| 211 | - | prev->next = current->next; | |
| 171 | + | if(!current->next) | |
| 172 | + | ll->tail = prev; | |
| 173 | + | ||
| 174 | + | if(prev) | |
| 175 | + | prev->next = current->next; | |
| 176 | + | else | |
| 177 | + | ll->head = current->next; | |
| 178 | + | ||
| 212 | 179 | free(current); | |
| 180 | + | ll->length--; | |
| 213 | 181 | } | |
| 214 | 182 | ||
| 215 | 183 | void dll_remove(LinkedList* ll, size_t index, void (*rmv)(void*)) | |
| 216 | 184 | { | |
| 217 | 185 | size_t i; | |
| 218 | - | DLnode* current; | |
| 186 | + | DLnode *current, *prev; | |
| 219 | 187 | ||
| 188 | + | prev = NULL; | |
| 220 | 189 | current = ll->head; | |
| 221 | 190 | ||
| 222 | 191 | for(i = 0; i < index; i++) | |
| 223 | 192 | { | |
| 224 | - | current = current->next; | |
| 193 | + | prev = current; | |
| 194 | + | current = current->sl.next; | |
| 225 | 195 | } | |
| 226 | 196 | ||
| 227 | 197 | if(rmv) | |
| 228 | - | rmv(current->item); | |
| 198 | + | rmv(current->sl.item); | |
| 199 | + | ||
| 200 | + | if(current->sl.next) | |
| 201 | + | ((DLnode*)(current->sl.next))->prev = prev; | |
| 202 | + | else | |
| 203 | + | ll->tail = prev; | |
| 204 | + | ||
| 205 | + | if(prev) | |
| 206 | + | prev->sl.next = current->sl.next; | |
| 207 | + | else | |
| 208 | + | ll->head = current->sl.next; | |
| 229 | 209 | ||
| 230 | - | current->prev->next = current->next; | |
| 231 | - | current->next->prev = current->prev; | |
| 232 | 210 | free(current); | |
| 211 | + | ll->length--; | |
| 233 | 212 | } | |
| 234 | 213 | ||
| 214 | + | ||
| 235 | 215 | void sll_remove_range(LinkedList* ll, size_t index, size_t length, void (*rmv)(void*)) | |
| 236 | 216 | { | |
| 237 | 217 | size_t i; | |
| @@ -250,18 +230,25 @@ void sll_remove_range(LinkedList* ll, size_t index, size_t length, void (*rmv)(v | |||
|---|---|---|---|
| 250 | 230 | { | |
| 251 | 231 | if(rmv) | |
| 252 | 232 | rmv(current->item); | |
| 253 | - | tmp = current; | |
| 233 | + | tmp = current->next; | |
| 254 | 234 | free(current); | |
| 255 | - | current = tmp->next; | |
| 235 | + | current = tmp; | |
| 256 | 236 | } | |
| 257 | 237 | ||
| 258 | - | prev->next = current; | |
| 238 | + | if(!current) | |
| 239 | + | ll->tail = prev; | |
| 240 | + | ||
| 241 | + | if(prev) | |
| 242 | + | prev->next = current; | |
| 243 | + | else | |
| 244 | + | ll->head = current; | |
| 245 | + | ll->length -= length; | |
| 259 | 246 | } | |
| 260 | 247 | ||
| 261 | 248 | void dll_remove_range(LinkedList* ll, size_t index, size_t length, void (*rmv)(void*)) | |
| 262 | 249 | { | |
| 263 | 250 | size_t i; | |
| 264 | - | DLnode *current, *prev; | |
| 251 | + | DLnode *current, *tmp, *prev; | |
| 265 | 252 | ||
| 266 | 253 | prev = NULL; | |
| 267 | 254 | current = ll->head; | |
| @@ -269,45 +256,36 @@ void dll_remove_range(LinkedList* ll, size_t index, size_t length, void (*rmv)(v | |||
|---|---|---|---|
| 269 | 256 | for(i = 0; i < index; i++) | |
| 270 | 257 | { | |
| 271 | 258 | prev = current; | |
| 272 | - | current = current->next; | |
| 259 | + | current = current->sl.next; | |
| 273 | 260 | } | |
| 274 | 261 | ||
| 275 | 262 | for(i = 0; i < length; i++) | |
| 276 | 263 | { | |
| 277 | 264 | if(rmv) | |
| 278 | - | rmv(current->item); | |
| 279 | - | current = current->next; | |
| 280 | - | free(current->prev); | |
| 265 | + | rmv(current->sl.item); | |
| 266 | + | tmp = current->sl.next; | |
| 267 | + | free(current); | |
| 268 | + | current = tmp; | |
| 281 | 269 | } | |
| 270 | + | if(current) | |
| 271 | + | current->prev = prev; | |
| 272 | + | else | |
| 273 | + | ll->tail = prev; | |
| 282 | 274 | ||
| 283 | - | prev->next = current; | |
| 284 | - | current->prev = prev; | |
| 285 | - | } | |
| 286 | - | ||
| 287 | - | size_t* sll_find(const LinkedList* haystack, const void* needle, int (*cmp)(const void*, const void*)) | |
| 288 | - | { | |
| 289 | - | size_t i, *ret; | |
| 290 | - | SLnode* current; | |
| 291 | - | ||
| 292 | - | current = haystack->head; | |
| 293 | - | ||
| 294 | - | for(i = 0; i < haystack->length; i++) | |
| 275 | + | if(prev) | |
| 295 | 276 | { | |
| 296 | - | if(cmp(current->item, needle) == 0) | |
| 297 | - | { | |
| 298 | - | ret = malloc(sizeof(*ret)); | |
| 299 | - | *ret = i; | |
| 300 | - | return ret; | |
| 301 | - | } | |
| 302 | - | current = current->next; | |
| 277 | + | prev->sl.next = current; | |
| 278 | + | } else { | |
| 279 | + | ll->head = current; | |
| 303 | 280 | } | |
| 304 | - | return NULL; | |
| 281 | + | ll->length -= length; | |
| 305 | 282 | } | |
| 306 | 283 | ||
| 307 | - | size_t* dll_find(const LinkedList* haystack, const void* needle, int (*cmp)(const void*, const void*)) | |
| 284 | + | ||
| 285 | + | size_t* ll_find(const LinkedList* haystack, const void* needle, int (*cmp)(const void*, const void*)) | |
| 308 | 286 | { | |
| 309 | 287 | size_t i, *ret; | |
| 310 | - | DLnode* current; | |
| 288 | + | SLnode* current; | |
| 311 | 289 | ||
| 312 | 290 | current = haystack->head; | |
| 313 | 291 | ||
| @@ -328,6 +306,7 @@ void sll_swap(LinkedList* ll, size_t item1, size_t item2) | |||
|---|---|---|---|
| 328 | 306 | { | |
| 329 | 307 | size_t i, first_index, second_index; | |
| 330 | 308 | SLnode *first, *second; | |
| 309 | + | void* tmp; | |
| 331 | 310 | ||
| 332 | 311 | first_index = item1 <= item2 ? item1 : item2; | |
| 333 | 312 | second_index = item1 <= item2 ? item2 : item1; | |
| @@ -338,14 +317,18 @@ void sll_swap(LinkedList* ll, size_t item1, size_t item2) | |||
|---|---|---|---|
| 338 | 317 | for(i = 0; i < second_index; i++) | |
| 339 | 318 | { | |
| 340 | 319 | if(i == first_index) | |
| 341 | - | first = second->next; | |
| 320 | + | first = second; | |
| 342 | 321 | second = second->next; | |
| 343 | 322 | } | |
| 344 | 323 | ||
| 345 | 324 | if(!first) | |
| 346 | 325 | first = second; | |
| 347 | 326 | ||
| 348 | - | memswap(&first->item, &second->item, sizeof(first->item)); | |
| 327 | + | tmp = first->item; | |
| 328 | + | first->item = second->item; | |
| 329 | + | second->item = tmp; | |
| 330 | + | ||
| 331 | + | /*memswap(&first->item, &second->item, sizeof(first->item));*/ | |
| 349 | 332 | } | |
| 350 | 333 | ||
| 351 | 334 | void dll_swap(LinkedList* ll, size_t item1, size_t item2) | |
| @@ -362,12 +345,12 @@ void dll_swap(LinkedList* ll, size_t item1, size_t item2) | |||
|---|---|---|---|
| 362 | 345 | for(i = 0; i < second_index; i++) | |
| 363 | 346 | { | |
| 364 | 347 | if(i == first_index) | |
| 365 | - | first = second->next; | |
| 366 | - | second = second->next; | |
| 348 | + | first = second; | |
| 349 | + | second = second->sl.next; | |
| 367 | 350 | } | |
| 368 | 351 | ||
| 369 | 352 | if(!first) | |
| 370 | 353 | first = second; | |
| 371 | 354 | ||
| 372 | - | memswap(&first->item, &second->item, sizeof(first->item)); | |
| 355 | + | memswap(&first->sl.item, &second->sl.item, sizeof(first->sl.item)); | |
| 373 | 356 | } | |
Msrc/test.c
| @@ -15,7 +15,7 @@ static int cmp_str(const void* str1, const void* str2) | |||
|---|---|---|---|
| 15 | 15 | return !((str1_s->a == str2_s->a) && (str1_s->b == str2_s->b)); | |
| 16 | 16 | } | |
| 17 | 17 | ||
| 18 | - | static void test1(void) | |
| 18 | + | static void test_vector(void) | |
| 19 | 19 | { | |
| 20 | 20 | size_t* find; | |
| 21 | 21 | Vector* vector; | |
| @@ -65,7 +65,7 @@ static void test1(void) | |||
|---|---|---|---|
| 65 | 65 | delete_vector(vector, free); | |
| 66 | 66 | } | |
| 67 | 67 | ||
| 68 | - | static void test2(void) | |
| 68 | + | static void test_string(void) | |
| 69 | 69 | { | |
| 70 | 70 | String* string; | |
| 71 | 71 | String* string2; | |
| @@ -115,7 +115,7 @@ static void test2(void) | |||
|---|---|---|---|
| 115 | 115 | delete_string(string); | |
| 116 | 116 | } | |
| 117 | 117 | ||
| 118 | - | static void test3(void) | |
| 118 | + | static void test_bytearray(void) | |
| 119 | 119 | { | |
| 120 | 120 | Bytearray* bt; | |
| 121 | 121 | char* tmpchar; | |
| @@ -160,7 +160,7 @@ static void test3(void) | |||
|---|---|---|---|
| 160 | 160 | delete_bytearray(bt, NULL); | |
| 161 | 161 | } | |
| 162 | 162 | #if __STDC_VERSION__ >= 201112L | |
| 163 | - | static void test4(void) | |
| 163 | + | static void test_timespec(void) | |
| 164 | 164 | { | |
| 165 | 165 | struct timespec ts1 = {10, 10}; | |
| 166 | 166 | struct timespec ts2 = {10, 10}; | |
| @@ -210,15 +210,60 @@ static void test4(void) | |||
|---|---|---|---|
| 210 | 210 | assert(res.tv_sec == 10 && res.tv_nsec == 999999998); | |
| 211 | 211 | } | |
| 212 | 212 | #endif | |
| 213 | + | static void test_ll(void) | |
| 214 | + | { | |
| 215 | + | LinkedList* ll; | |
| 216 | + | struct test my_structa, my_structb, *my_structptr; | |
| 217 | + | int truth; | |
| 218 | + | my_structa.a = 5; | |
| 219 | + | my_structa.b = 5; | |
| 220 | + | my_structb.a = 7; | |
| 221 | + | my_structb.b = 7; | |
| 222 | + | ||
| 223 | + | for(truth = 0; truth<2; truth++) | |
| 224 | + | { | |
| 225 | + | ll = new_ll(truth,truth); | |
| 226 | + | ||
| 227 | + | ll_push(ll, &my_structa); | |
| 228 | + | my_structptr = ll_pop(ll); | |
| 229 | + | assert(my_structptr->a == 5 && my_structptr->b == 5); | |
| 230 | + | ||
| 231 | + | ll_push(ll, &my_structa); | |
| 232 | + | ll_push(ll, &my_structa); | |
| 233 | + | ll_push(ll, &my_structa); | |
| 234 | + | ll_push(ll, &my_structb); | |
| 235 | + | ||
| 236 | + | my_structptr = ll_at(ll, ll->length-1); | |
| 237 | + | assert(my_structptr->a == 7); | |
| 238 | + | ||
| 239 | + | ll_swap(ll, 0, ll->length-1); | |
| 240 | + | ||
| 241 | + | my_structptr = ll_at(ll, ll->length-1); | |
| 242 | + | assert(my_structptr->a == 5); | |
| 243 | + | ||
| 244 | + | ||
| 245 | + | ll_remove_range(ll, 0, ll->length-1, NULL); | |
| 246 | + | ||
| 247 | + | delete_ll(ll, NULL); | |
| 248 | + | } | |
| 249 | + | ||
| 250 | + | } | |
| 213 | 251 | ||
| 214 | 252 | int main(int argc, char** argv) | |
| 215 | 253 | { | |
| 216 | - | test1(); | |
| 217 | - | test2(); | |
| 218 | - | test3(); | |
| 254 | + | int a = 5; | |
| 255 | + | int b = 2; | |
| 256 | + | memswap(&a, &b, sizeof(int)); | |
| 257 | + | assert(a == 2 && b == 5); | |
| 258 | + | ||
| 259 | + | test_vector(); | |
| 260 | + | test_string(); | |
| 261 | + | test_bytearray(); | |
| 219 | 262 | #if __STDC_VERSION__ >= 201112L | |
| 220 | - | test4(); | |
| 263 | + | test_timespec(); | |
| 221 | 264 | #endif | |
| 265 | + | test_ll(); | |
| 266 | + | ||
| 222 | 267 | sleep_ms(1000); | |
| 223 | 268 | return 0; | |
| 224 | 269 | } | |
Msrc/vector.c
| @@ -48,7 +48,7 @@ void vector_remove(Vector* vector, size_t index, void (*rmv)(void*)) | |||
|---|---|---|---|
| 48 | 48 | vector->length--; | |
| 49 | 49 | } | |
| 50 | 50 | } | |
| 51 | - | ||
| 51 | + | /* TODO: optimize */ | |
| 52 | 52 | void vector_remove_range(Vector* vector, size_t index, size_t length, void (*rmv)(void*)) | |
| 53 | 53 | { | |
| 54 | 54 | size_t i; | |
| @@ -74,18 +74,18 @@ size_t* vector_find(const Vector* haystack, const void* needle, int (*cmp)(const | |||
|---|---|---|---|
| 74 | 74 | return NULL; | |
| 75 | 75 | } | |
| 76 | 76 | ||
| 77 | - | bool_t vector_insert(Vector* vector, size_t index, void* item) | |
| 77 | + | bool vector_insert(Vector* vector, size_t index, void* item) | |
| 78 | 78 | { | |
| 79 | 79 | if(index > vector->length || !vector_adjust_size(vector, vector->length+1)) | |
| 80 | - | return b_false; | |
| 80 | + | return false; | |
| 81 | 81 | ||
| 82 | 82 | memmove(vector->items+index+1, vector->items+index, (vector->length-index)*sizeof(*vector->items)); | |
| 83 | 83 | vector->items[index] = item; | |
| 84 | 84 | vector->length++; | |
| 85 | - | return b_true; | |
| 85 | + | return true; | |
| 86 | 86 | } | |
| 87 | 87 | ||
| 88 | - | bool_t vector_adjust_size(Vector* vector, size_t size) | |
| 88 | + | bool vector_adjust_size(Vector* vector, size_t size) | |
| 89 | 89 | { | |
| 90 | 90 | while(vector->capacity < size) | |
| 91 | 91 | { | |
| @@ -94,14 +94,14 @@ bool_t vector_adjust_size(Vector* vector, size_t size) | |||
|---|---|---|---|
| 94 | 94 | if(!vector->items) | |
| 95 | 95 | { | |
| 96 | 96 | vector->items = tmp; | |
| 97 | - | return b_false; | |
| 97 | + | return false; | |
| 98 | 98 | } | |
| 99 | 99 | vector->capacity *= 2; | |
| 100 | 100 | } | |
| 101 | - | return b_true; | |
| 101 | + | return true; | |
| 102 | 102 | } | |
| 103 | 103 | ||
| 104 | - | bool_t vector_shrink(Vector* vector) | |
| 104 | + | bool vector_shrink(Vector* vector) | |
| 105 | 105 | { | |
| 106 | 106 | while(vector->capacity > (vector->length*2)) | |
| 107 | 107 | { | |
| @@ -110,11 +110,11 @@ bool_t vector_shrink(Vector* vector) | |||
|---|---|---|---|
| 110 | 110 | if(!vector->items) | |
| 111 | 111 | { | |
| 112 | 112 | vector->items = tmp; | |
| 113 | - | return b_false; | |
| 113 | + | return false; | |
| 114 | 114 | } | |
| 115 | 115 | vector->capacity /= 2; | |
| 116 | 116 | } | |
| 117 | - | return b_true; | |
| 117 | + | return true; | |
| 118 | 118 | } | |
| 119 | 119 | ||
| 120 | 120 | void delete_vector(Vector* vector, void (*rmv)(void*)) | |