diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile | 4 | ||||
-rw-r--r-- | src/apk.c | 38 | ||||
-rw-r--r-- | src/apk_applet.h | 9 |
3 files changed, 37 insertions, 14 deletions
diff --git a/src/Makefile b/src/Makefile index 4487007..8fdaf4b 100644 --- a/src/Makefile +++ b/src/Makefile @@ -62,8 +62,8 @@ progs-$(STATIC) += apk.static apk.static-objs := $(filter-out apk.o,$(apk-objs)) apk-static.o LDFLAGS_apk.static := -static LIBS_apk.static := -Wl,--as-needed -ldl -Wl,--no-as-needed -LDFLAGS_apk += -nopie -L$(obj) -LDFLAGS_apk-test += -nopie -L$(obj) +LDFLAGS_apk += -L$(obj) +LDFLAGS_apk-test += -L$(obj) CFLAGS_ALL += $(shell $(PKG_CONFIG) --cflags $(PKGDEPS)) LIBS := -Wl,--as-needed \ @@ -33,6 +33,9 @@ #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) + char **apk_argv; static struct apk_option generic_options[] = { @@ -150,17 +153,16 @@ static int usage(struct apk_applet *applet) { version(); if (applet == NULL) { - struct apk_applet **a; + struct apk_applet *a; print_usage("COMMAND", "[ARGS]...", ARRAY_SIZE(generic_options), generic_options); printf("\nThe following commands are available:\n"); - for (a = &__start_apkapplets; a < &__stop_apkapplets; a++) { + foreach_applet(a) { struct apk_indent indent = { .indent = 12 }; - - indent.x = printf(" %-*s", indent.indent - 3, (*a)->name); - apk_print_indented_words(&indent, (*a)->help); + indent.x = printf(" %-*s", indent.indent - 3, a->name); + apk_print_indented_words(&indent, a->help); printf("\n"); } } else { @@ -186,11 +188,11 @@ static int usage(struct apk_applet *applet) static struct apk_applet *find_applet(const char *name) { - struct apk_applet **a; + struct apk_applet *a; - for (a = &__start_apkapplets; a < &__stop_apkapplets; a++) { - if (strcmp(name, (*a)->name) == 0) - return *a; + foreach_applet(a) { + if (strcmp(name, a->name) == 0) + return a; } return NULL; @@ -289,6 +291,22 @@ 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)(); +} + int main(int argc, char **argv) { struct apk_applet *applet; @@ -309,6 +327,8 @@ int main(int argc, char **argv) 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])); apk_argv[argc] = NULL; diff --git a/src/apk_applet.h b/src/apk_applet.h index fa690fc..d11c259 100644 --- a/src/apk_applet.h +++ b/src/apk_applet.h @@ -25,6 +25,8 @@ struct apk_option { }; struct apk_applet { + struct list_head node; + const char *name; const char *arguments; const char *help; @@ -39,10 +41,11 @@ struct apk_applet { int (*main)(void *ctx, struct apk_database *db, struct apk_string_array *args); }; -extern struct apk_applet *__start_apkapplets, *__stop_apkapplets; +void apk_applet_register(struct apk_applet *); +typedef void (*apk_init_func_t)(void); #define APK_DEFINE_APPLET(x) \ - static struct apk_applet *__applet_##x \ - __attribute__((__section__("apkapplets"))) __attribute((used)) = &x; +static void __register_##x(void) { apk_applet_register(&x); } \ +static apk_init_func_t __regfunc_##x __attribute__((__section__("initapplets"))) __attribute((used)) = __register_##x; #endif |