summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeremy Kerr <jk@ozlabs.org>2009-01-02 18:27:00 +0900
committerJeremy Kerr <jk@ozlabs.org>2009-01-02 18:27:00 +0900
commit89ccc8e6dc81bc1d613454b9944c2f3324d43e2a (patch)
treeaab4c63f6e29336ae423c905b55acf4329e6db15
parentce5eab024583af5a4725503bad6ed2aee452b1aa (diff)
downloadpetitboot-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.c2
-rw-r--r--discover/kboot-parser.c6
-rw-r--r--discover/parser-utils.h10
-rw-r--r--discover/parser.c36
-rw-r--r--discover/parser.h2
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 */
OpenPOWER on IntegriCloud