plugins: add some of the missing functionality (plugin metadata, checks)
authorKrisztian Litkey <krisztian.litkey@intel.com>
Fri, 13 Apr 2012 13:17:09 +0000 (16:17 +0300)
committerKrisztian Litkey <kli@iki.fi>
Tue, 17 Apr 2012 21:50:00 +0000 (00:50 +0300)
Added plugin and API versioning, singletons, author et al metadata,
API version check and singletonnes check. Started adding plugin states.

src/Makefile.am
src/common/macros.h
src/core/plugin.c
src/core/plugin.h
src/daemon/config.c
src/daemon/daemon.c
src/plugins/plugin-dbus.c
src/plugins/plugin-glib.c
src/plugins/plugin-test.c

index e360ad7..1d6179c 100644 (file)
@@ -28,14 +28,16 @@ libmurphy_common_la_HEADERS =               \
                common/mm.h             \
                common/hashtbl.h        \
                common/mainloop.h       \
-               common/utils.h
+               common/utils.h          \
+               common/file-utils.h
 
 libmurphy_common_la_SOURCES =          \
                common/log.c            \
                common/mm.c             \
                common/hashtbl.c        \
                common/mainloop.c       \
-               common/utils.c
+               common/utils.c          \
+               common/file-utils.c
 
 libmurphy_common_la_CFLAGS  =          \
                $(AM_CFLAGS)
index 332d421..1754a73 100644 (file)
 #    define MRP_ASSERT(expr, msg) do { } while (0)
 #endif
 
+/** Create a version integer from a (major, minor, micro) tuple. */
+#define MRP_VERSION_INT(maj, min, mic) \
+    ((((maj) & 0xff) << 16) | (((min) & 0xff) << 8) | ((mic) & 0xff))
+
+/** Create a version string from a (const) (major, minor, micro) tuple.  */
+#define MRP_VERSION_STRING(maj, min, mic) #maj"."#min"."#mic
+
+/** Extract major version from a version integer. */
+#define MRP_VERSION_MAJOR(ver) (((ver) >> 16) & 0xff)
+
+/** Extract minor version from a version integer. */
+#define MRP_VERSION_MINOR(ver) (((ver) >>  8) & 0xff)
+
+/** Extract micro version from a version intege. */
+#define MRP_VERSION_MICRO(ver) ((ver) & 0xff)
+
 
 /** C++-compatibility macros. */
 #ifdef __cplusplus
index 443d4bd..357bca9 100644 (file)
@@ -5,6 +5,7 @@
 #include <sys/types.h>
 
 #include <murphy/common/list.h>
+#include <murphy/common/file-utils.h>
 #include <murphy/core/plugin.h>
 
 #define PLUGIN_PREFIX "plugin-"
@@ -62,13 +63,43 @@ int mrp_plugin_exists(mrp_context_t *ctx, const char *name)
 }
 
 
+static inline int check_plugin_version(mrp_plugin_descr_t *descr)
+{
+    int major, minor;
+    
+    major = MRP_VERSION_MAJOR(descr->mrp_version);
+    minor = MRP_VERSION_MINOR(descr->mrp_version);
+
+    if (major != MRP_PLUGIN_API_MAJOR || minor > MRP_PLUGIN_API_MINOR) {
+       mrp_log_error("Plugin '%s' uses incompatible version (%d.%d vs. %d.%d)",
+                     descr->name, major, minor,
+                     MRP_PLUGIN_API_MAJOR, MRP_PLUGIN_API_MINOR);
+       return FALSE;
+    }
+    
+    return TRUE;
+}
+
+
+static inline int check_plugin_singleton(mrp_plugin_descr_t *descr)
+{
+    if (descr->singleton && descr->ninstance > 1) {
+       mrp_log_error("Singleton plugin '%s' has already been instantiated.",
+                     descr->name);
+       return FALSE;
+    }
+    else
+       return TRUE;
+}
+
+
 mrp_plugin_t *mrp_load_plugin(mrp_context_t *ctx, const char *name,
                              const char *instance, mrp_plugin_arg_t *args,
                              int narg)
 {
     mrp_plugin_t       *plugin;
     char                path[PATH_MAX];
-    mrp_plugin_descr_t *dynamic, *builtin;
+    mrp_plugin_descr_t *dynamic, *builtin, *descr;
     void               *handle;
     
     if (name == NULL)
@@ -94,19 +125,26 @@ mrp_plugin_t *mrp_load_plugin(mrp_context_t *ctx, const char *name,
        if (builtin != NULL)
            mrp_log_warning("Dynamic plugin '%s' shadows builtin plugin '%s'.",
                            path, builtin->path);
+       descr = dynamic;
     }
     else {
        if (builtin == NULL) {
            mrp_log_error("Could not find plugin '%s'.", name);
            return NULL;
        }
+       descr = builtin;
     }
-       
+
+    descr->ninstance++;
+
+    if (!check_plugin_version(descr) || !check_plugin_singleton(descr))
+       goto fail;
+    
     if ((plugin = mrp_allocz(sizeof(*plugin))) != NULL) {
        mrp_list_init(&plugin->hook);
        
        plugin->instance = mrp_strdup(instance);
-       plugin->path     = mrp_strdup(handle ? path : builtin->path);
+       plugin->path     = mrp_strdup(handle ? path : descr->path);
 
        if (plugin->instance == NULL || plugin->path == NULL) {
            mrp_log_error("Failed to allocate plugin '%s'.", name);
@@ -114,7 +152,7 @@ mrp_plugin_t *mrp_load_plugin(mrp_context_t *ctx, const char *name,
        }
        
        plugin->ctx        = ctx;
-       plugin->descriptor = handle ? dynamic : builtin;
+       plugin->descriptor = descr;
        plugin->refcnt     = 1;
        plugin->handle     = handle;
        
@@ -135,6 +173,67 @@ mrp_plugin_t *mrp_load_plugin(mrp_context_t *ctx, const char *name,
 }
 
 
+static int load_plugin_cb(const char *file, mrp_dirent_type_t type, void *data)
+{
+    mrp_context_t *ctx = (mrp_context_t *)data;
+    char           name[PATH_MAX], *start, *end;
+    int            len;
+
+    MRP_UNUSED(type);
+
+    if ((start = strstr(file, PLUGIN_PREFIX)) != NULL) {
+       start += sizeof(PLUGIN_PREFIX) - 1;
+       if ((end = strstr(start, ".so")) != NULL) {
+           len = end - start;
+           strncpy(name, start, len);
+           name[len] = '\0';
+           mrp_load_plugin(ctx, name, NULL, NULL, 0);
+       }
+    }
+
+    return TRUE;
+}
+
+
+int mrp_load_all_plugins(mrp_context_t *ctx)
+{
+    mrp_dirent_type_t  type;
+    const char        *pattern;
+    mrp_list_hook_t   *p, *n;
+    mrp_plugin_t      *plugin;
+    
+    type    = MRP_DIRENT_REG;
+    pattern = PLUGIN_PREFIX".*\\.so$";
+    mrp_scan_dir(ctx->plugin_dir, pattern, type, load_plugin_cb, ctx);
+
+
+    mrp_list_foreach(&builtin_plugins, p, n) {
+       plugin = mrp_list_entry(p, typeof(*plugin), hook);
+       
+       mrp_load_plugin(ctx, plugin->descriptor->name, NULL, NULL, 0);
+    }
+
+    return TRUE;
+}
+
+
+int mrp_request_plugin(mrp_context_t *ctx, const char *name,
+                      const char *instance)
+{
+    mrp_plugin_t *plugin;
+
+    if (instance == NULL)
+       instance = name;
+
+    if ((plugin = find_plugin_instance(ctx, instance)) != NULL) {
+       if (instance == name || !strcmp(plugin->descriptor->name, name))
+           return TRUE;
+    }
+
+    return (mrp_load_plugin(ctx, name, instance, NULL, 0) != NULL);
+}
+
+
 int mrp_unload_plugin(mrp_plugin_t *plugin)
 {
     mrp_plugin_arg_t *pa, *da;
@@ -155,6 +254,8 @@ int mrp_unload_plugin(mrp_plugin_t *plugin)
                mrp_free(plugin->args);
            }
 
+           plugin->descriptor->ninstance--;
+
            if (plugin->handle != NULL)
                dlclose(plugin->handle);
        
index 2418f79..f0633a4 100644 (file)
@@ -33,13 +33,13 @@ typedef enum {
 
 typedef struct {
     char                  *key;          /* plugin argument name */
-    mrp_plugin_arg_type_t  type;         /* expected type */
+    mrp_plugin_arg_type_t  type;         /* plugin argument type */
     union {                              /* default/supplied value */
-       char              *str;
-       bool               bln;
-       uint32_t           u32;
-       int32_t            i32;
-       double             dbl;
+       char              *str;          /* string values */
+       bool               bln;          /* boolean values */
+       uint32_t           u32;          /* 32-bit unsigned values */
+       int32_t            i32;          /* 32-bit signed values */
+       double             dbl;          /* double prec. floating pt. values */
     };
 } mrp_plugin_arg_t;
 
@@ -86,6 +86,8 @@ typedef struct {
  * arguments:
  *
  * #define TEST_HELP "Just a stupid test..."
+ * #define TEST_DESCRIPTION "A test plugin."
+ * #define TEST_AUTHORS "D. Duck <donald.duck@ducksburg.org>"
  *
  * enum {
  *     ARG_FOO,
@@ -115,33 +117,57 @@ typedef struct {
  *     ...
  * }
  *
- * MURPHY_REGISTER_PLUGIN("test", TEST_HELP, test_init, test_exit, test_args);
+ * MURPHY_REGISTER_PLUGIN("test", TEST_DESCRIPTION, TEST_AUTHORS, TEST_HELP,
+ *                        MRP_MULTIPLE, test_init, test_exit, test_args);
  */
 
 #define MRP_PLUGIN_ARGIDX(idx, type, name, defval)     \
     [idx] MRP_PLUGIN_ARG_##type(name, defval)
 
 
+/*
+ * plugin API version
+ */
+
+#define MRP_PLUGIN_API_MAJOR 0
+#define MRP_PLUGIN_API_MINOR 1
+
+#define MRP_PLUGIN_API_VERSION \
+    MRP_VERSION_INT(MRP_PLUGIN_API_MAJOR, MRP_PLUGIN_API_MINOR, 0)
+
+#define MRP_PLUGIN_API_VERSION_STRING \
+    MRP_VERSION_STRING(MRP_PLUGIN_API_MAJOR, MRP_PLUGIN_API_MINOR, 0)
+
 
 /*
  * plugin descriptors
  */
 
+
 typedef struct mrp_plugin_s mrp_plugin_t;
 
 typedef int  (*mrp_plugin_init_t)(mrp_plugin_t *);
 typedef void (*mrp_plugin_exit_t)(mrp_plugin_t *);
 
+#define MRP_SINGLETON TRUE
+#define MRP_MULTIPLE  FALSE
 
 typedef struct {
-    char                *name;                   /* plugin name */
-    char                *path;                   /* plugin path */
-    mrp_plugin_init_t    init;                   /* initialize plugin */
-    mrp_plugin_exit_t    exit;                   /* cleanup plugin */
-    const char          *help;                   /* plugin help */
-    int                  core;                   /* whether a core plugin */
-    mrp_plugin_arg_t    *args;                   /* table of valid arguments */
-    int                  narg;                   /* number of valid arguments */
+    char                *name;                 /* plugin name */
+    char                *path;                 /* plugin path */
+    mrp_plugin_init_t    init;                 /* initialize plugin */
+    mrp_plugin_exit_t    exit;                 /* cleanup plugin */
+    mrp_plugin_arg_t    *args;                 /* table of valid arguments */
+    int                  narg;                 /* number of valid arguments */
+    int                  core : 1;             /* is this a core plugin? */
+    int                  singleton : 1;        /* deny multiple instances? */
+    int                  ninstance;            /* number of instances */
+    /* miscallaneous plugin metadata */
+    int                  version;              /* plugin version */
+    int                  mrp_version;          /* murphy API version */
+    const char          *description;          /* plugin description */
+    const char          *authors;              /* plugin authors */
+    const char          *help;                 /* plugin help string */
 } mrp_plugin_descr_t;
 
 
@@ -149,39 +175,56 @@ typedef struct {
  * plugins
  */
 
+typedef enum {
+    MRP_PLUGIN_LOADED = 0,                     /* has been loaded */
+    MRP_PLUGIN_RUNNING,                        /* has been started */
+    MRP_PLUGIN_STOPPED,                        /* has been stopped */
+} mrp_plugin_state_t;
+
 struct mrp_plugin_s {
-    char               *path;                    /* plugin path */
-    char               *instance;                /* plugin instance */
-    mrp_list_hook_t     hook;                    /* hook to list of plugins */
-    mrp_context_t      *ctx;                     /* murphy context */
-    mrp_plugin_descr_t *descriptor;              /* plugin descriptor */
-    void               *handle;                  /* DSO handle */
-    int                 refcnt;                  /* reference count */
-    void               *data;                    /* private plugin data */
-    mrp_plugin_arg_t   *args;                    /* plugin arguments */
+    char               *path;                  /* plugin path */
+    char               *instance;              /* plugin instance */
+    mrp_list_hook_t     hook;                  /* hook to list of plugins */
+    mrp_context_t      *ctx;                   /* murphy context */
+    mrp_plugin_descr_t *descriptor;            /* plugin descriptor */
+    void               *handle;                /* DSO handle */
+    mrp_plugin_state_t  state;                 /* plugin state */
+    int                 refcnt;                /* reference count */
+    void               *data;                  /* private plugin data */
+    mrp_plugin_arg_t   *args;                  /* plugin arguments */
 };
 
 
 #ifdef __MURPHY_BUILTIN_PLUGIN__
 /*   statically linked in plugins */
 #    define __MURPHY_REGISTER_PLUGIN(_name,                            \
+                                    _version,                          \
+                                    _description,                      \
+                                    _authors,                          \
                                     _help,                             \
+                                    _core,                             \
+                                    _single,                           \
                                     _init,                             \
                                     _exit,                             \
-                                    _core,                             \
                                     _args)                             \
     static void register_plugin(void) __attribute__((constructor));    \
                                                                        \
     static void register_plugin(void) {                                        \
        char *path = __FILE__, *base;                                   \
        static mrp_plugin_descr_t descriptor = {                        \
-           .name = _name,                                              \
-           .init = _init,                                              \
-           .exit = _exit,                                              \
-           .help = _help,                                              \
-           .core = _core,                                              \
-            .args = _args,                                             \
-           .narg = MRP_ARRAY_SIZE(_args),                              \
+           .name        = _name,                                       \
+           .version     = _version,                                    \
+           .description = _description,                                \
+           .authors     = _authors,                                    \
+           .mrp_version = MRP_PLUGIN_API_VERSION,                      \
+           .help        = _help,                                       \
+           .init        = _init,                                       \
+           .exit        = _exit,                                       \
+           .core        = _core,                                       \
+           .singleton   = _single,                                     \
+           .ninstance   = 0,                                           \
+            .args        = _args,                                      \
+           .narg        = MRP_ARRAY_SIZE(_args),                       \
        };                                                              \
                                                                        \
        if ((base = strrchr(path, '/')) != NULL)                        \
@@ -194,21 +237,31 @@ struct mrp_plugin_s {
     struct mrp_allow_trailing_semicolon
 #else /* dynamically loaded plugins */
 #    define __MURPHY_REGISTER_PLUGIN(_name,                            \
+                                    _version,                          \
+                                    _description,                      \
+                                    _authors,                          \
                                     _help,                             \
+                                    _core,                             \
+                                    _single,                           \
                                     _init,                             \
                                     _exit,                             \
-                                    _core,                             \
                                     _args)                             \
                                                                        \
     mrp_plugin_descr_t *mrp_get_plugin_descriptor(void) {              \
        static mrp_plugin_descr_t descriptor = {                        \
-           .name = _name,                                              \
-           .init = _init,                                              \
-           .exit = _exit,                                              \
-           .help = _help,                                              \
-           .core = _core,                                              \
-           .args = _args,                                              \
-           .narg = MRP_ARRAY_SIZE(_args),                              \
+           .name        = _name,                                       \
+           .version     = _version,                                    \
+           .description = _description,                                \
+           .authors     = _authors,                                    \
+           .mrp_version = MRP_PLUGIN_API_VERSION,                      \
+           .help        = _help,                                       \
+           .init        = _init,                                       \
+           .exit        = _exit,                                       \
+           .core        = _core,                                       \
+           .singleton   = _single,                                     \
+           .ninstance   = 0,                                           \
+           .args        = _args,                                       \
+           .narg        = MRP_ARRAY_SIZE(_args),                       \
        };                                                              \
                                                                        \
        return &descriptor;                                             \
@@ -217,11 +270,11 @@ struct mrp_plugin_s {
 #endif
 
 
-#define MURPHY_REGISTER_PLUGIN(_n, _h, _i, _e, _a)             \
-    __MURPHY_REGISTER_PLUGIN(_n, _h, _i, _e, FALSE, _a)
+#define MURPHY_REGISTER_PLUGIN(_n, _v, _d, _a, _h, _s, _i, _e, _args)  \
+    __MURPHY_REGISTER_PLUGIN(_n, _v, _d, _a, _h, FALSE, _s, _i, _e, _args)
 
-#define MURPHY_REGISTER_CORE_PLUGIN(_n, _h, _i, _e, _a)        \
-    __MURPHY_REGISTER_PLUGIN(_n, _h, _i, _e, TRUE, _a)
+#define MURPHY_REGISTER_CORE_PLUGIN(_n, _v, _d, _a, _h, _s, _i, _e, _args) \
+    __MURPHY_REGISTER_PLUGIN(_n, _v, _d, _a, _h, TRUE, _s, _i, _e, _args)
 
 #define MRP_REGISTER_PLUGIN MURPHY_REGISTER_PLUGIN
 #define MRP_REGISTER_CORE_PLUGIN MURPHY_REGISTER_CORE_PLUGIN
@@ -232,9 +285,13 @@ int mrp_plugin_exists(mrp_context_t *ctx, const char *name);
 mrp_plugin_t *mrp_load_plugin(mrp_context_t *ctx, const char *name,
                              const char *instance, mrp_plugin_arg_t *args,
                              int narg);
+int mrp_load_all_plugins(mrp_context_t *ctx);
 int mrp_unload_plugin(mrp_plugin_t *plugin);
 int mrp_start_plugins(mrp_context_t *ctx);
 int mrp_start_plugin(mrp_plugin_t *plugin);
 int mrp_stop_plugin(mrp_plugin_t *plugin);
+int mrp_request_plugin(mrp_context_t *ctx, const char *name,
+                      const char *instance);
+
 
 #endif /* __MURPHY_PLUGIN_H__ */
index 2b16a09..7f25447 100644 (file)
@@ -49,7 +49,9 @@ static void print_usage(const char *argv0, int exit_code, const char *fmt, ...)
           "      E.g -a foo:bar=xyzzy sets the value of configuration key\n"
           "      'bar' to the value 'xyzzy' for plugin 'foo'.\n"
 #endif
-           "  -h, --help                     show help on usage\n",
+           "  -h, --help                     show help on usage\n"
+           "  -q, --query-plugins            show detailed information about\n"
+          "                                 all the available plugins\n",
            argv0, MRP_DEFAULT_CONFIG_FILE, MRP_DEFAULT_CONFIG_DIR,
           MRP_DEFAULT_PLUGIN_DIR);
 
@@ -60,29 +62,83 @@ static void print_usage(const char *argv0, int exit_code, const char *fmt, ...)
 }
 
 
-static void print_plugin_help(mrp_context_t *ctx)
+static void print_plugin_help(mrp_context_t *ctx, int detailed)
 {
-    MRP_UNUSED(ctx);
-
-#if 0
-    mrp_plugin_t    *plugin;
-    mrp_list_hook_t *p, *n;
-
+#define PRNT(fmt, arg) snprintf(defval, sizeof(defval), fmt, arg)
+
+    mrp_plugin_t       *plugin;
+    mrp_plugin_descr_t *descr;
+    mrp_plugin_arg_t   *arg;
+    mrp_list_hook_t    *p, *n;
+    char               *type, defval[64];
+    int                 i;
+    
     mrp_load_all_plugins(ctx);
     
-    printf("\n");
-    printf("Available plugins:\n\n");
+    printf("\nAvailable plugins:\n\n");
+
     mrp_list_foreach(&ctx->plugins, p, n) {
        plugin = mrp_list_entry(p, typeof(*plugin), hook);
-       printf("- %s plugin '%s' (%s)\n",
-              plugin->dynamic ? "external" : "internal",
-              plugin->descriptor->name, plugin->path);
+       descr  = plugin->descriptor;
+       
+       printf("- %splugin %s:", plugin->handle ? "" : "Builtin ", descr->name);
+       if (detailed) {
+           printf(" (%s, version %d.%d.%d)\n", plugin->path,
+                  MRP_VERSION_MAJOR(descr->version),
+                  MRP_VERSION_MINOR(descr->version),
+                  MRP_VERSION_MICRO(descr->version));
+           printf("  Authors: %s\n", descr->authors);
+       }
+       else
+           printf("\n");
        
-       if (plugin->descriptor->help != NULL && plugin->descriptor->help[0])
-           printf("%s\n", plugin->descriptor->help);
+       if (detailed)
+           printf("  Description:\n    %s\n", descr->description);
+       
+       if (descr->args != NULL) {
+           printf("  Arguments:\n");
+
+           for (i = 0, arg = descr->args; i < descr->narg; i++, arg++) {
+               printf("    %s: ", arg->key);
+               switch (arg->type) {
+               case MRP_PLUGIN_ARG_TYPE_STRING:
+                   type = "string";
+                   PRNT("%s", arg->str ? arg->str : "<none>");
+                   break;
+               case MRP_PLUGIN_ARG_TYPE_BOOL:
+                   type = "boolean";
+                   PRNT("%s", arg->bln ? "TRUE" : "FALSE");
+                   break;
+               case MRP_PLUGIN_ARG_TYPE_UINT32:
+                   type = "unsigned 32-bit integer";
+                   PRNT("%u", arg->u32);
+                   break;
+               case MRP_PLUGIN_ARG_TYPE_INT32:
+                   type = "signed 32-bit integer";
+                   PRNT("%d", arg->i32);
+                   break;
+               case MRP_PLUGIN_ARG_TYPE_DOUBLE:
+                   type = "double-precision floating point";
+                   PRNT("%f", arg->dbl);
+                   break;
+               default:
+                   type = "<unknown argument type>";
+                   PRNT("%s", "<unknown>");
+               }
+
+               printf("%s, default value=%s\n", type, defval);
+           }
+       }
+       
+       if (descr->help != NULL && descr->help[0])
+           printf("  Help:\n    %s\n", descr->help);
+       
+       printf("\n");
     }
     
     printf("\n");
+
+#if 0
     printf("Note that you can disable any plugin from the command line by\n");
     printf("using the '-a name:%s' option.\n", MURPHY_PLUGIN_ARG_DISABLED);
 #endif
@@ -101,20 +157,21 @@ static void config_set_defaults(mrp_context_t *ctx)
 
 int mrp_parse_cmdline(mrp_context_t *ctx, int argc, char **argv)
 {
-    #define OPTIONS "C:D:l:t:fP:a:vdh"
+    #define OPTIONS "C:D:l:t:fP:a:vdhq"
     struct option options[] = {
-       { "config-file", required_argument, NULL, 'C' },
-       { "config-dir" , required_argument, NULL, 'D' },
-       { "plugin-dir" , required_argument, NULL, 'P' },
-       { "log-level"  , required_argument, NULL, 'l' },
-       { "log-target" , required_argument, NULL, 't' },
-       { "verbose"    , optional_argument, NULL, 'v' },
-       { "debug"      , no_argument      , NULL, 'd' },
-       { "foreground" , no_argument      , NULL, 'f' },
+       { "config-file"  , required_argument, NULL, 'C' },
+       { "config-dir"   , required_argument, NULL, 'D' },
+       { "plugin-dir"   , required_argument, NULL, 'P' },
+       { "log-level"    , required_argument, NULL, 'l' },
+       { "log-target"   , required_argument, NULL, 't' },
+       { "verbose"      , optional_argument, NULL, 'v' },
+       { "debug"        , no_argument      , NULL, 'd' },
+       { "foreground"   , no_argument      , NULL, 'f' },
 #if 0
-       { "plugin"    , required_argument, NULL, 'a' },
+       { "plugin"       , required_argument, NULL, 'a' },
 #endif
-       { "help"      , no_argument      , NULL, 'h' },
+       { "help"         , no_argument      , NULL, 'h' },
+       { "query-plugins", no_argument      , NULL, 'q' },
        { NULL, 0, NULL, 0 }
     };
 
@@ -192,9 +249,13 @@ int mrp_parse_cmdline(mrp_context_t *ctx, int argc, char **argv)
            
        case 'h':
            print_usage(argv[0], -1, "");
-           print_plugin_help(ctx);
+           print_plugin_help(ctx, FALSE);
            exit(0);
            break;
+
+       case 'q':
+           print_plugin_help(ctx, TRUE);
+           break;
            
         default:
            print_usage(argv[0], EINVAL, "invalid option '%c'", opt);
index 2683cc2..6663b81 100644 (file)
@@ -32,11 +32,6 @@ static void signal_handler(mrp_mainloop_t *ml, mrp_sighandler_t *h,
 }
 
 
-/*
- * a quick-hack plugin test
- */
-
-
 int main(int argc, char *argv[])
 {
     mrp_context_t *ctx;
index c6f7b4f..553ee02 100644 (file)
@@ -345,6 +345,12 @@ static void dbus_exit(mrp_plugin_t *plugin)
 }
 
 
-#define DBUS_HELP "DBUS pump plugin (DBUS-mainloop integration)."
-
-MURPHY_REGISTER_CORE_PLUGIN("dbus", DBUS_HELP, dbus_init, dbus_exit, NULL);
+#define DBPLG_DESCRIPTION "A plugin to pump DBusConnections."
+#define DBPLG_HELP "DBUS pump plugin (DBUS-mainloop integration)."
+#define DBPLG_VERSION     MRP_VERSION_INT(0, 0, 1)
+#define DBPLG_AUTHORS     "Krisztian Litkey <krisztian.litkey@intel.com>"
+
+MURPHY_REGISTER_CORE_PLUGIN("dbus",
+                           DBPLG_VERSION, DBPLG_DESCRIPTION, DBPLG_AUTHORS,
+                           DBPLG_HELP, MRP_SINGLETON,
+                           dbus_init, dbus_exit, NULL);
index d77d379..fec76a5 100644 (file)
@@ -139,6 +139,12 @@ static void plugin_exit(mrp_plugin_t *plugin)
 }
 
 
-#define PLUGIN_HELP "Glib mainloop pump plugin."
+#define GLIB_DESCRIPTION "Glib mainloop pump plugin."
+#define GLIB_HELP        "Glib pump plugin (GMainLoop integration)."
+#define GLIB_VERSION     MRP_VERSION_INT(0, 0, 1)
+#define GLIB_AUTHORS     "Krisztian Litkey <krisztian.litkey@intel.com>"
+
+MURPHY_REGISTER_PLUGIN("glib", GLIB_VERSION, GLIB_DESCRIPTION, GLIB_AUTHORS,
+                      GLIB_HELP, MRP_SINGLETON,
+                      plugin_init, plugin_exit, NULL);
 
-MURPHY_REGISTER_PLUGIN("glib", PLUGIN_HELP, plugin_init, plugin_exit, NULL);
index fa4451a..a7ab344 100644 (file)
@@ -1,56 +1,37 @@
 #include <murphy/core/plugin.h>
 
 enum {
-    STRING1,
-    STRING2,
-    BOOLEAN1,
-    BOOLEAN2,
-    UINT321,
-    INT321,
-    DOUBLE1,
+    ARG_STRING1,
+    ARG_STRING2,
+    ARG_BOOLEAN1,
+    ARG_BOOLEAN2,
+    ARG_UINT321,
+    ARG_INT321,
+    ARG_DOUBLE1,
+    ARG_FAILINIT,
+    ARG_FAILEXIT,
 };
 
 
 static int test_init(mrp_plugin_t *plugin)
 {
-    mrp_plugin_arg_t *arg, *args;
-    int               i;
+    mrp_plugin_arg_t *args;
 
     mrp_log_info("%s() called for test instance '%s'...", __FUNCTION__,
                 plugin->instance);
-
-    for (i = 0, arg = plugin->args; i < plugin->descriptor->narg; i++, arg++) {
-       switch (arg->type) {
-       case MRP_PLUGIN_ARG_TYPE_STRING:
-           printf("string argument: %s=%s\n", arg->key, arg->str);
-           break;
-       case MRP_PLUGIN_ARG_TYPE_BOOL:
-           printf("boolean argument: %s=%d\n", arg->key, arg->bln);
-           break;
-       case MRP_PLUGIN_ARG_TYPE_UINT32:
-           printf("string argument: %s=%u\n", arg->key, arg->u32);
-           break;
-       case MRP_PLUGIN_ARG_TYPE_INT32:
-           printf("string argument: %s=%d\n", arg->key, arg->i32);
-           break;
-       case MRP_PLUGIN_ARG_TYPE_DOUBLE:
-           printf("double argument: %s=%f\n", arg->key, arg->dbl);
-           break;
-       default:
-           printf("argument of invalid type 0x%x\n", arg->type);
-       }
-    }
-
+    
     args = plugin->args;
-    printf("string1:  %s=%s\n", args[STRING1].key, args[STRING1].str);
-    printf("string2:  %s=%s\n", args[STRING2].key, args[STRING2].str);
-    printf("boolean1: %s=%d\n", args[BOOLEAN1].key, args[BOOLEAN1].bln);
-    printf("boolean2: %s=%d\n", args[BOOLEAN2].key, args[BOOLEAN2].bln);
-    printf("uint32: %s=%d\n", args[UINT321].key, args[UINT321].u32);
-    printf("int32: %s=%d\n", args[INT321].key, args[INT321].i32);
-    printf("double: %s=%f\n", args[DOUBLE1].key, args[DOUBLE1].dbl);
-
-    return TRUE;
+    printf(" string1:  %s\n", args[ARG_STRING1].str);
+    printf(" string2:  %s\n", args[ARG_STRING2].str);
+    printf("boolean1:  %s\n", args[ARG_BOOLEAN1].bln ? "TRUE" : "FALSE");
+    printf("boolean2:  %s\n", args[ARG_BOOLEAN2].bln ? "TRUE" : "FALSE");
+    printf("  uint32:  %u\n", args[ARG_UINT321].u32);
+    printf("   int32:  %d\n", args[ARG_INT321].i32);
+    printf("  double:  %f\n", args[ARG_DOUBLE1].dbl);
+    printf("init fail: %s\n", args[ARG_FAILINIT].bln ? "TRUE" : "FALSE");
+    printf("exit fail: %s\n", args[ARG_FAILEXIT].bln ? "TRUE" : "FALSE");
+    
+    return !args[ARG_FAILINIT].bln;
 }
 
 
@@ -58,20 +39,28 @@ static void test_exit(mrp_plugin_t *plugin)
 {
     mrp_log_info("%s() called for test instance '%s'...", __FUNCTION__,
                 plugin->instance);
-}
 
+    /*return !args[ARG_FAILINIT].bln;*/
+}
 
-#define TEST_HELP "Just a load/unload test."
 
+#define TEST_DESCRIPTION "A primitive plugin just to test the plugin infra."
+#define TEST_HELP        "Just a load/unload test."
+#define TEST_VERSION     MRP_VERSION_INT(0, 0, 1)
+#define TEST_AUTHORS     "D. Duck <donald.duck@ducksburg.org>"
 
 static mrp_plugin_arg_t args[] = {
-    MRP_PLUGIN_ARGIDX(STRING1 , STRING, "string1" , "default string1"),
-    MRP_PLUGIN_ARGIDX(STRING2 , STRING, "string2" , "default string2"),
-    MRP_PLUGIN_ARGIDX(BOOLEAN1, BOOL  , "boolean1", TRUE             ),
-    MRP_PLUGIN_ARGIDX(BOOLEAN2, BOOL  , "boolean2", FALSE            ),
-    MRP_PLUGIN_ARGIDX(UINT321 , UINT32, "uint32"  , 3141             ),
-    MRP_PLUGIN_ARGIDX(INT321  , INT32 , "int32"   ,-3141             ),
-    MRP_PLUGIN_ARGIDX(DOUBLE1 , DOUBLE, "double"  ,-3.141            ),
+    MRP_PLUGIN_ARGIDX(ARG_STRING1 , STRING, "string1" , "default string1"),
+    MRP_PLUGIN_ARGIDX(ARG_STRING2 , STRING, "string2" , "default string2"),
+    MRP_PLUGIN_ARGIDX(ARG_BOOLEAN1, BOOL  , "boolean1", TRUE             ),
+    MRP_PLUGIN_ARGIDX(ARG_BOOLEAN2, BOOL  , "boolean2", FALSE            ),
+    MRP_PLUGIN_ARGIDX(ARG_UINT321 , UINT32, "uint32"  , 3141             ),
+    MRP_PLUGIN_ARGIDX(ARG_INT321  , INT32 , "int32"   , -3141            ),
+    MRP_PLUGIN_ARGIDX(ARG_DOUBLE1 , DOUBLE, "double"  , -3.141           ),
+    MRP_PLUGIN_ARGIDX(ARG_FAILINIT, BOOL  , "failinit", FALSE            ),
+    MRP_PLUGIN_ARGIDX(ARG_FAILEXIT, BOOL  , "failexit", FALSE            ),
 };
 
-MURPHY_REGISTER_PLUGIN("test", TEST_HELP, test_init, test_exit, args);
+MURPHY_REGISTER_PLUGIN("test",
+                      TEST_VERSION, TEST_DESCRIPTION, TEST_AUTHORS, TEST_HELP,
+                      MRP_MULTIPLE, test_init, test_exit, args);