Merge branch 'descrete-tests' of lirent/libcdsb into develop
This commit is contained in:
		
						commit
						283cc9ba4a
					
				
							
								
								
									
										40
									
								
								examples/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								examples/Makefile
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,40 @@ | |||||||
|  | # This software is licensed by the MIT License, see LICENSE file
 | ||||||
|  | #                                Copyright © 2022 Gregory Lirent
 | ||||||
|  | 
 | ||||||
|  | ########################################################################################################################
 | ||||||
|  | 
 | ||||||
|  | BUILD_PATH  ?= ./bin | ||||||
|  | 
 | ||||||
|  | ########################################################################################################################
 | ||||||
|  | 
 | ||||||
|  | CC    = clang | ||||||
|  | MKDIR = mkdir -p | ||||||
|  | RMRF  = rm -rf | ||||||
|  | AR    = ar crs | ||||||
|  | CP    = cp | ||||||
|  | 
 | ||||||
|  | ########################################################################################################################
 | ||||||
|  | 
 | ||||||
|  | examples: modules | ||||||
|  | examples: $(addprefix $(BUILD_PATH)/,$(notdir $(basename $(wildcard ./*.c)))) | ||||||
|  | 
 | ||||||
|  | $(BUILD_PATH)/%: ./%.c | $(BUILD_PATH)/ | ||||||
|  | 	$(CC) $^ ../bin/release/libcdsb.a ../modules/libunic/bin/libunic.a -o $@ $(CFLAGS) -O2 -Wall | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | $(BUILD_PATH)/: | ||||||
|  | 	$(MKDIR) $@ | ||||||
|  | $(BUILD_PATH)/obj/:   | $(BUILD_PATH)/ | ||||||
|  | 	$(MKDIR) $@ | ||||||
|  | 
 | ||||||
|  | clean: | ||||||
|  | 	$(RMRF) ./bin/ | ||||||
|  | 	cd ../ && $(MAKE) clean | ||||||
|  | 
 | ||||||
|  | ########################################################################################################################
 | ||||||
|  | 
 | ||||||
|  | FORCE: | ||||||
|  | modules: ../bin/release/libcdsb.a | ||||||
|  | 
 | ||||||
|  | ../bin/release/libcdsb.a: FORCE | ||||||
|  | 	cd ../ && $(MAKE) release | ||||||
							
								
								
									
										37
									
								
								examples/array.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								examples/array.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,37 @@ | |||||||
|  | /* This software is licensed by the MIT License, see LICENSE file */ | ||||||
|  | /*                                Copyright © 2022 Gregory Lirent */ | ||||||
|  | 
 | ||||||
|  | #include <assert.h> | ||||||
|  | #include <stdio.h> | ||||||
|  | #include "../include/extra/array.h" | ||||||
|  | 
 | ||||||
|  | typedef vtype_array arr_t; | ||||||
|  | 
 | ||||||
|  | int print_value(void* value, ssize_t index, vtype type, void* data) { | ||||||
|  |     const char  *n = data; | ||||||
|  |     vtype_int32 *v = value; | ||||||
|  | 
 | ||||||
|  |     assert(type == VTYPE_INT32); | ||||||
|  | 
 | ||||||
|  |     printf("%s %d (index: %ld)\n", n, *v, index); | ||||||
|  | 
 | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | int main(int argc, char** argv) { | ||||||
|  | 
 | ||||||
|  |     arr_t arr; | ||||||
|  | 
 | ||||||
|  |     array_init(&arr, VTYPE_INT32); | ||||||
|  | 
 | ||||||
|  |     for (size_t i = 0; i < 28; ++i) { | ||||||
|  |         array_push_back(&arr, i); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     array_get_by_index(&arr, 13, "Get value:", print_value); | ||||||
|  |     array_pop_by_index(&arr, 18, "Pop value:", print_value); | ||||||
|  | 
 | ||||||
|  |     array_foreach(&arr, "Foreach loop:", print_value); | ||||||
|  | 
 | ||||||
|  |     array_free(&arr); | ||||||
|  | } | ||||||
							
								
								
									
										61
									
								
								examples/dict.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								examples/dict.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,61 @@ | |||||||
|  | /* This software is licensed by the MIT License, see LICENSE file */ | ||||||
|  | /*                                Copyright © 2022 Gregory Lirent */ | ||||||
|  | 
 | ||||||
|  | #include <assert.h> | ||||||
|  | #include <stdlib.h> | ||||||
|  | #include <stdio.h> | ||||||
|  | #include "../include/extra/dict.h" | ||||||
|  | 
 | ||||||
|  | typedef vtype_dict dict_t; | ||||||
|  | 
 | ||||||
|  | int print_value(const void* key, vtype key_type, void* value, vtype value_type, void* data) { | ||||||
|  |     const char *n = data; | ||||||
|  | 
 | ||||||
|  |     switch (key_type) { | ||||||
|  |         default: abort(); | ||||||
|  | 
 | ||||||
|  |         case VTYPE_INT32: | ||||||
|  |             printf("%s %d: ", n, *(vtype_int32*)key); | ||||||
|  |             break; | ||||||
|  |         case VTYPE_FLOAT: | ||||||
|  |             printf("%s %f: ", n, *(vtype_float*)key); | ||||||
|  |             break; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     switch (value_type) { | ||||||
|  |         default: abort(); | ||||||
|  | 
 | ||||||
|  |         case VTYPE_INT32: | ||||||
|  |             printf("%d\n", *(vtype_int32*)value); | ||||||
|  |             break; | ||||||
|  |         case VTYPE_FLOAT: | ||||||
|  |             printf("%f\n", *(vtype_float*)value); | ||||||
|  |             break; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | int main(int argc, char** argv) { | ||||||
|  | 
 | ||||||
|  |     dict_t dict; | ||||||
|  |     vtype_float fl = 0.0; | ||||||
|  | 
 | ||||||
|  |     dict_init(&dict); | ||||||
|  | 
 | ||||||
|  |     for (size_t i = 0; i < 28; ++i) { | ||||||
|  |         if (i%2) { | ||||||
|  |             dict_update(&dict, (vtype_float)fl, (vtype_int32)i); | ||||||
|  |         } else { | ||||||
|  |             dict_update(&dict, (vtype_int32)i, (vtype_float)fl); | ||||||
|  |         } | ||||||
|  |         fl += 0.05; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     dict_get(&dict, 14,   "Get value:", print_value); | ||||||
|  |     dict_pop(&dict, 0.25, "Pop value:", print_value); | ||||||
|  | 
 | ||||||
|  |     dict_foreach(&dict, "Foreach loop:", print_value); | ||||||
|  | 
 | ||||||
|  |     dict_free(&dict); | ||||||
|  | } | ||||||
							
								
								
									
										51
									
								
								examples/list.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								examples/list.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,51 @@ | |||||||
|  | /* This software is licensed by the MIT License, see LICENSE file */ | ||||||
|  | /*                                Copyright © 2022 Gregory Lirent */ | ||||||
|  | 
 | ||||||
|  | #include <stdio.h> | ||||||
|  | #include <stdlib.h> | ||||||
|  | #include "../include/extra/list.h" | ||||||
|  | 
 | ||||||
|  | typedef vtype_list list_t; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | int print_value(void* value, ssize_t index, vtype type, void* data) { | ||||||
|  |     const char *n = data; | ||||||
|  | 
 | ||||||
|  |     switch (type) { | ||||||
|  |         default: abort(); | ||||||
|  | 
 | ||||||
|  |         case VTYPE_INT32: | ||||||
|  |             printf("%s %d (index: %ld)\n", n, *(vtype_int32*)value, index); | ||||||
|  |             break; | ||||||
|  |         case VTYPE_FLOAT: | ||||||
|  |             printf("%s %f (index: %ld)\n", n, *(vtype_float*)value, index); | ||||||
|  |             break; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | int main(int argc, char** argv) { | ||||||
|  | 
 | ||||||
|  |     list_t list; | ||||||
|  |     vtype_float fl = 0.0; | ||||||
|  | 
 | ||||||
|  |     list_init(&list); | ||||||
|  | 
 | ||||||
|  |     for (size_t i = 0; i < 28; ++i) { | ||||||
|  |         if (i%2) { | ||||||
|  |             list_push_back(&list, (vtype_int32)i); | ||||||
|  |         } else { | ||||||
|  |             list_push_back(&list, (vtype_float)fl); | ||||||
|  |             fl += 0.05; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     list_get_by_index(&list, 13, "Get value:", print_value); | ||||||
|  |     list_pop_by_index(&list, 18, "Pop value:", print_value); | ||||||
|  | 
 | ||||||
|  |     list_foreach(&list, "Foreach loop:", print_value); | ||||||
|  | 
 | ||||||
|  |     list_free(&list); | ||||||
|  | } | ||||||
							
								
								
									
										55
									
								
								examples/map.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								examples/map.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,55 @@ | |||||||
|  | /* This software is licensed by the MIT License, see LICENSE file */ | ||||||
|  | /*                                Copyright © 2022 Gregory Lirent */ | ||||||
|  | 
 | ||||||
|  | #include <assert.h> | ||||||
|  | #include <stdlib.h> | ||||||
|  | #include <stdio.h> | ||||||
|  | #include "../include/extra/map.h" | ||||||
|  | 
 | ||||||
|  | typedef vtype_map map_t; | ||||||
|  | 
 | ||||||
|  | int print_value(const void* key, vtype key_type, void* value, vtype value_type, void* data) { | ||||||
|  |     const char  *n = data; | ||||||
|  |     vtype_int32 *k = (void*)key; | ||||||
|  | 
 | ||||||
|  |     assert(key_type == VTYPE_INT32); | ||||||
|  | 
 | ||||||
|  |     printf("%s %d: ", n, *k); | ||||||
|  | 
 | ||||||
|  |     switch (value_type) { | ||||||
|  |         default: abort(); | ||||||
|  | 
 | ||||||
|  |         case VTYPE_INT32: | ||||||
|  |             printf("%d\n", *(vtype_int32*)value); | ||||||
|  |             break; | ||||||
|  |         case VTYPE_FLOAT: | ||||||
|  |             printf("%f\n", *(vtype_float*)value); | ||||||
|  |             break; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | int main(int argc, char** argv) { | ||||||
|  | 
 | ||||||
|  |     map_t map; | ||||||
|  |     vtype_float fl = 0.0; | ||||||
|  | 
 | ||||||
|  |     map_init(&map, VTYPE_INT32); | ||||||
|  | 
 | ||||||
|  |     for (size_t i = 0; i < 28; ++i) { | ||||||
|  |         if (i%2) { | ||||||
|  |             map_update(&map, i, (vtype_int32)i); | ||||||
|  |         } else { | ||||||
|  |             map_update(&map, i, (vtype_float)fl); | ||||||
|  |             fl += 0.05; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     map_get(&map, 13, "Get value:", print_value); | ||||||
|  |     map_pop(&map, 18, "Pop value:", print_value); | ||||||
|  | 
 | ||||||
|  |     map_foreach(&map, "Foreach loop:", print_value); | ||||||
|  | 
 | ||||||
|  |     map_free(&map); | ||||||
|  | } | ||||||
							
								
								
									
										38
									
								
								examples/set.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								examples/set.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,38 @@ | |||||||
|  | /* This software is licensed by the MIT License, see LICENSE file */ | ||||||
|  | /*                                Copyright © 2022 Gregory Lirent */ | ||||||
|  | 
 | ||||||
|  | #include <assert.h> | ||||||
|  | #include <stdio.h> | ||||||
|  | #include "../include/extra/set.h" | ||||||
|  | 
 | ||||||
|  | typedef vtype_set vset_t; | ||||||
|  | 
 | ||||||
|  | int print_value(const void* value, vtype type, void* data) { | ||||||
|  |     const char  *n = data; | ||||||
|  |     vtype_int32 *v = (void*)value; | ||||||
|  | 
 | ||||||
|  |     assert(type == VTYPE_INT32); | ||||||
|  | 
 | ||||||
|  |     printf("%s %d\n", n, *v); | ||||||
|  | 
 | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | int main(int argc, char** argv) { | ||||||
|  | 
 | ||||||
|  |     vset_t set; | ||||||
|  | 
 | ||||||
|  |     vset_init(&set, VTYPE_INT32); | ||||||
|  | 
 | ||||||
|  |     for (size_t i = 0; i < 28; ++i) { | ||||||
|  |         vset_push(&set, i); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     vset_get(&set, 13, "Get value:", print_value); | ||||||
|  |     vset_pop(&set, 18, "Pop value:", print_value); | ||||||
|  | 
 | ||||||
|  |     vset_foreach(&set, "Foreach loop:", print_value); | ||||||
|  | 
 | ||||||
|  |     vset_free(&set); | ||||||
|  | } | ||||||
							
								
								
									
										42
									
								
								examples/string.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								examples/string.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,42 @@ | |||||||
|  | /* This software is licensed by the MIT License, see LICENSE file */ | ||||||
|  | /*                                Copyright © 2022 Gregory Lirent */ | ||||||
|  | 
 | ||||||
|  | #include <stdio.h> | ||||||
|  | #include "../include/extra/string.h" | ||||||
|  | #include "../include/extra/array.h" | ||||||
|  | 
 | ||||||
|  | typedef vtype_string str_t; | ||||||
|  | typedef vtype_array  arr_t; | ||||||
|  | 
 | ||||||
|  | int main(int argc, char** argv) { | ||||||
|  | 
 | ||||||
|  |     str_t str; | ||||||
|  | 
 | ||||||
|  |     string_init(&str, "sed ut perspiciatis"); | ||||||
|  | 
 | ||||||
|  |     string_concat(&str, ", Unde omnis iste natus error sit voluptatem accusantium doloremque laudantium"); | ||||||
|  |     string_concat(&str, ", Totam rem aperiam eaque ipsa"); | ||||||
|  |     string_concat(&str, ", Quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt"); | ||||||
|  |     string_concat(&str, ", Explicabo."); | ||||||
|  | 
 | ||||||
|  |     string_capitalize(&str); | ||||||
|  | 
 | ||||||
|  |     string_reverse(&str); | ||||||
|  | 
 | ||||||
|  |     printf("%s\n", str.buffer); | ||||||
|  | 
 | ||||||
|  |     arr_t parts = string_split(&str, ',', -1); | ||||||
|  | 
 | ||||||
|  |     printf("%lu\n", array_size(&parts)); | ||||||
|  | 
 | ||||||
|  |     for (size_t i = 0; i < array_size(&parts); ++i) { | ||||||
|  |         str_t* value = array_at(&parts, i); | ||||||
|  | 
 | ||||||
|  |         string_trim_spaces(value); | ||||||
|  | 
 | ||||||
|  |         printf("%s (%lu)\n", value->buffer, string_nmemb(value)); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     array_free(&parts); | ||||||
|  |     string_free(&str); | ||||||
|  | } | ||||||
| @ -21,7 +21,7 @@ extern void array_reverse(vtype_array* x) Nonnull__(1); | |||||||
| #define array_pop(x, value, data, callback)   _LIBCDSB_Generic(libcdsb_array, find, value)(x, value, data, callback, 0, 1) | #define array_pop(x, value, data, callback)   _LIBCDSB_Generic(libcdsb_array, find, value)(x, value, data, callback, 0, 1) | ||||||
| #define array_find(x, value, data, callback)  _LIBCDSB_Generic(libcdsb_array, find, value)(x, value, data, callback, 0, 0) | #define array_find(x, value, data, callback)  _LIBCDSB_Generic(libcdsb_array, find, value)(x, value, data, callback, 0, 0) | ||||||
| #define array_rfind(x, value, data, callback) _LIBCDSB_Generic(libcdsb_array, find, value)(x, value, data, callback, 1, 0) | #define array_rfind(x, value, data, callback) _LIBCDSB_Generic(libcdsb_array, find, value)(x, value, data, callback, 1, 0) | ||||||
| #define list_countof(x, value)                _LIBCDSB_Generic(libcdsb_array, count, value)(x, value) | #define array_countof(x, value)               _LIBCDSB_Generic(libcdsb_array, count, value)(x, value) | ||||||
| #define array_remove(x, value)                array_pop(x, value, 0, 0) | #define array_remove(x, value)                array_pop(x, value, 0, 0) | ||||||
| #define in_array(x, value)                    (array_find(x, value, 0, 0) == 0) | #define in_array(x, value)                    (array_find(x, value, 0, 0) == 0) | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -8,9 +8,8 @@ | |||||||
| 
 | 
 | ||||||
| #define vset_foreach(x, data, callback) libcdsb_vset_foreach(x, data, callback, 0) | #define vset_foreach(x, data, callback) libcdsb_vset_foreach(x, data, callback, 0) | ||||||
| 
 | 
 | ||||||
| extern bool libcdsb_vset_insert(vtype_set* x, const void* value, vtype type) LIBCDSB_nn12__; | extern bool libcdsb_vset_insert (vtype_set* x, const void* value, vtype type)                                             Nonnull__(1); | ||||||
| 
 |  | ||||||
| extern int  libcdsb_vset_find   (vtype_set* x, const void* value, vtype type, void* data, vset_access_callback, bool cut) Nonnull__(1); | extern int  libcdsb_vset_find   (vtype_set* x, const void* value, vtype type, void* data, vset_access_callback, bool cut) Nonnull__(1); | ||||||
| extern int libcdsb_vset_foreach(vtype_set* x, void* data, vset_access_callback, bool flush) LIBCDSB_nn13__; | extern int  libcdsb_vset_foreach(vtype_set* x, void* data, vset_access_callback, bool flush)                              Nonnull__(1,3); | ||||||
| 
 | 
 | ||||||
| #endif /* LIBCDSB_EXTRA_SET_H */ | #endif /* LIBCDSB_EXTRA_SET_H */ | ||||||
|  | |||||||
| @ -11,10 +11,11 @@ typedef int (*vset_access_callback)(const void* value, vtype type, void* data); | |||||||
| 
 | 
 | ||||||
| extern void vset_init(vtype_set* x, vtype type) Nonnull__(1); | extern void vset_init(vtype_set* x, vtype type) Nonnull__(1); | ||||||
| 
 | 
 | ||||||
| #define vset_remove(x, value) _LIBCDSB_Generic (libcdsb_vset, touch, value)(x, value, 1) | #define vset_pop(x, value, data, callback) _LIBCDSB_Generic (libcdsb_vset, find, value)(x, value, data, callback, 1) | ||||||
|  | #define vset_get(x, value, data, callback) _LIBCDSB_Generic (libcdsb_vset, find, value)(x, value, data, callback, 0) | ||||||
| #define vset_push(x, value)                _LIBCDSB_Generic (libcdsb_vset, push,  value)(x, value) | #define vset_push(x, value)                _LIBCDSB_Generic (libcdsb_vset, push,  value)(x, value) | ||||||
| 
 | 
 | ||||||
| #define in_vset(x, value)     _LIBCDSB_Generic (libcdsb_vset, touch, value)(x, value, 0) | #define in_vset(x, value)                  (vset_get(&x, value, 0, 0, 0) == 0) | ||||||
| 
 | 
 | ||||||
| extern bool libcdsb_vset_push_pointer(vtype_set* x,  const         void* value) Nonnull__(1); | extern bool libcdsb_vset_push_pointer(vtype_set* x,  const         void* value) Nonnull__(1); | ||||||
| extern bool libcdsb_vset_push_cstring(vtype_set* x,  const         char* value) Nonnull__(1,2); | extern bool libcdsb_vset_push_cstring(vtype_set* x,  const         char* value) Nonnull__(1,2); | ||||||
|  | |||||||
| @ -32,7 +32,7 @@ extern rbnode_t* libcdsb_rbtree_node_delete(rbnode_t** root, rbnode_t* node) | |||||||
| extern void* libcdsb_rbtree_duplicate(const rbnode_t* s, void* (*node_duplicate)(void* src, void* parent, void* info), void* info)                                        wur__   Nonnull__(1); | extern void* libcdsb_rbtree_duplicate(const rbnode_t* s, void* (*node_duplicate)(void* src, void* parent, void* info), void* info)                                        wur__   Nonnull__(1); | ||||||
| extern int   libcdsb_rbtree_compare  (const rbnode_t* s0, const rbnode_t* s1, int (*node_compare)(const rbnode_t* s0, const rbnode_t* s1, void* info), void* info) pure__ wur__ Nonnull__(1,2); | extern int   libcdsb_rbtree_compare  (const rbnode_t* s0, const rbnode_t* s1, int (*node_compare)(const rbnode_t* s0, const rbnode_t* s1, void* info), void* info) pure__ wur__ Nonnull__(1,2); | ||||||
| 
 | 
 | ||||||
| extern hash_t libcdsb_rbtree_hash(const void* s, hash_t (*node_hash)(const void* s, void* info), void* info) pure__ wur__ Nonnull__(1,2); | extern hash_t libcdsb_rbtree_hash(const void* s, hash_t (*node_hash)(const void* s, void* info), void* info) pure__ wur__ Nonnull__(1); | ||||||
| extern size_t libcdsb_rbtree_size(const void* s)                                                             pure__ wur__ Nonnull__(1); | extern size_t libcdsb_rbtree_size(const void* s)                                                             pure__ wur__ Nonnull__(1); | ||||||
| extern void   libcdsb_rbtree_free(void* x, void (*node_free)(void* x, void* info), void* info)                            Nonnull__(1); | extern void   libcdsb_rbtree_free(void* x, void (*node_free)(void* x, void* info), void* info)                            Nonnull__(1); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -11,7 +11,7 @@ | |||||||
| typedef union { | typedef union { | ||||||
|     void* ptr; bool    b; |     void* ptr; bool    b; | ||||||
|     str_t   s; arr_t   a; list_t  l; |     str_t   s; arr_t   a; list_t  l; | ||||||
|     map_t   m; set_t  vs; |     map_t   m; set_t  vs; dict_t vd; | ||||||
|     u8_t   u8; u16_t u16; u32_t u32; u64_t u64; |     u8_t   u8; u16_t u16; u32_t u32; u64_t u64; | ||||||
|     fl_t    f; dbl_t   d; ldbl_t ld; |     fl_t    f; dbl_t   d; ldbl_t ld; | ||||||
| } var_t; | } var_t; | ||||||
|  | |||||||
| @ -165,7 +165,7 @@ int libcdsb_dict_get(dict_t* x, const void* k, vtype t, void* _, dict_access_cal | |||||||
|             cmp = vtype_compare(k, t, key, c->key_type); |             cmp = vtype_compare(k, t, key, c->key_type); | ||||||
| 
 | 
 | ||||||
|             if (cmp == 0) { |             if (cmp == 0) { | ||||||
|                 cmp = (callback) ? callback(key, t, vnode_peek(&c->value, c->val_type), c->val_type, _) : 0; |                 cmp = (callback) ? callback(key, c->key_type, vnode_peek(&c->value, c->val_type), c->val_type, _) : 0; | ||||||
| 
 | 
 | ||||||
|                 if (cut) { |                 if (cut) { | ||||||
|                     c = dnode_delete(x->nodes + index, c); |                     c = dnode_delete(x->nodes + index, c); | ||||||
|  | |||||||
| @ -55,6 +55,9 @@ char* libcdsb_strdup(const char* s) { | |||||||
|     void*  x; |     void*  x; | ||||||
|     size_t n; |     size_t n; | ||||||
| 
 | 
 | ||||||
|  |     if (is_null(s)) | ||||||
|  |         return nullptr; | ||||||
|  | 
 | ||||||
|     if ((x = malloc(n = strlen(s) + 1))) |     if ((x = malloc(n = strlen(s) + 1))) | ||||||
|         return memcpy(x, s, n); |         return memcpy(x, s, n); | ||||||
|     abort(); |     abort(); | ||||||
|  | |||||||
							
								
								
									
										106
									
								
								tests/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										106
									
								
								tests/Makefile
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,106 @@ | |||||||
|  | # This software is licensed by the MIT License, see LICENSE file
 | ||||||
|  | #                                Copyright © 2022 Gregory Lirent
 | ||||||
|  | 
 | ||||||
|  | ########################################################################################################################
 | ||||||
|  | 
 | ||||||
|  | BUILD_PATH  ?= ./bin | ||||||
|  | 
 | ||||||
|  | ########################################################################################################################
 | ||||||
|  | 
 | ||||||
|  | CC    = clang | ||||||
|  | MKDIR = mkdir -p | ||||||
|  | RMRF  = rm -rf | ||||||
|  | AR    = ar crs | ||||||
|  | CP    = cp | ||||||
|  | 
 | ||||||
|  | $(BUILD_PATH)/obj/%.o: CFLAGS := $(CFLAGS) -Og -fPIC -c -g3 -Wall | ||||||
|  | 
 | ||||||
|  | ########################################################################################################################
 | ||||||
|  | 
 | ||||||
|  | c_objects = $(addsuffix .o,$(addprefix $(2),$(notdir $(basename $(wildcard $(1)*.c))))) | ||||||
|  | 
 | ||||||
|  | OBJECTS_TESTS  := $(addprefix $(BUILD_PATH)/obj/,$(call c_objects,./src/,)) | ||||||
|  | OBJECTS_BASE   := $(addprefix ../bin/debug/obj/,$(call c_objects,../src/,)) | ||||||
|  | OBJECTS_STRING := $(addprefix ../bin/debug/obj/,$(call c_objects,../src/string/,string-)) | ||||||
|  | OBJECTS_ARRAY  := $(addprefix ../bin/debug/obj/,$(call c_objects,../src/array/,array-)) | ||||||
|  | OBJECTS_LIST   := $(addprefix ../bin/debug/obj/,$(call c_objects,../src/list/,list-)) | ||||||
|  | OBJECTS_MAP    := $(addprefix ../bin/debug/obj/,$(call c_objects,../src/map/,map-)) | ||||||
|  | OBJECTS_SET    := $(addprefix ../bin/debug/obj/,$(call c_objects,../src/set/,set-)) | ||||||
|  | OBJECTS_DICT   := $(addprefix ../bin/debug/obj/,$(call c_objects,../src/dict/,dict-)) | ||||||
|  | 
 | ||||||
|  | OBJECTS_GLOBAL := $(OBJECTS_TESTS) $(addprefix $(BUILD_PATH)/obj/,$(call c_objects,./src/global/src/,global-)) | ||||||
|  | 
 | ||||||
|  | OBJECTS_STRING := $(OBJECTS_BASE) $(OBJECTS_TESTS) $(OBJECTS_STRING) $(addprefix $(BUILD_PATH)/obj/,$(call c_objects,./src/string/src/,string-)) | ||||||
|  | OBJECTS_ARRAY  := $(OBJECTS_BASE) $(OBJECTS_TESTS) $(OBJECTS_ARRAY)	 $(addprefix $(BUILD_PATH)/obj/,$(call c_objects,./src/array/src/,array-)) | ||||||
|  | OBJECTS_LIST   := $(OBJECTS_BASE) $(OBJECTS_TESTS) $(OBJECTS_LIST)	 $(addprefix $(BUILD_PATH)/obj/,$(call c_objects,./src/list/src/,list-)) | ||||||
|  | OBJECTS_MAP    := $(OBJECTS_BASE) $(OBJECTS_TESTS) $(OBJECTS_MAP)	 $(addprefix $(BUILD_PATH)/obj/,$(call c_objects,./src/map/src/,map-)) | ||||||
|  | OBJECTS_SET    := $(OBJECTS_BASE) $(OBJECTS_TESTS) $(OBJECTS_SET)	 $(addprefix $(BUILD_PATH)/obj/,$(call c_objects,./src/set/src/,set-)) | ||||||
|  | OBJECTS_DICT   := $(OBJECTS_BASE) $(OBJECTS_TESTS) $(OBJECTS_DICT)	 $(addprefix $(BUILD_PATH)/obj/,$(call c_objects,./src/dict/src/,dict-)) | ||||||
|  | 
 | ||||||
|  | ########################################################################################################################
 | ||||||
|  | 
 | ||||||
|  | tests: modules | ||||||
|  | tests: $(addprefix $(BUILD_PATH)/array-,$(notdir $(basename $(wildcard ./src/array/*.c)))) | ||||||
|  | tests: $(addprefix $(BUILD_PATH)/string-,$(notdir $(basename $(wildcard ./src/string/*.c)))) | ||||||
|  | tests: $(addprefix $(BUILD_PATH)/list-,$(notdir $(basename $(wildcard ./src/list/*.c)))) | ||||||
|  | tests: $(addprefix $(BUILD_PATH)/map-,$(notdir $(basename $(wildcard ./src/map/*.c)))) | ||||||
|  | tests: $(addprefix $(BUILD_PATH)/set-,$(notdir $(basename $(wildcard ./src/set/*.c)))) | ||||||
|  | tests: $(addprefix $(BUILD_PATH)/dict-,$(notdir $(basename $(wildcard ./src/dict/*.c)))) | ||||||
|  | tests: $(addprefix $(BUILD_PATH)/global-,$(notdir $(basename $(wildcard ./src/global/*.c)))) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | ########################################################################################################################
 | ||||||
|  | 
 | ||||||
|  | $(BUILD_PATH)/obj/%.o: ./src/%.c | $(BUILD_PATH)/obj/ | ||||||
|  | 	$(CC) $^ -o $@ $(CFLAGS) | ||||||
|  | 
 | ||||||
|  | $(BUILD_PATH)/obj/array-%.o:  ./src/array/src/%.c  | $(BUILD_PATH)/obj/ | ||||||
|  | 	$(CC) $^ -o $@ $(CFLAGS) | ||||||
|  | $(BUILD_PATH)/obj/string-%.o: ./src/string/src/%.c | $(BUILD_PATH)/obj/ | ||||||
|  | 	$(CC) $^ -o $@ $(CFLAGS) | ||||||
|  | $(BUILD_PATH)/obj/list-%.o:   ./src/list/src/%.c   | $(BUILD_PATH)/obj/ | ||||||
|  | 	$(CC) $^ -o $@ $(CFLAGS) | ||||||
|  | $(BUILD_PATH)/obj/map-%.o:    ./src/map/src/%.c    | $(BUILD_PATH)/obj/ | ||||||
|  | 	$(CC) $^ -o $@ $(CFLAGS) | ||||||
|  | $(BUILD_PATH)/obj/set-%.o:    ./src/set/src/%.c    | $(BUILD_PATH)/obj/ | ||||||
|  | 	$(CC) $^ -o $@ $(CFLAGS) | ||||||
|  | $(BUILD_PATH)/obj/dict-%.o:   ./src/dict/src/%.c   | $(BUILD_PATH)/obj/ | ||||||
|  | 	$(CC) $^ -o $@ $(CFLAGS) | ||||||
|  | $(BUILD_PATH)/obj/global-%.o: ./src/global/src/%.c | $(BUILD_PATH)/obj/ | ||||||
|  | 	$(CC) $^ -o $@ $(CFLAGS) | ||||||
|  | 
 | ||||||
|  | $(BUILD_PATH)/array-%:  ./src/array/%.c  $(OBJECTS_ARRAY)  | $(BUILD_PATH)/ | ||||||
|  | 	$(CC) $^ -o $@ $(CFLAGS) -g3 -Wall | ||||||
|  | $(BUILD_PATH)/string-%: ./src/string/%.c $(OBJECTS_STRING) | $(BUILD_PATH)/ | ||||||
|  | 	$(CC) $^ -o $@ ../modules/libunic/bin/libunic.a $(CFLAGS) -g3 -Wall | ||||||
|  | $(BUILD_PATH)/list-%:   ./src/list/%.c   $(OBJECTS_LIST)   | $(BUILD_PATH)/ | ||||||
|  | 	$(CC) $^ -o $@ $(CFLAGS) -g3 -Wall | ||||||
|  | $(BUILD_PATH)/map-%:    ./src/map/%.c    $(OBJECTS_MAP)    | $(BUILD_PATH)/ | ||||||
|  | 	$(CC) $^ -o $@ $(CFLAGS) -g3 -Wall | ||||||
|  | $(BUILD_PATH)/set-%:    ./src/set/%.c    $(OBJECTS_SET)    | $(BUILD_PATH)/ | ||||||
|  | 	$(CC) $^ -o $@ $(CFLAGS) -g3 -Wall | ||||||
|  | $(BUILD_PATH)/dict-%:   ./src/dict/%.c   $(OBJECTS_DICT)   | $(BUILD_PATH)/ | ||||||
|  | 	$(CC) $^ -o $@ $(CFLAGS) -g3 -Wall | ||||||
|  | $(BUILD_PATH)/global-%: ./src/global/%.c $(OBJECTS_GLOBAL) | $(BUILD_PATH)/ | ||||||
|  | 	$(CC) $^ ../bin/debug/libcdsb.a ../modules/libunic/bin/libunic.a -o $@ $(CFLAGS) -g3 -Wall | ||||||
|  | 
 | ||||||
|  | ########################################################################################################################
 | ||||||
|  | 
 | ||||||
|  | $(BUILD_PATH)/: | ||||||
|  | 	$(MKDIR) $@ | ||||||
|  | $(BUILD_PATH)/obj/:   | $(BUILD_PATH)/ | ||||||
|  | 	$(MKDIR) $@ | ||||||
|  | 
 | ||||||
|  | ########################################################################################################################
 | ||||||
|  | 
 | ||||||
|  | clean: | ||||||
|  | 	$(RMRF) ./bin/ | ||||||
|  | 	cd ../ && $(MAKE) clean | ||||||
|  | 
 | ||||||
|  | ########################################################################################################################
 | ||||||
|  | 
 | ||||||
|  | FORCE: | ||||||
|  | modules: ../bin/debug/libcdsb.a | ||||||
|  | 
 | ||||||
|  | ../bin/debug/libcdsb.a: FORCE | ||||||
|  | 	cd ../ && CFLAGS=-DDICT_CAPACITY_BLOCK\=5 $(MAKE) debug | ||||||
							
								
								
									
										37
									
								
								tests/include/random.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								tests/include/random.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,37 @@ | |||||||
|  | /* This software is licensed by the MIT License, see LICENSE file */ | ||||||
|  | /*                                Copyright © 2022 Gregory Lirent */ | ||||||
|  | 
 | ||||||
|  | #include "../../include/vtype.h" | ||||||
|  | #include "../../src/__internal/vnode.h" | ||||||
|  | 
 | ||||||
|  | #ifndef LIBCDSB_TESTS_RANDOM_H | ||||||
|  | #define LIBCDSB_TESTS_RANDOM_H | ||||||
|  | 
 | ||||||
|  | typedef struct { | ||||||
|  |     var_t value[1]; | ||||||
|  |     vtype type; | ||||||
|  | } value_t; | ||||||
|  | 
 | ||||||
|  | extern int random_init(int argc, char** argv); | ||||||
|  | 
 | ||||||
|  | extern vtype_bool    random_boolean(); | ||||||
|  | extern vtype_float   random_float(); | ||||||
|  | extern vtype_double  random_double(); | ||||||
|  | extern vtype_ldouble random_ldouble(); | ||||||
|  | 
 | ||||||
|  | extern vtype_uint8  random_uint8(); | ||||||
|  | extern vtype_uint16 random_uint16(); | ||||||
|  | extern vtype_uint32 random_uint32(); | ||||||
|  | extern vtype_uint64 random_uint64(); | ||||||
|  | 
 | ||||||
|  | extern vtype_int8  random_int8(); | ||||||
|  | extern vtype_int16 random_int16(); | ||||||
|  | extern vtype_int32 random_int32(); | ||||||
|  | extern vtype_int64 random_int64(); | ||||||
|  | 
 | ||||||
|  | extern char random_ascii_char(); | ||||||
|  | extern unsigned int random_unicode_symbol(); | ||||||
|  | 
 | ||||||
|  | extern value_t random_value(); | ||||||
|  | 
 | ||||||
|  | #endif /* LIBCDSB_TESTS_RANDOM_H */ | ||||||
							
								
								
									
										17
									
								
								tests/include/test.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								tests/include/test.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,17 @@ | |||||||
|  | /* This software is licensed by the MIT License, see LICENSE file */ | ||||||
|  | /*                                Copyright © 2022 Gregory Lirent */ | ||||||
|  | 
 | ||||||
|  | #include <stdio.h> | ||||||
|  | #include "../../include/extra/vtype.h" | ||||||
|  | 
 | ||||||
|  | #ifndef LIBCDSB_TESTS_TEST_H | ||||||
|  | #define LIBCDSB_TESTS_TEST_H | ||||||
|  | 
 | ||||||
|  | extern void put_separator(unsigned int hpos); | ||||||
|  | extern void print_container_values_prefix(const char* name, const char* prefix, unsigned int hpos); | ||||||
|  | extern void print_container_value(const ssize_t* index, const void* value, const vtype type, _Bool print_type, unsigned int hpos); | ||||||
|  | extern void print_container_info(const char* name, const char* el_name, const vtype* type, ssize_t size, ssize_t nmemb, unsigned int hpos); | ||||||
|  | 
 | ||||||
|  | extern void test_init(int argc, char** argv); | ||||||
|  | 
 | ||||||
|  | #endif /* LIBCDSB_TESTS_TEST_H */ | ||||||
							
								
								
									
										24
									
								
								tests/include/time.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								tests/include/time.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,24 @@ | |||||||
|  | /* This software is licensed by the MIT License, see LICENSE file */ | ||||||
|  | /*                                Copyright © 2022 Gregory Lirent */ | ||||||
|  | 
 | ||||||
|  | #include "../../include/vtype.h" | ||||||
|  | 
 | ||||||
|  | #ifndef LIBCDSB_TESTS_TIME_H | ||||||
|  | #define LIBCDSB_TESTS_TIME_H | ||||||
|  | 
 | ||||||
|  | typedef struct timer { | ||||||
|  |     void* info; | ||||||
|  | } TIMER; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | extern void timer_init (TIMER* timer); | ||||||
|  | extern void timer_start(TIMER* timer); | ||||||
|  | extern void timer_stop (TIMER* timer); | ||||||
|  | extern void timer_free (TIMER* timer); | ||||||
|  | 
 | ||||||
|  | extern vtype_ldouble timer_value(TIMER* timer); | ||||||
|  | 
 | ||||||
|  | extern void psleep(unsigned long microsec); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #endif /* LIBCDSB_TESTS_TIME_H */ | ||||||
							
								
								
									
										23
									
								
								tests/src/array/main.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								tests/src/array/main.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,23 @@ | |||||||
|  | /* This software is licensed by the MIT License, see LICENSE file */ | ||||||
|  | /*                                Copyright © 2022 Gregory Lirent */ | ||||||
|  | 
 | ||||||
|  | #include "plug.h" | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | int main(int argc, char** argv) { | ||||||
|  |     test_init(argc, argv); | ||||||
|  | 
 | ||||||
|  |     arr_t x = { .mem = 0, .size = 0, .type = random_uint8()%(VTYPE_LDOUBLE + 1) }; | ||||||
|  |     arr_t y = { .mem = 0, .size = 0, .type = x.type }; | ||||||
|  | 
 | ||||||
|  |     visual_push(&x, (random_uint8()%17) + 16); | ||||||
|  | 
 | ||||||
|  |     visual_slice(&x, &y); | ||||||
|  |     visual_push2(&x, (random_uint8()%5) + 12, &y, (random_uint8()%5) + 12); | ||||||
|  | 
 | ||||||
|  |     visual_sort2(&x, &y); | ||||||
|  |     visual_remove2(&x, &y); | ||||||
|  | 
 | ||||||
|  |     array_free(&y); | ||||||
|  |     array_free(&y); | ||||||
|  | } | ||||||
							
								
								
									
										24
									
								
								tests/src/array/plug.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								tests/src/array/plug.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,24 @@ | |||||||
|  | /* This software is licensed by the MIT License, see LICENSE file */ | ||||||
|  | /*                                Copyright © 2022 Gregory Lirent */ | ||||||
|  | 
 | ||||||
|  | #include <string.h> | ||||||
|  | #include "../../../include/extra/vtype.h" | ||||||
|  | #include "../../../include/extra/array.h" | ||||||
|  | 
 | ||||||
|  | #include "../../include/random.h" | ||||||
|  | #include "../../include/test.h" | ||||||
|  | #include "../../include/time.h" | ||||||
|  | 
 | ||||||
|  | extern void array_print(arr_t* x, const char* prefix, unsigned int hpos); | ||||||
|  | extern void array_info(arr_t* x, unsigned int hpos); | ||||||
|  | 
 | ||||||
|  | extern void visual_push(arr_t* x, size_t n); | ||||||
|  | extern void visual_sort(arr_t* x); | ||||||
|  | extern void visual_remove(arr_t* x); | ||||||
|  | extern void visual_push2(arr_t* x0, size_t n0, arr_t* x1, size_t n1); | ||||||
|  | extern void visual_remove2(arr_t* x0, arr_t* x1); | ||||||
|  | extern void visual_sort2(arr_t* x0, arr_t* x1); | ||||||
|  | extern void visual_slice(arr_t* x, arr_t* s); | ||||||
|  | 
 | ||||||
|  | extern void array_push_random  (arr_t* x, _Bool silent, unsigned int hpos); | ||||||
|  | extern void array_remove_random(arr_t* x, _Bool silent, unsigned int hpos); | ||||||
							
								
								
									
										197
									
								
								tests/src/array/src/io.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										197
									
								
								tests/src/array/src/io.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,197 @@ | |||||||
|  | /* This software is licensed by the MIT License, see LICENSE file */ | ||||||
|  | /*                                Copyright © 2022 Gregory Lirent */ | ||||||
|  | 
 | ||||||
|  | #include "../plug.h" | ||||||
|  | 
 | ||||||
|  | static int array_value_print(void* v, ssize_t i, vtype t, void* _) { | ||||||
|  |     print_container_value(&i, v, t, 1, *(unsigned int*)_); | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void array_print(arr_t* x, const char* prefix, unsigned int hpos) { | ||||||
|  |     print_container_values_prefix("Array", prefix, hpos); | ||||||
|  |     array_foreach(x, &hpos, array_value_print); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void array_info(arr_t* x, unsigned int hpos) { | ||||||
|  |     print_container_info("Array", "nodes", 0, array_size(x), -1, hpos); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | void visual_push(arr_t* x, size_t n) { | ||||||
|  |     for (int i = 0; i < n; ++i) { | ||||||
|  |         fputs("\e[s", stdout); | ||||||
|  | 
 | ||||||
|  |         array_push_random(x, 0, 0); | ||||||
|  | 
 | ||||||
|  |         array_info(x, 0); | ||||||
|  |         array_print(x, 0, 0); | ||||||
|  | 
 | ||||||
|  |         psleep(100000); | ||||||
|  |         fputs("\e[u\e[J", stdout); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void visual_sort(arr_t* x) { | ||||||
|  |     puts("\e[s\e[36mTry to sort array values:\e[m\n\n"); | ||||||
|  |     put_separator(0); | ||||||
|  |     array_sort(x); | ||||||
|  |     array_info(x, 0); | ||||||
|  |     array_print(x, "sorted", 0); | ||||||
|  |     psleep(900000); | ||||||
|  |     fputs("\e[u\e[J", stdout); | ||||||
|  | 
 | ||||||
|  |     puts("\e[s\e[36mTry to reverse array values:\e[m\n\n"); | ||||||
|  |     put_separator(0); | ||||||
|  |     array_reverse(x); | ||||||
|  |     array_info(x, 0); | ||||||
|  |     array_print(x, "reversed", 0); | ||||||
|  |     psleep(900000); | ||||||
|  |     fputs("\e[u\e[J", stdout); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void visual_remove(arr_t* x) { | ||||||
|  |     while (x->size) { | ||||||
|  |         fputs("\e[s", stdout); | ||||||
|  |         array_remove_random(x, 0, 0); | ||||||
|  |         array_info(x, 0); | ||||||
|  |         array_print(x, 0, 0); | ||||||
|  | 
 | ||||||
|  |         psleep(100000); | ||||||
|  |         if (!0) fputs("\e[u\e[J", stdout); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void visual_push2(arr_t* x0, size_t n0, arr_t* x1, size_t n1) { | ||||||
|  | 
 | ||||||
|  |     for (;n0 || n1;) { | ||||||
|  |         fputs("\e[s", stdout); | ||||||
|  |         if (n0) { | ||||||
|  |             array_push_random(x0, 0, 0); | ||||||
|  |             --n0; | ||||||
|  |         } else { | ||||||
|  |             puts("\n\n"); | ||||||
|  |             put_separator(0); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         fputs("\e[u\e[s", stdout); | ||||||
|  | 
 | ||||||
|  |         if (n1) { | ||||||
|  |             array_push_random(x1, 0, 60); | ||||||
|  |             --n1; | ||||||
|  |         } else { | ||||||
|  |             puts("\n\n"); | ||||||
|  |             put_separator(60); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         array_info(x0, 0); | ||||||
|  |         array_print(x0, 0, 0); | ||||||
|  |         fputs("\e[u\e[s\e[4E", stdout); | ||||||
|  |         array_info(x1, 60); | ||||||
|  |         array_print(x1, 0, 60); | ||||||
|  |         psleep(100000); | ||||||
|  | 
 | ||||||
|  |         fputs("\e[u\e[J", stdout); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void visual_remove2(arr_t* x0, arr_t* x1) { | ||||||
|  | 
 | ||||||
|  |     for (;x0->size || x1->size;) { | ||||||
|  |         fputs("\e[s", stdout); | ||||||
|  | 
 | ||||||
|  |         if (x0->size) { | ||||||
|  |             array_remove_random(x0, 0, 0); | ||||||
|  |         } else { | ||||||
|  |             puts("\n\n"); | ||||||
|  |             put_separator(0); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         fputs("\e[u\e[s", stdout); | ||||||
|  | 
 | ||||||
|  |         if (x1->size) { | ||||||
|  |             array_remove_random(x1, 0, 60); | ||||||
|  |         } else { | ||||||
|  |             puts("\n\n"); | ||||||
|  |             put_separator(60); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         array_info(x0, 0); | ||||||
|  |         array_print(x0, 0, 0); | ||||||
|  |         fputs("\e[u\e[s\e[4E", stdout); | ||||||
|  |         array_info(x1, 60); | ||||||
|  |         array_print(x1, 0, 60); | ||||||
|  |         psleep(100000); | ||||||
|  | 
 | ||||||
|  |         fputs("\e[u\e[J", stdout); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | void visual_sort2(arr_t* x0, arr_t* x1) { | ||||||
|  |     printf("\e[s\e[36m%-60s%s\e[m\n\n","Try to sort array values:", "Try to sort array values:"); | ||||||
|  |     printf("\e[32;1m%-60s%s\e[m\n", "SUCCESS", "SUCCESS"); | ||||||
|  |     printf("\e[37;2m%-60s%s\e[m\n", "=== === === === === === === ===", "=== === === === === === === ==="); | ||||||
|  | 
 | ||||||
|  |     array_sort(x0); | ||||||
|  |     array_sort(x1); | ||||||
|  | 
 | ||||||
|  |     array_info(x0, 0); | ||||||
|  |     array_print(x0, "sorted", 0); | ||||||
|  |     fputs("\e[u\e[s\e[4E", stdout); | ||||||
|  |     array_info(x1, 60); | ||||||
|  |     array_print(x1, "sorted", 60); | ||||||
|  | 
 | ||||||
|  |     psleep(900000); | ||||||
|  |     fputs("\e[u\e[J", stdout); | ||||||
|  | 
 | ||||||
|  |     printf("\e[s\e[36m%-60s%s\e[m\n\n","Try to reverse array values:", "Try to reverse array values:"); | ||||||
|  |     printf("\e[32;1m%-60s%s\e[m\n", "SUCCESS", "SUCCESS"); | ||||||
|  |     printf("\e[37;2m%-60s%s\e[m\n", "=== === === === === === === ===", "=== === === === === === === ==="); | ||||||
|  | 
 | ||||||
|  |     array_reverse(x0); | ||||||
|  |     array_reverse(x1); | ||||||
|  | 
 | ||||||
|  |     array_info(x0, 0); | ||||||
|  |     array_print(x0, "reversed", 0); | ||||||
|  |     fputs("\e[u\e[s\e[4E", stdout); | ||||||
|  |     array_info(x1, 60); | ||||||
|  |     array_print(x1, "reversed", 60); | ||||||
|  | 
 | ||||||
|  |     psleep(900000); | ||||||
|  |     fputs("\e[u\e[J", stdout); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void visual_slice(arr_t* x, arr_t* s) { | ||||||
|  | 
 | ||||||
|  |     size_t  n = array_size(x); | ||||||
|  |     ssize_t i = random_uint64()%(n - 1); | ||||||
|  | 
 | ||||||
|  |     n = n - (i + 1); | ||||||
|  | 
 | ||||||
|  |     puts("\e[s\e[36mTry to slice array:\e[m\n\n"); | ||||||
|  |     printf("\e[37;2m%-60s%s\e[m\n", "=== === === === === === === ===", "=== === === === === === === ==="); | ||||||
|  | 
 | ||||||
|  |     array_info(x, 0); | ||||||
|  |     array_print(x, "(src)", 0); | ||||||
|  |     fputs("\e[u\e[s\e[4E", stdout); | ||||||
|  |     array_info(s, 60); | ||||||
|  |     array_print(s, "(dest)", 60); | ||||||
|  | 
 | ||||||
|  |     psleep(900000); | ||||||
|  | 
 | ||||||
|  |     array_slice(s, x, i, n, 1); | ||||||
|  |     fputs("\e[u\e[s\e[2E\e[32;1mSUCCESS\e[m\e[J", stdout); | ||||||
|  | 
 | ||||||
|  |     puts(""); | ||||||
|  |     put_separator(0); | ||||||
|  | 
 | ||||||
|  |     array_info(x, 0); | ||||||
|  |     array_print(x, "(src)", 0); | ||||||
|  |     fputs("\e[u\e[s\e[4E", stdout); | ||||||
|  |     array_info(s, 60); | ||||||
|  |     array_print(s, "(dest)", 60); | ||||||
|  |     psleep(900000); | ||||||
|  | 
 | ||||||
|  |     fputs("\e[u\e[J", stdout); | ||||||
|  | } | ||||||
							
								
								
									
										36
									
								
								tests/src/array/src/plug.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								tests/src/array/src/plug.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,36 @@ | |||||||
|  | /* This software is licensed by the MIT License, see LICENSE file */ | ||||||
|  | /*                                Copyright © 2022 Gregory Lirent */ | ||||||
|  | 
 | ||||||
|  | #include <string.h> | ||||||
|  | #include "../../../../include/extra/vtype.h" | ||||||
|  | #include "../../../include/random.h" | ||||||
|  | 
 | ||||||
|  | vtype_string* string_duplicate(const vtype_string* x) { return 0; } | ||||||
|  | vtype_list*   list_duplicate  (const vtype_list*   x) { return 0; } | ||||||
|  | vtype_map*    map_duplicate   (const vtype_map*    x) { return 0; } | ||||||
|  | vtype_set*    vset_duplicate  (const vtype_set*    x) { return 0; } | ||||||
|  | vtype_dict*   dict_duplicate  (const vtype_dict*   x) { return 0; } | ||||||
|  | 
 | ||||||
|  | void string_free(vtype_string* x) {} | ||||||
|  | void list_free  (vtype_list*   x) {} | ||||||
|  | void map_free   (vtype_map*    x) {} | ||||||
|  | void vset_free  (vtype_set*    x) {} | ||||||
|  | void dict_free  (vtype_dict*   x) {} | ||||||
|  | 
 | ||||||
|  | int string_compare(const vtype_string* s0, const vtype_string* s1) { return random_int8(); } | ||||||
|  | int list_compare  (const vtype_list*   s0, const vtype_list*   s1) { return random_int8(); } | ||||||
|  | int map_compare   (const vtype_map*    s0, const vtype_map*    s1) { return random_int8(); } | ||||||
|  | int vset_compare  (const vtype_set*    s0, const vtype_set*    s1) { return random_int8(); } | ||||||
|  | int dict_compare  (const vtype_dict*   s0, const vtype_dict*   s1) { return random_int8(); } | ||||||
|  | 
 | ||||||
|  | hash_t string_hash(const vtype_string* s) { return 0; } | ||||||
|  | hash_t list_hash  (const vtype_list*   s) { return 0; } | ||||||
|  | hash_t map_hash   (const vtype_map*    s) { return 0; } | ||||||
|  | hash_t vset_hash  (const vtype_set*    s) { return 0; } | ||||||
|  | hash_t dict_hash  (const vtype_dict*   s) { return 0; } | ||||||
|  | 
 | ||||||
|  | void string_copy_init(vtype_string* x, const vtype_string* s) { memset(x, 0, sizeof(*x)); } | ||||||
|  | void list_copy_init  (vtype_list*   x, const vtype_list*   s) { memset(x, 0, sizeof(*x)); } | ||||||
|  | void map_copy_init   (vtype_map*    x, const vtype_map*    s) { memset(x, 0, sizeof(*x)); } | ||||||
|  | void vset_copy_init  (vtype_set*    x, const vtype_set*    s) { memset(x, 0, sizeof(*x)); } | ||||||
|  | void dict_copy_init  (vtype_dict*   x, const vtype_dict*   s) { memset(x, 0, sizeof(*x)); } | ||||||
							
								
								
									
										83
									
								
								tests/src/array/src/random.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										83
									
								
								tests/src/array/src/random.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,83 @@ | |||||||
|  | /* This software is licensed by the MIT License, see LICENSE file */ | ||||||
|  | /*                                Copyright © 2022 Gregory Lirent */ | ||||||
|  | 
 | ||||||
|  | #include "../plug.h" | ||||||
|  | 
 | ||||||
|  | static int remove_callback(void* v, ssize_t i, vtype t, void* _) { | ||||||
|  |     struct { arr_t* x; _Bool s; unsigned int p; } *x = _; | ||||||
|  |     if (!x->s) print_container_value(0, v, t, 1, x->p); | ||||||
|  | 
 | ||||||
|  |     if (libcdsb_array_find(x->x, v, t, 0, 0, 1, 1)) | ||||||
|  |         return -2; | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static int change_callback(void* v, ssize_t i, vtype t, void* _) { | ||||||
|  |     struct { value_t v; _Bool s; unsigned int p; } *x = _; | ||||||
|  | 
 | ||||||
|  |     while (x->v.type != t) { x->v = random_value(); } | ||||||
|  | 
 | ||||||
|  |     memcpy(v, &x->v, vtype_size(t)); | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void array_push_random(arr_t* x, _Bool silent, unsigned int hpos) { | ||||||
|  | 
 | ||||||
|  |     struct { value_t v; _Bool s; unsigned int p; } _ = { .v = random_value(), .s = silent, .p = hpos }; | ||||||
|  |     _Bool   r; | ||||||
|  | 
 | ||||||
|  |     if (random_boolean()) { | ||||||
|  |         if (!silent) { | ||||||
|  |             printf("\e[%dG\e[36mTry to push value to back of the array:\e[m\n", hpos+1); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         r = libcdsb_array_push(x, _.v.value, _.v.type) >= 0; | ||||||
|  |     } else { | ||||||
|  |         ssize_t i = array_size(x); | ||||||
|  | 
 | ||||||
|  |         i = random_uint64()  % (i ? i : 1); | ||||||
|  |         i = random_boolean() ? ~i + 1 : i ; | ||||||
|  | 
 | ||||||
|  |         if (!silent) { | ||||||
|  |             printf("\e[%dG\e[36mTry to change value in the array with index \e[32;1m%ld\e[36m:\e[m\n", hpos+1, i); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         r = array_get_by_index(x, i, &_, change_callback) == 0; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (!silent) { | ||||||
|  |         print_container_value(0, _.v.value, _.v.type, 1, hpos); | ||||||
|  |         printf("\e[%dG%s\n", hpos+1, r ? "\e[32;1mSUCCESS\e[m" : "\e[31;1mFAILURE\e[m"); | ||||||
|  |         put_separator(hpos); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void array_remove_random(arr_t* x, _Bool silent, unsigned int hpos) { | ||||||
|  | 
 | ||||||
|  |     size_t  n = array_size(x); | ||||||
|  |     ssize_t i = random_uint64()%n; | ||||||
|  | 
 | ||||||
|  |     if (random_boolean()) i = ~i + 1; | ||||||
|  | 
 | ||||||
|  |     if (random_boolean()) { | ||||||
|  |         if (!silent) { | ||||||
|  |             printf("\e[%dG\e[36mTry to remove value from list by index:\e[m\n", hpos+1); | ||||||
|  |             print_container_value(0, &i, (sizeof(ssize_t) == 8) ? VTYPE_INT64 : VTYPE_INT32, 0, hpos); | ||||||
|  |         } | ||||||
|  |         switch (array_remove_by_index(x, i)) { | ||||||
|  |             case  0: if (!silent) printf("\e[%dG\e[32;1mSUCCESS\e[m\n", hpos+1); break; | ||||||
|  |             default: if (!silent) printf("\e[%dG\e[32;1mFAILURE\e[m\n", hpos+1); break; | ||||||
|  |         } | ||||||
|  |     } else { | ||||||
|  |         struct { arr_t* x; _Bool s; unsigned int p; } v = { .x = x, .s = silent, .p = hpos }; | ||||||
|  | 
 | ||||||
|  |         if (!silent) printf("\e[%dG\e[36mTry to remove value from list:\e[m\n", hpos+1); | ||||||
|  | 
 | ||||||
|  |         switch (libcdsb_array_get(x, i, &v, remove_callback, 0)) { | ||||||
|  |             case  0: if (!silent) printf("\e[%dG\e[32;1mSUCCESS\e[m\n", hpos+1); break; | ||||||
|  |             default: if (!silent) printf("\e[%dG\e[32;1mFAILURE\e[m\n", hpos+1); break; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (!silent) put_separator(hpos); | ||||||
|  | } | ||||||
							
								
								
									
										15
									
								
								tests/src/dict/main.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								tests/src/dict/main.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,15 @@ | |||||||
|  | /* This software is licensed by the MIT License, see LICENSE file */ | ||||||
|  | /*                                Copyright © 2022 Gregory Lirent */ | ||||||
|  | 
 | ||||||
|  | #include "plug.h" | ||||||
|  | 
 | ||||||
|  | int main(int argc, char** argv) { | ||||||
|  |     test_init(argc, argv); | ||||||
|  | 
 | ||||||
|  |     dict_t x; | ||||||
|  | 
 | ||||||
|  |     dict_init(&x); | ||||||
|  | 
 | ||||||
|  |     visual_push(&x, random_uint8()%17 + 16); | ||||||
|  |     visual_remove(&x); | ||||||
|  | } | ||||||
							
								
								
									
										17
									
								
								tests/src/dict/plug.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								tests/src/dict/plug.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,17 @@ | |||||||
|  | /* This software is licensed by the MIT License, see LICENSE file */ | ||||||
|  | /*                                Copyright © 2022 Gregory Lirent */ | ||||||
|  | 
 | ||||||
|  | #include "../../../include/extra/dict.h" | ||||||
|  | 
 | ||||||
|  | #include "../../include/random.h" | ||||||
|  | #include "../../include/test.h" | ||||||
|  | #include "../../include/time.h" | ||||||
|  | 
 | ||||||
|  | extern void dict_push_random(dict_t* x, bool silent, unsigned int hpos); | ||||||
|  | extern void dict_remove_random(dict_t* x, bool silent, unsigned int hpos); | ||||||
|  | 
 | ||||||
|  | extern void dict_info(const dict_t* x, unsigned int hpos); | ||||||
|  | extern void dict_print(dict_t* x, const char* prefix, unsigned int hpos); | ||||||
|  | 
 | ||||||
|  | extern void visual_push(dict_t* x, size_t n); | ||||||
|  | extern void visual_remove(dict_t* x); | ||||||
							
								
								
									
										47
									
								
								tests/src/dict/src/io.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								tests/src/dict/src/io.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,47 @@ | |||||||
|  | /* This software is licensed by the MIT License, see LICENSE file */ | ||||||
|  | /*                                Copyright © 2022 Gregory Lirent */ | ||||||
|  | 
 | ||||||
|  | #include "../plug.h" | ||||||
|  | 
 | ||||||
|  | static int node_print_callback(const void* k, vtype kt, void* v, vtype vt, void* _) { | ||||||
|  |     print_container_value(0, k, kt, 0, *(unsigned int*)_); | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void dict_print(dict_t* x, const char* prefix, unsigned int hpos) { | ||||||
|  |     print_container_values_prefix("Dict", prefix, 0); | ||||||
|  |     dict_foreach(x, &hpos, node_print_callback); | ||||||
|  |     put_separator(0); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void dict_info(const dict_t* x, unsigned int hpos) { | ||||||
|  |     print_container_info("Dict", "nodes", 0, dict_size(x), -1, 0); | ||||||
|  |     put_separator(0); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void visual_push(dict_t* x, size_t n) { | ||||||
|  |     while (n--) { | ||||||
|  |         fputs("\e[s", stdout); | ||||||
|  | 
 | ||||||
|  |         dict_push_random(x, 0, 0); | ||||||
|  | 
 | ||||||
|  |         dict_info(x, 0); | ||||||
|  |         dict_print(x, 0, 0); | ||||||
|  | 
 | ||||||
|  |         psleep(100000); | ||||||
|  |         fputs("\e[u\e[J", stdout); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void visual_remove(dict_t* x) { | ||||||
|  |     while (x->size) { | ||||||
|  |         fputs("\e[s", stdout); | ||||||
|  |         dict_remove_random(x, 0, 0); | ||||||
|  | 
 | ||||||
|  |         dict_info(x, 0); | ||||||
|  |         dict_print(x, 0, 0); | ||||||
|  | 
 | ||||||
|  |         psleep(100000); | ||||||
|  |         fputs("\e[u\e[J", stdout); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										29
									
								
								tests/src/dict/src/plug.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								tests/src/dict/src/plug.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,29 @@ | |||||||
|  | /* This software is licensed by the MIT License, see LICENSE file */ | ||||||
|  | /*                                Copyright © 2022 Gregory Lirent */ | ||||||
|  | 
 | ||||||
|  | #include "../../../../src/__internal/include.h" | ||||||
|  | #include "../../../include/random.h" | ||||||
|  | 
 | ||||||
|  | vtype_string* string_duplicate(const vtype_string* x) { return 0; } | ||||||
|  | vtype_array*  array_duplicate (const vtype_array*  x) { return 0; } | ||||||
|  | vtype_list*   list_duplicate  (const vtype_list*   x) { return 0; } | ||||||
|  | vtype_map*    map_duplicate   (const vtype_map*    x) { return 0; } | ||||||
|  | vtype_set*    vset_duplicate  (const vtype_set*    x) { return 0; } | ||||||
|  | 
 | ||||||
|  | void string_free(vtype_string* x) {} | ||||||
|  | void array_free (vtype_array*  x) {} | ||||||
|  | void list_free  (vtype_list*   x) {} | ||||||
|  | void map_free   (vtype_map*    x) {} | ||||||
|  | void vset_free  (vtype_set*    x) {} | ||||||
|  | 
 | ||||||
|  | int string_compare(const vtype_string* s0, const vtype_string* s1) { return random_int8(); } | ||||||
|  | int array_compare (const vtype_array*  s0, const vtype_array*  s1) { return random_int8(); } | ||||||
|  | int list_compare  (const vtype_list*   s0, const vtype_list*   s1) { return random_int8(); } | ||||||
|  | int map_compare   (const vtype_map*    s0, const vtype_map*    s1) { return random_int8(); } | ||||||
|  | int vset_compare  (const vtype_set*    s0, const vtype_set*    s1) { return random_int8(); } | ||||||
|  | 
 | ||||||
|  | hash_t string_hash(const vtype_string* s) { return 0; } | ||||||
|  | hash_t array_hash (const vtype_array*  s) { return 0; } | ||||||
|  | hash_t list_hash  (const vtype_list*   s) { return 0; } | ||||||
|  | hash_t map_hash   (const vtype_map*    s) { return 0; } | ||||||
|  | hash_t vset_hash  (const vtype_set*    s) { return 0; } | ||||||
							
								
								
									
										53
									
								
								tests/src/dict/src/random.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								tests/src/dict/src/random.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,53 @@ | |||||||
|  | /* This software is licensed by the MIT License, see LICENSE file */ | ||||||
|  | /*                                Copyright © 2022 Gregory Lirent */ | ||||||
|  | 
 | ||||||
|  | #include "../plug.h" | ||||||
|  | 
 | ||||||
|  | static int remove_callback(const void* k, vtype kt, void* v, vtype vt, void* _) { | ||||||
|  |     struct { size_t n; dict_t* x; unsigned int hp; } *d = _; | ||||||
|  | 
 | ||||||
|  |     if (!d->n--) { | ||||||
|  |         print_container_value(0, k, kt, 0, d->hp); | ||||||
|  | 
 | ||||||
|  |         if (libcdsb_dict_get(d->x, k, kt, 0, 0, 1) == 0) { | ||||||
|  |             printf("\e[%dG\e[32;1mSUCCESS\e[m\n", d->hp+1); | ||||||
|  |         } else printf("\e[%dG\e[31;1mFAILURE\e[m\n", d->hp+1); | ||||||
|  | 
 | ||||||
|  |         return -2; | ||||||
|  |     } | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void dict_push_random(dict_t* x, _Bool silent, unsigned int hpos) { | ||||||
|  | 
 | ||||||
|  |     value_t k = random_value(); | ||||||
|  |     value_t v = random_value(); | ||||||
|  | 
 | ||||||
|  |     if (!silent) { | ||||||
|  |         printf("\e[%dG\e[36mUpdate value in dict with key:\e[m\n", hpos+1); | ||||||
|  |         print_container_value(0, k.value, k.type, 1, hpos); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (libcdsb_dict_update(x, k.value, k.type, v.value, v.type)) { | ||||||
|  |         if (!silent) printf("\e[%dG\e[33;1mCHANGE\e[m\n", hpos+1); | ||||||
|  |     } else if (!silent) printf("\e[%dG\e[32;1mINSERT\e[m\n", hpos+1); | ||||||
|  | 
 | ||||||
|  |     if (!silent) put_separator(0); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | void dict_remove_random(dict_t* x, _Bool silent, unsigned int hpos) { | ||||||
|  |     struct { size_t n; dict_t* x; unsigned int hp; } d = { .n = dict_size(x), .x = x, .hp = hpos }; | ||||||
|  | 
 | ||||||
|  |     if (!silent) | ||||||
|  |         printf("\e[%dG\e[36mTry to remove value from dict by key:\e[m\n", hpos+1); | ||||||
|  | 
 | ||||||
|  |     if (d.n) { | ||||||
|  |         d.n = random_uint32()%d.n; | ||||||
|  |         dict_foreach(x, &d, remove_callback); | ||||||
|  |     } else if (!silent) { | ||||||
|  |         printf("\e[%dG\e[32;1m\nFAILURE\e[m\n", hpos+1); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (!silent) put_separator(hpos); | ||||||
|  | } | ||||||
							
								
								
									
										34
									
								
								tests/src/global/main.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								tests/src/global/main.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,34 @@ | |||||||
|  | /* This software is licensed by the MIT License, see LICENSE file */ | ||||||
|  | /*                                Copyright © 2022 Gregory Lirent */ | ||||||
|  | 
 | ||||||
|  | #include "plug.h" | ||||||
|  | 
 | ||||||
|  | int main(int argc, char** argv) { | ||||||
|  |     test_init(argc, argv); | ||||||
|  | 
 | ||||||
|  |     value_t x = random_container(0); | ||||||
|  | 
 | ||||||
|  |     switch (x.type) { | ||||||
|  |         default: abort(); | ||||||
|  |         case VTYPE_ARRAY: | ||||||
|  |             array_info((void*)x.value, 0); | ||||||
|  |             array_free((void*)x.value); | ||||||
|  |             return 0; | ||||||
|  |         case VTYPE_MAP: | ||||||
|  |             map_info((void*)x.value, 0); | ||||||
|  |             map_free((void*)x.value); | ||||||
|  |             return 0; | ||||||
|  |         case VTYPE_LIST: | ||||||
|  |             list_info((void*)x.value, 0); | ||||||
|  |             list_free((void*)x.value); | ||||||
|  |             return 0; | ||||||
|  |         case VTYPE_SET: | ||||||
|  |             vset_info((void*)x.value, 0); | ||||||
|  |             vset_free((void*)x.value); | ||||||
|  |             return 0; | ||||||
|  |         case VTYPE_DICT: | ||||||
|  |             dict_info((void*)x.value, 0); | ||||||
|  |             dict_free((void*)x.value); | ||||||
|  |             return 0; | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										23
									
								
								tests/src/global/plug.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								tests/src/global/plug.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,23 @@ | |||||||
|  | /* This software is licensed by the MIT License, see LICENSE file */ | ||||||
|  | /*                                Copyright © 2022 Gregory Lirent */ | ||||||
|  | 
 | ||||||
|  | #include "../../../include/extra/string.h" | ||||||
|  | #include "../../../include/extra/array.h" | ||||||
|  | #include "../../../include/extra/list.h" | ||||||
|  | #include "../../../include/extra/set.h" | ||||||
|  | #include "../../../include/extra/map.h" | ||||||
|  | #include "../../../include/extra/dict.h" | ||||||
|  | 
 | ||||||
|  | #include "../../include/random.h" | ||||||
|  | #include "../../include/test.h" | ||||||
|  | #include "../../include/time.h" | ||||||
|  | 
 | ||||||
|  | extern value_t random_container(bool embd); | ||||||
|  | extern value_t real_random_value(bool embd); | ||||||
|  | 
 | ||||||
|  | extern void array_info(arr_t* x, unsigned int hpos); | ||||||
|  | extern void list_info (list_t* x, unsigned int hpos); | ||||||
|  | extern void dict_info(const dict_t* x, unsigned int hpos); | ||||||
|  | extern void map_info(const map_t* x, unsigned int hpos); | ||||||
|  | extern void vset_info(const set_t* x, unsigned int hpos); | ||||||
|  | extern void string_info(str_t* x); | ||||||
							
								
								
									
										33
									
								
								tests/src/global/src/io.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								tests/src/global/src/io.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,33 @@ | |||||||
|  | /* This software is licensed by the MIT License, see LICENSE file */ | ||||||
|  | /*                                Copyright © 2022 Gregory Lirent */ | ||||||
|  | 
 | ||||||
|  | #include "../plug.h" | ||||||
|  | 
 | ||||||
|  | void map_info(const map_t* x, unsigned int hpos) { | ||||||
|  |     print_container_info("Map", "nodes", &x->type, map_size(x), -1, 0); | ||||||
|  |     put_separator(0); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void array_info(arr_t* x, unsigned int hpos) { | ||||||
|  |     print_container_info("Array", "nodes", 0, array_size(x), -1, hpos); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | void dict_info(const dict_t* x, unsigned int hpos) { | ||||||
|  |     print_container_info("Dict", "nodes", 0, dict_size(x), -1, 0); | ||||||
|  |     put_separator(0); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void list_info(list_t* x, unsigned int hpos) { | ||||||
|  |     print_container_info("List", "nodes", 0, list_size(x), -1, hpos); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void vset_info(const set_t* x, unsigned int hpos) { | ||||||
|  |     print_container_info("Set", "nodes", &x->type, vset_size(x), -1, 0); | ||||||
|  |     put_separator(0); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void string_info(str_t* x) { | ||||||
|  |     print_container_info("String", "utf8 chars", 0, string_size(x), string_nmemb(x), 0); | ||||||
|  |     put_separator(0); | ||||||
|  | } | ||||||
							
								
								
									
										265
									
								
								tests/src/global/src/random.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										265
									
								
								tests/src/global/src/random.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,265 @@ | |||||||
|  | /* This software is licensed by the MIT License, see LICENSE file */ | ||||||
|  | /*                                Copyright © 2022 Gregory Lirent */ | ||||||
|  | 
 | ||||||
|  | #include "../plug.h" | ||||||
|  | 
 | ||||||
|  | #define MAX_ELEMENTS 2000 | ||||||
|  | 
 | ||||||
|  | static arr_t  random_array(bool embd); | ||||||
|  | static list_t random_list (bool embd); | ||||||
|  | static set_t  random_set  (bool embd); | ||||||
|  | static map_t  random_map  (bool embd); | ||||||
|  | static dict_t random_dict (bool embd); | ||||||
|  | 
 | ||||||
|  | static str_t random_string() { | ||||||
|  |     str_t  x; | ||||||
|  |     size_t n = random_uint16()%MAX_ELEMENTS; | ||||||
|  | 
 | ||||||
|  |     string_init(&x, 0); | ||||||
|  | 
 | ||||||
|  |     while (n--) { | ||||||
|  |         string_concat(&x, random_unicode_symbol()); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return x; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static value_t random_value2() { | ||||||
|  |     value_t v; | ||||||
|  |     switch (random_uint8()%14) { | ||||||
|  |         default: | ||||||
|  |         case  0: v.value[0].b   = random_boolean(); v.type = VTYPE_BOOLEAN; break; | ||||||
|  |         case  1: v.value[0].u8  = random_uint8  (); v.type = VTYPE_UINT8;   break; | ||||||
|  |         case  2: v.value[0].u16 = random_uint16 (); v.type = VTYPE_UINT16;  break; | ||||||
|  |         case  3: v.value[0].u32 = random_uint32 (); v.type = VTYPE_UINT32;  break; | ||||||
|  |         case  4: v.value[0].u64 = random_uint64 (); v.type = VTYPE_UINT64;  break; | ||||||
|  |         case  5: v.value[0].u8  = random_int8   (); v.type = VTYPE_INT8;    break; | ||||||
|  |         case  6: v.value[0].u16 = random_uint16  (); v.type = VTYPE_INT16;   break; | ||||||
|  |         case  7: v.value[0].u32 = random_int32  (); v.type = VTYPE_INT32;   break; | ||||||
|  |         case  8: v.value[0].u64 = random_int64  (); v.type = VTYPE_INT64;   break; | ||||||
|  |         case  9: v.value[0].f   = random_float  (); v.type = VTYPE_FLOAT;   break; | ||||||
|  |         case 10: v.value[0].d   = random_double (); v.type = VTYPE_DOUBLE;  break; | ||||||
|  |         case 11: v.value[0].ld  = random_ldouble(); v.type = VTYPE_LDOUBLE; break; | ||||||
|  |         case 12: v.value[0].ptr = (void*)(uintptr_t)random_uint64(); v.type = VTYPE_POINTER; break; | ||||||
|  |         case 13: v.value[0].s   = random_string();  v.type = VTYPE_STRING;  break; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return v; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static value_t random_value_by_type(vtype type, bool embd) { | ||||||
|  |     value_t v; | ||||||
|  |     switch ((v.type = type)) { | ||||||
|  |         default: | ||||||
|  |         case VTYPE_BOOLEAN: v.value[0].b   = random_boolean();   break; | ||||||
|  |         case   VTYPE_UINT8: v.value[0].u8  = random_uint8  ();   break; | ||||||
|  |         case  VTYPE_UINT16: v.value[0].u16 = random_uint16 ();   break; | ||||||
|  |         case  VTYPE_UINT32: v.value[0].u32 = random_uint32 ();   break; | ||||||
|  |         case  VTYPE_UINT64: v.value[0].u64 = random_uint64 ();   break; | ||||||
|  |         case    VTYPE_INT8: v.value[0].u8  = random_int8   ();   break; | ||||||
|  |         case   VTYPE_INT16: v.value[0].u16 = random_uint16  ();   break; | ||||||
|  |         case   VTYPE_INT32: v.value[0].u32 = random_int32  ();   break; | ||||||
|  |         case   VTYPE_INT64: v.value[0].u64 = random_int64  ();   break; | ||||||
|  |         case   VTYPE_FLOAT: v.value[0].f   = random_float  ();   break; | ||||||
|  |         case  VTYPE_DOUBLE: v.value[0].d   = random_double ();   break; | ||||||
|  |         case VTYPE_LDOUBLE: v.value[0].ld  = random_ldouble();   break; | ||||||
|  |         case  VTYPE_STRING: v.value[0].s   = random_string();    break; | ||||||
|  |         case   VTYPE_ARRAY: v.value[0].a   = random_array(embd); break; | ||||||
|  |         case     VTYPE_MAP: v.value[0].m   = random_map  (embd); break; | ||||||
|  |         case    VTYPE_DICT: v.value[0].vd  = random_dict (embd); break; | ||||||
|  |         case    VTYPE_LIST: v.value[0].l   = random_list (embd); break; | ||||||
|  |         case     VTYPE_SET: v.value[0].vs  = random_set  (embd); break; | ||||||
|  |         case VTYPE_POINTER: v.value[0].ptr = (void*)(uintptr_t)random_uint64(); break; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return v; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static arr_t random_array(bool embd) { | ||||||
|  |     arr_t   x; | ||||||
|  |     size_t  n = random_uint16()%((!embd)?MAX_ELEMENTS:100); | ||||||
|  |     value_t v = (!embd) ? random_value2() : real_random_value(1); | ||||||
|  | 
 | ||||||
|  |     void (*callback)(void*); | ||||||
|  | 
 | ||||||
|  |     switch (v.type) { | ||||||
|  |         default: callback = nullptr; break; | ||||||
|  |         case VTYPE_STRING: callback = (void*)string_free; break; | ||||||
|  |         case  VTYPE_ARRAY: callback = (void*)array_free;  break; | ||||||
|  |         case   VTYPE_LIST: callback = (void*)list_free;   break; | ||||||
|  |         case    VTYPE_MAP: callback = (void*)map_free;    break; | ||||||
|  |         case    VTYPE_SET: callback = (void*)vset_free;   break; | ||||||
|  |         case   VTYPE_DICT: callback = (void*)dict_free;   break; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     array_init(&x, v.type); | ||||||
|  | 
 | ||||||
|  |     while(n--) { | ||||||
|  | 
 | ||||||
|  |         libcdsb_array_push(&x, v.value, v.type); | ||||||
|  | 
 | ||||||
|  |         if (callback) callback(v.value); | ||||||
|  | 
 | ||||||
|  |         v = random_value_by_type(v.type, 1); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (callback) callback(v.value); | ||||||
|  | 
 | ||||||
|  |     return x; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static set_t random_set(bool embd) { | ||||||
|  |     set_t   x; | ||||||
|  |     size_t  n = random_uint16()%((!embd)?MAX_ELEMENTS:100); | ||||||
|  |     value_t v = (!embd) ? random_value2() : real_random_value(1); | ||||||
|  | 
 | ||||||
|  |     void (*callback)(void*); | ||||||
|  | 
 | ||||||
|  |     switch (v.type) { | ||||||
|  |         default: callback = nullptr; break; | ||||||
|  |         case VTYPE_STRING: callback = (void*)string_free; break; | ||||||
|  |         case  VTYPE_ARRAY: callback = (void*)array_free;  break; | ||||||
|  |         case   VTYPE_LIST: callback = (void*)list_free;   break; | ||||||
|  |         case    VTYPE_MAP: callback = (void*)map_free;    break; | ||||||
|  |         case    VTYPE_SET: callback = (void*)vset_free;   break; | ||||||
|  |         case   VTYPE_DICT: callback = (void*)dict_free;   break; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     vset_init(&x, v.type); | ||||||
|  | 
 | ||||||
|  |     while(n--) { | ||||||
|  | 
 | ||||||
|  |         libcdsb_vset_insert(&x, v.value, v.type); | ||||||
|  | 
 | ||||||
|  |         if (callback) callback(v.value); | ||||||
|  | 
 | ||||||
|  |         v = random_value_by_type(v.type, 1); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (callback) callback(v.value); | ||||||
|  |     return x; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static list_t random_list(bool embd) { | ||||||
|  |     list_t  x; | ||||||
|  |     value_t v; | ||||||
|  |     size_t  n = random_uint16()%((!embd)?MAX_ELEMENTS:100); | ||||||
|  | 
 | ||||||
|  |     list_init(&x); | ||||||
|  | 
 | ||||||
|  |     while(n--) { | ||||||
|  |         v = (!embd) ? random_value2() : real_random_value(1); | ||||||
|  |         libcdsb_list_update(&x, -1, v.value, v.type, 1); | ||||||
|  | 
 | ||||||
|  |         switch (v.type) { | ||||||
|  |             default: break; | ||||||
|  |             case VTYPE_STRING: string_free((void*)v.value); break; | ||||||
|  |             case  VTYPE_ARRAY: array_free ((void*)v.value); break; | ||||||
|  |             case   VTYPE_LIST: list_free  ((void*)v.value); break; | ||||||
|  |             case    VTYPE_MAP: map_free   ((void*)v.value); break; | ||||||
|  |             case    VTYPE_SET: vset_free  ((void*)v.value); break; | ||||||
|  |             case   VTYPE_DICT: dict_free  ((void*)v.value); break; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return x; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static map_t random_map(bool embd) { | ||||||
|  |     map_t   x; | ||||||
|  |     size_t  n = random_uint16()%((!embd)?MAX_ELEMENTS:100); | ||||||
|  |     value_t k = (!embd) ? random_value2() : real_random_value(1); | ||||||
|  | 
 | ||||||
|  |     void (*callback)(void*); | ||||||
|  | 
 | ||||||
|  |     switch (k.type) { | ||||||
|  |         default: callback = nullptr; break; | ||||||
|  |         case VTYPE_STRING: callback = (void*)string_free; break; | ||||||
|  |         case  VTYPE_ARRAY: callback = (void*)array_free;  break; | ||||||
|  |         case   VTYPE_LIST: callback = (void*)list_free;   break; | ||||||
|  |         case    VTYPE_MAP: callback = (void*)map_free;    break; | ||||||
|  |         case    VTYPE_SET: callback = (void*)vset_free;   break; | ||||||
|  |         case   VTYPE_DICT: callback = (void*)dict_free;   break; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     map_init(&x, k.type); | ||||||
|  | 
 | ||||||
|  |     while(n--) { | ||||||
|  |         value_t v = (!embd) ? random_value2() : real_random_value(1); | ||||||
|  | 
 | ||||||
|  |         libcdsb_map_update(&x, k.value, k.type, v.value, v.type); | ||||||
|  | 
 | ||||||
|  |         if (callback) callback(k.value); | ||||||
|  | 
 | ||||||
|  |         switch (v.type) { | ||||||
|  |             default: break; | ||||||
|  |             case VTYPE_STRING: string_free((void*)v.value); break; | ||||||
|  |             case  VTYPE_ARRAY: array_free ((void*)v.value); break; | ||||||
|  |             case   VTYPE_LIST: list_free  ((void*)v.value); break; | ||||||
|  |             case    VTYPE_MAP: map_free   ((void*)v.value); break; | ||||||
|  |             case    VTYPE_SET: vset_free  ((void*)v.value); break; | ||||||
|  |             case   VTYPE_DICT: dict_free  ((void*)v.value); break; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         k = random_value_by_type(k.type, 1); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (callback) callback(k.value); | ||||||
|  |     return x; | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static dict_t random_dict(bool embd) { | ||||||
|  |     dict_t  x; | ||||||
|  |     value_t k, v; | ||||||
|  |     size_t  n = random_uint16()%((!embd)?MAX_ELEMENTS:100); | ||||||
|  | 
 | ||||||
|  |     dict_init(&x); | ||||||
|  | 
 | ||||||
|  |     while(n--) { | ||||||
|  |         k = (!embd) ? random_value2() : real_random_value(1); | ||||||
|  |         v = (!embd) ? random_value2() : real_random_value(1); | ||||||
|  |         libcdsb_dict_update(&x, k.value, k.type, v.value, v.type); | ||||||
|  | 
 | ||||||
|  |         switch (v.type) { | ||||||
|  |             default: break; | ||||||
|  |             case VTYPE_STRING: string_free((void*)v.value); break; | ||||||
|  |             case  VTYPE_ARRAY: array_free ((void*)v.value); break; | ||||||
|  |             case   VTYPE_LIST: list_free  ((void*)v.value); break; | ||||||
|  |             case    VTYPE_MAP: map_free   ((void*)v.value); break; | ||||||
|  |             case    VTYPE_SET: vset_free  ((void*)v.value); break; | ||||||
|  |             case   VTYPE_DICT: dict_free  ((void*)v.value); break; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         switch (k.type) { | ||||||
|  |             default: break; | ||||||
|  |             case VTYPE_STRING: string_free((void*)k.value); break; | ||||||
|  |             case  VTYPE_ARRAY: array_free ((void*)k.value); break; | ||||||
|  |             case   VTYPE_LIST: list_free  ((void*)k.value); break; | ||||||
|  |             case    VTYPE_MAP: map_free   ((void*)k.value); break; | ||||||
|  |             case    VTYPE_SET: vset_free  ((void*)k.value); break; | ||||||
|  |             case   VTYPE_DICT: dict_free  ((void*)k.value); break; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return x; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | value_t random_container(bool embd) { | ||||||
|  |     value_t v; | ||||||
|  | 
 | ||||||
|  |     switch (random_uint8()%5) { | ||||||
|  |         default: | ||||||
|  |         case  0: v.value[0].a  = random_array(embd); v.type = VTYPE_ARRAY;  break; | ||||||
|  |         case  1: v.value[0].m  = random_map  (embd); v.type = VTYPE_MAP;    break; | ||||||
|  |         case  2: v.value[0].vd = random_dict (embd); v.type = VTYPE_DICT;   break; | ||||||
|  |         case  3: v.value[0].l  = random_list (embd); v.type = VTYPE_LIST;   break; | ||||||
|  |         case  4: v.value[0].vs = random_set  (embd); v.type = VTYPE_SET;    break; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return v; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | value_t real_random_value(bool embd) { | ||||||
|  |     return random_boolean() ? random_value2() : random_container(embd); | ||||||
|  | } | ||||||
							
								
								
									
										23
									
								
								tests/src/list/main.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								tests/src/list/main.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,23 @@ | |||||||
|  | /* This software is licensed by the MIT License, see LICENSE file */ | ||||||
|  | /*                                Copyright © 2022 Gregory Lirent */ | ||||||
|  | 
 | ||||||
|  | #include "plug.h" | ||||||
|  | 
 | ||||||
|  | int main(int argc, char** argv) { | ||||||
|  |     test_init(argc, argv); | ||||||
|  | 
 | ||||||
|  |     list_t x = { .first = 0, .last = 0 }; | ||||||
|  |     list_t y = { .first = 0, .last = 0 }; | ||||||
|  | 
 | ||||||
|  |     visual_push(&x, (random_uint8()%9) + 8); | ||||||
|  |     visual_slice(&x, &y); | ||||||
|  | 
 | ||||||
|  |     visual_push2(&x, (random_uint8()%5) + 12, &y, (random_uint8()%3) + 6); | ||||||
|  |     visual_extend(&x, &y); | ||||||
|  | 
 | ||||||
|  |     visual_sort2(&x, &y); | ||||||
|  |     visual_remove2(&x, &y); | ||||||
|  | 
 | ||||||
|  |     list_free(&y); | ||||||
|  |     list_free(&y); | ||||||
|  | } | ||||||
							
								
								
									
										26
									
								
								tests/src/list/plug.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								tests/src/list/plug.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,26 @@ | |||||||
|  | /* This software is licensed by the MIT License, see LICENSE file */ | ||||||
|  | /*                                Copyright © 2022 Gregory Lirent */ | ||||||
|  | 
 | ||||||
|  | #include "../../../include/extra/list.h" | ||||||
|  | 
 | ||||||
|  | #include "../../include/random.h" | ||||||
|  | #include "../../include/test.h" | ||||||
|  | #include "../../include/time.h" | ||||||
|  | 
 | ||||||
|  | #include "../../../src/__internal/vnode.h" | ||||||
|  | 
 | ||||||
|  | extern void list_print(list_t* x, const char* prefix, unsigned int hpos); | ||||||
|  | extern void list_info (list_t* x, unsigned int hpos); | ||||||
|  | 
 | ||||||
|  | extern void list_push_random(list_t* x, _Bool silent, unsigned int hpos); | ||||||
|  | extern void list_remove_random(list_t* x, _Bool silent, unsigned int hpos); | ||||||
|  | 
 | ||||||
|  | extern void visual_push(list_t* x, size_t n); | ||||||
|  | extern void visual_sort(list_t* x); | ||||||
|  | extern void visual_remove(list_t* x); | ||||||
|  | 
 | ||||||
|  | extern void visual_push2(list_t* x0, size_t n0, list_t* x1, size_t n1); | ||||||
|  | extern void visual_remove2(list_t* x0, list_t* x1); | ||||||
|  | extern void visual_sort2(list_t* x0, list_t* x1); | ||||||
|  | extern void visual_extend(list_t* x, list_t* s); | ||||||
|  | extern void visual_slice(list_t* x, list_t* s); | ||||||
							
								
								
									
										222
									
								
								tests/src/list/src/io.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										222
									
								
								tests/src/list/src/io.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,222 @@ | |||||||
|  | /* This software is licensed by the MIT License, see LICENSE file */ | ||||||
|  | /*                                Copyright © 2022 Gregory Lirent */ | ||||||
|  | 
 | ||||||
|  | #include "../plug.h" | ||||||
|  | 
 | ||||||
|  | static int list_node_print(void* v, ssize_t i, vtype t, void* _) { | ||||||
|  |     print_container_value(&i, v, t, 1, *(unsigned int*)_); | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void list_print(list_t* x, const char* prefix, unsigned int hpos) { | ||||||
|  |     print_container_values_prefix("List", prefix, hpos); | ||||||
|  |     list_foreach(x, &hpos, list_node_print); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void list_info(list_t* x, unsigned int hpos) { | ||||||
|  |     print_container_info("List", "nodes", 0, list_size(x), -1, hpos); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void visual_push(list_t* x, size_t n) { | ||||||
|  |     for (int i = 0; i < n; ++i) { | ||||||
|  |         fputs("\e[s", stdout); | ||||||
|  | 
 | ||||||
|  |         list_push_random(x, 0, 0); | ||||||
|  | 
 | ||||||
|  |         list_info(x, 0); | ||||||
|  |         list_print(x, 0, 0); | ||||||
|  | 
 | ||||||
|  |         psleep(100000); | ||||||
|  |         fputs("\e[u\e[J", stdout); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void visual_sort(list_t* x) { | ||||||
|  |     puts("\e[s\e[36mTry to sort list values:\e[m\n\n"); | ||||||
|  |     put_separator(0); | ||||||
|  |     list_sort(x); | ||||||
|  |     list_info(x, 0); | ||||||
|  |     list_print(x, "sorted", 0); | ||||||
|  |     psleep(900000); | ||||||
|  |     fputs("\e[u\e[J", stdout); | ||||||
|  | 
 | ||||||
|  |     puts("\e[s\e[36mTry to reverse list values:\e[m\n\n"); | ||||||
|  |     put_separator(0); | ||||||
|  |     list_reverse(x); | ||||||
|  |     list_info(x, 0); | ||||||
|  |     list_print(x, "reversed", 0); | ||||||
|  |     psleep(900000); | ||||||
|  |     fputs("\e[u\e[J", stdout); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void visual_remove(list_t* x) { | ||||||
|  |     while (x->first) { | ||||||
|  |         fputs("\e[s", stdout); | ||||||
|  |         list_remove_random(x, 0, 0); | ||||||
|  |         list_info(x, 0); | ||||||
|  |         list_print(x, 0, 0); | ||||||
|  | 
 | ||||||
|  |         psleep(100000); | ||||||
|  |         fputs("\e[u\e[J", stdout); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void visual_push2(list_t* x0, size_t n0, list_t* x1, size_t n1) { | ||||||
|  | 
 | ||||||
|  |     for (;n0 || n1;) { | ||||||
|  |         fputs("\e[s", stdout); | ||||||
|  |         if (n0) { | ||||||
|  |             list_push_random(x0, 0, 0); | ||||||
|  |             --n0; | ||||||
|  |         } else { | ||||||
|  |             puts("\n\n"); | ||||||
|  |             put_separator(0); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         fputs("\e[u\e[s", stdout); | ||||||
|  | 
 | ||||||
|  |         if (n1) { | ||||||
|  |             list_push_random(x1, 0, 60); | ||||||
|  |             --n1; | ||||||
|  |         } else { | ||||||
|  |             puts("\n\n"); | ||||||
|  |             put_separator(60); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         list_info(x0, 0); | ||||||
|  |         list_print(x0, 0, 0); | ||||||
|  |         fputs("\e[u\e[s\e[4E", stdout); | ||||||
|  |         list_info(x1, 60); | ||||||
|  |         list_print(x1, 0, 60); | ||||||
|  |         psleep(100000); | ||||||
|  | 
 | ||||||
|  |         fputs("\e[u\e[J", stdout); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void visual_remove2(list_t* x0, list_t* x1) { | ||||||
|  | 
 | ||||||
|  |     for (;x0->first || x1->first;) { | ||||||
|  |         fputs("\e[s", stdout); | ||||||
|  | 
 | ||||||
|  |         if (x0->first) { | ||||||
|  |             list_remove_random(x0, 0, 0); | ||||||
|  |         } else { | ||||||
|  |             puts("\n\n"); | ||||||
|  |             put_separator(0); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         fputs("\e[u\e[s", stdout); | ||||||
|  | 
 | ||||||
|  |         if (x1->first) { | ||||||
|  |             list_remove_random(x1, 0, 60); | ||||||
|  |         } else { | ||||||
|  |             puts("\n\n"); | ||||||
|  |             put_separator(60); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         list_info(x0, 0); | ||||||
|  |         list_print(x0, 0, 0); | ||||||
|  |         fputs("\e[u\e[s\e[4E", stdout); | ||||||
|  |         list_info(x1, 60); | ||||||
|  |         list_print(x1, 0, 60); | ||||||
|  |         psleep(100000); | ||||||
|  | 
 | ||||||
|  |         fputs("\e[u\e[J", stdout); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | void visual_sort2(list_t* x0, list_t* x1) { | ||||||
|  |     printf("\e[s\e[36m%-60s%s\e[m\n\n","Try to sort list values:", "Try to sort list values:"); | ||||||
|  |     printf("\e[32;1m%-60s%s\e[m\n", "SUCCESS", "SUCCESS"); | ||||||
|  |     printf("\e[37;2m%-60s%s\e[m\n", "=== === === === === === === ===", "=== === === === === === === ==="); | ||||||
|  | 
 | ||||||
|  |     list_sort(x0); | ||||||
|  |     list_sort(x1); | ||||||
|  | 
 | ||||||
|  |     list_info(x0, 0); | ||||||
|  |     list_print(x0, "sorted", 0); | ||||||
|  |     fputs("\e[u\e[s\e[4E", stdout); | ||||||
|  |     list_info(x1, 60); | ||||||
|  |     list_print(x1, "sorted", 60); | ||||||
|  | 
 | ||||||
|  |     psleep(900000); | ||||||
|  |     fputs("\e[u\e[J", stdout); | ||||||
|  | 
 | ||||||
|  |     printf("\e[s\e[36m%-60s%s\e[m\n\n","Try to reverse list values:", "Try to reverse list values:"); | ||||||
|  |     printf("\e[32;1m%-60s%s\e[m\n", "SUCCESS", "SUCCESS"); | ||||||
|  |     printf("\e[37;2m%-60s%s\e[m\n", "=== === === === === === === ===", "=== === === === === === === ==="); | ||||||
|  | 
 | ||||||
|  |     list_reverse(x0); | ||||||
|  |     list_reverse(x1); | ||||||
|  | 
 | ||||||
|  |     list_info(x0, 0); | ||||||
|  |     list_print(x0, "reversed", 0); | ||||||
|  |     fputs("\e[u\e[s\e[4E", stdout); | ||||||
|  |     list_info(x1, 60); | ||||||
|  |     list_print(x1, "reversed", 60); | ||||||
|  | 
 | ||||||
|  |     psleep(900000); | ||||||
|  |     fputs("\e[u\e[J", stdout); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void visual_extend(list_t* x, list_t* s) { | ||||||
|  | 
 | ||||||
|  |     puts("\e[s\e[36mTry to extend list:\e[m\n\n"); | ||||||
|  |     printf("\e[37;2m%-60s%s\e[m\n", "=== === === === === === === ===", "=== === === === === === === ==="); | ||||||
|  | 
 | ||||||
|  |     list_info(x, 0); | ||||||
|  |     list_print(x, "(dest)", 0); | ||||||
|  |     fputs("\e[u\e[s\e[4E", stdout); | ||||||
|  |     list_info(s, 60); | ||||||
|  |     list_print(s, "(src)", 60); | ||||||
|  | 
 | ||||||
|  |     psleep(900000); | ||||||
|  |     fputs("\e[u\e[s\e[2E\e[32;1mSUCCESS\e[m\e[J", stdout); | ||||||
|  | 
 | ||||||
|  |     list_extend(x, s); | ||||||
|  | 
 | ||||||
|  |     puts(""); | ||||||
|  |     put_separator(0); | ||||||
|  | 
 | ||||||
|  |     list_info(x, 0); | ||||||
|  |     list_print(x, "(dest)", 0); | ||||||
|  |     psleep(900000); | ||||||
|  |     fputs("\e[u\e[J", stdout); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | void visual_slice(list_t* x, list_t* s) { | ||||||
|  | 
 | ||||||
|  |     size_t  n = list_size(x); | ||||||
|  |     ssize_t i = random_uint64()%(n - 1); | ||||||
|  | 
 | ||||||
|  |     n = n - (i + 1); | ||||||
|  | 
 | ||||||
|  |     puts("\e[s\e[36mTry to slice list:\e[m\n\n"); | ||||||
|  |     printf("\e[37;2m%-60s%s\e[m\n", "=== === === === === === === ===", "=== === === === === === === ==="); | ||||||
|  | 
 | ||||||
|  |     list_info(x, 0); | ||||||
|  |     list_print(x, "(src)", 0); | ||||||
|  |     fputs("\e[u\e[s\e[4E", stdout); | ||||||
|  |     list_info(s, 60); | ||||||
|  |     list_print(s, "(dest)", 60); | ||||||
|  | 
 | ||||||
|  |     psleep(900000); | ||||||
|  | 
 | ||||||
|  |     list_slice(s, x, i, n, 1); | ||||||
|  |     fputs("\e[u\e[s\e[2E\e[32;1mSUCCESS\e[m\e[J", stdout); | ||||||
|  | 
 | ||||||
|  |     puts(""); | ||||||
|  |     put_separator(0); | ||||||
|  | 
 | ||||||
|  |     list_info(x, 0); | ||||||
|  |     list_print(x, "(src)", 0); | ||||||
|  |     fputs("\e[u\e[s\e[4E", stdout); | ||||||
|  |     list_info(s, 60); | ||||||
|  |     list_print(s, "(dest)", 60); | ||||||
|  |     psleep(900000); | ||||||
|  | 
 | ||||||
|  |     fputs("\e[u\e[J", stdout); | ||||||
|  | } | ||||||
							
								
								
									
										29
									
								
								tests/src/list/src/plug.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								tests/src/list/src/plug.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,29 @@ | |||||||
|  | /* This software is licensed by the MIT License, see LICENSE file */ | ||||||
|  | /*                                Copyright © 2022 Gregory Lirent */ | ||||||
|  | 
 | ||||||
|  | #include "../../../../src/__internal/include.h" | ||||||
|  | #include "../../../include/random.h" | ||||||
|  | 
 | ||||||
|  | vtype_string* string_duplicate(const vtype_string* x) { return 0; } | ||||||
|  | vtype_array*  array_duplicate (const vtype_array*  x) { return 0; } | ||||||
|  | vtype_map*    map_duplicate   (const vtype_map*    x) { return 0; } | ||||||
|  | vtype_set*    vset_duplicate  (const vtype_set*    x) { return 0; } | ||||||
|  | vtype_dict*   dict_duplicate  (const vtype_dict*   x) { return 0; } | ||||||
|  | 
 | ||||||
|  | void string_free(vtype_string* x) {} | ||||||
|  | void array_free (vtype_array*  x) {} | ||||||
|  | void map_free   (vtype_map*    x) {} | ||||||
|  | void vset_free  (vtype_set*    x) {} | ||||||
|  | void dict_free  (vtype_dict*   x) {} | ||||||
|  | 
 | ||||||
|  | int string_compare(const vtype_string* s0, const vtype_string* s1) { return random_int8(); } | ||||||
|  | int array_compare (const vtype_array*  s0, const vtype_array*  s1) { return random_int8(); } | ||||||
|  | int map_compare   (const vtype_map*    s0, const vtype_map*    s1) { return random_int8(); } | ||||||
|  | int vset_compare  (const vtype_set*    s0, const vtype_set*    s1) { return random_int8(); } | ||||||
|  | int dict_compare  (const vtype_dict*   s0, const vtype_dict*   s1) { return random_int8(); } | ||||||
|  | 
 | ||||||
|  | hash_t string_hash(const vtype_string* s) { return 0; } | ||||||
|  | hash_t array_hash (const vtype_array*  s) { return 0; } | ||||||
|  | hash_t map_hash   (const vtype_map*    s) { return 0; } | ||||||
|  | hash_t vset_hash  (const vtype_set*    s) { return 0; } | ||||||
|  | hash_t dict_hash  (const vtype_dict*   s) { return 0; } | ||||||
							
								
								
									
										82
									
								
								tests/src/list/src/random.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								tests/src/list/src/random.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,82 @@ | |||||||
|  | /* This software is licensed by the MIT License, see LICENSE file */ | ||||||
|  | /*                                Copyright © 2022 Gregory Lirent */ | ||||||
|  | 
 | ||||||
|  | #include "../plug.h" | ||||||
|  | 
 | ||||||
|  | static int remove_callback(void* v, ssize_t i, vtype t, void* _) { | ||||||
|  |     struct { list_t* x; _Bool s; unsigned int p; } *x = _; | ||||||
|  |     if (!x->s) { | ||||||
|  |         print_container_value(0, v, t, 1, x->p); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (libcdsb_list_find(x->x, v, t, 0, 0, 1, 1)) { | ||||||
|  |         return -2; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | void list_push_random(list_t* x, _Bool silent, unsigned int hpos) { | ||||||
|  | 
 | ||||||
|  |     value_t v = random_value(); | ||||||
|  |     _Bool   r; | ||||||
|  | 
 | ||||||
|  |     if (random_boolean()) { | ||||||
|  |         if (!silent) { | ||||||
|  |             printf("\e[%dG\e[36mTry to push value to back of the list:\e[m\n", hpos+1); | ||||||
|  |         } | ||||||
|  |         r = libcdsb_list_update(x, -1, v.value, v.type,  1); | ||||||
|  |     } else if (random_boolean()) { | ||||||
|  |         if (!silent) { | ||||||
|  |             printf("\e[%dG\e[36mTry to push value to front of the list:\e[m\n", hpos+1); | ||||||
|  |         } | ||||||
|  |         r = libcdsb_list_update(x, -1, v.value, v.type,  1); | ||||||
|  |     } else { | ||||||
|  |         ssize_t i = list_size(x); | ||||||
|  |         i = random_uint64()% (i ? i : 1); | ||||||
|  |         if (random_boolean()) i = ~i + 1; | ||||||
|  | 
 | ||||||
|  |         if (!silent) { | ||||||
|  |             printf("\e[%dG\e[36mTry to change value with index \e[32;1m%ld\e[36m in the list:\e[m\n", hpos+1, i); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         r = libcdsb_list_update(x, i, v.value, v.type, 0); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (!silent) { | ||||||
|  |         print_container_value(0, v.value, v.type, 1, hpos); | ||||||
|  |         printf("\e[%dG%s\n", hpos+1, r ? "\e[32;1mSUCCESS\e[m" : "\e[31;1mFAILURE\e[m"); | ||||||
|  |         put_separator(hpos); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void list_remove_random(list_t* x, _Bool silent, unsigned int hpos) { | ||||||
|  | 
 | ||||||
|  |     size_t  n = list_size(x); | ||||||
|  |     ssize_t i = random_uint64()%n; | ||||||
|  | 
 | ||||||
|  |     if (random_boolean()) i = ~i + 1; | ||||||
|  | 
 | ||||||
|  |     if (random_boolean()) { | ||||||
|  |         if (!silent) { | ||||||
|  |             printf("\e[%dG\e[36mTry to remove value from list by index:\e[m\n", hpos+1); | ||||||
|  |             print_container_value(0, &i, (sizeof(ssize_t) == 8) ? VTYPE_INT64 : VTYPE_INT32, 0, hpos); | ||||||
|  |         } | ||||||
|  |         switch (list_remove_by_index(x, i)) { | ||||||
|  |             case  0: if (!silent) printf("\e[%dG\e[32;1mSUCCESS\e[m\n", hpos+1); break; | ||||||
|  |             default: if (!silent) printf("\e[%dG\e[32;1mFAILURE\e[m\n", hpos+1); break; | ||||||
|  |         } | ||||||
|  |     } else { | ||||||
|  |         struct { list_t* x; _Bool s; unsigned int p; } v = { .x = x, .s = silent, .p = hpos }; | ||||||
|  | 
 | ||||||
|  |         if (!silent) printf("\e[%dG\e[36mTry to remove value from list:\e[m\n", hpos+1); | ||||||
|  | 
 | ||||||
|  |         switch (libcdsb_list_get(x, i, &v, remove_callback, 0)) { | ||||||
|  |             case  0: if (!silent) printf("\e[%dG\e[32;1mSUCCESS\e[m\n", hpos+1); break; | ||||||
|  |             default: if (!silent) printf("\e[%dG\e[32;1mFAILURE\e[m\n", hpos+1); break; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (!silent) put_separator(hpos); | ||||||
|  | } | ||||||
							
								
								
									
										15
									
								
								tests/src/map/main.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								tests/src/map/main.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,15 @@ | |||||||
|  | /* This software is licensed by the MIT License, see LICENSE file */ | ||||||
|  | /*                                Copyright © 2022 Gregory Lirent */ | ||||||
|  | 
 | ||||||
|  | #include "plug.h" | ||||||
|  | 
 | ||||||
|  | int main(int argc, char** argv) { | ||||||
|  |     test_init(argc, argv); | ||||||
|  | 
 | ||||||
|  |     map_t x; | ||||||
|  | 
 | ||||||
|  |     map_init(&x, random_uint8()%VTYPE_LDOUBLE + 1); | ||||||
|  | 
 | ||||||
|  |     visual_push(&x, random_uint8()%17 + 16); | ||||||
|  |     visual_remove(&x); | ||||||
|  | } | ||||||
							
								
								
									
										18
									
								
								tests/src/map/plug.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								tests/src/map/plug.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,18 @@ | |||||||
|  | /* This software is licensed by the MIT License, see LICENSE file */ | ||||||
|  | /*                                Copyright © 2022 Gregory Lirent */ | ||||||
|  | 
 | ||||||
|  | #include "../../../src/map/include.h" | ||||||
|  | 
 | ||||||
|  | #include "../../include/random.h" | ||||||
|  | #include "../../include/test.h" | ||||||
|  | #include "../../include/time.h" | ||||||
|  | 
 | ||||||
|  | extern void map_push_random(map_t* x, _Bool silent, unsigned int hpos); | ||||||
|  | extern void map_remove_random(map_t* x, _Bool silent, unsigned int hpos); | ||||||
|  | 
 | ||||||
|  | extern void map_info(const map_t* x, unsigned int hpos); | ||||||
|  | extern void map_print(map_t* x, const char* prefix, unsigned int hpos); | ||||||
|  | extern void map_rbtree_print(map_t *x, const char* prefix, unsigned int hpos); | ||||||
|  | 
 | ||||||
|  | extern void visual_push(map_t* x, size_t n); | ||||||
|  | extern void visual_remove(map_t* x); | ||||||
							
								
								
									
										84
									
								
								tests/src/map/src/io.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								tests/src/map/src/io.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,84 @@ | |||||||
|  | /* This software is licensed by the MIT License, see LICENSE file */ | ||||||
|  | /*                                Copyright © 2022 Gregory Lirent */ | ||||||
|  | 
 | ||||||
|  | #include "../plug.h" | ||||||
|  | 
 | ||||||
|  | static int node_print_callback(const void* k, vtype kt, void* v, vtype vt, void* _) { | ||||||
|  |     print_container_value(0, k, kt, 0, *(unsigned int*)_); | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void rbtree_print(const mnode_t* s, vtype t, const char* ind, bool br, unsigned int hpos) { | ||||||
|  |     if (!ind) { | ||||||
|  |         ind = "\e[36m"; | ||||||
|  |         br  = 1; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     size_t n = strlen(ind); | ||||||
|  |     char x[n + 10]; | ||||||
|  | 
 | ||||||
|  |     if (mnode_is_empty(s)) return; | ||||||
|  | 
 | ||||||
|  |     memcpy(x, ind, n); | ||||||
|  |     memcpy(x + n, "     \0  ", 9); | ||||||
|  | 
 | ||||||
|  |     printf("\e[%dG%s", hpos+1, ind); | ||||||
|  | 
 | ||||||
|  |     if (br) { | ||||||
|  |         fputs("\e[m\e[36;1mR\e[m\e[36m────\e[m", stdout); | ||||||
|  |     } else { | ||||||
|  |         fputs("\e[m\e[36;1mL\e[m\e[36m────\e[m", stdout); | ||||||
|  |         memcpy(x + n, "│", 3); | ||||||
|  |         x[n + 5] = ' '; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fputs((s->colored) ? "\e[31;1m" : "\e[37m", stdout); | ||||||
|  |     printf("%s\e[m \e[36m:\e[m ", vnode_stringify(&s->key, t)); | ||||||
|  |     printf("\e[31m%s\e[m", vnode_stringify(&s->value, s->type)); | ||||||
|  |     printf(" \e[36m(\e[m\e[32;1m%s\e[m\e[36m)\e[m\n", vtype_name(s->type)); | ||||||
|  | 
 | ||||||
|  |     rbtree_print(s->left,  t, x, false, hpos); | ||||||
|  |     rbtree_print(s->right, t, x, true, hpos); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void map_print(map_t* x, const char* prefix, unsigned int hpos) { | ||||||
|  |     print_container_values_prefix("Map", prefix, 0); | ||||||
|  |     map_foreach(x, &hpos, node_print_callback); | ||||||
|  |     put_separator(0); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void map_info(const map_t* x, unsigned int hpos) { | ||||||
|  |     print_container_info("Map", "nodes", &x->type, map_size(x), -1, 0); | ||||||
|  |     put_separator(0); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void map_rbtree_print(map_t *x, const char* prefix, unsigned int hpos) { | ||||||
|  |     print_container_values_prefix("Map", prefix, 0); | ||||||
|  |     rbtree_print(x->root, x->type, 0, 0, hpos); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | void visual_push(map_t* x, size_t n) { | ||||||
|  |     while (n--) { | ||||||
|  |         fputs("\e[s", stdout); | ||||||
|  | 
 | ||||||
|  |         map_push_random(x, 0, 0); | ||||||
|  | 
 | ||||||
|  |         map_info(x, 0); | ||||||
|  |         map_rbtree_print(x, 0, 0); | ||||||
|  | 
 | ||||||
|  |         psleep(100000); | ||||||
|  |         fputs("\e[u\e[J", stdout); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void visual_remove(map_t* x) { | ||||||
|  |     while (!mnode_is_empty(x->root)) { | ||||||
|  |         fputs("\e[s", stdout); | ||||||
|  |         map_remove_random(x, 0, 0); | ||||||
|  |         map_info(x, 0); | ||||||
|  |         map_rbtree_print(x, 0, 0); | ||||||
|  |         psleep(100000); | ||||||
|  |         fputs("\e[u\e[J", stdout); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										29
									
								
								tests/src/map/src/plug.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								tests/src/map/src/plug.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,29 @@ | |||||||
|  | /* This software is licensed by the MIT License, see LICENSE file */ | ||||||
|  | /*                                Copyright © 2022 Gregory Lirent */ | ||||||
|  | 
 | ||||||
|  | #include "../../../../src/__internal/include.h" | ||||||
|  | #include "../../../include/random.h" | ||||||
|  | 
 | ||||||
|  | vtype_string* string_duplicate(const vtype_string* x) { return 0; } | ||||||
|  | vtype_array*  array_duplicate (const vtype_array*  x) { return 0; } | ||||||
|  | vtype_list*   list_duplicate  (const vtype_list*   x) { return 0; } | ||||||
|  | vtype_set*    vset_duplicate  (const vtype_set*    x) { return 0; } | ||||||
|  | vtype_dict*   dict_duplicate  (const vtype_dict*   x) { return 0; } | ||||||
|  | 
 | ||||||
|  | void string_free(vtype_string* x) {} | ||||||
|  | void array_free (vtype_array*  x) {} | ||||||
|  | void list_free  (vtype_list*   x) {} | ||||||
|  | void vset_free  (vtype_set*    x) {} | ||||||
|  | void dict_free  (vtype_dict*   x) {} | ||||||
|  | 
 | ||||||
|  | int string_compare(const vtype_string* s0, const vtype_string* s1) { return random_int8(); } | ||||||
|  | int array_compare (const vtype_array*  s0, const vtype_array*  s1) { return random_int8(); } | ||||||
|  | int list_compare  (const vtype_list*   s0, const vtype_list*   s1) { return random_int8(); } | ||||||
|  | int vset_compare  (const vtype_set*    s0, const vtype_set*    s1) { return random_int8(); } | ||||||
|  | int dict_compare  (const vtype_dict*   s0, const vtype_dict*   s1) { return random_int8(); } | ||||||
|  | 
 | ||||||
|  | hash_t string_hash(const vtype_string* s) { return 0; } | ||||||
|  | hash_t array_hash (const vtype_array*  s) { return 0; } | ||||||
|  | hash_t list_hash  (const vtype_list*   s) { return 0; } | ||||||
|  | hash_t vset_hash  (const vtype_set*    s) { return 0; } | ||||||
|  | hash_t dict_hash  (const vtype_dict*   s) { return 0; } | ||||||
							
								
								
									
										53
									
								
								tests/src/map/src/random.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								tests/src/map/src/random.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,53 @@ | |||||||
|  | /* This software is licensed by the MIT License, see LICENSE file */ | ||||||
|  | /*                                Copyright © 2022 Gregory Lirent */ | ||||||
|  | 
 | ||||||
|  | #include "../plug.h" | ||||||
|  | 
 | ||||||
|  | static int remove_callback(const void* k, vtype kt, void* v, vtype vt, void* _) { | ||||||
|  |     struct { size_t n; map_t* x; unsigned int hp; } *d = _; | ||||||
|  | 
 | ||||||
|  |     if (!d->n--) { | ||||||
|  |         print_container_value(0, k, kt, 0, d->hp); | ||||||
|  | 
 | ||||||
|  |         if (libcdsb_map_find(d->x, k, kt, 0, 0, 1) == 0) { | ||||||
|  |             printf("\e[%dG\e[32;1mSUCCESS\e[m\n", d->hp+1); | ||||||
|  |         } else printf("\e[%dG\e[31;1mFAILURE\e[m\n", d->hp+1); | ||||||
|  | 
 | ||||||
|  |         return -2; | ||||||
|  |     } | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void map_push_random(map_t* x, _Bool silent, unsigned int hpos) { | ||||||
|  | 
 | ||||||
|  |     value_t k = random_value(); | ||||||
|  |     value_t v = random_value(); | ||||||
|  | 
 | ||||||
|  |     if (!silent) { | ||||||
|  |         printf("\e[%dG\e[36mUpdate value in map (\e[m\e[32;1m%s\e[m\e[36m) with key:\e[m\n", hpos+1, vtype_name(x->type)); | ||||||
|  |         print_container_value(0, k.value, k.type, 1, hpos); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (libcdsb_map_update(x, k.value, k.type, v.value, v.type)) { | ||||||
|  |         if (!silent) printf("\e[%dG\e[33;1mCHANGE\e[m\n", hpos+1); | ||||||
|  |     } else if (!silent) printf("\e[%dG\e[32;1mINSERT\e[m\n", hpos+1); | ||||||
|  | 
 | ||||||
|  |     if (!silent) put_separator(0); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | void map_remove_random(map_t* x, _Bool silent, unsigned int hpos) { | ||||||
|  |     struct { size_t n; map_t* x; unsigned int hp; } d = { .n = map_size(x), .x = x, .hp = hpos }; | ||||||
|  | 
 | ||||||
|  |     if (!silent) | ||||||
|  |         printf("\e[%dG\e[36mTry to remove value from map (\e[m\e[32;1m%s\e[m\e[36m) by key:\e[m\n", hpos+1, libcdsb_vtype_name(x->type)); | ||||||
|  | 
 | ||||||
|  |     if (d.n) { | ||||||
|  |         d.n = random_uint32()%d.n; | ||||||
|  |         map_foreach(x, &d, remove_callback); | ||||||
|  |     } else if (!silent) { | ||||||
|  |         printf("\e[%dG\e[32;1m\nFAILURE\e[m\n", hpos+1); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (!silent) put_separator(hpos); | ||||||
|  | } | ||||||
							
								
								
									
										133
									
								
								tests/src/random.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										133
									
								
								tests/src/random.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,133 @@ | |||||||
|  | /* This software is licensed by the MIT License, see LICENSE file */ | ||||||
|  | /*                                Copyright © 2022 Gregory Lirent */ | ||||||
|  | 
 | ||||||
|  | #include <time.h> | ||||||
|  | #include <stdlib.h> | ||||||
|  | 
 | ||||||
|  | #include "../include/test.h" | ||||||
|  | #include "../include/random.h" | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | static void init(unsigned int seed) { | ||||||
|  |     if (!seed) seed = time(0); | ||||||
|  |     printf("\e[36mRandom module initialized with seed: \e[m\e[32m%u\n\e[m", seed); | ||||||
|  |     put_separator(0); | ||||||
|  |     srand(seed); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | int random_init(int argc, char** argv) { | ||||||
|  |     if (argc < 2) { | ||||||
|  |         init(0); | ||||||
|  |     } else init(atol(argv[1])); | ||||||
|  | 
 | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | vtype_bool random_boolean() { | ||||||
|  |     return rand()&1; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | vtype_float random_float() { | ||||||
|  |     if (rand()&1) { | ||||||
|  |         return ((vtype_float)random_uint16() / (vtype_float)random_int16()) * -1; | ||||||
|  |     } | ||||||
|  |     return (vtype_float)random_uint16() / (vtype_float)random_int16(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | vtype_double random_double() { | ||||||
|  |     if (rand()&1) { | ||||||
|  |         return ((vtype_double)random_uint32() / (vtype_double)random_int32()) * -1; | ||||||
|  |     } | ||||||
|  |     return (vtype_double)random_uint32() / (vtype_double)random_int32(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | vtype_ldouble random_ldouble() { | ||||||
|  |     if (rand()&1) { | ||||||
|  |         return ((vtype_ldouble)random_uint64() / (vtype_ldouble)random_int64()) * -1; | ||||||
|  |     } | ||||||
|  |     return (vtype_ldouble)random_uint64() / (vtype_ldouble)random_int64(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | vtype_int8 random_int8() { | ||||||
|  |     return random_uint8(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | vtype_int16 random_int16() { | ||||||
|  |     return random_uint16(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | vtype_int32 random_int32()  { | ||||||
|  |     return rand() | ((rand()&1) << 31); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | vtype_uint8  random_uint8()  { | ||||||
|  |     return rand() % 0x100; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | vtype_uint16 random_uint16() { | ||||||
|  |     return rand() % 0x10000; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | vtype_uint32 random_uint32() { | ||||||
|  |     return (rand()<<1) | (rand()&1); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | vtype_uint64 random_uint64() { | ||||||
|  |     return random_int32()  * random_int32(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | vtype_int64  random_int64() { | ||||||
|  |     return random_uint32() * random_uint32(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | char random_ascii_char() { | ||||||
|  |     return (rand()%0x5f) + 0x20; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | unsigned int random_unicode_symbol() { | ||||||
|  |     switch (rand()%20) { | ||||||
|  |         default: | ||||||
|  |         case  0: return (random_uint16()%0x005f) + 0x000020; | ||||||
|  |         case  1: return (random_uint16()%0x020f) + 0x0000a1; | ||||||
|  |         case  2: return (random_uint16()%0x01a8) + 0x000388; | ||||||
|  |         case  3: return (random_uint16()%0x0026) + 0x000531; | ||||||
|  |         case  4: return (random_uint16()%0x002a) + 0x000560; | ||||||
|  |         case  5: return (random_uint16()%0x00c6) + 0x001000; | ||||||
|  |         case  6: return (random_uint16()%0x0030) + 0x0010d0; | ||||||
|  |         case  7: return (random_uint16()%0x029d) + 0x001400; | ||||||
|  |         case  8: return (random_uint16()%0x0058) + 0x0016a0; | ||||||
|  |         case  9: return (random_uint16()%0x0074) + 0x001b80; | ||||||
|  |         case 10: return (random_uint16()%0x00f4) + 0x001d00; | ||||||
|  |         case 11: return (random_uint16()%0x0115) + 0x001e00; | ||||||
|  |         case 12: return (random_uint16()%0x008b) + 0x002100; | ||||||
|  |         case 13: return (random_uint16()%0x0297) + 0x002190; | ||||||
|  |         case 14: return (random_uint16()%0x0714) + 0x002460; | ||||||
|  |         case 15: return (random_uint16()%0x00b7) + 0x00a640; | ||||||
|  |         case 16: return (random_uint16()%0x0074) + 0x00a8e0; | ||||||
|  |         case 17: return (random_uint16()%0x009e) + 0x010400; | ||||||
|  |         case 18: return (random_uint16()%0x0137) + 0x010600; | ||||||
|  |         case 19: return (random_uint16()%0x03d8) + 0x01f300; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | value_t random_value() { | ||||||
|  |     value_t v; | ||||||
|  |     switch (random_uint8()%13) { | ||||||
|  |         default: | ||||||
|  |         case  0: v.value[0].b   = random_boolean(); v.type = VTYPE_BOOLEAN; break; | ||||||
|  |         case  1: v.value[0].u8  = random_uint8  (); v.type = VTYPE_UINT8;   break; | ||||||
|  |         case  2: v.value[0].u16 = random_uint16 (); v.type = VTYPE_UINT16;  break; | ||||||
|  |         case  3: v.value[0].u32 = random_uint32 (); v.type = VTYPE_UINT32;  break; | ||||||
|  |         case  4: v.value[0].u64 = random_uint64 (); v.type = VTYPE_UINT64;  break; | ||||||
|  |         case  5: v.value[0].u8  = random_int8   (); v.type = VTYPE_INT8;    break; | ||||||
|  |         case  6: v.value[0].u16 = random_int16  (); v.type = VTYPE_INT16;   break; | ||||||
|  |         case  7: v.value[0].u32 = random_int32  (); v.type = VTYPE_INT32;   break; | ||||||
|  |         case  8: v.value[0].u64 = random_int64  (); v.type = VTYPE_INT64;   break; | ||||||
|  |         case  9: v.value[0].f   = random_float  (); v.type = VTYPE_FLOAT;   break; | ||||||
|  |         case 10: v.value[0].d   = random_double (); v.type = VTYPE_DOUBLE;  break; | ||||||
|  |         case 11: v.value[0].ld  = random_ldouble(); v.type = VTYPE_LDOUBLE; break; | ||||||
|  |         case 12: v.value[0].ptr = (void*)(uintptr_t)random_uint64(); v.type = VTYPE_POINTER; break; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return v; | ||||||
|  | } | ||||||
							
								
								
									
										15
									
								
								tests/src/set/main.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								tests/src/set/main.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,15 @@ | |||||||
|  | /* This software is licensed by the MIT License, see LICENSE file */ | ||||||
|  | /*                                Copyright © 2022 Gregory Lirent */ | ||||||
|  | 
 | ||||||
|  | #include "plug.h" | ||||||
|  | 
 | ||||||
|  | int main(int argc, char** argv) { | ||||||
|  |     test_init(argc, argv); | ||||||
|  | 
 | ||||||
|  |     set_t x; | ||||||
|  | 
 | ||||||
|  |     vset_init(&x, random_uint8()%VTYPE_LDOUBLE + 1); | ||||||
|  | 
 | ||||||
|  |     visual_push(&x, random_uint8()%17 + 16); | ||||||
|  |     visual_remove(&x); | ||||||
|  | } | ||||||
							
								
								
									
										18
									
								
								tests/src/set/plug.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								tests/src/set/plug.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,18 @@ | |||||||
|  | /* This software is licensed by the MIT License, see LICENSE file */ | ||||||
|  | /*                                Copyright © 2022 Gregory Lirent */ | ||||||
|  | 
 | ||||||
|  | #include "../../../include/extra/set.h" | ||||||
|  | #include "../../../src/__internal/rbtree.h" | ||||||
|  | 
 | ||||||
|  | #include "../../include/random.h" | ||||||
|  | #include "../../include/test.h" | ||||||
|  | #include "../../include/time.h" | ||||||
|  | 
 | ||||||
|  | extern void vset_push_random(set_t* x, _Bool silent, unsigned int hpos); | ||||||
|  | extern void vset_remove_random(set_t* x, _Bool silent, unsigned int hpos); | ||||||
|  | 
 | ||||||
|  | extern void vset_print(set_t* x, const char* prefix, unsigned int hpos); | ||||||
|  | extern void vset_info(const set_t* x, unsigned int hpos); | ||||||
|  | extern void vset_rbtree_print(set_t *x, const char* prefix, unsigned int hpos); | ||||||
|  | extern void visual_push(set_t* x, size_t n); | ||||||
|  | extern void visual_remove(set_t* x); | ||||||
							
								
								
									
										82
									
								
								tests/src/set/src/io.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								tests/src/set/src/io.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,82 @@ | |||||||
|  | /* This software is licensed by the MIT License, see LICENSE file */ | ||||||
|  | /*                                Copyright © 2022 Gregory Lirent */ | ||||||
|  | 
 | ||||||
|  | #include "../plug.h" | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | static int node_print_callback(const void* v, vtype t, void* _) { | ||||||
|  |     print_container_value(0, v, t, 0, *(unsigned int*)_); | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void rbtree_print(const rbnode_t* s, vtype t, const char* ind, bool br, unsigned int hpos) { | ||||||
|  |     if (!ind) { | ||||||
|  |         ind = "\e[36m"; | ||||||
|  |         br  = 1; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     size_t n = strlen(ind); | ||||||
|  |     char x[n + 10]; | ||||||
|  | 
 | ||||||
|  |     if (rbnode_is_empty(s)) return; | ||||||
|  | 
 | ||||||
|  |     memcpy(x, ind, n); | ||||||
|  |     memcpy(x + n, "     \0  ", 9); | ||||||
|  | 
 | ||||||
|  |     printf("\e[%dG%s", hpos+1, ind); | ||||||
|  | 
 | ||||||
|  |     if (br) { | ||||||
|  |         fputs("\e[m\e[36;1mR\e[m\e[36m────\e[m", stdout); | ||||||
|  |     } else { | ||||||
|  |         fputs("\e[m\e[36;1mL\e[m\e[36m────\e[m", stdout); | ||||||
|  |         memcpy(x + n, "│", 3); | ||||||
|  |         x[n + 5] = ' '; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fputs((s->colored) ? "\e[31;1m" : "\e[37m", stdout); | ||||||
|  |     printf("%s\e[m \e[36m\e[m\n", vnode_stringify(&s->value, t)); | ||||||
|  | 
 | ||||||
|  |     rbtree_print(s->left,  t, x, false, hpos); | ||||||
|  |     rbtree_print(s->right, t, x, true, hpos); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void vset_print(set_t* x, const char* prefix, unsigned int hpos) { | ||||||
|  |     print_container_values_prefix("Set", prefix, 0); | ||||||
|  |     vset_foreach(x, &hpos, node_print_callback); | ||||||
|  |     put_separator(0); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void vset_info(const set_t* x, unsigned int hpos) { | ||||||
|  |     print_container_info("Set", "nodes", &x->type, vset_size(x), -1, 0); | ||||||
|  |     put_separator(0); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void vset_rbtree_print(set_t *x, const char* prefix, unsigned int hpos) { | ||||||
|  |     print_container_values_prefix("Set", prefix, 0); | ||||||
|  |     rbtree_print(x->root, x->type, 0, 0, hpos); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void visual_push(set_t* x, size_t n) { | ||||||
|  |     while (n--) { | ||||||
|  |         fputs("\e[s", stdout); | ||||||
|  | 
 | ||||||
|  |         vset_push_random(x, 0, 0); | ||||||
|  | 
 | ||||||
|  |         vset_info(x, 0); | ||||||
|  |         vset_rbtree_print(x, 0, 0); | ||||||
|  | 
 | ||||||
|  |         psleep(100000); | ||||||
|  |         fputs("\e[u\e[J", stdout); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void visual_remove(set_t* x) { | ||||||
|  |     while (!rbnode_is_empty(x->root)) { | ||||||
|  |         fputs("\e[s", stdout); | ||||||
|  |         vset_remove_random(x, 0, 0); | ||||||
|  |         vset_info(x, 0); | ||||||
|  |         vset_rbtree_print(x, 0, 0); | ||||||
|  |         psleep(100000); | ||||||
|  |         fputs("\e[u\e[J", stdout); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										29
									
								
								tests/src/set/src/plug.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								tests/src/set/src/plug.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,29 @@ | |||||||
|  | /* This software is licensed by the MIT License, see LICENSE file */ | ||||||
|  | /*                                Copyright © 2022 Gregory Lirent */ | ||||||
|  | 
 | ||||||
|  | #include "../../../../src/__internal/include.h" | ||||||
|  | #include "../../../include/random.h" | ||||||
|  | 
 | ||||||
|  | vtype_string* string_duplicate(const vtype_string* x) { return 0; } | ||||||
|  | vtype_array*  array_duplicate (const vtype_array*  x) { return 0; } | ||||||
|  | vtype_list*   list_duplicate  (const vtype_list*   x) { return 0; } | ||||||
|  | vtype_map*    map_duplicate   (const vtype_map*    x) { return 0; } | ||||||
|  | vtype_dict*   dict_duplicate  (const vtype_dict*   x) { return 0; } | ||||||
|  | 
 | ||||||
|  | void string_free(vtype_string* x) {} | ||||||
|  | void array_free (vtype_array*  x) {} | ||||||
|  | void list_free  (vtype_list*   x) {} | ||||||
|  | void map_free   (vtype_map*    x) {} | ||||||
|  | void dict_free  (vtype_dict*   x) {} | ||||||
|  | 
 | ||||||
|  | int string_compare(const vtype_string* s0, const vtype_string* s1) { return random_int8(); } | ||||||
|  | int array_compare (const vtype_array*  s0, const vtype_array*  s1) { return random_int8(); } | ||||||
|  | int list_compare  (const vtype_list*   s0, const vtype_list*   s1) { return random_int8(); } | ||||||
|  | int map_compare   (const vtype_map*    s0, const vtype_map*    s1) { return random_int8(); } | ||||||
|  | int dict_compare  (const vtype_dict*   s0, const vtype_dict*   s1) { return random_int8(); } | ||||||
|  | 
 | ||||||
|  | hash_t string_hash(const vtype_string* s) { return 0; } | ||||||
|  | hash_t array_hash (const vtype_array*  s) { return 0; } | ||||||
|  | hash_t list_hash  (const vtype_list*   s) { return 0; } | ||||||
|  | hash_t map_hash   (const vtype_map*    s) { return 0; } | ||||||
|  | hash_t dict_hash  (const vtype_dict*   s) { return 0; } | ||||||
							
								
								
									
										52
									
								
								tests/src/set/src/random.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								tests/src/set/src/random.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,52 @@ | |||||||
|  | /* This software is licensed by the MIT License, see LICENSE file */ | ||||||
|  | /*                                Copyright © 2022 Gregory Lirent */ | ||||||
|  | 
 | ||||||
|  | #include "../plug.h" | ||||||
|  | 
 | ||||||
|  | static int remove_callback(const void* v, vtype t, void* _) { | ||||||
|  |     struct { size_t n; set_t* x; unsigned int hp; } *d = _; | ||||||
|  | 
 | ||||||
|  |     if (!d->n--) { | ||||||
|  |         print_container_value(0, v, t, 0, d->hp); | ||||||
|  | 
 | ||||||
|  |         if (libcdsb_vset_find(d->x, v, t, 0, 0, 1) == 0) { | ||||||
|  |             printf("\e[%dG\e[32;1mSUCCESS\e[m\n", d->hp+1); | ||||||
|  |         } else printf("\e[%dG\e[31;1mFAILURE\e[m\n", d->hp+1); | ||||||
|  | 
 | ||||||
|  |         return -2; | ||||||
|  |     } | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void vset_push_random(set_t* x, _Bool silent, unsigned int hpos) { | ||||||
|  | 
 | ||||||
|  |     value_t v = random_value(); | ||||||
|  | 
 | ||||||
|  |     if (!silent) { | ||||||
|  |         printf("\e[%dG\e[36mUpdate value in set (\e[m\e[32;1m%s\e[m\e[36m):\e[m\n", hpos+1, vtype_name(x->type)); | ||||||
|  |         print_container_value(0, v.value, v.type, 1, hpos); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (libcdsb_vset_insert(x, v.value, v.type)) { | ||||||
|  |         if (!silent) printf("\e[%dG\e[32;1mSUCCESS\e[m\n", hpos+1); | ||||||
|  |     } else if (!silent) printf("\e[%dG\e[31;1mFAILURE\e[m\n", hpos+1); | ||||||
|  | 
 | ||||||
|  |     if (!silent) put_separator(0); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | void vset_remove_random(set_t* x, _Bool silent, unsigned int hpos) { | ||||||
|  |     struct { size_t n; set_t* x; unsigned int hp; } d = { .n = vset_size(x), .x = x, .hp = hpos }; | ||||||
|  | 
 | ||||||
|  |     if (!silent) | ||||||
|  |         printf("\e[%dG\e[36mTry to remove value from set (\e[m\e[32;1m%s\e[m\e[36m):\e[m\n", hpos+1, libcdsb_vtype_name(x->type)); | ||||||
|  | 
 | ||||||
|  |     if (d.n) { | ||||||
|  |         d.n = random_uint32()%d.n; | ||||||
|  |         vset_foreach(x, &d, remove_callback); | ||||||
|  |     } else if (!silent) { | ||||||
|  |         printf("\e[%dG\e[32;1m\nFAILURE\e[m\n", hpos+1); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (!silent) put_separator(hpos); | ||||||
|  | } | ||||||
							
								
								
									
										77
									
								
								tests/src/string/main.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								tests/src/string/main.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,77 @@ | |||||||
|  | /* This software is licensed by the MIT License, see LICENSE file */ | ||||||
|  | /*                                Copyright © 2022 Gregory Lirent */ | ||||||
|  | 
 | ||||||
|  | #include "plug.h" | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | int main(int argc, char** argv) { | ||||||
|  |     test_init(argc, argv); | ||||||
|  |     str_t x, y; | ||||||
|  |     int c = random_unicode_symbol(); | ||||||
|  | 
 | ||||||
|  |     fputs("\e[s", stdout); | ||||||
|  |     x = string_random(30); | ||||||
|  |     string_print(&x, "(part 1)"); | ||||||
|  | 
 | ||||||
|  |     string_concat(&x, '\n'); | ||||||
|  |     string_concat_random(&x, 30); | ||||||
|  | 
 | ||||||
|  |     { | ||||||
|  |         char* repl = random_utf8_cstring(30); | ||||||
|  |         void* hack = string_at(&x, 31); | ||||||
|  |         string_print((void*)&hack, "(part 2)"); | ||||||
|  |         string_print((void*)&repl, "(part 2 replaced)"); | ||||||
|  |         string_replace(&x, hack, repl, -1); | ||||||
|  |         free(repl); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     string_info(&x); | ||||||
|  |     string_print(&x, "concatenated"); | ||||||
|  | 
 | ||||||
|  |     do { | ||||||
|  |         string_replace_random(&x, 12); | ||||||
|  |     } while (string_size(&x) == string_nmemb(&x)); | ||||||
|  | 
 | ||||||
|  |     y = string_copy(&x); | ||||||
|  | 
 | ||||||
|  |     string_to_lower(&x); | ||||||
|  |     string_to_upper(&y); | ||||||
|  | 
 | ||||||
|  |     visual_compare(&x, &y); | ||||||
|  |     visual_case_compare(&x, &y); | ||||||
|  | 
 | ||||||
|  |     string_reverse(&y); | ||||||
|  |     string_capitalize(&y); | ||||||
|  | 
 | ||||||
|  |     string_print(&y, "reversed & capitalized"); | ||||||
|  | 
 | ||||||
|  |     string_free(&x); | ||||||
|  |     string_free(&y); | ||||||
|  | 
 | ||||||
|  |     psleep(900000); | ||||||
|  | 
 | ||||||
|  |     fputs("\e[u\e[J", stdout); | ||||||
|  | 
 | ||||||
|  |     x = string_random(12); | ||||||
|  | 
 | ||||||
|  |     string_align_center(&x, 30, 0); | ||||||
|  |     string_info(&x); | ||||||
|  |     string_print(&x, 0); | ||||||
|  | 
 | ||||||
|  |     string_trim_spaces(&x); | ||||||
|  |     string_info(&x); | ||||||
|  |     string_print(&x, "trimmed"); | ||||||
|  | 
 | ||||||
|  |     put_separator(0); | ||||||
|  |     string_align_center(&x, 30, c); | ||||||
|  |     string_info(&x); | ||||||
|  |     string_print(&x, 0); | ||||||
|  | 
 | ||||||
|  |     string_trim(&x, c); | ||||||
|  |     string_info(&x); | ||||||
|  |     string_print(&x, "trimmed"); | ||||||
|  | 
 | ||||||
|  |     psleep(900000); | ||||||
|  | 
 | ||||||
|  |     string_free(&x); | ||||||
|  | } | ||||||
							
								
								
									
										22
									
								
								tests/src/string/plug.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								tests/src/string/plug.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,22 @@ | |||||||
|  | /* This software is licensed by the MIT License, see LICENSE file */ | ||||||
|  | /*                                Copyright © 2022 Gregory Lirent */ | ||||||
|  | 
 | ||||||
|  | #include <stdlib.h> | ||||||
|  | #include "../../../modules/libunic/include.h" | ||||||
|  | #include "../../../include/extra/string.h" | ||||||
|  | 
 | ||||||
|  | #include "../../include/random.h" | ||||||
|  | #include "../../include/test.h" | ||||||
|  | #include "../../include/time.h" | ||||||
|  | 
 | ||||||
|  | extern char* random_ascii_cstring(size_t size); | ||||||
|  | extern char* random_utf8_cstring(size_t size); | ||||||
|  | extern void string_concat_random(str_t* x, unsigned int n); | ||||||
|  | extern void string_replace_random(str_t* x, unsigned int n); | ||||||
|  | 
 | ||||||
|  | extern void string_info(str_t* x); | ||||||
|  | extern void string_print(const str_t* x, const char* prefix); | ||||||
|  | extern str_t string_random(unsigned int n); | ||||||
|  | 
 | ||||||
|  | extern void visual_compare(const str_t* s0, const str_t* s1); | ||||||
|  | extern void visual_case_compare(const str_t* s0, const str_t* s1); | ||||||
							
								
								
									
										48
									
								
								tests/src/string/src/io.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								tests/src/string/src/io.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,48 @@ | |||||||
|  | /* This software is licensed by the MIT License, see LICENSE file */ | ||||||
|  | /*                                Copyright © 2022 Gregory Lirent */ | ||||||
|  | 
 | ||||||
|  | #include "../plug.h" | ||||||
|  | 
 | ||||||
|  | void string_info(str_t* x) { | ||||||
|  |     print_container_info("String", "utf8 chars", 0, string_size(x), string_nmemb(x), 0); | ||||||
|  |     put_separator(0); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void string_print(const str_t* x, const char* prefix) { | ||||||
|  |     if (prefix) { | ||||||
|  |         printf("\e[36m%s %s content:\e[m\n", "String", prefix); | ||||||
|  |     } else printf("\e[36m%s content:\e[m\n", "String"); | ||||||
|  | 
 | ||||||
|  |     printf("\e[33m\"%s\"\e[m\n", x->buffer); | ||||||
|  |     put_separator(0); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | str_t string_random(unsigned int n) { | ||||||
|  |     str_t x; | ||||||
|  | 
 | ||||||
|  |     if (random_boolean()) { | ||||||
|  |         x.buffer = random_utf8_cstring(n); | ||||||
|  |     } else x.buffer = random_ascii_cstring(n); | ||||||
|  | 
 | ||||||
|  |     return x; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void visual_compare(const str_t* s0, const str_t* s1) { | ||||||
|  |     int c = string_compare(s0, s1); | ||||||
|  |     char* m; | ||||||
|  |     if (c == 0) m = "=="; | ||||||
|  |     else m = (c < 0) ? "<" : ">"; | ||||||
|  | 
 | ||||||
|  |     puts("\e[36mStrings comparsion:\e[m\n"); | ||||||
|  |     printf("\e[33m\"%s\"\e[m \e[31m%s\e[m \e[33m\"%s\"\e[m\n", s0->buffer, m, s1->buffer); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void visual_case_compare(const str_t* s0, const str_t* s1) { | ||||||
|  |     int c = string_case_compare(s0, s1); | ||||||
|  |     char* m; | ||||||
|  |     if (c == 0) m = "=="; | ||||||
|  |     else m = (c < 0) ? "<" : ">"; | ||||||
|  | 
 | ||||||
|  |     puts("\e[36mStrings case insensitive comparsion:\e[m\n"); | ||||||
|  |     printf("\e[33m\"%s\"\e[m \e[31m%s\e[m \e[33m\"%s\"\e[m\n", s0->buffer, m, s1->buffer); | ||||||
|  | } | ||||||
							
								
								
									
										29
									
								
								tests/src/string/src/plug.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								tests/src/string/src/plug.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,29 @@ | |||||||
|  | /* This software is licensed by the MIT License, see LICENSE file */ | ||||||
|  | /*                                Copyright © 2022 Gregory Lirent */ | ||||||
|  | 
 | ||||||
|  | #include "../../../../src/__internal/include.h" | ||||||
|  | #include "../../../include/random.h" | ||||||
|  | 
 | ||||||
|  | vtype_array*  array_duplicate (const vtype_array*  x) { return 0; } | ||||||
|  | vtype_list*   list_duplicate  (const vtype_list*   x) { return 0; } | ||||||
|  | vtype_map*    map_duplicate   (const vtype_map*    x) { return 0; } | ||||||
|  | vtype_set*    vset_duplicate  (const vtype_set*    x) { return 0; } | ||||||
|  | vtype_dict*   dict_duplicate  (const vtype_dict*   x) { return 0; } | ||||||
|  | 
 | ||||||
|  | void array_free (vtype_array*  x) {} | ||||||
|  | void list_free  (vtype_list*   x) {} | ||||||
|  | void map_free   (vtype_map*    x) {} | ||||||
|  | void vset_free  (vtype_set*    x) {} | ||||||
|  | void dict_free  (vtype_dict*   x) {} | ||||||
|  | 
 | ||||||
|  | int array_compare (const vtype_array*  s0, const vtype_array*  s1) { return random_int8(); } | ||||||
|  | int list_compare  (const vtype_list*   s0, const vtype_list*   s1) { return random_int8(); } | ||||||
|  | int map_compare   (const vtype_map*    s0, const vtype_map*    s1) { return random_int8(); } | ||||||
|  | int vset_compare  (const vtype_set*    s0, const vtype_set*    s1) { return random_int8(); } | ||||||
|  | int dict_compare  (const vtype_dict*   s0, const vtype_dict*   s1) { return random_int8(); } | ||||||
|  | 
 | ||||||
|  | hash_t array_hash (const vtype_array*  s) { return 0; } | ||||||
|  | hash_t list_hash  (const vtype_list*   s) { return 0; } | ||||||
|  | hash_t map_hash   (const vtype_map*    s) { return 0; } | ||||||
|  | hash_t vset_hash  (const vtype_set*    s) { return 0; } | ||||||
|  | hash_t dict_hash  (const vtype_dict*   s) { return 0; } | ||||||
							
								
								
									
										51
									
								
								tests/src/string/src/random.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								tests/src/string/src/random.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,51 @@ | |||||||
|  | /* This software is licensed by the MIT License, see LICENSE file */ | ||||||
|  | /*                                Copyright © 2022 Gregory Lirent */ | ||||||
|  | 
 | ||||||
|  | #include "../plug.h" | ||||||
|  | 
 | ||||||
|  | char* random_ascii_cstring(size_t size) { | ||||||
|  |     char* v = malloc(size + 1); | ||||||
|  |     char* p = v; | ||||||
|  | 
 | ||||||
|  |     while (size--) { | ||||||
|  |         *(p++) = random_ascii_char(); | ||||||
|  |     } | ||||||
|  |     *p = 0; | ||||||
|  | 
 | ||||||
|  |     return v; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | char* random_utf8_cstring(size_t size) { | ||||||
|  |     char* v = malloc(size * 4 + 1); | ||||||
|  |     char* p = v; | ||||||
|  | 
 | ||||||
|  |     while (size--) { | ||||||
|  |         p = tochar_unicode(p, random_unicode_symbol()); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     *p = 0; | ||||||
|  |     return v; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void string_concat_random(str_t* x, unsigned int n) { | ||||||
|  |     char* v; | ||||||
|  | 
 | ||||||
|  |     if (random_boolean()) { | ||||||
|  |         v = random_utf8_cstring(n); | ||||||
|  |     } else v = random_ascii_cstring(n); | ||||||
|  | 
 | ||||||
|  |     string_concat(x, v); | ||||||
|  |     free(v); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void string_replace_random(str_t* x, unsigned int n) { | ||||||
|  |     char* v; | ||||||
|  | 
 | ||||||
|  |     if (random_boolean()) { | ||||||
|  |         v = random_utf8_cstring(n); | ||||||
|  |     } else v = random_ascii_cstring(n); | ||||||
|  | 
 | ||||||
|  |     string_replace(x, x, v, -1); | ||||||
|  | 
 | ||||||
|  |     free(v); | ||||||
|  | } | ||||||
							
								
								
									
										103
									
								
								tests/src/test.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										103
									
								
								tests/src/test.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,103 @@ | |||||||
|  | /* This software is licensed by the MIT License, see LICENSE file */ | ||||||
|  | /*                                Copyright © 2022 Gregory Lirent */ | ||||||
|  | 
 | ||||||
|  | #include <stdarg.h> | ||||||
|  | #include <string.h> | ||||||
|  | #include "../include/test.h" | ||||||
|  | #include "../include/time.h" | ||||||
|  | #include "../include/random.h" | ||||||
|  | 
 | ||||||
|  | static TIMER GLOBAL_TIMER; | ||||||
|  | static const char* TEST_NAME = 0; | ||||||
|  | 
 | ||||||
|  | static void test_uload() __attribute__((destructor)); | ||||||
|  | 
 | ||||||
|  | static void test_uload() { | ||||||
|  |     if (TEST_NAME) { | ||||||
|  |         timer_stop(&GLOBAL_TIMER); | ||||||
|  |         puts(""); | ||||||
|  |         put_separator(0); | ||||||
|  |         printf("\e[36mTest \"\e[m\e[32;1m%s\e[m\e[36m\" is end.\nExecusion time: \e[m\e[32m%.6Lf sec\e[m\n", TEST_NAME, timer_value(&GLOBAL_TIMER)); | ||||||
|  |         put_separator(0); | ||||||
|  |         timer_free(&GLOBAL_TIMER); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void test_init(int argc, char** argv) { | ||||||
|  |     timer_init(&GLOBAL_TIMER); | ||||||
|  |     timer_start(&GLOBAL_TIMER); | ||||||
|  | 
 | ||||||
|  |     TEST_NAME = strrchr(argv[0], '/') ? strrchr(argv[0], '/') + 1 : argv[0]; | ||||||
|  | 
 | ||||||
|  |     put_separator(0); | ||||||
|  |     printf("\e[H\e[J\e[36mTest \"\e[m\e[32;1m%s\e[m\e[36m\" is loaded\e[m\n", TEST_NAME); | ||||||
|  |     put_separator(0); | ||||||
|  | 
 | ||||||
|  |     random_init(argc, argv); | ||||||
|  | 
 | ||||||
|  |     puts(""); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void hp_printf(unsigned int hpos, const char* format, ...) { | ||||||
|  |     va_list args; | ||||||
|  | 
 | ||||||
|  |     va_start(args, format); | ||||||
|  |     vprintf(format, args); | ||||||
|  | 
 | ||||||
|  |     printf("\e[%dG", hpos+1); | ||||||
|  | 
 | ||||||
|  |     vprintf(format, args); | ||||||
|  |     va_end(args); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | void put_separator(unsigned int hpos) { | ||||||
|  |     printf("\e[%dG\e[37;2m=== === === === === === === ===\e[m\n", hpos+1); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void print_container_values_prefix(const char* name, const char* prefix, unsigned int hpos) { | ||||||
|  |     if (prefix) { | ||||||
|  |         printf("\e[%dG\e[36m%s %s values:\e[m\n", hpos+1, name, prefix); | ||||||
|  |     } else { | ||||||
|  |         printf("\e[%dG\e[36m%s values:\e[m\n", hpos+1, name); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void print_container_value(const ssize_t* index, const void* value, const vtype type, _Bool print_type, unsigned int hpos) { | ||||||
|  |     if (index) { | ||||||
|  |         printf("\e[%dG\e[32;1m%5ld: \e[m", hpos+1, *index); | ||||||
|  |     } else { | ||||||
|  |         printf("\e[%dG       ", hpos+1); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     printf("\e[31m%24s\e[m", libcdsb_vtype_stringify(value, type)); | ||||||
|  | 
 | ||||||
|  |     if (print_type) { | ||||||
|  |         printf(" \e[36m(\e[m\e[32;1m%s\e[m\e[36m)\e[m", libcdsb_vtype_name(type)); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     puts(""); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void print_container_info(const char* name, const char* el_name, const vtype* type, ssize_t size, ssize_t nmemb, unsigned int hpos) { | ||||||
|  |     if (!el_name) el_name = "elements"; | ||||||
|  | 
 | ||||||
|  |     if (type) { | ||||||
|  |         printf("\e[%dG\e[36m%s initialized with type `\e[m\e[32;1m%s\e[m\e[36m`\n", hpos+1, name, libcdsb_vtype_name(*type)); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (size >= 0 || nmemb >= 0) { | ||||||
|  |         printf("\e[%dG\e[36m%s consists of \e[m", hpos+1, name); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (size >= 0) { | ||||||
|  |         printf("\e[32m%ld\e[m \e[36m%s", size, el_name); | ||||||
|  | 
 | ||||||
|  |         if (nmemb >= 0) { | ||||||
|  |             printf(" (\e[m\e[32m%ld bytes\e[m\e[36m)\e[m\n", nmemb); | ||||||
|  |         } else puts("\e[m"); | ||||||
|  | 
 | ||||||
|  |     } else if (nmemb >= 0) { | ||||||
|  |         printf("\e[32m%ld bytes\e[m\n", nmemb); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										122
									
								
								tests/src/time.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										122
									
								
								tests/src/time.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,122 @@ | |||||||
|  | /* This software is licensed by the MIT License, see LICENSE file */ | ||||||
|  | /*                                Copyright © 2022 Gregory Lirent */ | ||||||
|  | 
 | ||||||
|  | #include <stdlib.h> | ||||||
|  | #include <string.h> | ||||||
|  | #ifndef __USE_MISC | ||||||
|  | #define __USE_MISC | ||||||
|  | #endif | ||||||
|  | #include <unistd.h> | ||||||
|  | #include <sys/resource.h> | ||||||
|  | #include <sys/times.h> | ||||||
|  | #include "../include/time.h" | ||||||
|  | 
 | ||||||
|  | typedef struct timer_internal { | ||||||
|  |     struct rusage begin; | ||||||
|  |     struct rusage end; | ||||||
|  |     struct rusage br; | ||||||
|  |     unsigned long offset; | ||||||
|  |     struct { | ||||||
|  |         int isbr:1; | ||||||
|  |         int isend:1; | ||||||
|  |     }; | ||||||
|  | } TIMER_INFO; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | void timer_init(TIMER* timer) { | ||||||
|  |     TIMER_INFO *t; | ||||||
|  |     if (!(t = timer->info = malloc(sizeof(TIMER_INFO)))) | ||||||
|  |         abort(); | ||||||
|  |     memset(t, 0, sizeof(*t)); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void timer_start(TIMER* timer) { | ||||||
|  |     TIMER_INFO *t = timer->info; | ||||||
|  | 
 | ||||||
|  |     if (t->isend) | ||||||
|  |         return; | ||||||
|  | 
 | ||||||
|  |     if (t->isbr) { | ||||||
|  |         struct rusage br; | ||||||
|  | 
 | ||||||
|  |         if (getrusage(RUSAGE_SELF, &br) < 0) | ||||||
|  |             abort(); | ||||||
|  | 
 | ||||||
|  |         t->offset += br.ru_utime.tv_sec * 1000000 - t->br.ru_utime.tv_sec * 1000000; | ||||||
|  |         t->offset -= t->br.ru_utime.tv_usec; | ||||||
|  |         t->offset += br.ru_utime.tv_usec; | ||||||
|  | 
 | ||||||
|  |         memset(&t->br, 0, sizeof(t->br)); | ||||||
|  |         t->isbr = 0; | ||||||
|  |     } else if (getrusage(RUSAGE_SELF, &t->begin) < 0) | ||||||
|  |         abort(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void timer_pause (TIMER* timer) { | ||||||
|  |     TIMER_INFO *t = timer->info; | ||||||
|  | 
 | ||||||
|  |     if (t->isend) | ||||||
|  |         return; | ||||||
|  | 
 | ||||||
|  |     if (!t->isbr) { | ||||||
|  |         if (getrusage(RUSAGE_SELF, &t->br) < 0) | ||||||
|  |             abort(); | ||||||
|  | 
 | ||||||
|  |         t->isbr = 1; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void timer_stop (TIMER* timer) { | ||||||
|  |     TIMER_INFO *t = timer->info; | ||||||
|  | 
 | ||||||
|  |     if (t->isend) | ||||||
|  |         return; | ||||||
|  | 
 | ||||||
|  |     if (getrusage(RUSAGE_SELF, &t->end) < 0) | ||||||
|  |         abort(); | ||||||
|  | 
 | ||||||
|  |     if (t->isbr) { | ||||||
|  |         t->offset += t->end.ru_utime.tv_sec * 1000000 - t->br.ru_utime.tv_sec * 1000000; | ||||||
|  |         t->offset -= t->br.ru_utime.tv_usec; | ||||||
|  |         t->offset += t->end.ru_utime.tv_usec; | ||||||
|  | 
 | ||||||
|  |         memset(&t->br, 0, sizeof(t->br)); | ||||||
|  |         t->isbr = 0; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     t->isend = 1; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void timer_free (TIMER* timer) { | ||||||
|  |     free(timer->info); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | vtype_ldouble timer_value(TIMER* timer) { | ||||||
|  |     static char empty[sizeof(struct rusage)] = { 0 }; | ||||||
|  | 
 | ||||||
|  |     TIMER_INFO *t = timer->info; | ||||||
|  | 
 | ||||||
|  |     struct rusage _; | ||||||
|  |     struct rusage *end; | ||||||
|  |     vtype_ldouble value; | ||||||
|  | 
 | ||||||
|  |     if (memcmp(&t->begin, empty, sizeof(struct rusage)) == 0) { | ||||||
|  |         return 0; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (!t->isend) { | ||||||
|  |         if (getrusage(RUSAGE_SELF, end = &_) < 0) | ||||||
|  |             abort(); | ||||||
|  |     } else end = &t->end; | ||||||
|  | 
 | ||||||
|  |     value  = end->ru_utime.tv_sec * 1000000 - t->begin.ru_utime.tv_sec * 1000000; | ||||||
|  |     value -= t->begin.ru_utime.tv_usec; | ||||||
|  |     value += end->ru_utime.tv_usec; | ||||||
|  |     value -= t->offset; | ||||||
|  | 
 | ||||||
|  |     return value / 1000000; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void psleep(unsigned long microsec) { | ||||||
|  |     usleep(microsec); | ||||||
|  | } | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Gogs
							Gogs