From 45e92aa32a80fdbbf5ad3ad64e34b1ac872018ef Mon Sep 17 00:00:00 2001 From: Jeremy Kerr Date: Mon, 18 Mar 2013 14:23:23 +0800 Subject: parsers: dynamically register parsers Currently, we require all parsers to be defined in an array in parsers.c. This change removes this requirement, by introducting a register_parser() macro, which adds a constructor to register the parser with the core parser infrastructure. Because each parser no longer resolves an undefined symbol, we need to use a `ld -r` object for libparser, instead of using libtool, which creates a .a (and hence has no parsers included). Signed-off-by: Jeremy Kerr --- discover/Makefile.am | 15 ++++++++------- discover/grub2-parser.c | 4 +++- discover/kboot-parser.c | 4 +++- discover/parser-utils.h | 17 +++++++++++------ discover/parser.c | 23 ++++++++++------------- discover/yaboot-parser.c | 4 +++- 6 files changed, 38 insertions(+), 29 deletions(-) (limited to 'discover') diff --git a/discover/Makefile.am b/discover/Makefile.am index a3087ef..8cbb0af 100644 --- a/discover/Makefile.am +++ b/discover/Makefile.am @@ -19,15 +19,13 @@ AM_CFLAGS = $(DEFAULT_CFLAGS) \ -DPKG_SHARE_DIR='"$(pkgdatadir)"' \ -DLOCAL_STATE_DIR='"$(localstatedir)"' -noinst_LTLIBRARIES = libparser.la +noinst_LIBRARIES = libparser.o -libparser_la_SOURCES = \ +libparser_o_SOURCES = \ parser.c \ parser.h \ parser-conf.c \ parser-conf.h \ - parser-utils.c \ - parser-utils.h \ paths.c \ paths.h \ resource.c \ @@ -36,9 +34,10 @@ libparser_la_SOURCES = \ grub2-parser.c \ yaboot-parser.c -EXTRA_DIST = native-parser.c +libparser.o: $(libparser_o_OBJECTS) + $(LD) -r -o $@ $^ -libparser_la_LIBADD = $(top_builddir)/lib/libpbcore.la +EXTRA_DIST = native-parser.c sbin_PROGRAMS = pb-discover @@ -54,6 +53,8 @@ pb_discover_SOURCES = \ event-parser.c \ params.c \ params.h \ + parser-utils.c \ + parser-utils.h \ pb-discover.c \ pb-discover.h \ udev.c \ @@ -61,6 +62,6 @@ pb_discover_SOURCES = \ user-event.c \ user-event.h -pb_discover_LDADD = libparser.la $(top_builddir)/lib/libpbcore.la +pb_discover_LDADD = libparser.o $(top_builddir)/lib/libpbcore.la MAINTAINERCLEANFILES = Makefile.in diff --git a/discover/grub2-parser.c b/discover/grub2-parser.c index eaf3cd3..4a1acf5 100644 --- a/discover/grub2-parser.c +++ b/discover/grub2-parser.c @@ -191,8 +191,10 @@ static int grub2_parse(struct discover_context *dc, char *buf, int len) return 1; } -struct parser __grub2_parser = { +static struct parser grub2_parser = { .name = "grub2", .parse = grub2_parse, .filenames = grub2_conf_files, }; + +register_parser(grub2_parser); diff --git a/discover/kboot-parser.c b/discover/kboot-parser.c index e602dc4..884658e 100644 --- a/discover/kboot-parser.c +++ b/discover/kboot-parser.c @@ -157,9 +157,11 @@ static int kboot_parse(struct discover_context *dc, char *buf, int len) return 1; } -struct parser __kboot_parser = { +static struct parser kboot_parser = { .name = "kboot", .parse = kboot_parse, .filenames = kboot_conf_files, .resolve_resource = resolve_devpath_resource, }; + +register_parser(kboot_parser); diff --git a/discover/parser-utils.h b/discover/parser-utils.h index 107f4f3..9096b31 100644 --- a/discover/parser-utils.h +++ b/discover/parser-utils.h @@ -8,12 +8,17 @@ #define artwork_pathname(file) (PKG_SHARE_DIR "/artwork/" file) -#define define_parser(__name, __parse_fn) \ - struct parser \ - __ ## __name ## _parser = { \ - .name = #__name, \ - .parse = __parse_fn, \ - }; +#define __parser_funcname(_n) __register_parser ## _ ## _n +#define _parser_funcname(_n) __parser_funcname(_n) + +#define register_parser(_parser) \ + static __attribute__((constructor)) \ + void _parser_funcname(__COUNTER__)(void) \ + { \ + __register_parser(&_parser); \ + } + +void __register_parser(struct parser *parser); void device_add_boot_option(struct device *device, struct boot_option *boot_option); diff --git a/discover/parser.c b/discover/parser.c index 0df8a73..641e06b 100644 --- a/discover/parser.c +++ b/discover/parser.c @@ -13,18 +13,8 @@ #include "parser-utils.h" #include "paths.h" -struct parser __grub2_parser; -struct parser __kboot_parser; -struct parser __native_parser; -struct parser __yaboot_parser; - -static struct parser *const parsers[] = { -// &__native_parser, - &__kboot_parser, - &__grub2_parser, - &__yaboot_parser, - NULL -}; +static int n_parsers; +static struct parser **parsers; static const int max_file_size = 1024 * 1024; @@ -114,7 +104,7 @@ void iterate_parsers(struct discover_context *ctx) pb_log("trying parsers for %s\n", ctx->device->device->id); - for (i = 0; parsers[i]; i++) { + for (i = 0; i < n_parsers; i++) { pb_log("\ttrying parser '%s'\n", parsers[i]->name); ctx->parser = parsers[i]; iterate_parser_files(ctx, parsers[i]); @@ -122,6 +112,13 @@ void iterate_parsers(struct discover_context *ctx) ctx->parser = NULL; } +void __register_parser(struct parser *parser) +{ + parsers = talloc_realloc(NULL, parsers, struct parser *, n_parsers + 1); + parsers[n_parsers] = parser; + n_parsers++; +} + void parser_init(void) { } diff --git a/discover/yaboot-parser.c b/discover/yaboot-parser.c index 0a66e8d..f51d2c6 100644 --- a/discover/yaboot-parser.c +++ b/discover/yaboot-parser.c @@ -313,8 +313,10 @@ static int yaboot_parse(struct discover_context *dc, char *buf, int len) return 1; } -struct parser __yaboot_parser = { +static struct parser yaboot_parser = { .name = "yaboot", .parse = yaboot_parse, .filenames = yaboot_conf_files, }; + +register_parser(yaboot_parser); -- cgit v1.2.1