summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAriadne Conill <ariadne@dereferenced.org>2021-12-10 14:33:52 -0600
committerTimo Teräs <timo.teras@iki.fi>2021-12-14 21:10:26 +0200
commit0fd415faf57bdf6e3e459b8315c3d9c8d69b0136 (patch)
treebff68e521ba540effc90868e99c40a972e2eaf05
parenteab6645cb8c03282fbe6b8484c3fd390cfd91a9c (diff)
downloadapk-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.c38
-rw-r--r--src/apk_applet.h7
-rw-r--r--src/apk_defines.h1
-rw-r--r--src/help.c23
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"