From 4056544d49a80fa7ac8dc351f99548b4dbc88e99 Mon Sep 17 00:00:00 2001 From: Gregory Lirent Date: Tue, 16 Aug 2022 18:36:50 +0300 Subject: [PATCH 1/5] Update tests headers --- tests/src/array/plug.h | 69 ----------------------------------------- tests/src/dict/plug.h | 12 +++---- tests/src/list/src/io.c | 1 - tests/src/map/plug.h | 14 ++++----- 4 files changed, 13 insertions(+), 83 deletions(-) diff --git a/tests/src/array/plug.h b/tests/src/array/plug.h index 254611a..f852e45 100644 --- a/tests/src/array/plug.h +++ b/tests/src/array/plug.h @@ -9,7 +9,6 @@ #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); @@ -23,71 +22,3 @@ 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); - -/* -static void array_push_random(vtype_array* x) { - switch (random_uint8()%13) { - default: - case 0: array_push(x, random_boolean()); break; - case 1: array_push(x, random_uint8()); break; - case 2: array_push(x, random_uint16()); break; - case 3: array_push(x, random_uint32()); break; - case 4: array_push(x, random_uint64()); break; - case 5: array_push(x, random_int8()); break; - case 6: array_push(x, random_int16()); break; - case 7: array_push(x, random_int32()); break; - case 8: array_push(x, random_int64()); break; - case 9: array_push(x, (void*)((sizeof(void*) == 8) ? random_uint64() : random_uint32())); break; - case 10: array_push(x, random_float()); break; - case 11: array_push(x, random_double()); break; - case 12: array_push(x, random_ldouble()); break; - } -} - -static void array_init_random(vtype_array* x) { - switch (random_uint8()%13) { - default: - case 0: array_init(x, VTYPE_BOOLEAN); break; - case 1: array_init(x, VTYPE_UINT8); break; - case 2: array_init(x, VTYPE_UINT16); break; - case 3: array_init(x, VTYPE_UINT32); break; - case 4: array_init(x, VTYPE_UINT64); break; - case 5: array_init(x, VTYPE_INT8); break; - case 6: array_init(x, VTYPE_INT16); break; - case 7: array_init(x, VTYPE_INT32); break; - case 8: array_init(x, VTYPE_INT64); break; - case 9: array_init(x, VTYPE_POINTER); break; - case 10: array_init(x, VTYPE_FLOAT); break; - case 11: array_init(x, VTYPE_DOUBLE); break; - case 12: array_init(x, VTYPE_LDOUBLE); break; - } -} - -static vtype_array array_random(unsigned int n) { - vtype_array x; - - array_init_random(&x); - - for (int i = 0; i < n; ++i) { - array_push_random(&x); - } - - return x; -} - -static int array_value_print(void* v, ssize_t i, vtype t, void* _) { - print_container_value(&i, v, t, false); - return 0; -} - -static void array_print(vtype_array* x, const char* prefix) { - print_container_values_prefix("Array", prefix); - array_foreach(x, 0, array_value_print); - put_separator(); -} - -static void array_info(const vtype_array* x) { - print_container_info("Array", 0, &x->type, array_size(x), array_nmemb(x)); - put_separator(); -} -*/ diff --git a/tests/src/dict/plug.h b/tests/src/dict/plug.h index 57f84dc..e6b73db 100644 --- a/tests/src/dict/plug.h +++ b/tests/src/dict/plug.h @@ -7,11 +7,11 @@ #include "../../include/test.h" #include "../../include/time.h" -void dict_push_random(dict_t* x, bool silent, unsigned int hpos); -void dict_remove_random(dict_t* x, bool silent, unsigned int hpos); +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); -void dict_print(dict_t* x, const char* prefix, unsigned int hpos); -void dict_info(const dict_t* x, 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); -void visual_push(dict_t* x, size_t n); -void visual_remove(dict_t* x); +extern void visual_push(dict_t* x, size_t n); +extern void visual_remove(dict_t* x); diff --git a/tests/src/list/src/io.c b/tests/src/list/src/io.c index 793ae33..fb61586 100644 --- a/tests/src/list/src/io.c +++ b/tests/src/list/src/io.c @@ -17,7 +17,6 @@ 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); diff --git a/tests/src/map/plug.h b/tests/src/map/plug.h index a2ae449..da2aeed 100644 --- a/tests/src/map/plug.h +++ b/tests/src/map/plug.h @@ -7,12 +7,12 @@ #include "../../include/test.h" #include "../../include/time.h" -void map_push_random(map_t* x, _Bool silent, unsigned int hpos); -void map_remove_random(map_t* x, _Bool silent, unsigned int hpos); +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); -void map_print(map_t* x, const char* prefix, unsigned int hpos); -void map_info(const map_t* x, unsigned int hpos); -void map_rbtree_print(map_t *x, const char* prefix, 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); -void visual_push(map_t* x, size_t n); -void visual_remove(map_t* x); +extern void visual_push(map_t* x, size_t n); +extern void visual_remove(map_t* x); From 382bd0070100b8c38c8c1cc0e2154cca90acac19 Mon Sep 17 00:00:00 2001 From: Gregory Lirent Date: Tue, 16 Aug 2022 18:38:35 +0300 Subject: [PATCH 2/5] Add global (communicative) test --- tests/Makefile | 42 +++--- tests/src/global/main.c | 34 +++++ tests/src/global/plug.h | 23 +++ tests/src/global/src/io.c | 33 +++++ tests/src/global/src/random.c | 265 ++++++++++++++++++++++++++++++++++ 5 files changed, 375 insertions(+), 22 deletions(-) create mode 100644 tests/src/global/main.c create mode 100644 tests/src/global/plug.h create mode 100644 tests/src/global/src/io.c create mode 100644 tests/src/global/src/random.c diff --git a/tests/Makefile b/tests/Makefile index b1f7a65..bb8f5ee 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -17,32 +17,25 @@ $(BUILD_PATH)/obj/%.o: CFLAGS := $(CFLAGS) -Og -fPIC -c -g3 -Wall ######################################################################################################################## - c_objects = $(addsuffix .o,$(addprefix $(2),$(notdir $(basename $(wildcard $(1)*.c))))) -OBJECTS_TESTS := $(call c_objects,./src/,) -OBJECTS_BASE := $(call c_objects,../src/,) -OBJECTS_STRING := $(OBJECTS_BASE) $(call c_objects,../src/string/,string-) -OBJECTS_ARRAY := $(OBJECTS_BASE) $(call c_objects,../src/array/,array-) -OBJECTS_LIST := $(OBJECTS_BASE) $(call c_objects,../src/list/,list-) -OBJECTS_MAP := $(OBJECTS_BASE) $(call c_objects,../src/map/,map-) -OBJECTS_SET := $(OBJECTS_BASE) $(call c_objects,../src/set/,set-) -OBJECTS_DICT := $(OBJECTS_BASE) $(call c_objects,../src/dict/,dict-) +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_BASE := $(addprefix $(BUILD_PATH)/obj/,$(OBJECTS_TESTS)) $(addprefix ../bin/debug/obj/,$(OBJECTS_BASE)) -OBJECTS_STRING := $(addprefix $(BUILD_PATH)/obj/,$(OBJECTS_TESTS)) $(addprefix ../bin/debug/obj/,$(OBJECTS_STRING)) -OBJECTS_ARRAY := $(addprefix $(BUILD_PATH)/obj/,$(OBJECTS_TESTS)) $(addprefix ../bin/debug/obj/,$(OBJECTS_ARRAY)) -OBJECTS_LIST := $(addprefix $(BUILD_PATH)/obj/,$(OBJECTS_TESTS)) $(addprefix ../bin/debug/obj/,$(OBJECTS_LIST)) -OBJECTS_MAP := $(addprefix $(BUILD_PATH)/obj/,$(OBJECTS_TESTS)) $(addprefix ../bin/debug/obj/,$(OBJECTS_MAP)) -OBJECTS_SET := $(addprefix $(BUILD_PATH)/obj/,$(OBJECTS_TESTS)) $(addprefix ../bin/debug/obj/,$(OBJECTS_SET)) -OBJECTS_DICT := $(addprefix $(BUILD_PATH)/obj/,$(OBJECTS_TESTS)) $(addprefix ../bin/debug/obj/,$(OBJECTS_DICT)) +OBJECTS_GLOBAL := $(OBJECTS_TESTS) $(addprefix $(BUILD_PATH)/obj/,$(call c_objects,./src/global/src/,global-)) -OBJECTS_STRING := $(OBJECTS_STRING) $(addprefix $(BUILD_PATH)/obj/,$(call c_objects,./src/string/src/,string-)) -OBJECTS_ARRAY := $(OBJECTS_ARRAY) $(addprefix $(BUILD_PATH)/obj/,$(call c_objects,./src/array/src/,array-)) -OBJECTS_LIST := $(OBJECTS_LIST) $(addprefix $(BUILD_PATH)/obj/,$(call c_objects,./src/list/src/,list-)) -OBJECTS_MAP := $(OBJECTS_MAP) $(addprefix $(BUILD_PATH)/obj/,$(call c_objects,./src/map/src/,map-)) -OBJECTS_SET := $(OBJECTS_SET) $(addprefix $(BUILD_PATH)/obj/,$(call c_objects,./src/set/src/,set-)) -OBJECTS_DICT := $(OBJECTS_DICT) $(addprefix $(BUILD_PATH)/obj/,$(call c_objects,./src/dict/src/,dict-)) +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-)) ######################################################################################################################## @@ -53,6 +46,7 @@ tests: $(addprefix $(BUILD_PATH)/list-,$(notdir $(basename $(wildcard ./src/list 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)))) ######################################################################################################################## @@ -72,6 +66,8 @@ $(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 @@ -85,6 +81,8 @@ $(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 ######################################################################################################################## 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); +} From 80ba7082d4c045af8e9809a3117bc73be5f5570e Mon Sep 17 00:00:00 2001 From: Gregory Lirent Date: Tue, 16 Aug 2022 18:39:55 +0300 Subject: [PATCH 3/5] Minor fixes --- include/array.h | 2 +- include/extra/set.h | 5 ++--- src/__internal/rbtree.h | 6 +++--- src/__internal/vnode.h | 2 +- src/extra-memory.c | 3 +++ 5 files changed, 10 insertions(+), 8 deletions(-) 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..a34113b 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 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) 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 */ 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/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(); From 125153076d5496637807f1b3a179101d2420174a Mon Sep 17 00:00:00 2001 From: Gregory Lirent Date: Tue, 16 Aug 2022 21:10:54 +0300 Subject: [PATCH 4/5] Minor fixes --- include/extra/set.h | 6 +++--- include/set.h | 7 ++++--- src/dict/extra.c | 2 +- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/include/extra/set.h b/include/extra/set.h index a34113b..42be364 100644 --- a/include/extra/set.h +++ b/include/extra/set.h @@ -8,8 +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) 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); +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/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); From 86928b4b221b16704c57a3482ab4e1e584673a05 Mon Sep 17 00:00:00 2001 From: Gregory Lirent Date: Tue, 16 Aug 2022 21:11:07 +0300 Subject: [PATCH 5/5] Add examples --- examples/Makefile | 40 +++++++++++++++++++++++++++++++ examples/array.c | 37 ++++++++++++++++++++++++++++ examples/dict.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++ examples/list.c | 51 +++++++++++++++++++++++++++++++++++++++ examples/map.c | 55 ++++++++++++++++++++++++++++++++++++++++++ examples/set.c | 38 +++++++++++++++++++++++++++++ examples/string.c | 42 ++++++++++++++++++++++++++++++++ 7 files changed, 324 insertions(+) create mode 100644 examples/Makefile create mode 100644 examples/array.c create mode 100644 examples/dict.c create mode 100644 examples/list.c create mode 100644 examples/map.c create mode 100644 examples/set.c create mode 100644 examples/string.c 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); +}