#include #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_entry *entry = b_queue_first(&sel->sel_args); while (entry) { struct ivy_selector_arg *arg = b_unbox(struct ivy_selector_arg, entry, arg_entry); b_queue_entry *next = b_queue_next(entry); b_queue_delete(&sel->sel_args, entry); if (arg->arg_label) { free(arg->arg_label); } if (arg->arg_name) { free(arg->arg_name); } free(arg); entry = next; } 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; } size_t ivy_selector_to_string(const struct ivy_selector *sel, char *out, size_t max) { b_stringstream *str = b_stringstream_create_with_buffer(out, max); switch (sel->sel_recipient) { case IVY_SEL_OBJECT: b_stream_write_char(str, '-'); break; case IVY_SEL_CLASS: b_stream_write_char(str, '+'); break; default: break; } if (sel->sel_name) { b_stream_write_string(str, sel->sel_name, NULL); } if (sel->sel_name && !b_queue_empty(&sel->sel_args)) { b_stream_write_char(str, '('); } b_queue_entry *entry = b_queue_first(&sel->sel_args); while (entry) { struct ivy_selector_arg *arg = b_unbox(struct ivy_selector_arg, entry, arg_entry); b_stream_write_fmt( str, NULL, "%s:", arg->arg_label ? arg->arg_label : "_"); entry = b_queue_next(entry); } if (sel->sel_name && !b_queue_empty(&sel->sel_args)) { b_stream_write_char(str, ')'); } size_t len = b_stringstream_get_length(str); b_stringstream_unref(str); return len; }