Add plugin_ prefix for plugin symbols version_check, init and

cleanup. Deprecate init and cleanup; update PLUGIN_VERSION_CHECK
macro.
Add a debug message and fail to load a plugin if it has no
plugin_version_check() function.
Check that plugin keybinding names have been set in plugin_init(),
otherwise print a debug message and ignore all of them.


git-svn-id: https://geany.svn.sourceforge.net/svnroot/geany/trunk@2616 ea778897-0a13-0410-b9d1-a72fbfd435f5
This commit is contained in:
Nick Treleaven 2008-05-26 17:09:43 +00:00
parent 84bd788bc3
commit df1a8e63a3
5 changed files with 61 additions and 27 deletions

View File

@ -3,6 +3,15 @@
* src/plugins.c:
Move all symbol lookups except plugin_set_info() into plugin_init().
Add debug message for missing init() function in a plugin.
* src/plugindata.h, src/plugins.c, doc/plugin-symbols.c,
doc/plugins.dox:
Add plugin_ prefix for plugin symbols version_check, init and
cleanup. Deprecate init and cleanup; update PLUGIN_VERSION_CHECK
macro.
Add a debug message and fail to load a plugin if it has no
plugin_version_check() function.
Check that plugin keybinding names have been set in plugin_init(),
otherwise print a debug message and ignore all of them.
2008-05-23 Nick Treleaven <nick(dot)treleaven(at)btinternet(dot)com>

View File

@ -35,7 +35,7 @@
*/
/** Use the PLUGIN_VERSION_CHECK() macro instead. Required by Geany. */
gint version_check(gint);
gint plugin_version_check(gint);
/** Use the PLUGIN_SET_INFO() macro to define it. Required by Geany.
* This function is called before the plugin is initialized, so Geany
@ -65,11 +65,11 @@ PluginFields* plugin_fields;
PluginCallback plugin_callbacks[];
/** Most plugins should use the PLUGIN_KEY_GROUP() macro to define it. However,
* its fields are not read until after init() is called for the plugin, so it
* its fields are not read until after plugin_init() is called for the plugin, so it
* is possible to setup a variable number of keybindings, e.g. based on the
* plugin's configuration file settings.
* - The @c name field must not be empty or match Geany's default group name.
* - The @c label field is set by Geany after init() is called to the name of the
* - The @c label field is set by Geany after plugin_init() is called to the name of the
* plugin.
* @note This is a single element array for implementation reasons,
* but you can treat it like a pointer. */
@ -83,9 +83,9 @@ void configure(GtkWidget *parent);
/** Called after loading the plugin.
* @param data The same as #geany_data. */
void init(GeanyData *data);
void plugin_init(GeanyData *data);
/** Called before unloading the plugin. Required for normal plugins - it should undo
* everything done in init() - e.g. destroy menu items, free memory. */
void cleanup();
* everything done in plugin_init() - e.g. destroy menu items, free memory. */
void plugin_cleanup();

View File

@ -189,8 +189,8 @@ PluginCallback plugin_callbacks[] =
* the plugin uses with the used Geany sources. Furthermore, it also checks
* the binary compatiblity of the plugin with Geany.
*
* A few functions are necessary to let Geany work with the plugin, at least init() must
* exist in the plugin. cleanup() should also be used to free allocated memory or destroy
* A few functions are necessary to let Geany work with the plugin, at least plugin_init() must
* exist in the plugin. plugin_cleanup() should also be used to free allocated memory or destroy
* created widgets.
*
* @subsection buildenv Build environment

View File

@ -36,19 +36,19 @@
/* The API version should be incremented whenever any plugin data types below are
* modified or appended to. */
static const gint api_version = 63;
static const gint api_version = 64;
/* The ABI version should be incremented whenever existing fields in the plugin
* data types below have to be changed or reordered. It should stay the same if fields
* are only appended, as this doesn't affect existing fields. */
static const gint abi_version = 33;
static const gint abi_version = 34;
/** Check the plugin can be loaded by Geany.
* This performs runtime checks that try to ensure:
* - Geany ABI data types are compatible with this plugin.
* - Geany sources provide the required API for this plugin. */
#define PLUGIN_VERSION_CHECK(api_required) \
gint version_check(gint abi_ver) \
gint plugin_version_check(gint abi_ver) \
{ \
if (abi_ver != abi_version) \
return -1; \
@ -93,8 +93,8 @@ PluginInfo;
/** Declare and initialise a keybinding group.
* @code KeyBindingGroup plugin_key_group[1]; @endcode
* You must then set the @c plugin_key_group::keys[] entries for the group in init().
* The @c plugin_key_group::label field is set by Geany after @c init()
* You must then set the @c plugin_key_group::keys[] entries for the group in plugin_init().
* The @c plugin_key_group::label field is set by Geany after @c plugin_init()
* is called, to the name of the plugin.
* @param group_name A unique group name (without quotes) to be used in the
* configuration file, such as @c html_chars.
@ -452,6 +452,9 @@ typedef PluginCallback GeanyCallback;
#define PLUGIN_INFO PLUGIN_SET_INFO
#define init plugin_init
#define cleanup plugin_cleanup
#endif /* GEANY_DISABLE_DEPRECATED */
#endif

View File

@ -352,13 +352,19 @@ static gboolean
plugin_check_version(GModule *module)
{
gint (*version_check)(gint) = NULL;
gint result;
g_module_symbol(module, "version_check", (void *) &version_check);
g_module_symbol(module, "plugin_version_check", (void *) &version_check);
if (version_check)
if (! version_check)
{
result = version_check(abi_version);
geany_debug("Plugin \"%s\" has no plugin_version_check() function - ignoring plugin!",
g_module_name(module));
return FALSE;
}
else
{
gint result = version_check(abi_version);
if (result < 0)
{
ui_set_statusbar(TRUE, _("The plugin \"%s\" is not binary compatible with this "
@ -410,12 +416,27 @@ static void add_callbacks(Plugin *plugin, PluginCallback *callbacks)
static void
add_kb_group(Plugin *plugin)
{
guint i;
g_return_if_fail(NZV(plugin->key_group->name));
g_return_if_fail(! g_str_equal(plugin->key_group->name, keybindings_keyfile_group_name));
for (i = 0; i < plugin->key_group->count; i++)
{
KeyBinding *kb = &plugin->key_group->keys[i];
if (!NZV(kb->name))
{
geany_debug("Plugin \"%s\" has not set a name for keybinding %d"
" - ignoring all keybindings!",
plugin->info.name, i);
plugin->key_group->count = 0;
break;
}
}
if (plugin->key_group->count == 0)
{
plugin->key_group = NULL; /* Ignore the group */
plugin->key_group = NULL; /* Ignore the group (maybe the plugin has optional KB) */
return;
}
@ -434,7 +455,7 @@ plugin_init(Plugin *plugin)
GeanyData **p_geany_data;
GeanyFunctions **p_geany_functions;
/* set these symbols before init() is called */
/* set these symbols before plugin_init() is called */
g_module_symbol(plugin->module, "plugin_info", (void *) &p_info);
if (p_info)
*p_info = &plugin->info;
@ -449,23 +470,23 @@ plugin_init(Plugin *plugin)
*plugin_fields = &plugin->fields;
/* start the plugin */
g_module_symbol(plugin->module, "init", (void *) &plugin->init);
g_module_symbol(plugin->module, "plugin_init", (void *) &plugin->init);
if (plugin->init != NULL)
plugin->init(&geany_data);
else
geany_debug("Plugin '%s' has no init() function!", plugin->info.name);
geany_debug("Plugin '%s' has no plugin_init() function!", plugin->info.name);
/* store some function pointers for later use */
g_module_symbol(plugin->module, "configure", (void *) &plugin->configure);
g_module_symbol(plugin->module, "cleanup", (void *) &plugin->cleanup);
g_module_symbol(plugin->module, "plugin_cleanup", (void *) &plugin->cleanup);
if (plugin->init != NULL && plugin->cleanup == NULL)
{
if (app->debug_mode)
g_warning("Plugin '%s' has no cleanup() function - there may be memory leaks!",
g_warning("Plugin '%s' has no plugin_cleanup() function - there may be memory leaks!",
plugin->info.name);
}
/* now read any plugin-owned data that might have been set in init() */
/* now read any plugin-owned data that might have been set in plugin_init() */
if (plugin->fields.flags & PLUGIN_IS_DOCUMENT_SENSITIVE)
{
@ -491,7 +512,7 @@ plugin_init(Plugin *plugin)
/* Load and init a plugin.
* init_plugin decides whether the plugin's init() function should be called or not. If it is
* init_plugin decides whether the plugin's plugin_init() function should be called or not. If it is
* called, the plugin will be started, if not the plugin will be read only (for the list of
* available plugins in the plugin manager).
* When add_to_list is set, the plugin will be added to the plugin manager's plugin_list. */
@ -548,7 +569,7 @@ plugin_new(const gchar *fname, gboolean init_plugin, gboolean add_to_list)
g_module_symbol(module, "plugin_set_info", (void *) &plugin_set_info);
if (plugin_set_info == NULL)
{
geany_debug("No plugin_set_info() defined for \"%s\"!", fname);
geany_debug("No plugin_set_info() defined for \"%s\" - ignoring plugin!", fname);
if (! g_module_close(module))
g_warning("%s: %s", fname, g_module_error());
@ -561,7 +582,8 @@ plugin_new(const gchar *fname, gboolean init_plugin, gboolean add_to_list)
plugin_set_info(&plugin->info);
if (!NZV(plugin->info.name))
{
geany_debug("No plugin name set in plugin_set_info() for \"%s\"!", fname);
geany_debug("No plugin name set in plugin_set_info() for \"%s\" - ignoring plugin!",
fname);
if (! g_module_close(module))
g_warning("%s: %s", fname, g_module_error());