diff --git a/examples/Makefile b/examples/Makefile new file mode 100644 index 0000000..2d99f6b --- /dev/null +++ b/examples/Makefile @@ -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 diff --git a/examples/array.c b/examples/array.c new file mode 100644 index 0000000..29108c4 --- /dev/null +++ b/examples/array.c @@ -0,0 +1,37 @@ +/* This software is licensed by the MIT License, see LICENSE file */ +/* Copyright © 2022 Gregory Lirent */ + +#include +#include +#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); +} diff --git a/examples/dict.c b/examples/dict.c new file mode 100644 index 0000000..1e548a4 --- /dev/null +++ b/examples/dict.c @@ -0,0 +1,61 @@ +/* This software is licensed by the MIT License, see LICENSE file */ +/* Copyright © 2022 Gregory Lirent */ + +#include +#include +#include +#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); +} diff --git a/examples/list.c b/examples/list.c new file mode 100644 index 0000000..449ba2d --- /dev/null +++ b/examples/list.c @@ -0,0 +1,51 @@ +/* This software is licensed by the MIT License, see LICENSE file */ +/* Copyright © 2022 Gregory Lirent */ + +#include +#include +#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); +} diff --git a/examples/map.c b/examples/map.c new file mode 100644 index 0000000..115dc2e --- /dev/null +++ b/examples/map.c @@ -0,0 +1,55 @@ +/* This software is licensed by the MIT License, see LICENSE file */ +/* Copyright © 2022 Gregory Lirent */ + +#include +#include +#include +#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); +} diff --git a/examples/set.c b/examples/set.c new file mode 100644 index 0000000..9b9b4d1 --- /dev/null +++ b/examples/set.c @@ -0,0 +1,38 @@ +/* This software is licensed by the MIT License, see LICENSE file */ +/* Copyright © 2022 Gregory Lirent */ + +#include +#include +#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); +} diff --git a/examples/string.c b/examples/string.c new file mode 100644 index 0000000..4072af5 --- /dev/null +++ b/examples/string.c @@ -0,0 +1,42 @@ +/* This software is licensed by the MIT License, see LICENSE file */ +/* Copyright © 2022 Gregory Lirent */ + +#include +#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); +} diff --git a/include/array.h b/include/array.h index 9e7dee1..5b6d177 100644 --- a/include/array.h +++ b/include/array.h @@ -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_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 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 in_array(x, value) (array_find(x, value, 0, 0) == 0) diff --git a/include/extra/set.h b/include/extra/set.h index 0b25cdb..42be364 100644 --- a/include/extra/set.h +++ b/include/extra/set.h @@ -8,9 +8,8 @@ #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 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 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_foreach(vtype_set* x, void* data, vset_access_callback, bool flush) Nonnull__(1,3); #endif /* LIBCDSB_EXTRA_SET_H */ diff --git a/include/set.h b/include/set.h index 2ea5c92..238c910 100644 --- a/include/set.h +++ b/include/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); -#define vset_remove(x, value) _LIBCDSB_Generic (libcdsb_vset, touch, value)(x, value, 1) -#define vset_push(x, value) _LIBCDSB_Generic (libcdsb_vset, push, value)(x, value) +#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 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_cstring(vtype_set* x, const char* value) Nonnull__(1,2); diff --git a/src/__internal/rbtree.h b/src/__internal/rbtree.h index c9db416..8564bc1 100644 --- a/src/__internal/rbtree.h +++ b/src/__internal/rbtree.h @@ -32,9 +32,9 @@ 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 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 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 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 void libcdsb_rbtree_free(void* x, void (*node_free)(void* x, void* info), void* info) Nonnull__(1); #define rbtree_duplicate libcdsb_rbtree_duplicate #define rbtree_compare libcdsb_rbtree_compare diff --git a/src/__internal/vnode.h b/src/__internal/vnode.h index c7a5d95..ad9a393 100644 --- a/src/__internal/vnode.h +++ b/src/__internal/vnode.h @@ -11,7 +11,7 @@ typedef union { void* ptr; bool b; 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; fl_t f; dbl_t d; ldbl_t ld; } var_t; diff --git a/src/dict/extra.c b/src/dict/extra.c index 8688703..5b4aba5 100644 --- a/src/dict/extra.c +++ b/src/dict/extra.c @@ -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); 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) { c = dnode_delete(x->nodes + index, c); diff --git a/src/extra-memory.c b/src/extra-memory.c index 72fdaab..0ff5783 100644 --- a/src/extra-memory.c +++ b/src/extra-memory.c @@ -55,6 +55,9 @@ char* libcdsb_strdup(const char* s) { void* x; size_t n; + if (is_null(s)) + return nullptr; + if ((x = malloc(n = strlen(s) + 1))) return memcpy(x, s, n); abort(); diff --git a/tests/Makefile b/tests/Makefile new file mode 100644 index 0000000..bb8f5ee --- /dev/null +++ b/tests/Makefile @@ -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 diff --git a/tests/include/random.h b/tests/include/random.h new file mode 100644 index 0000000..517c27b --- /dev/null +++ b/tests/include/random.h @@ -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 */ diff --git a/tests/include/test.h b/tests/include/test.h new file mode 100644 index 0000000..ac3d5e9 --- /dev/null +++ b/tests/include/test.h @@ -0,0 +1,17 @@ +/* This software is licensed by the MIT License, see LICENSE file */ +/* Copyright © 2022 Gregory Lirent */ + +#include +#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 */ diff --git a/tests/include/time.h b/tests/include/time.h new file mode 100644 index 0000000..0558e5c --- /dev/null +++ b/tests/include/time.h @@ -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 */ diff --git a/tests/src/array/main.c b/tests/src/array/main.c new file mode 100644 index 0000000..18b31fd --- /dev/null +++ b/tests/src/array/main.c @@ -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); +} diff --git a/tests/src/array/plug.h b/tests/src/array/plug.h new file mode 100644 index 0000000..f852e45 --- /dev/null +++ b/tests/src/array/plug.h @@ -0,0 +1,24 @@ +/* This software is licensed by the MIT License, see LICENSE file */ +/* Copyright © 2022 Gregory Lirent */ + +#include +#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); diff --git a/tests/src/array/src/io.c b/tests/src/array/src/io.c new file mode 100644 index 0000000..127eaec --- /dev/null +++ b/tests/src/array/src/io.c @@ -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); +} diff --git a/tests/src/array/src/plug.c b/tests/src/array/src/plug.c new file mode 100644 index 0000000..0ed9a6b --- /dev/null +++ b/tests/src/array/src/plug.c @@ -0,0 +1,36 @@ +/* This software is licensed by the MIT License, see LICENSE file */ +/* Copyright © 2022 Gregory Lirent */ + +#include +#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)); } diff --git a/tests/src/array/src/random.c b/tests/src/array/src/random.c new file mode 100644 index 0000000..4dcc8b7 --- /dev/null +++ b/tests/src/array/src/random.c @@ -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); +} diff --git a/tests/src/dict/main.c b/tests/src/dict/main.c new file mode 100644 index 0000000..e1b73dc --- /dev/null +++ b/tests/src/dict/main.c @@ -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); +} diff --git a/tests/src/dict/plug.h b/tests/src/dict/plug.h new file mode 100644 index 0000000..e6b73db --- /dev/null +++ b/tests/src/dict/plug.h @@ -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); diff --git a/tests/src/dict/src/io.c b/tests/src/dict/src/io.c new file mode 100644 index 0000000..d0c4336 --- /dev/null +++ b/tests/src/dict/src/io.c @@ -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); + } +} diff --git a/tests/src/dict/src/plug.c b/tests/src/dict/src/plug.c new file mode 100644 index 0000000..bb5545a --- /dev/null +++ b/tests/src/dict/src/plug.c @@ -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; } diff --git a/tests/src/dict/src/random.c b/tests/src/dict/src/random.c new file mode 100644 index 0000000..0218398 --- /dev/null +++ b/tests/src/dict/src/random.c @@ -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); +} diff --git a/tests/src/global/main.c b/tests/src/global/main.c new file mode 100644 index 0000000..6717c31 --- /dev/null +++ b/tests/src/global/main.c @@ -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; + } +} diff --git a/tests/src/global/plug.h b/tests/src/global/plug.h new file mode 100644 index 0000000..6b280eb --- /dev/null +++ b/tests/src/global/plug.h @@ -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); diff --git a/tests/src/global/src/io.c b/tests/src/global/src/io.c new file mode 100644 index 0000000..d7a5900 --- /dev/null +++ b/tests/src/global/src/io.c @@ -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); +} diff --git a/tests/src/global/src/random.c b/tests/src/global/src/random.c new file mode 100644 index 0000000..df0de0f --- /dev/null +++ b/tests/src/global/src/random.c @@ -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); +} diff --git a/tests/src/list/main.c b/tests/src/list/main.c new file mode 100644 index 0000000..71a3352 --- /dev/null +++ b/tests/src/list/main.c @@ -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); +} diff --git a/tests/src/list/plug.h b/tests/src/list/plug.h new file mode 100644 index 0000000..21c7aa5 --- /dev/null +++ b/tests/src/list/plug.h @@ -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); diff --git a/tests/src/list/src/io.c b/tests/src/list/src/io.c new file mode 100644 index 0000000..fb61586 --- /dev/null +++ b/tests/src/list/src/io.c @@ -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); +} diff --git a/tests/src/list/src/plug.c b/tests/src/list/src/plug.c new file mode 100644 index 0000000..7a32c0e --- /dev/null +++ b/tests/src/list/src/plug.c @@ -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; } diff --git a/tests/src/list/src/random.c b/tests/src/list/src/random.c new file mode 100644 index 0000000..5a4a1a9 --- /dev/null +++ b/tests/src/list/src/random.c @@ -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); +} diff --git a/tests/src/map/main.c b/tests/src/map/main.c new file mode 100644 index 0000000..d054ec0 --- /dev/null +++ b/tests/src/map/main.c @@ -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); +} diff --git a/tests/src/map/plug.h b/tests/src/map/plug.h new file mode 100644 index 0000000..da2aeed --- /dev/null +++ b/tests/src/map/plug.h @@ -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); diff --git a/tests/src/map/src/io.c b/tests/src/map/src/io.c new file mode 100644 index 0000000..a01da4b --- /dev/null +++ b/tests/src/map/src/io.c @@ -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); + } +} diff --git a/tests/src/map/src/plug.c b/tests/src/map/src/plug.c new file mode 100644 index 0000000..2462c64 --- /dev/null +++ b/tests/src/map/src/plug.c @@ -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; } diff --git a/tests/src/map/src/random.c b/tests/src/map/src/random.c new file mode 100644 index 0000000..c4615f2 --- /dev/null +++ b/tests/src/map/src/random.c @@ -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); +} diff --git a/tests/src/random.c b/tests/src/random.c new file mode 100644 index 0000000..337932c --- /dev/null +++ b/tests/src/random.c @@ -0,0 +1,133 @@ +/* This software is licensed by the MIT License, see LICENSE file */ +/* Copyright © 2022 Gregory Lirent */ + +#include +#include + +#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; +} diff --git a/tests/src/set/main.c b/tests/src/set/main.c new file mode 100644 index 0000000..1ba5f76 --- /dev/null +++ b/tests/src/set/main.c @@ -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); +} diff --git a/tests/src/set/plug.h b/tests/src/set/plug.h new file mode 100644 index 0000000..756e649 --- /dev/null +++ b/tests/src/set/plug.h @@ -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); diff --git a/tests/src/set/src/io.c b/tests/src/set/src/io.c new file mode 100644 index 0000000..378aaf6 --- /dev/null +++ b/tests/src/set/src/io.c @@ -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); + } +} diff --git a/tests/src/set/src/plug.c b/tests/src/set/src/plug.c new file mode 100644 index 0000000..6dc338a --- /dev/null +++ b/tests/src/set/src/plug.c @@ -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; } diff --git a/tests/src/set/src/random.c b/tests/src/set/src/random.c new file mode 100644 index 0000000..dc6d6d5 --- /dev/null +++ b/tests/src/set/src/random.c @@ -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); +} diff --git a/tests/src/string/main.c b/tests/src/string/main.c new file mode 100644 index 0000000..522b3f8 --- /dev/null +++ b/tests/src/string/main.c @@ -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); +} diff --git a/tests/src/string/plug.h b/tests/src/string/plug.h new file mode 100644 index 0000000..241dc93 --- /dev/null +++ b/tests/src/string/plug.h @@ -0,0 +1,22 @@ +/* This software is licensed by the MIT License, see LICENSE file */ +/* Copyright © 2022 Gregory Lirent */ + +#include +#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); diff --git a/tests/src/string/src/io.c b/tests/src/string/src/io.c new file mode 100644 index 0000000..1da8654 --- /dev/null +++ b/tests/src/string/src/io.c @@ -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); +} diff --git a/tests/src/string/src/plug.c b/tests/src/string/src/plug.c new file mode 100644 index 0000000..02f7f0f --- /dev/null +++ b/tests/src/string/src/plug.c @@ -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; } diff --git a/tests/src/string/src/random.c b/tests/src/string/src/random.c new file mode 100644 index 0000000..36a587c --- /dev/null +++ b/tests/src/string/src/random.c @@ -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); +} diff --git a/tests/src/test.c b/tests/src/test.c new file mode 100644 index 0000000..32e11e4 --- /dev/null +++ b/tests/src/test.c @@ -0,0 +1,103 @@ +/* This software is licensed by the MIT License, see LICENSE file */ +/* Copyright © 2022 Gregory Lirent */ + +#include +#include +#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); + } +} diff --git a/tests/src/time.c b/tests/src/time.c new file mode 100644 index 0000000..255f799 --- /dev/null +++ b/tests/src/time.c @@ -0,0 +1,122 @@ +/* This software is licensed by the MIT License, see LICENSE file */ +/* Copyright © 2022 Gregory Lirent */ + +#include +#include +#ifndef __USE_MISC +#define __USE_MISC +#endif +#include +#include +#include +#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); +}