Use separate section for parsers array
authorJeremy Kerr <jk@ozlabs.org>
Fri, 2 Jan 2009 09:27:00 +0000 (18:27 +0900)
committerJeremy Kerr <jk@ozlabs.org>
Fri, 2 Jan 2009 09:27:00 +0000 (18:27 +0900)
Instead of hardcoding the array of parsers, use the linker to do the
work for us.

Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
discover/device-handler.c
discover/kboot-parser.c
discover/parser-utils.h
discover/parser.c
discover/parser.h

index 593b8e0a961e8f0c3463a46702988442eca06135..c7e0227f242529d0673c22655c4064a5daf8e930 100644 (file)
@@ -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;
 }
 
index f227ee35f910e604c6c4623ff9166d3d64a01f63..f8cd61d5b2e66a2cd971265cdcecccd6822d9af3 100644 (file)
@@ -290,8 +290,4 @@ out:
        return rc;
 }
 
-struct parser kboot_parser = {
-       .name     = "kboot.conf parser",
-       .priority = 98,
-       .parse    = parse
-};
+define_parser(kboot, 98, parse);
index e82e3f9c81638be7cdbe2bedcbcca2eba98f66fa..955f5f4d7e6b7c730c3f4e7a2f8313dacd71afe1 100644 (file)
@@ -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);
 
index 5b1a7abdab600656bc803721bef66f07bdcc9b88..87241a9cdb2e60b98913791b81eae86f371d08f3 100644 (file)
@@ -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);
+}
index bf9a4d02b4e5f55a96f9e604f49cb653bcad40c5..ff8657813e8d8ddc27bb7629bb1f81769d2859ef 100644 (file)
@@ -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 */