From 0a8d913fdd9fd944d776f301d89a07d2f72bd004 Mon Sep 17 00:00:00 2001 From: Max Wash Date: Fri, 13 Dec 2024 12:25:40 +0000 Subject: [PATCH] common: implement ident and selector manipulation --- common/CMakeLists.txt | 3 +- common/ident.c | 69 +++++++++++++++++++++++++++ common/include/ivy/ident.h | 23 +++++++++ common/include/ivy/selector.h | 23 ++++++--- common/selector.c | 90 +++++++++++++++++++++++++++++++++++ 5 files changed, 201 insertions(+), 7 deletions(-) create mode 100644 common/ident.c create mode 100644 common/include/ivy/ident.h diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index 0a2e4bf..184014a 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -11,4 +11,5 @@ else () endif () target_include_directories(ivy-common PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include/) -target_compile_definitions(ivy-common PRIVATE IVY_EXPORT=1 IVY_STATIC=${IVY_STATIC}) \ No newline at end of file +target_compile_definitions(ivy-common PRIVATE IVY_EXPORT=1 IVY_STATIC=${IVY_STATIC}) +target_link_libraries(ivy-common Bluelib::Core Bluelib::Object) \ No newline at end of file diff --git a/common/ident.c b/common/ident.c new file mode 100644 index 0000000..d63c5d0 --- /dev/null +++ b/common/ident.c @@ -0,0 +1,69 @@ +#include +#include +#include +#include +#include + +struct ivy_ident *ivy_ident_create(void) +{ + struct ivy_ident *id = malloc(sizeof *id); + + if (!id) { + return NULL; + } + + memset(id, 0x0, sizeof *id); + + return id; +} + +void ivy_ident_destroy(struct ivy_ident *ident) +{ + b_queue_iterator it = {0}; + b_queue_iterator_begin(&ident->id_parts, &it); + + while (b_queue_iterator_is_valid(&it)) { + struct ivy_ident_part *part = b_unbox(struct ivy_ident_part, it.entry, p_entry); + b_queue_iterator_erase(&it); + + free(part->p_str); + free(part); + } + + free(ident); +} + +void ivy_ident_add_part(struct ivy_ident *ident, const char *s) +{ + struct ivy_ident_part *part = malloc(sizeof *part); + if (!part) { + return; + } + + memset(part, 0x0, sizeof *part); + + part->p_str = b_strdup(s); + + b_queue_push_back(&ident->id_parts, &part->p_entry); +} + +size_t ivy_ident_to_string(const struct ivy_ident *ident, char *out, size_t max) +{ + b_strv_builder strv; + b_strv_builder_begin(&strv, out, max); + + int i = 0; + b_queue_iterator it = {0}; + b_queue_foreach (&it, &ident->id_parts) { + if (i > 0) { + b_strv_builder_add(&strv, "."); + } + + struct ivy_ident_part *part = b_unbox(struct ivy_ident_part, it.entry, p_entry); + b_strv_builder_add(&strv, part->p_str); + i++; + } + + /* TODO return string length. */ + return 0; +} \ No newline at end of file diff --git a/common/include/ivy/ident.h b/common/include/ivy/ident.h new file mode 100644 index 0000000..c06190c --- /dev/null +++ b/common/include/ivy/ident.h @@ -0,0 +1,23 @@ +#ifndef IVY_IDENT_H_ +#define IVY_IDENT_H_ + +#include +#include +#include + +struct ivy_ident_part { + char *p_str; + b_queue_entry p_entry; +}; + +struct ivy_ident { + b_queue id_parts; +}; + +IVY_API struct ivy_ident *ivy_ident_create(void); +IVY_API void ivy_ident_destroy(struct ivy_ident *ident); + +IVY_API void ivy_ident_add_part(struct ivy_ident *ident, const char *s); +IVY_API size_t ivy_ident_to_string(const struct ivy_ident *ident, char *out, size_t max); + +#endif \ No newline at end of file diff --git a/common/include/ivy/selector.h b/common/include/ivy/selector.h index d307c54..e5e0651 100644 --- a/common/include/ivy/selector.h +++ b/common/include/ivy/selector.h @@ -2,6 +2,7 @@ #define IVY_SELECTOR_H_ #include +#include enum ivy_selector_recipient { IVY_SEL_NONE = 0, @@ -9,15 +10,25 @@ enum ivy_selector_recipient { IVY_SEL_OBJECT, }; -struct ivy_selector; +struct ivy_selector { + enum ivy_selector_recipient sel_recipient; + char *sel_name; + b_queue sel_args; +}; -extern enum ivy_status ivy_selector_create(struct ivy_selector **sel); -extern void ivy_selector_destroy(struct ivy_selector *sel); +struct ivy_selector_arg { + char *arg_label; + char *arg_name; + b_queue_entry arg_entry; +}; -extern void ivy_selector_set_recipient( +IVY_API enum ivy_status ivy_selector_create(struct ivy_selector **sel); +IVY_API void ivy_selector_destroy(struct ivy_selector *sel); + +IVY_API void ivy_selector_set_recipient( struct ivy_selector *sel, enum ivy_selector_recipient r); -extern void ivy_selector_set_name(struct ivy_selector *sel, const char *name); -extern void ivy_selector_add_arg( +IVY_API enum ivy_status ivy_selector_set_name(struct ivy_selector *sel, const char *name); +IVY_API enum ivy_status ivy_selector_add_arg( struct ivy_selector *sel, const char *label, const char *name); #endif diff --git a/common/selector.c b/common/selector.c index e69de29..79ee256 100644 --- a/common/selector.c +++ b/common/selector.c @@ -0,0 +1,90 @@ +#include +#include +#include +#include +#include + +enum ivy_status ivy_selector_create(struct ivy_selector **sel) +{ + struct ivy_selector *out = malloc(sizeof *out); + + if (!out) { + return IVY_ERR_NO_MEMORY; + } + + memset(out, 0x0, sizeof *out); + + *sel = out; + return IVY_OK; +} + +void ivy_selector_destroy(struct ivy_selector *sel) +{ + if (sel->sel_name) { + free(sel->sel_name); + } + + b_queue_iterator it = {0}; + b_queue_iterator_begin(&sel->sel_args, &it); + while (b_queue_iterator_is_valid(&it)) { + struct ivy_selector_arg *arg = b_unbox(struct ivy_selector_arg, it.entry, arg_entry); + b_queue_iterator_erase(&it); + + if (arg->arg_label) { + free(arg->arg_label); + } + + if (arg->arg_name) { + free(arg->arg_name); + } + + free(arg); + } + + free(sel); +} + +void ivy_selector_set_recipient( + struct ivy_selector *sel, enum ivy_selector_recipient r) +{ + sel->sel_recipient = r; +} + +enum ivy_status ivy_selector_set_name(struct ivy_selector *sel, const char *name) +{ + sel->sel_name = b_strdup(name); + return sel->sel_name ? IVY_OK : IVY_ERR_NO_MEMORY; +} + +enum ivy_status ivy_selector_add_arg( + struct ivy_selector *sel, const char *label, const char *name) +{ + struct ivy_selector_arg *arg = malloc(sizeof *arg); + if (!arg) { + return IVY_ERR_NO_MEMORY; + } + + memset(arg, 0x0, sizeof *arg); + + if (label) { + arg->arg_label = b_strdup(label); + + if (!arg->arg_label) { + free(arg); + return IVY_ERR_NO_MEMORY; + } + } + + if (name) { + arg->arg_name = b_strdup(name); + + if (!arg->arg_name) { + free(arg->arg_label); + free(arg); + return IVY_ERR_NO_MEMORY; + } + } + + b_queue_push_back(&sel->sel_args, &arg->arg_entry); + return IVY_OK; +} \ No newline at end of file