diff --git a/.gitignore b/.gitignore index fa31ebb..423bd8e 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,4 @@ zathura.pc *.gcda gcov/ *.swp +version.h diff --git a/Makefile b/Makefile index 105a003..64fbd67 100644 --- a/Makefile +++ b/Makefile @@ -28,6 +28,12 @@ options: @echo "DFLAGS = ${DFLAGS}" @echo "CC = ${CC}" +version.h: version.h.in config.mk + $(QUIET)sed 's/ZVMAJOR/${ZATHURA_VERSION_MAJOR}/' < version.h.in | \ + sed 's/ZVMINOR/${ZATHURA_VERSION_MINOR}/' | \ + sed 's/ZVREV/${ZATHURA_VERSION_REV}/' | \ + sed 's/ZVAPI/${ZATHURA_API_VERSION}/' > version.h + %.o: %.c $(ECHO) CC $< @mkdir -p .depend @@ -41,8 +47,8 @@ options: # force recompilation of database.o if DATABASE has changed database.o: database-${DATABASE}.o -${OBJECTS}: config.mk -${DOBJECTS}: config.mk +${OBJECTS}: config.mk version.h +${DOBJECTS}: config.mk version.h ${PROJECT}: ${OBJECTS} $(ECHO) CC -o $@ @@ -50,7 +56,8 @@ ${PROJECT}: ${OBJECTS} clean: $(QUIET)rm -rf ${PROJECT} ${OBJECTS} ${PROJECT}-${VERSION}.tar.gz \ - ${DOBJECTS} ${PROJECT}-debug .depend ${PROJECT}.pc doc *gcda *gcno $(PROJECT).info gcov + ${DOBJECTS} ${PROJECT}-debug .depend ${PROJECT}.pc doc version.h \ + *gcda *gcno $(PROJECT).info gcov $(QUIET)make -C tests clean ${PROJECT}-debug: ${DOBJECTS} @@ -62,6 +69,7 @@ debug: ${PROJECT}-debug ${PROJECT}.pc: ${PROJECT}.pc.in config.mk $(QUIET)echo project=${PROJECT} > ${PROJECT}.pc $(QUIET)echo version=${VERSION} >> ${PROJECT}.pc + $(QUIET)echo apiversion=${ZATHHRA_API_VERSION} >> ${PROJECT}.pc $(QUIET)echo includedir=${PREFIX}/include >> ${PROJECT}.pc $(QUIET)echo plugindir=${PLUGINDIR} >> ${PROJECT}.pc $(QUIET)echo GTK_VERSION=${ZATHURA_GTK_VERSION} >> ${PROJECT}.pc @@ -82,7 +90,7 @@ dist: clean $(QUIET)mkdir -p ${PROJECT}-${VERSION}/tests $(QUIET)cp LICENSE Makefile config.mk common.mk README AUTHORS Doxyfile \ ${PROJECT}.1.rst ${PROJECT}rc.5.rst ${SOURCE} ${HEADER} ${PROJECT}.pc.in \ - ${PROJECT}.desktop \ + ${PROJECT}.desktop version.h.in \ ${PROJECT}-${VERSION} $(QUIET)cp tests/Makefile tests/config.mk tests/*.c \ ${PROJECT}-${VERSION}/tests diff --git a/config.mk b/config.mk index 2a9792e..ebd4f8f 100644 --- a/config.mk +++ b/config.mk @@ -1,7 +1,11 @@ # See LICENSE file for license and copyright information # zathura make config -VERSION = 0.1.0 +ZATHURA_VERSION_MAJOR = 0 +ZATHURA_VERSION_MINOR = 1 +ZATHURA_VERSION_REV = 0 +ZATHURA_API_VERSION = 1 +VERSION = ${ZATHURA_VERSION_MAJOR}.${ZATHURA_VERSION_MINOR}.${ZATHURA_VERSION_REV} # the GTK version to use ZATHURA_GTK_VERSION ?= 2 @@ -29,7 +33,7 @@ SQLITE_LIB ?= $(shell pkg-config --libs sqlite3) DL_LIB ?= -ldl INCS = ${GIRARA_INC} ${GTK_INC} -LIBS = ${GIRARA_LIB} ${GTK_LIB} $(DL_LIB) -lpthread -lm +LIBS = ${GIRARA_LIB} ${GTK_LIB} ${DL_LIB} -lpthread -lm # flags CFLAGS += -std=c99 -pedantic -Wall -Wno-format-zero-length -Wextra $(INCS) diff --git a/document.c b/document.c index fbaef7c..6dfb8b2 100644 --- a/document.c +++ b/document.c @@ -87,7 +87,21 @@ zathura_document_plugins_load(zathura_t* zathura) continue; } - /* resolve symbol */ + /* resolve symbol and check API version*/ + zathura_plugin_api_version_t api_version; + *(void**)(&api_version) = dlsym(handle, PLUGIN_API_VERSION_FUNCTION); + if (api_version != NULL) { + if (api_version() != ZATHURA_API_VERSION) { + girara_error("plugin %s has been built againt zathura with a different API version (plugin: %d, zathura: %d)", + path, api_version(), ZATHURA_API_VERSION); + g_free(path); + dlclose(handle); + continue; + } + } else { + girara_warning("could not find '%s' function in plugin %s ... loading anyway", PLUGIN_API_VERSION_FUNCTION, path); + } + zathura_plugin_register_service_t register_plugin; *(void**)(®ister_plugin) = dlsym(handle, PLUGIN_REGISTER_FUNCTION); diff --git a/document.h b/document.h index d17fa42..1494b34 100644 --- a/document.h +++ b/document.h @@ -9,8 +9,38 @@ #include #include "zathura.h" +#include "version.h" #define PLUGIN_REGISTER_FUNCTION "plugin_register" +#define PLUGIN_API_VERSION_FUNCTION "plugin_api_version" + +/** + * Register a plugin. + * + * @param plugin_name the name of the plugin + * @param major the plugin's major version + * @param minor the plugin's minor version + * @param rev the plugin's revision + * @param plugin_open_function the plugin's open function + * @param mimetypes a char array of mime types supported by the plugin + */ +#define PLUGIN_REGISTER(plugin_name, major, minor, rev, plugin_open_function, mimetypes) \ + unsigned int plugin_version_major() { return major; } \ + unsigned int plugin_version_minor() { return minor; } \ + unsigned int plugin_version_revision() { return rev; } \ + unsigned int plugin_api_version() { return ZATHURA_API_VERSION; } \ + \ + void plugin_register(zathura_document_plugin_t* plugin) \ + { \ + if (plugin == NULL) { \ + return; \ + } \ + plugin->open_function = (plugin_open_function); \ + static const char* mime_types[] = mimetypes; \ + for (size_t s = 0; s != sizeof(mime_types) / sizeof(const char*); ++s) { \ + girara_list_append(plugin->content_types, g_content_type_from_mime_type(mime_types[s])); \ + } \ + } \ /** * Error types for plugins @@ -80,6 +110,13 @@ typedef struct zathura_password_dialog_info_s */ typedef void (*zathura_plugin_register_service_t)(zathura_document_plugin_t*); +/** + * Function prototype that is called to get the plugin's API version. + * + * @return plugin's API version + */ +typedef unsigned int (*zathura_plugin_api_version_t)(); + /** * Image buffer */ diff --git a/version.h.in b/version.h.in new file mode 100644 index 0000000..891eb47 --- /dev/null +++ b/version.h.in @@ -0,0 +1,12 @@ +/* See LICENSE file for license and copyright information */ + +#ifndef ZATHURA_VERSION_H +#define ZATHURA_VERSION_H + +#define ZATHURA_VERSION_MAJOR ZVMAJOR +#define ZATHUAR_VERSION_MINOR ZVMINOR +#define ZATHURA_VERSION_REV ZVREV +#define ZATHURA_VERSION "ZVMAJOR.ZVMINOR.ZVREV" +#define ZATHURA_API_VERSION ZVAPI + +#endif