-#include <petitboot-paths.h>
#include <stdlib.h>
-#include <string.h>
-#include "parser.h"
+#include "pb-protocol/pb-protocol.h"
+#include <log/log.h>
-extern struct parser native_parser;
-extern struct parser yaboot_parser;
-extern struct parser kboot_parser;
+#include "device-handler.h"
+#include "parser.h"
+#include "parser-utils.h"
-/* array of parsers, ordered by priority */
-static struct parser *parsers[] = {
- &native_parser,
- &yaboot_parser,
- &kboot_parser,
- NULL
-};
+extern struct parser __start_parsers[], __stop_parsers[];
-void iterate_parsers(const char *devpath, const char *mountpoint)
+void iterate_parsers(struct discover_context *ctx)
{
- int i;
+ struct parser *parser;
+ unsigned int count = 0;
- pb_log("trying parsers for %s\n", devpath);
+ 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);
- /* just use a dummy device path for now */
- if (parsers[i]->parse(devpath))
- return;
+ for (parser = __start_parsers; parser < __stop_parsers; parser++) {
+ pb_log("\ttrying parser '%s'\n", parser->name);
+ count += parser->parse(ctx);
}
- pb_log("\tno boot_options found\n");
+ if (!count)
+ pb_log("\tno boot_options found\n");
}
-/* convenience functions for parsers */
-void free_device(struct device *dev)
+static int compare_parsers(const void *a, const void *b)
{
- if (!dev)
- return;
- if (dev->id)
- free(dev->id);
- if (dev->name)
- free(dev->name);
- if (dev->description)
- free(dev->description);
- if (dev->icon_file)
- free(dev->icon_file);
- free(dev);
-}
+ const struct parser *parser_a = a, *parser_b = b;
-void free_boot_option(struct boot_option *opt)
-{
- if (!opt)
- return;
- if (opt->name)
- free(opt->name);
- if (opt->description)
- free(opt->description);
- if (opt->icon_file)
- free(opt->icon_file);
- if (opt->boot_image_file)
- free(opt->boot_image_file);
- if (opt->initrd_file)
- free(opt->initrd_file);
- if (opt->boot_args)
- free(opt->boot_args);
- free(opt);
+ if (parser_a->priority > parser_b->priority)
+ return -1;
+
+ if (parser_a->priority < parser_b->priority)
+ return 1;
+
+ return 0;
}
-const char *generic_icon_file(enum generic_icon_type type)
+void parser_init(void)
{
- switch (type) {
- case ICON_TYPE_DISK:
- return artwork_pathname("hdd.png");
- case ICON_TYPE_USB:
- return artwork_pathname("usbpen.png");
- case ICON_TYPE_OPTICAL:
- return artwork_pathname("cdrom.png");
- case ICON_TYPE_NETWORK:
- case ICON_TYPE_UNKNOWN:
- break;
- }
- return artwork_pathname("hdd.png");
+ /* sort our parsers into descending priority order */
+ qsort(__start_parsers, __stop_parsers - __start_parsers,
+ sizeof(struct parser), compare_parsers);
}
-