diff options
author | Jeremy Kerr <jk@ozlabs.org> | 2009-01-02 18:27:00 +0900 |
---|---|---|
committer | Jeremy Kerr <jk@ozlabs.org> | 2009-01-02 18:27:00 +0900 |
commit | 89ccc8e6dc81bc1d613454b9944c2f3324d43e2a (patch) | |
tree | aab4c63f6e29336ae423c905b55acf4329e6db15 | |
parent | ce5eab024583af5a4725503bad6ed2aee452b1aa (diff) | |
download | petitboot-89ccc8e6dc81bc1d613454b9944c2f3324d43e2a.zip petitboot-89ccc8e6dc81bc1d613454b9944c2f3324d43e2a.tar.gz |
Use separate section for parsers array
Instead of hardcoding the array of parsers, use the linker to do the
work for us.
Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
-rw-r--r-- | discover/device-handler.c | 2 | ||||
-rw-r--r-- | discover/kboot-parser.c | 6 | ||||
-rw-r--r-- | discover/parser-utils.h | 10 | ||||
-rw-r--r-- | discover/parser.c | 36 | ||||
-rw-r--r-- | discover/parser.h | 2 |
5 files changed, 41 insertions, 15 deletions
diff --git a/discover/device-handler.c b/discover/device-handler.c index 593b8e0..c7e0227 100644 --- a/discover/device-handler.c +++ b/discover/device-handler.c @@ -395,6 +395,8 @@ struct device_handler *device_handler_init(struct discover_server *server) for (i = 0; i < sizeof(options) / sizeof(options[0]); i++) list_add(&device.boot_options, &options[i].list); + parser_init(); + return handler; } diff --git a/discover/kboot-parser.c b/discover/kboot-parser.c index f227ee3..f8cd61d 100644 --- a/discover/kboot-parser.c +++ b/discover/kboot-parser.c @@ -290,8 +290,4 @@ out: return rc; } -struct parser kboot_parser = { - .name = "kboot.conf parser", - .priority = 98, - .parse = parse -}; +define_parser(kboot, 98, parse); diff --git a/discover/parser-utils.h b/discover/parser-utils.h index e82e3f9..955f5f4 100644 --- a/discover/parser-utils.h +++ b/discover/parser-utils.h @@ -7,6 +7,16 @@ #define artwork_pathname(file) (PKG_SHARE_DIR "/artwork/" file) +#define define_parser(__name, __priority, __parse_fn) \ + struct parser \ + __attribute__((unused, section("parsers"))) \ + __ ## __name ## _parser = { \ + .name = #__name, \ + .priority = __priority, \ + .parse = __parse_fn, \ + }; + + void device_add_boot_option(struct device *device, struct boot_option *boot_option); diff --git a/discover/parser.c b/discover/parser.c index 5b1a7ab..87241a9 100644 --- a/discover/parser.c +++ b/discover/parser.c @@ -6,25 +6,41 @@ #include "device-handler.h" #include "log.h" #include "parser.h" -extern struct parser kboot_parser; +#include "parser-utils.h" -/* array of parsers, ordered by priority */ -static struct parser *parsers[] = { - &kboot_parser, - NULL -}; +extern struct parser __start_parsers[], __stop_parsers[]; void iterate_parsers(struct discover_context *ctx) { - int i; + struct parser *parser; pb_log("trying parsers for %s\n", ctx->device_path); - for (i = 0; parsers[i]; i++) { - pb_log("\ttrying parser '%s'\n", parsers[i]->name); + for (parser = __start_parsers; parser < __stop_parsers; parser++) { + pb_log("\ttrying parser '%s'\n", parser->name); /* just use a dummy device path for now */ - if (parsers[i]->parse(ctx)) + if (parser->parse(ctx)) return; } pb_log("\tno boot_options found\n"); } + +static int compare_parsers(const void *a, const void *b) +{ + const struct parser *parser_a = a, *parser_b = b; + + if (parser_a->priority > parser_b->priority) + return -1; + + if (parser_a->priority < parser_b->priority) + return 1; + + return 0; +} + +void parser_init(void) +{ + /* sort our parsers into descending priority order */ + qsort(__start_parsers, __stop_parsers - __start_parsers, + sizeof(struct parser), compare_parsers); +} diff --git a/discover/parser.h b/discover/parser.h index bf9a4d0..ff86578 100644 --- a/discover/parser.h +++ b/discover/parser.h @@ -20,6 +20,8 @@ enum generic_icon_type { #define streq(a,b) (!strcasecmp((a),(b))) +void parser_init(void); + void iterate_parsers(struct discover_context *ctx); #endif /* _PARSER_H */ |