From: Jeremy Kerr Date: Fri, 2 Jan 2009 09:27:00 +0000 (+0900) Subject: Use separate section for parsers array X-Git-Tag: v1.0.0~938 X-Git-Url: https://git.ozlabs.org/?p=petitboot;a=commitdiff_plain;h=89ccc8e6dc81bc1d613454b9944c2f3324d43e2a;ds=sidebyside 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 --- 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 */