diff options
author | Ariadne Conill <ariadne@dereferenced.org> | 2021-12-10 14:33:52 -0600 |
---|---|---|
committer | Timo Teräs <timo.teras@iki.fi> | 2021-12-14 21:10:26 +0200 |
commit | 0fd415faf57bdf6e3e459b8315c3d9c8d69b0136 (patch) | |
tree | bff68e521ba540effc90868e99c40a972e2eaf05 | |
parent | eab6645cb8c03282fbe6b8484c3fd390cfd91a9c (diff) | |
download | apk-tools-0fd415faf57bdf6e3e459b8315c3d9c8d69b0136.tar.gz apk-tools-0fd415faf57bdf6e3e459b8315c3d9c8d69b0136.tar.bz2 apk-tools-0fd415faf57bdf6e3e459b8315c3d9c8d69b0136.tar.xz apk-tools-0fd415faf57bdf6e3e459b8315c3d9c8d69b0136.zip |
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]
-rw-r--r-- | src/apk.c | 38 | ||||
-rw-r--r-- | src/apk_applet.h | 7 | ||||
-rw-r--r-- | src/apk_defines.h | 1 | ||||
-rw-r--r-- | src/help.c | 23 |
4 files changed, 29 insertions, 40 deletions
@@ -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 @@ -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" |