From: Krisztian Litkey Date: Fri, 13 Apr 2012 13:17:09 +0000 (+0300) Subject: plugins: add some of the missing functionality (plugin metadata, checks) X-Git-Tag: build/2012-07-04.133153~118 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=32a947f9ee2909bb6761e659c968ca07e353a680;p=profile%2Fivi%2Fmurphy.git plugins: add some of the missing functionality (plugin metadata, checks) Added plugin and API versioning, singletons, author et al metadata, API version check and singletonnes check. Started adding plugin states. --- diff --git a/src/Makefile.am b/src/Makefile.am index e360ad7..1d6179c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -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) diff --git a/src/common/macros.h b/src/common/macros.h index 332d421..1754a73 100644 --- a/src/common/macros.h +++ b/src/common/macros.h @@ -95,6 +95,22 @@ # 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 diff --git a/src/core/plugin.c b/src/core/plugin.c index 443d4bd..357bca9 100644 --- a/src/core/plugin.c +++ b/src/core/plugin.c @@ -5,6 +5,7 @@ #include #include +#include #include #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); diff --git a/src/core/plugin.h b/src/core/plugin.h index 2418f79..f0633a4 100644 --- a/src/core/plugin.h +++ b/src/core/plugin.h @@ -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 " * * 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__ */ diff --git a/src/daemon/config.c b/src/daemon/config.c index 2b16a09..7f25447 100644 --- a/src/daemon/config.c +++ b/src/daemon/config.c @@ -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 : ""); + 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 = ""; + PRNT("%s", ""); + } + + 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); diff --git a/src/daemon/daemon.c b/src/daemon/daemon.c index 2683cc2..6663b81 100644 --- a/src/daemon/daemon.c +++ b/src/daemon/daemon.c @@ -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; diff --git a/src/plugins/plugin-dbus.c b/src/plugins/plugin-dbus.c index c6f7b4f..553ee02 100644 --- a/src/plugins/plugin-dbus.c +++ b/src/plugins/plugin-dbus.c @@ -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 " + +MURPHY_REGISTER_CORE_PLUGIN("dbus", + DBPLG_VERSION, DBPLG_DESCRIPTION, DBPLG_AUTHORS, + DBPLG_HELP, MRP_SINGLETON, + dbus_init, dbus_exit, NULL); diff --git a/src/plugins/plugin-glib.c b/src/plugins/plugin-glib.c index d77d379..fec76a5 100644 --- a/src/plugins/plugin-glib.c +++ b/src/plugins/plugin-glib.c @@ -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 " + +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); diff --git a/src/plugins/plugin-test.c b/src/plugins/plugin-test.c index fa4451a..a7ab344 100644 --- a/src/plugins/plugin-test.c +++ b/src/plugins/plugin-test.c @@ -1,56 +1,37 @@ #include 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 " 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);