diff --git a/config-verify.c b/config-verify.c index 97ea8cf..d9f3220 100644 --- a/config-verify.c +++ b/config-verify.c @@ -284,18 +284,17 @@ conf_verify_particle_dictionary(keychain_t *chain, const struct yml_node *node) return false; } - const struct particle_info *info = plugin_load_particle(particle_name); - if (info == NULL) { - LOG_ERR( - "%s: invalid particle name: %s", - conf_err_prefix(chain, particle), particle_name); + const struct particle_iface *iface = plugin_load_particle(particle_name); + if (iface == NULL) { + LOG_ERR("%s: invalid particle name: %s", + conf_err_prefix(chain, particle), particle_name); return false; } - assert(info->verify_conf != NULL); + assert(iface->verify_conf != NULL); chain_push(chain, particle_name); - if (!info->verify_conf(chain, values)) + if (!iface->verify_conf(chain, values)) return false; chain_pop(chain); diff --git a/config.c b/config.c index a2d759e..aae4607 100644 --- a/config.c +++ b/config.c @@ -211,10 +211,10 @@ conf_to_particle(const struct yml_node *node, struct conf_inherit inherited) struct particle *common = particle_common_new( left, right, on_click_template, font, foreground, deco); - const struct particle_info *info = plugin_load_particle(type); + const struct particle_iface *iface = plugin_load_particle(type); - assert(info != NULL); - return info->from_conf(pair.value, common); + assert(iface != NULL); + return iface->from_conf(pair.value, common); } struct bar * diff --git a/particle.h b/particle.h index f6048ad..db552d1 100644 --- a/particle.h +++ b/particle.h @@ -9,25 +9,6 @@ #include "yml.h" struct bar; -struct particle; -struct exposable; - -struct particle_info { - bool (*verify_conf)(keychain_t *chain, const struct yml_node *node); - struct particle *(*from_conf)( - const struct yml_node *node, struct particle *common); - -#define PARTICLE_COMMON_ATTRS \ - {"margin", false, &conf_verify_int}, \ - {"left-margin", false, &conf_verify_int}, \ - {"right-margin", false, &conf_verify_int}, \ - {"on-click", false, &conf_verify_string}, \ - {"font", false, &conf_verify_font}, \ - {"foreground", false, &conf_verify_color}, \ - {"deco", false, &conf_verify_decoration}, \ - {NULL, false, NULL} - -}; struct particle { void *private; @@ -80,3 +61,14 @@ void exposable_render_deco( void exposable_default_on_mouse( struct exposable *exposable, struct bar *bar, enum mouse_event event, int x, int y); + +/* List of attributes *all* particles implement */ +#define PARTICLE_COMMON_ATTRS \ + {"margin", false, &conf_verify_int}, \ + {"left-margin", false, &conf_verify_int}, \ + {"right-margin", false, &conf_verify_int}, \ + {"on-click", false, &conf_verify_string}, \ + {"font", false, &conf_verify_font}, \ + {"foreground", false, &conf_verify_color}, \ + {"deco", false, &conf_verify_decoration}, \ + {NULL, false, NULL} diff --git a/particles/empty.c b/particles/empty.c index 4b7ab37..8ed3813 100644 --- a/particles/empty.c +++ b/particles/empty.c @@ -38,13 +38,13 @@ empty_new(struct particle *common) return common; } -static struct particle * +struct particle * from_conf(const struct yml_node *node, struct particle *common) { return empty_new(common); } -static bool +bool verify_conf(keychain_t *chain, const struct yml_node *node) { static const struct attr_info attrs[] = { @@ -53,8 +53,3 @@ verify_conf(keychain_t *chain, const struct yml_node *node) return conf_verify_dict(chain, node, attrs); } - -const struct particle_info plugin_info = { - .verify_conf = &verify_conf, - .from_conf = &from_conf, -}; diff --git a/particles/list.c b/particles/list.c index b190ec6..3ee6abb 100644 --- a/particles/list.c +++ b/particles/list.c @@ -162,7 +162,7 @@ particle_list_new(struct particle *common, return common; } -static struct particle * +struct particle * from_conf(const struct yml_node *node, struct particle *common) { const struct yml_node *items = yml_get_value(node, "items"); @@ -190,7 +190,7 @@ from_conf(const struct yml_node *node, struct particle *common) return particle_list_new(common, parts, count, left_spacing, right_spacing); } -static bool +bool verify_conf(keychain_t *chain, const struct yml_node *node) { static const struct attr_info attrs[] = { @@ -203,8 +203,3 @@ verify_conf(keychain_t *chain, const struct yml_node *node) return conf_verify_dict(chain, node, attrs); } - -const struct particle_info plugin_info = { - .verify_conf = &verify_conf, - .from_conf = &from_conf, -}; diff --git a/particles/map.c b/particles/map.c index 4aac2fe..405060e 100644 --- a/particles/map.c +++ b/particles/map.c @@ -195,7 +195,7 @@ verify_map_values(keychain_t *chain, const struct yml_node *node) return true; } -static struct particle * +struct particle * from_conf(const struct yml_node *node, struct particle *common) { const struct yml_node *tag = yml_get_value(node, "tag"); @@ -226,7 +226,7 @@ from_conf(const struct yml_node *node, struct particle *common) default_particle); } -static bool +bool verify_conf(keychain_t *chain, const struct yml_node *node) { static const struct attr_info attrs[] = { @@ -238,8 +238,3 @@ verify_conf(keychain_t *chain, const struct yml_node *node) return conf_verify_dict(chain, node, attrs); } - -const struct particle_info plugin_info = { - .verify_conf = &verify_conf, - .from_conf = &from_conf, -}; diff --git a/particles/progress-bar.c b/particles/progress-bar.c index 93ae285..ff71b98 100644 --- a/particles/progress-bar.c +++ b/particles/progress-bar.c @@ -227,7 +227,7 @@ progress_bar_new(struct particle *common, const char *tag, int width, return common; } -static struct particle * +struct particle * from_conf(const struct yml_node *node, struct particle *common) { const struct yml_node *tag = yml_get_value(node, "tag"); @@ -254,7 +254,7 @@ from_conf(const struct yml_node *node, struct particle *common) conf_to_particle(indicator, inherited)); } -static bool +bool verify_conf(keychain_t *chain, const struct yml_node *node) { static const struct attr_info attrs[] = { @@ -271,8 +271,3 @@ verify_conf(keychain_t *chain, const struct yml_node *node) return conf_verify_dict(chain, node, attrs); } - -const struct particle_info plugin_info = { - .verify_conf = &verify_conf, - .from_conf = &from_conf, -}; diff --git a/particles/ramp.c b/particles/ramp.c index 30c2e5e..f8b4091 100644 --- a/particles/ramp.c +++ b/particles/ramp.c @@ -152,7 +152,7 @@ ramp_new(struct particle *common, const char *tag, return common; } -static struct particle * +struct particle * from_conf(const struct yml_node *node, struct particle *common) { const struct yml_node *tag = yml_get_value(node, "tag"); @@ -173,7 +173,7 @@ from_conf(const struct yml_node *node, struct particle *common) return ramp_new(common, yml_value_as_string(tag), parts, count); } -static bool +bool verify_conf(keychain_t *chain, const struct yml_node *node) { static const struct attr_info attrs[] = { @@ -184,8 +184,3 @@ verify_conf(keychain_t *chain, const struct yml_node *node) return conf_verify_dict(chain, node, attrs); } - -const struct particle_info plugin_info = { - .verify_conf = &verify_conf, - .from_conf = &from_conf, -}; diff --git a/particles/string.c b/particles/string.c index ce4b305..1ebe4e4 100644 --- a/particles/string.c +++ b/particles/string.c @@ -133,7 +133,7 @@ string_new(struct particle *common, const char *text, size_t max_len) return common; } -static struct particle * +struct particle * from_conf(const struct yml_node *node, struct particle *common) { const struct yml_node *text = yml_get_value(node, "text"); @@ -145,7 +145,7 @@ from_conf(const struct yml_node *node, struct particle *common) max != NULL ? yml_value_as_int(max) : 0); } -static bool +bool verify_conf(keychain_t *chain, const struct yml_node *node) { static const struct attr_info attrs[] = { @@ -156,8 +156,3 @@ verify_conf(keychain_t *chain, const struct yml_node *node) return conf_verify_dict(chain, node, attrs); } - -const struct particle_info plugin_info = { - .verify_conf = &verify_conf, - .from_conf = &from_conf, -}; diff --git a/plugin.c b/plugin.c index 3420820..ca16f91 100644 --- a/plugin.c +++ b/plugin.c @@ -66,15 +66,27 @@ plugin_load(const char *name, enum plugin_type type) return NULL; } - tll_push_back(plugins, ((struct plugin){strdup(name), type, lib, NULL})); + tll_push_back(plugins, ((struct plugin){strdup(name), type, lib, {NULL}})); struct plugin *plug = &tll_back(plugins); dlerror(); /* Clear previous error */ - plug->sym = dlsym(lib, "plugin_info"); + const char *dl_error = NULL; - const char *dlsym_error = dlerror(); - if (dlsym_error != NULL) { - LOG_ERR("%s: %s: dlsym: %s", type2str(type), name, dlsym_error); + if (type == PLUGIN_MODULE) { + plug->sym = dlsym(lib, "plugin_info"); + dl_error = dlerror(); + } else { + plug->particle.verify_conf = dlsym(lib, "verify_conf"); + dl_error = dlerror(); + + if (dl_error == NULL) { + plug->particle.from_conf = dlsym(lib, "from_conf"); + dl_error = dlerror(); + } + } + + if (dl_error != NULL) { + LOG_ERR("%s: %s: dlsym: %s", type2str(type), name, dl_error); return NULL; } @@ -88,9 +100,9 @@ plugin_load_module(const char *name) return plug != NULL ? plug->sym : NULL; } -const struct particle_info * +const struct particle_iface * plugin_load_particle(const char *name) { const struct plugin *plug = plugin_load(name, PLUGIN_PARTICLE); - return plug != NULL ? plug->sym : NULL; + return plug != NULL ? &plug->particle : NULL; } diff --git a/plugin.h b/plugin.h index aaa84c4..c91c46d 100644 --- a/plugin.h +++ b/plugin.h @@ -1,10 +1,17 @@ #pragma once +#include "config-verify.h" #include "module.h" #include "particle.h" +struct particle_iface { + bool (*verify_conf)(keychain_t *chain, const struct yml_node *node); + struct particle *(*from_conf)( + const struct yml_node *node, struct particle *common); +}; + const struct module_info *plugin_load_module(const char *name); -const struct particle_info *plugin_load_particle(const char *name); +const struct particle_iface *plugin_load_particle(const char *name); enum plugin_type { PLUGIN_MODULE, PLUGIN_PARTICLE }; @@ -13,7 +20,10 @@ struct plugin { enum plugin_type type; void *lib; - const void *sym; + union { + void *sym; + struct particle_iface particle; + }; }; const struct plugin *plugin_load(const char *name, enum plugin_type type);