parsers: dynamically register parsers
authorJeremy Kerr <jk@ozlabs.org>
Mon, 18 Mar 2013 06:23:23 +0000 (14:23 +0800)
committerJeremy Kerr <jk@ozlabs.org>
Mon, 29 Apr 2013 04:41:04 +0000 (14:41 +1000)
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 <jk@ozlabs.org>
discover/Makefile.am
discover/grub2-parser.c
discover/kboot-parser.c
discover/parser-utils.h
discover/parser.c
discover/yaboot-parser.c
test/parser/Makefile.am

index a3087ef8fefe223796427b65998f45b4a1fcc7cf..8cbb0af7c3727d6fab2d70e23606ee9e1c544adb 100644 (file)
@@ -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
index eaf3cd3c64d5adcc5ac34e7601998ff4d0415799..4a1acf5da371113562005a07fa763a2033138240 100644 (file)
@@ -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);
index e602dc4142582b31db7ad2ac25d96481bc895554..884658e8d07bcd6da655fb536bf13d56f27aad85 100644 (file)
@@ -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);
index 107f4f3ab02c6bba935e09b4552e72faf7cb5ed0..9096b311ce6ecc00b4fd0d3f0c851fe8f588a4c5 100644 (file)
@@ -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);
index 0df8a737c103c5265782c75a6b140ef0fb945648..641e06b1cb54e9bdf34d1547e8a3de465a2097f2 100644 (file)
 #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)
 {
 }
index 0a66e8d588241d69b66a9fc3d1119edce7f3c38a..f51d2c61d886b07c0992ba776fb430fce52a63d4 100644 (file)
@@ -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);
index d90c368103299ad7676daaf7ba0f3d4253622f6a..7360926056bfd3c36feca4bb07394cd64fb3a042 100644 (file)
@@ -23,7 +23,7 @@ AM_CFLAGS = \
 
 common_libs = \
        $(top_builddir)/lib/libpbcore.la \
-       $(top_builddir)/discover/libparser.la
+       $(top_builddir)/discover/libparser.o
 
 noinst_PROGRAMS = parser-test