diff --git a/client/command.c b/client/command.c index 966ac594..745bc8f5 100644 --- a/client/command.c +++ b/client/command.c @@ -24,6 +24,7 @@ #include #endif +#include #include #include "command.h" @@ -187,13 +188,40 @@ void command_family_unregister(const struct command_family *family) l_queue_remove(command_families, (void *) family); } +extern struct command_family_desc __start___command[]; +extern struct command_family_desc __stop___command[]; + void command_init(void) { + struct command_family_desc *desc; + command_families = l_queue_new(); + + if (__start___command == NULL || __stop___command == NULL) + return; + + for (desc = __start___command; desc < __stop___command; desc++) { + if (!desc->init) + continue; + + desc->init(); + } } void command_exit(void) { + struct command_family_desc *desc; + + if (__start___command == NULL || __stop___command == NULL) + return; + + for (desc = __start___command; desc < __stop___command; desc++) { + if (!desc->exit) + continue; + + desc->exit(); + } + l_queue_destroy(command_families, NULL); command_families = NULL; } diff --git a/client/command.h b/client/command.h index 02564398..33ad1cdd 100644 --- a/client/command.h +++ b/client/command.h @@ -42,5 +42,17 @@ void command_process_prompt(char *prompt); void command_family_register(const struct command_family *family); void command_family_unregister(const struct command_family *family); +struct command_family_desc { + const char *name; + int (*init)(void); + void (*exit)(void); +} __attribute__((aligned(8))); + +#define COMMAND_FAMILY(name, init, exit) \ + static struct command_family_desc __command_family_ ## name \ + __attribute__((used, section("__command"), aligned(8))) = {\ + #name, init, exit \ + }; \ + void command_init(void); void command_exit(void);