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)
# 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
#include <sys/types.h>
#include <murphy/common/list.h>
+#include <murphy/common/file-utils.h>
#include <murphy/core/plugin.h>
#define PLUGIN_PREFIX "plugin-"
}
+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)
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);
}
plugin->ctx = ctx;
- plugin->descriptor = handle ? dynamic : builtin;
+ plugin->descriptor = descr;
plugin->refcnt = 1;
plugin->handle = handle;
}
+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;
mrp_free(plugin->args);
}
+ plugin->descriptor->ninstance--;
+
if (plugin->handle != NULL)
dlclose(plugin->handle);
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;
* 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,
* ...
* }
*
- * 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;
* 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) \
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; \
#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
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__ */
" 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);
}
-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
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 }
};
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);
}
-/*
- * a quick-hack plugin test
- */
-
-
int main(int argc, char *argv[])
{
mrp_context_t *ctx;
}
-#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);
}
-#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);
#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;
}
{
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);