Replace plugin register function call with const struct

This gets rid of a lot of back and forth between zathura and the plugins.

Signed-off-by: Sebastian Ramacher <sebastian+dev@ramacher.at>
This commit is contained in:
Sebastian Ramacher 2017-01-26 22:23:12 +01:00
parent b64b7132a2
commit be7b4c1ad1
4 changed files with 63 additions and 143 deletions

View File

@ -10,7 +10,7 @@ ZATHURA_VERSION_REV = 7
# If the API changes, the API version and the ABI version have to be bumped. # If the API changes, the API version and the ABI version have to be bumped.
ZATHURA_API_VERSION = 2 ZATHURA_API_VERSION = 2
# If the ABI breaks for any reason, this has to be bumped. # If the ABI breaks for any reason, this has to be bumped.
ZATHURA_ABI_VERSION = 2 ZATHURA_ABI_VERSION = 3
VERSION = ${ZATHURA_VERSION_MAJOR}.${ZATHURA_VERSION_MINOR}.${ZATHURA_VERSION_REV} VERSION = ${ZATHURA_VERSION_MAJOR}.${ZATHURA_VERSION_MINOR}.${ZATHURA_VERSION_REV}
# version checks # version checks

View File

@ -9,7 +9,6 @@
#include "version.h" #include "version.h"
typedef struct zathura_plugin_functions_s zathura_plugin_functions_t; typedef struct zathura_plugin_functions_s zathura_plugin_functions_t;
/** /**
* Functions register function * Functions register function
* *
@ -17,31 +16,26 @@ typedef struct zathura_plugin_functions_s zathura_plugin_functions_t;
*/ */
typedef void (*zathura_plugin_register_function_t)(zathura_plugin_functions_t* functions); typedef void (*zathura_plugin_register_function_t)(zathura_plugin_functions_t* functions);
/** typedef struct zathura_plugin_version_s {
* Sets the functions register function of the plugin unsigned int major; /**< Major */
* unsigned int minor; /**< Minor */
* @param plugin The plugin unsigned int rev; /**< Revision */
* @param register_function The register function that registers the document } zathura_plugin_version_t;
* functions
*/
void zathura_plugin_set_register_functions_function(zathura_plugin_t* plugin,
zathura_plugin_register_function_t register_function);
/** typedef struct zathura_plugin_definition_s
* Sets the name of the plugin {
* const char* name;
* @param plugin The plugin const zathura_plugin_version_t version;
* @param name The name of the plugin zathura_plugin_register_function_t register_function;
*/ const size_t mime_types_size;
void zathura_plugin_set_name(zathura_plugin_t* plugin, const char* name); const char** mime_types;
} zathura_plugin_definition_t;
/** #define JOIN(x, y) JOIN2(x, y)
* Sets the functions register function of the plugin #define JOIN2(x, y) x ## _ ## y
*
* @param plugin The plugin #define ZATHURA_PLUGIN_DEFINITION_SYMBOL \
* @param mime_type The mime type that should be added JOIN(zathura_plugin, JOIN(ZATHURA_API_VERSION, ZATHURA_ABI_VERSION))
*/
void zathura_plugin_add_mimetype(zathura_plugin_t* plugin, const char* mime_type);
/** /**
* Register a plugin. * Register a plugin.
@ -54,24 +48,15 @@ void zathura_plugin_add_mimetype(zathura_plugin_t* plugin, const char* mime_type
* @param mimetypes a char array of mime types supported by the plugin * @param mimetypes a char array of mime types supported by the plugin
*/ */
#define ZATHURA_PLUGIN_REGISTER(plugin_name, major, minor, rev, register_functions, mimetypes) \ #define ZATHURA_PLUGIN_REGISTER(plugin_name, major, minor, rev, register_functions, mimetypes) \
unsigned int zathura_plugin_version_major(void) { return major; } \ static const char* zathura_plugin_mime_types[] = mimetypes; \
unsigned int zathura_plugin_version_minor(void) { return minor; } \
unsigned int zathura_plugin_version_revision(void) { return rev; } \
unsigned int zathura_plugin_api_version(void) { return ZATHURA_API_VERSION; } \
unsigned int zathura_plugin_abi_version(void) { return ZATHURA_ABI_VERSION; } \
\ \
void zathura_plugin_register(zathura_plugin_t* plugin) \ const zathura_plugin_definition_t ZATHURA_PLUGIN_DEFINITION_SYMBOL = { \
{ \ .name = plugin_name, \
if (plugin == NULL) { \ .version = { major, minor, rev }, \
return; \ .register_function = register_functions, \
} \ .mime_types_size = sizeof(zathura_plugin_mime_types) / sizeof(zathura_plugin_mime_types[0]), \
zathura_plugin_set_register_functions_function(plugin, register_functions); \ .mime_types = zathura_plugin_mime_types \
zathura_plugin_set_name(plugin, plugin_name); \ }; \
static const char* mime_types[] = mimetypes; \
for (size_t s = 0; s != sizeof(mime_types) / sizeof(const char*); ++s) { \
zathura_plugin_add_mimetype(plugin, mime_types[s]); \
} \
} \
#define ZATHURA_PLUGIN_MIMETYPES(...) __VA_ARGS__ #define ZATHURA_PLUGIN_MIMETYPES(...) __VA_ARGS__

View File

@ -16,12 +16,10 @@
*/ */
struct zathura_plugin_s { struct zathura_plugin_s {
girara_list_t* content_types; /**< List of supported content types */ girara_list_t* content_types; /**< List of supported content types */
zathura_plugin_register_function_t register_function; /**< Document open function */
zathura_plugin_functions_t functions; /**< Document functions */ zathura_plugin_functions_t functions; /**< Document functions */
GModule* handle; /**< DLL handle */ GModule* handle; /**< DLL handle */
char* name; /**< Name of the plugin */
char* path; /**< Path to the plugin */ char* path; /**< Path to the plugin */
zathura_plugin_version_t version; /**< Version information */ const zathura_plugin_definition_t* definition;
}; };
/** /**
@ -41,11 +39,7 @@ struct zathura_plugin_manager_s {
girara_list_t* type_plugin_mapping; /**< List of type -> plugin mappings */ girara_list_t* type_plugin_mapping; /**< List of type -> plugin mappings */
}; };
typedef void (*zathura_plugin_register_service_t)(zathura_plugin_t*); static void zathura_plugin_add_mimetype(zathura_plugin_t* plugin, const char* mime_type);
typedef unsigned int (*zathura_plugin_api_version_t)(void);
typedef unsigned int (*zathura_plugin_abi_version_t)(void);
typedef unsigned int (*zathura_plugin_version_function_t)(void);
static bool register_plugin(zathura_plugin_manager_t* plugin_manager, zathura_plugin_t* plugin); static bool register_plugin(zathura_plugin_manager_t* plugin_manager, zathura_plugin_t* plugin);
static bool plugin_mapping_new(zathura_plugin_manager_t* plugin_manager, const gchar* type, zathura_plugin_t* plugin); static bool plugin_mapping_new(zathura_plugin_manager_t* plugin_manager, const gchar* type, zathura_plugin_t* plugin);
static void zathura_plugin_free(zathura_plugin_t* plugin); static void zathura_plugin_free(zathura_plugin_t* plugin);
@ -141,45 +135,38 @@ zathura_plugin_manager_load(zathura_plugin_manager_t* plugin_manager)
} }
/* resolve symbols and check API and ABI version*/ /* resolve symbols and check API and ABI version*/
zathura_plugin_api_version_t api_version = NULL; const zathura_plugin_definition_t* plugin_definition = NULL;
if (g_module_symbol(handle, PLUGIN_API_VERSION_FUNCTION, (gpointer*) &api_version) == FALSE || if (g_module_symbol(handle, G_STRINGIFY(ZATHURA_PLUGIN_DEFINITION_SYMBOL), (void**) &plugin_definition) == FALSE ||
api_version == NULL) { plugin_definition == NULL) {
girara_error("could not find '%s' function in plugin %s", PLUGIN_API_VERSION_FUNCTION, path); girara_error("could not find '%s' in plugin %s - is not a plugin or needs to be rebuilt", G_STRINGIFY(ZATHURA_PLUGIN_DEFINITION_SYMBOL), path);
g_free(path); g_free(path);
g_module_close(handle); g_module_close(handle);
continue; continue;
} }
if (api_version() != ZATHURA_API_VERSION) { /* check name */
girara_error("plugin %s has been built againt zathura with a different API version (plugin: %d, zathura: %d)", if (plugin_definition->name == NULL) {
path, api_version(), ZATHURA_API_VERSION); girara_error("plugin has no name");
g_free(path); g_free(path);
g_free(plugin);
g_module_close(handle); g_module_close(handle);
continue; continue;
} }
zathura_plugin_abi_version_t abi_version = NULL; /* check mime type */
if (g_module_symbol(handle, PLUGIN_ABI_VERSION_FUNCTION, (gpointer*) &abi_version) == FALSE || if (plugin_definition->mime_types == NULL || plugin_definition->mime_types_size == 0) {
abi_version == NULL) { girara_error("plugin has no mime_types");
girara_error("could not find '%s' function in plugin %s", PLUGIN_ABI_VERSION_FUNCTION, path);
g_free(path); g_free(path);
g_free(plugin);
g_module_close(handle); g_module_close(handle);
continue; continue;
} }
if (abi_version() != ZATHURA_ABI_VERSION) { /* check register functions */
girara_error("plugin %s has been built againt zathura with a different ABI version (plugin: %d, zathura: %d)", if (plugin_definition->register_function == NULL) {
path, abi_version(), ZATHURA_ABI_VERSION); girara_error("plugin has no document functions register function");
g_free(path);
g_module_close(handle);
continue;
}
zathura_plugin_register_service_t register_service = NULL;
if (g_module_symbol(handle, PLUGIN_REGISTER_FUNCTION, (gpointer*) &register_service) == FALSE ||
register_service == NULL) {
girara_error("could not find '%s' function in plugin %s", PLUGIN_REGISTER_FUNCTION, path);
g_free(path); g_free(path);
g_free(plugin);
g_module_close(handle); g_module_close(handle);
continue; continue;
} }
@ -192,42 +179,27 @@ zathura_plugin_manager_load(zathura_plugin_manager_t* plugin_manager)
continue; continue;
} }
plugin->definition = plugin_definition;
plugin->content_types = girara_list_new2(g_free); plugin->content_types = girara_list_new2(g_free);
plugin->handle = handle; plugin->handle = handle;
register_service(plugin);
/* register functions */
if (plugin->register_function == NULL) {
girara_error("plugin has no document functions register function");
g_free(path);
g_free(plugin);
g_module_close(handle);
continue;
}
plugin->register_function(&(plugin->functions));
plugin->path = path; plugin->path = path;
// register mime types
for (size_t s = 0; s != plugin_definition->mime_types_size; ++s) {
zathura_plugin_add_mimetype(plugin, plugin_definition->mime_types[s]);
}
// register functions
plugin->definition->register_function(&(plugin->functions));
bool ret = register_plugin(plugin_manager, plugin); bool ret = register_plugin(plugin_manager, plugin);
if (ret == false) { if (ret == false) {
girara_error("could not register plugin %s", path); girara_error("could not register plugin %s", path);
zathura_plugin_free(plugin); zathura_plugin_free(plugin);
} else { } else {
girara_debug("successfully loaded plugin %s", path); girara_debug("successfully loaded plugin %s", path);
girara_debug("plugin '%s': version %u.%u.%u", path,
zathura_plugin_version_function_t plugin_major = NULL, plugin_minor = NULL, plugin_rev = NULL; plugin_definition->version.major, plugin_definition->version.minor,
g_module_symbol(handle, PLUGIN_VERSION_MAJOR_FUNCTION, (gpointer*) &plugin_major); plugin_definition->version.rev);
g_module_symbol(handle, PLUGIN_VERSION_MINOR_FUNCTION, (gpointer*) &plugin_minor);
g_module_symbol(handle, PLUGIN_VERSION_REVISION_FUNCTION, (gpointer*) &plugin_rev);
if (plugin_major != NULL && plugin_minor != NULL && plugin_rev != NULL) {
plugin->version.major = plugin_major();
plugin->version.minor = plugin_minor();
plugin->version.rev = plugin_rev();
girara_debug("plugin '%s': version %u.%u.%u", path,
plugin->version.major, plugin->version.minor,
plugin->version.rev);
}
} }
} }
g_dir_close(dir); g_dir_close(dir);
@ -289,7 +261,6 @@ register_plugin(zathura_plugin_manager_t* plugin_manager, zathura_plugin_t* plug
{ {
if (plugin == NULL if (plugin == NULL
|| plugin->content_types == NULL || plugin->content_types == NULL
|| plugin->register_function == NULL
|| plugin_manager == NULL || plugin_manager == NULL
|| plugin_manager->plugins == NULL) { || plugin_manager->plugins == NULL) {
girara_error("plugin: could not register\n"); girara_error("plugin: could not register\n");
@ -355,11 +326,7 @@ zathura_plugin_free(zathura_plugin_t* plugin)
if (plugin == NULL) { if (plugin == NULL) {
return; return;
} }
if (plugin->name != NULL) {
g_free(plugin->name);
}
if (plugin->path != NULL) { if (plugin->path != NULL) {
g_free(plugin->path); g_free(plugin->path);
} }
@ -370,18 +337,7 @@ zathura_plugin_free(zathura_plugin_t* plugin)
g_free(plugin); g_free(plugin);
} }
/* plugin-api.h */ static void
void
zathura_plugin_set_register_functions_function(zathura_plugin_t* plugin, zathura_plugin_register_function_t register_function)
{
if (plugin == NULL || register_function == NULL) {
return;
}
plugin->register_function = register_function;
}
void
zathura_plugin_add_mimetype(zathura_plugin_t* plugin, const char* mime_type) zathura_plugin_add_mimetype(zathura_plugin_t* plugin, const char* mime_type)
{ {
if (plugin == NULL || mime_type == NULL) { if (plugin == NULL || mime_type == NULL) {
@ -401,19 +357,11 @@ zathura_plugin_get_functions(zathura_plugin_t* plugin)
} }
} }
void
zathura_plugin_set_name(zathura_plugin_t* plugin, const char* name)
{
if (plugin != NULL && name != NULL) {
plugin->name = g_strdup(name);
}
}
const char* const char*
zathura_plugin_get_name(zathura_plugin_t* plugin) zathura_plugin_get_name(zathura_plugin_t* plugin)
{ {
if (plugin != NULL) { if (plugin != NULL && plugin->definition != NULL) {
return plugin->name; return plugin->definition->name;
} else { } else {
return NULL; return NULL;
} }
@ -432,8 +380,8 @@ zathura_plugin_get_path(zathura_plugin_t* plugin)
zathura_plugin_version_t zathura_plugin_version_t
zathura_plugin_get_version(zathura_plugin_t* plugin) zathura_plugin_get_version(zathura_plugin_t* plugin)
{ {
if (plugin != NULL) { if (plugin != NULL && plugin->definition != NULL) {
return plugin->version; return plugin->definition->version;
} }
zathura_plugin_version_t version = { 0, 0, 0 }; zathura_plugin_version_t version = { 0, 0, 0 };

View File

@ -11,19 +11,6 @@
#include "version.h" #include "version.h"
#include "zathura.h" #include "zathura.h"
#define PLUGIN_REGISTER_FUNCTION "zathura_plugin_register"
#define PLUGIN_API_VERSION_FUNCTION "zathura_plugin_api_version"
#define PLUGIN_ABI_VERSION_FUNCTION "zathura_plugin_abi_version"
#define PLUGIN_VERSION_MAJOR_FUNCTION "zathura_plugin_version_major"
#define PLUGIN_VERSION_MINOR_FUNCTION "zathura_plugin_version_minor"
#define PLUGIN_VERSION_REVISION_FUNCTION "zathura_plugin_version_revision"
typedef struct zathura_plugin_version_s {
unsigned int major; /**< Major */
unsigned int minor; /**< Minor */
unsigned int rev; /**< Revision */
} zathura_plugin_version_t;
/** /**
* Creates a new instance of the plugin manager * Creates a new instance of the plugin manager
* *
@ -84,7 +71,7 @@ zathura_plugin_functions_t* zathura_plugin_get_functions(zathura_plugin_t* plugi
* @param plugin The plugin * @param plugin The plugin
* @return The name of the plugin or NULL * @return The name of the plugin or NULL
*/ */
char* zathura_plugin_get_name(zathura_plugin_t* plugin); const char* zathura_plugin_get_name(zathura_plugin_t* plugin);
/** /**
* Returns the path to the plugin * Returns the path to the plugin