From 0fd415faf57bdf6e3e459b8315c3d9c8d69b0136 Mon Sep 17 00:00:00 2001 From: Ariadne Conill Date: Fri, 10 Dec 2021 14:33:52 -0600 Subject: applet: rework APK_DEFINE_APPLET to use constructor attribute this allows the applet registration to work in a portable way, without having to weird things with the linker. ref #10794 [TT: rebased for 2.12] --- src/apk.c | 38 +++----------------------------------- src/apk_applet.h | 7 +++---- src/apk_defines.h | 1 + src/help.c | 23 ++++++++++++++++++++++- 4 files changed, 29 insertions(+), 40 deletions(-) diff --git a/src/apk.c b/src/apk.c index 33d2ec1..7cb173d 100644 --- a/src/apk.c +++ b/src/apk.c @@ -34,9 +34,6 @@ #include "apk_print.h" #include "apk_io.h" -static struct list_head apk_applet_list; -#define foreach_applet(iter) list_for_each_entry(iter, &apk_applet_list, node) - #ifdef TEST_MODE static const char *test_installed_db = NULL; static const char *test_world = NULL; @@ -282,22 +279,10 @@ const struct apk_option_group optgroup_commit = { static int usage(struct apk_applet *applet) { version(); - apk_help(applet); + apk_applet_help(applet); return 1; } -static struct apk_applet *find_applet(const char *name) -{ - struct apk_applet *a; - - foreach_applet(a) { - if (strcmp(name, a->name) == 0) - return a; - } - - return NULL; -} - static struct apk_applet *deduce_applet(int argc, char **argv) { struct apk_applet *a; @@ -311,11 +296,11 @@ static struct apk_applet *deduce_applet(int argc, char **argv) prog++; if (strncmp(prog, "apk_", 4) == 0) - return find_applet(prog + 4); + return apk_applet_find(prog + 4); for (i = 1; i < argc; i++) { if (argv[i][0] == '-') continue; - a = find_applet(argv[i]); + a = apk_applet_find(argv[i]); if (a) return a; } @@ -432,22 +417,6 @@ static void setup_automatic_flags(void) apk_flags |= APK_INTERACTIVE; } -void apk_applet_register(struct apk_applet *applet) -{ - list_init(&applet->node); - list_add_tail(&applet->node, &apk_applet_list); -} - -static void apk_applet_register_builtin(void) -{ - extern apk_init_func_t __start_initapplets[], __stop_initapplets[]; - apk_init_func_t *p; - - list_init(&apk_applet_list); - for (p = __start_initapplets; p < __stop_initapplets; p++) - (*p)(); -} - static struct apk_database db; static void on_sigint(int s) @@ -468,7 +437,6 @@ int main(int argc, char **argv) #ifdef TEST_MODE apk_string_array_init(&test_repos); #endif - apk_applet_register_builtin(); apk_argv = malloc(sizeof(char*[argc+2])); memcpy(apk_argv, argv, sizeof(char*[argc])); diff --git a/src/apk_applet.h b/src/apk_applet.h index 3bc2eb9..0ae33b4 100644 --- a/src/apk_applet.h +++ b/src/apk_applet.h @@ -63,12 +63,11 @@ struct apk_applet { extern const struct apk_option_group optgroup_global, optgroup_commit; -void apk_help(struct apk_applet *applet); void apk_applet_register(struct apk_applet *); -typedef void (*apk_init_func_t)(void); +struct apk_applet *apk_applet_find(const char *name); +void apk_applet_help(struct apk_applet *applet); #define APK_DEFINE_APPLET(x) \ -static void __register_##x(void) { apk_applet_register(&x); } \ -static apk_init_func_t __regfunc_##x __attribute__((__section__("initapplets"))) __attribute((used)) = __register_##x; +__attribute__((constructor)) static void __register_##x(void) { apk_applet_register(&x); } #endif diff --git a/src/apk_defines.h b/src/apk_defines.h index 6e54076..dbb21bf 100644 --- a/src/apk_defines.h +++ b/src/apk_defines.h @@ -212,6 +212,7 @@ APK_ARRAY(apk_string_array, char *); #define foreach_array_item(iter, array) \ for (iter = &(array)->item[0]; iter < &(array)->item[(array)->num]; iter++) +#define LIST_HEAD(name) struct list_head name = { &name, &name } #define LIST_END (void *) 0xe01 #define LIST_POISON1 (void *) 0xdeadbeef #define LIST_POISON2 (void *) 0xabbaabba diff --git a/src/help.c b/src/help.c index 3034da2..c8bba70 100644 --- a/src/help.c +++ b/src/help.c @@ -10,6 +10,27 @@ #include "apk_applet.h" #include "apk_print.h" +static LIST_HEAD(apk_applet_list); + +#define apk_applet_foreach(iter) list_for_each_entry(iter, &apk_applet_list, node) + +void apk_applet_register(struct apk_applet *applet) +{ + list_init(&applet->node); + list_add_tail(&applet->node, &apk_applet_list); +} + +struct apk_applet *apk_applet_find(const char *name) +{ + struct apk_applet *a; + + apk_applet_foreach(a) { + if (strcmp(name, a->name) == 0) + return a; + } + return NULL; +} + static inline int is_group(struct apk_applet *applet, const char *topic) { if (!applet) return strcasecmp(topic, "apk") == 0; @@ -19,7 +40,7 @@ static inline int is_group(struct apk_applet *applet, const char *topic) return 0; } -void apk_help(struct apk_applet *applet) +void apk_applet_help(struct apk_applet *applet) { #include "help.h" -- cgit v1.2.3-70-g09d2